diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md index d56da9d5d025a..de823dc300d15 100644 --- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/library_tracking_issue.md @@ -51,6 +51,7 @@ If the feature is changed later, please add those PRs here as well. (Remember to update the `S-tracking-*` label when checking boxes.) +- [ ] ACP: rust-lang/libs-team#... - [ ] Implementation: #... - [ ] Final comment period (FCP)[^1] - [ ] Stabilization PR diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f539b64d8c829..d440b296d2753 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -246,6 +246,8 @@ jobs: run: src/ci/scripts/create-doc-artifacts.sh - name: print disk usage + # We also want to know the disk usage when the job fails. + if: always() run: | echo "disk usage:" df -h diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index 12ff4be4f1e8c..56978bcbed8e5 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -6,7 +6,7 @@ name: Post merge analysis on: push: branches: - - master + - main jobs: analysis: diff --git a/.mailmap b/.mailmap index 6e3eed1226e0c..fc8e83d6493cd 100644 --- a/.mailmap +++ b/.mailmap @@ -427,6 +427,7 @@ Marcell Pardavi Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Marcus Klaas de Vries Margaret Meyerhofer +Marijn Schouten Mark Mansi Mark Mansi Mark Rousskov @@ -609,6 +610,7 @@ Shohei Wada Shotaro Yamada Shotaro Yamada Shyam Sundar B +Sidney Cammeresi Simon Barber-Dueck Simon BD Simon Sapin Simonas Kazlauskas Simonas Kazlauskas diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aadc7c48ea839..2b5699dcd098d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,8 +31,8 @@ bootstrapping, the compiler architecture, source code representation, and more. ## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) -There are many ways you can get help when you're stuck. Rust has many platforms for this: -[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on +There are many ways you can get help when you're stuck. Rust has two platforms for this: +[internals] and [rust-zulip]. It is recommended to ask for help on the [rust-zulip], but any of these platforms are great ways to seek help and even find a mentor! You can learn more about asking questions and getting help in the [Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide]. @@ -47,5 +47,4 @@ refer to [this section][contributing-bug-reports] and [open an issue][issue temp [contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports [issue template]: https://github.com/rust-lang/rust/issues/new/choose [internals]: https://internals.rust-lang.org -[rust-discord]: http://discord.gg/rust-lang [rust-zulip]: https://rust-lang.zulipchat.com diff --git a/Cargo.lock b/Cargo.lock index 4677d34d2a630..2c290b392d591 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,9 +95,9 @@ dependencies = [ [[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 = "anstyle-lossy" @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "anstyle-svg" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc03a770ef506fe1396c0e476120ac0e6523cf14b74218dd5f18cd6833326fa9" +checksum = "26b9ec8c976eada1b0f9747a3d7cc4eae3bef10613e443746e7487f26c872fde" dependencies = [ "anstyle", "anstyle-lossy", @@ -216,7 +216,7 @@ dependencies = [ "memchr", "serde", "serde_derive", - "winnow 0.7.12", + "winnow 0.7.13", ] [[package]] @@ -334,8 +334,10 @@ dependencies = [ "anyhow", "build_helper", "curl", + "hex", "indexmap", "serde", + "sha2", "toml 0.8.23", ] @@ -493,7 +495,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -568,7 +570,7 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clippy" -version = "0.1.91" +version = "0.1.92" dependencies = [ "anstream", "askama", @@ -588,14 +590,14 @@ dependencies = [ "serde_json", "tempfile", "termize", - "toml 0.7.8", + "toml 0.9.7", "ui_test", "walkdir", ] [[package]] name = "clippy_config" -version = "0.1.91" +version = "0.1.92" dependencies = [ "clippy_utils", "itertools", @@ -618,7 +620,7 @@ dependencies = [ [[package]] name = "clippy_lints" -version = "0.1.91" +version = "0.1.92" dependencies = [ "arrayvec", "cargo_metadata 0.18.1", @@ -630,7 +632,7 @@ dependencies = [ "regex-syntax 0.8.5", "semver", "serde", - "toml 0.7.8", + "toml 0.9.7", "unicode-normalization", "unicode-script", "url", @@ -643,13 +645,14 @@ version = "0.0.1" dependencies = [ "clippy_config", "clippy_utils", + "itertools", "regex", "rustc-semver", ] [[package]] name = "clippy_utils" -version = "0.1.91" +version = "0.1.92" dependencies = [ "arrayvec", "itertools", @@ -674,7 +677,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width 0.1.14", + "unicode-width 0.2.1", ] [[package]] @@ -684,6 +687,7 @@ dependencies = [ "anyhow", "serde", "serde_json", + "similar", "spdx-rs", ] @@ -937,23 +941,24 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.168" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa144b12f11741f0dab5b4182896afad46faa0598b6a061f7b9d17a21837ba7" +checksum = "2f81de88da10862f22b5b3a60f18f6f42bbe7cb8faa24845dd7b1e4e22190e77" dependencies = [ "cc", + "cxx-build", "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", - "foldhash", + "foldhash 0.2.0", "link-cplusplus", ] [[package]] name = "cxx-build" -version = "1.0.168" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12d3cbb84fb003242941c231b45ca9417e786e66e94baa39584bd99df3a270b6" +checksum = "5edd58bf75c3fdfc80d79806403af626570662f7b6cc782a7fabe156166bd6d6" dependencies = [ "cc", "codespan-reporting", @@ -966,9 +971,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.168" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fa36b7b249d43f67a3f54bd65788e35e7afe64bbc671396387a48b3e8aaea94" +checksum = "fd46bf2b541a4e0c2d5abba76607379ee05d68e714868e3cb406dc8d591ce2d2" dependencies = [ "clap", "codespan-reporting", @@ -980,15 +985,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.168" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77707c70f6563edc5429618ca34a07241b75ebab35bd01d46697c75d58f8ddfe" +checksum = "2c79b68f6a3a8f809d39b38ae8af61305a6113819b19b262643b9c21353b92d9" [[package]] name = "cxxbridge-macro" -version = "1.0.168" +version = "1.0.185" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede6c0fb7e318f0a11799b86ee29dcf17b9be2960bd379a6c38e1a96a6010fff" +checksum = "862b7fdb048ff9ef0779a0d0a03affd09746c4c875543746b640756be9cff2af" dependencies = [ "indexmap", "proc-macro2", @@ -1051,7 +1056,7 @@ dependencies = [ [[package]] name = "declare_clippy_lint" -version = "0.1.91" +version = "0.1.92" [[package]] name = "derive-where" @@ -1160,7 +1165,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1331,6 +1336,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" + [[package]] name = "flate2" version = "1.1.2" @@ -1388,6 +1399,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1567,7 +1584,7 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", "serde", ] @@ -1851,13 +1868,14 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.10.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", "hashbrown", "serde", + "serde_core", ] [[package]] @@ -2089,9 +2107,9 @@ dependencies = [ [[package]] name = "libffi" -version = "4.1.1" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7681c6fab541f799a829e44a445a0666cf8d8a6cfebf89419e6aed52c604e87" +checksum = "0444124f3ffd67e1b0b0c661a7f81a278a135eb54aaad4078e79fbc8be50c8a5" dependencies = [ "libc", "libffi-sys", @@ -2099,9 +2117,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "3.3.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0d828d367b4450ed08e7d510dc46636cd660055f50d67ac943bfe788767c29" +checksum = "3d722da8817ea580d0669da6babe2262d7b86a1af1103da24102b8bb9c101ce7" dependencies = [ "cc", ] @@ -2160,9 +2178,9 @@ 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", ] @@ -2357,7 +2375,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "536bfad37a309d62069485248eeaba1e8d9853aaf951caaeaed0585a95346f08" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -3549,7 +3567,7 @@ dependencies = [ "ar_archive_writer", "bitflags", "bstr", - "cc", + "find-msvc-tools", "itertools", "libc", "object 0.37.3", @@ -3739,6 +3757,8 @@ name = "rustc_errors" version = "0.0.0" dependencies = [ "annotate-snippets 0.11.5", + "anstream", + "anstyle", "derive_setters", "rustc_abi", "rustc_ast", @@ -3755,7 +3775,6 @@ dependencies = [ "rustc_span", "serde", "serde_json", - "termcolor", "termize", "tracing", "windows 0.61.3", @@ -4102,6 +4121,7 @@ name = "rustc_log" version = "0.0.0" dependencies = [ "tracing", + "tracing-core", "tracing-subscriber", "tracing-tree", ] @@ -4235,6 +4255,7 @@ name = "rustc_mir_transform" version = "0.0.0" dependencies = [ "either", + "hashbrown", "itertools", "rustc_abi", "rustc_arena", @@ -4307,7 +4328,6 @@ dependencies = [ "rustc_macros", "rustc_session", "rustc_span", - "termcolor", "thin-vec", "tracing", "unicode-normalization", @@ -4752,7 +4772,7 @@ dependencies = [ name = "rustc_windows_rc" version = "0.0.0" dependencies = [ - "cc", + "find-msvc-tools", ] [[package]] @@ -4787,7 +4807,6 @@ name = "rustdoc-gui-test" version = "0.1.0" dependencies = [ "build_helper", - "camino", "compiletest", "getopts", "walkdir", @@ -4817,9 +4836,9 @@ dependencies = [ [[package]] name = "rustfix" -version = "0.8.1" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81864b097046da5df3758fdc6e4822bbb70afa06317e8ca45ea1b51cb8c5e5a4" +checksum = "82fa69b198d894d84e23afde8e9ab2af4400b2cba20d6bf2b428a8b01c222c5a" dependencies = [ "serde", "serde_json", @@ -4987,10 +5006,11 @@ dependencies = [ [[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", ] @@ -5015,11 +5035,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", @@ -5068,6 +5097,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" +dependencies = [ + "serde_core", +] + [[package]] name = "sha1" version = "0.10.6" @@ -5225,9 +5263,9 @@ dependencies = [ [[package]] name = "stringdex" -version = "0.0.1-alpha9" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7081029913fd7d591c0112182aba8c98ae886b4f12edb208130496cd17dc3c15" +checksum = "18b3bd4f10d15ef859c40291769f0d85209de6b0f1c30713ff9cdf45ac43ea36" dependencies = [ "stacker", ] @@ -5529,8 +5567,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit 0.19.15", ] @@ -5542,11 +5580,26 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_edit 0.22.27", ] +[[package]] +name = "toml" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned 1.0.2", + "toml_datetime 0.7.2", + "toml_parser", + "toml_writer", + "winnow 0.7.13", +] + [[package]] name = "toml_datetime" version = "0.6.11" @@ -5556,6 +5609,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.19.15" @@ -5564,8 +5626,8 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -5577,10 +5639,19 @@ checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", - "serde_spanned", - "toml_datetime", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", "toml_write", - "winnow 0.7.12", + "winnow 0.7.13", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ + "winnow 0.7.13", ] [[package]] @@ -5589,6 +5660,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "toml_writer" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" + [[package]] name = "tracing" version = "0.1.41" @@ -5983,9 +6060,9 @@ dependencies = [ [[package]] name = "wasi-preview1-component-adapter-provider" -version = "36.0.1" +version = "37.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20689c88791776219f78c2529700d15e6a9bd57a27858c62e9ef8487956b571c" +checksum = "8d0fcd636ad2b29a7c0490799a23ad61d1c8dedfafdb970447fddd0549502b60" [[package]] name = "wasm-bindgen" @@ -6047,9 +6124,9 @@ dependencies = [ [[package]] name = "wasm-component-ld" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c9208f87cac2332fd80dcf36d54e9163d3446e28301e0c6e424984425738984" +checksum = "11f565dfcfd9aabb10d865b608a92ce1f93051aeb56f4c89550ed9cd97d8ce0e" dependencies = [ "anyhow", "clap", @@ -6057,9 +6134,9 @@ dependencies = [ "libc", "tempfile", "wasi-preview1-component-adapter-provider", - "wasmparser 0.239.0", + "wasmparser 0.240.0", "wat", - "windows-sys 0.60.2", + "windows-sys 0.61.2", "winsplit", "wit-component", "wit-parser", @@ -6084,24 +6161,24 @@ dependencies = [ [[package]] name = "wasm-encoder" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be00faa2b4950c76fe618c409d2c3ea5a3c9422013e079482d78544bb2d184c" +checksum = "06d642d8c5ecc083aafe9ceb32809276a304547a3a6eeecceb5d8152598bc71f" dependencies = [ "leb128fmt", - "wasmparser 0.239.0", + "wasmparser 0.240.0", ] [[package]] name = "wasm-metadata" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b3ec880a9ac69ccd92fbdbcf46ee833071cf09f82bb005b2327c7ae6025ae2" +checksum = "ee093e1e1ccffa005b9b778f7a10ccfd58e25a20eccad294a1a93168d076befb" dependencies = [ "anyhow", "indexmap", - "wasm-encoder 0.239.0", - "wasmparser 0.239.0", + "wasm-encoder 0.240.0", + "wasmparser 0.240.0", ] [[package]] @@ -6126,9 +6203,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9d90bb93e764f6beabf1d02028c70a2156a6583e63ac4218dd07ef733368b0" +checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" dependencies = [ "bitflags", "hashbrown", @@ -6139,22 +6216,22 @@ dependencies = [ [[package]] name = "wast" -version = "239.0.0" +version = "240.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9139176fe8a2590e0fb174cdcaf373b224cb93c3dde08e4297c1361d2ba1ea5d" +checksum = "b0efe1c93db4ac562b9733e3dca19ed7fc878dba29aef22245acf84f13da4a19" dependencies = [ "bumpalo", "leb128fmt", "memchr", "unicode-width 0.2.1", - "wasm-encoder 0.239.0", + "wasm-encoder 0.240.0", ] [[package]] name = "wat" -version = "1.239.0" +version = "1.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1c941927d34709f255558166f8901a2005f8ab4a9650432e9281b7cc6f3b75" +checksum = "4ec9b6eab7ecd4d639d78515e9ea491c9bacf494aa5eda10823bd35992cf8c1e" dependencies = [ "wast", ] @@ -6219,7 +6296,7 @@ dependencies = [ "windows-collections", "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -6264,7 +6341,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement 0.60.0", "windows-interface 0.59.1", - "windows-link", + "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", ] @@ -6276,7 +6353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", "windows-threading", ] @@ -6330,6 +6407,12 @@ 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" @@ -6337,7 +6420,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ "windows-core 0.61.2", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -6355,7 +6438,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -6374,7 +6457,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -6404,6 +6487,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -6426,7 +6518,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -6443,7 +6535,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -6553,9 +6645,9 @@ dependencies = [ [[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", ] @@ -6577,9 +6669,9 @@ dependencies = [ [[package]] name = "wit-component" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a866b19dba2c94d706ec58c92a4c62ab63e482b4c935d2a085ac94caecb136" +checksum = "7dc5474b078addc5fe8a72736de8da3acfb3ff324c2491133f8b59594afa1a20" dependencies = [ "anyhow", "bitflags", @@ -6588,17 +6680,17 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "wasm-encoder 0.239.0", + "wasm-encoder 0.240.0", "wasm-metadata", - "wasmparser 0.239.0", + "wasmparser 0.240.0", "wit-parser", ] [[package]] name = "wit-parser" -version = "0.239.0" +version = "0.240.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c92c939d667b7bf0c6bf2d1f67196529758f99a2a45a3355cc56964fd5315d" +checksum = "9875ea3fa272f57cc1fc50f225a7b94021a7878c484b33792bccad0d93223439" dependencies = [ "anyhow", "id-arena", @@ -6609,7 +6701,7 @@ dependencies = [ "serde_derive", "serde_json", "unicode-xid", - "wasmparser 0.239.0", + "wasmparser 0.240.0", ] [[package]] diff --git a/RELEASES.md b/RELEASES.md index 33abe45ce4629..a0590c4f138e4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,432 @@ +Version 1.92.0 (2025-12-11) +========================== + + + +Language +-------- +- [Document `MaybeUninit` representation and validity](https://github.com/rust-lang/rust/pull/140463) +- [Allow `&raw [mut | const]` for union field in safe code](https://github.com/rust-lang/rust/pull/141469) +- [Prefer item bounds of associated types over where-bounds for auto-traits and `Sized`](https://github.com/rust-lang/rust/pull/144064) +- [Do not materialize `X` in `[X; 0]` when `X` is unsizing a const](https://github.com/rust-lang/rust/pull/145277) +- [Support combining `#[track_caller]` and `#[no_mangle]` (requires every declaration specifying `#[track_caller]` as well)](https://github.com/rust-lang/rust/pull/145724) +- [Make never type lints `never_type_fallback_flowing_into_unsafe` and `dependency_on_unit_never_type_fallback` deny-by-default](https://github.com/rust-lang/rust/pull/146167) +- [Allow specifying multiple bounds for same associated item, except in trait objects](https://github.com/rust-lang/rust/pull/146593) +- [Slightly strengthen higher-ranked region handling in coherence](https://github.com/rust-lang/rust/pull/146725) +- [The `unused_must_use` lint no longer warns on `Result<(), Uninhabited>` (for instance, `Result<(), !>`), or `ControlFlow`](https://github.com/rust-lang/rust/pull/147382). This avoids having to check for an error that can never happen. + + + +Compiler +-------- +- [Make `mips64el-unknown-linux-muslabi64` link dynamically](https://github.com/rust-lang/rust/pull/146858) +- [Remove current code for embedding command-line args in PDB](https://github.com/rust-lang/rust/pull/147022) + Command-line information is typically not needed by debugging tools, and the removed code + was causing problems for incremental builds even on targets that don't use PDB debuginfo. + + + +Libraries +--------- +- [Specialize `Iterator::eq{_by}` for `TrustedLen` iterators](https://github.com/rust-lang/rust/pull/137122) +- [Simplify `Extend` for tuples](https://github.com/rust-lang/rust/pull/138799) +- [Added details to `Debug` for `EncodeWide`](https://github.com/rust-lang/rust/pull/140153). +- [`iter::Repeat::last`](https://github.com/rust-lang/rust/pull/147258) and [`count`](https://github.com/rust-lang/rust/pull/146410) will now panic, rather than looping infinitely. + + + +Stabilized APIs +--------------- + +- [`NonZero::div_ceil`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.div_ceil) +- [`Location::file_as_c_str`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file_as_c_str) +- [`RwLockWriteGuard::downgrade`](https://doc.rust-lang.org/stable/std/sync/struct.RwLockWriteGuard.html#method.downgrade) +- [`Box::new_zeroed`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed) +- [`Box::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_zeroed_slice) +- [`Rc::new_zeroed`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed) +- [`Rc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.new_zeroed_slice) +- [`Arc::new_zeroed`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed) +- [`Arc::new_zeroed_slice`](https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.new_zeroed_slice) +- [`btree_map::Entry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.insert_entry) +- [`btree_map::VacantEntry::insert_entry`](https://doc.rust-lang.org/stable/std/collections/btree_map/struct.VacantEntry.html#method.insert_entry) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CGroup%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CLiteral%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CPunct%3E-for-TokenStream) +- [`impl Extend for proc_macro::TokenStream`](https://doc.rust-lang.org/stable/proc_macro/struct.TokenStream.html#impl-Extend%3CIdent%3E-for-TokenStream) + +These previously stable APIs are now stable in const contexts: + +- [`<[_]>::rotate_left`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_left) +- [`<[_]>::rotate_right`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.rotate_right) + + + +Cargo +----- +- [Added a new chapter](https://github.com/rust-lang/cargo/issues/16119) to the Cargo book, ["Optimizing Build Performance"](https://doc.rust-lang.org/stable/cargo/guide/build-performance.html). + + + +Rustdoc +----- +- [If a trait item appears in rustdoc search, hide the corresponding impl items](https://github.com/rust-lang/rust/pull/145898). Previously a search for "last" would show both `Iterator::last` as well as impl methods like `std::vec::IntoIter::last`. Now these impl methods will be hidden, freeing up space for inherent methods like `BTreeSet::last`. +- [Relax rules for identifiers in search](https://github.com/rust-lang/rust/pull/147860). Previously you could only search for identifiers that were valid in rust code, now searches only need to be valid as part of an identifier. For example, you can now perform a search that starts with a digit. + + + +Compatibility Notes +------------------- +* [Fix backtraces with `-C panic=abort` on Linux by generating unwind tables by default](https://github.com/rust-lang/rust/pull/143613). Build with `-C force-unwind-tables=no` to keep omitting unwind tables. +- As part of the larger effort refactoring compiler built-in attributes and their diagnostics, [the future-compatibility lint `invalid_macro_export_arguments` is upgraded to deny-by-default and will be reported in dependencies too.](https://github.com/rust-lang/rust/pull/143857) +- [Update the minimum external LLVM to 20](https://github.com/rust-lang/rust/pull/145071) +- [Prevent downstream `impl DerefMut for Pin`](https://github.com/rust-lang/rust/pull/145608) +- [Don't apply temporary lifetime extension rules to the arguments of non-extended `pin!` and formatting macros](https://github.com/rust-lang/rust/pull/145838) + + +Version 1.91.1 (2025-11-10) +=========================== + + + +- [Enable file locking support in illumos](https://github.com/rust-lang/rust/pull/148322). This fixes Cargo not locking the build directory on illumos. +- [Fix `wasm_import_module` attribute cross-crate](https://github.com/rust-lang/rust/pull/148363). This fixes linker errors on WASM targets. + +Version 1.91.0 (2025-10-30) +========================== + + + +Language +-------- + +- [Lower pattern bindings in the order they're written and base drop order on primary bindings' order](https://github.com/rust-lang/rust/pull/143764) +- [Stabilize declaration of C-style variadic functions for `sysv64`, `win64`, `efiapi`, and `aapcs` ABIs](https://github.com/rust-lang/rust/pull/144066). + This brings these ABIs in line with the C ABI: variadic functions can be declared in extern blocks but not defined. +- [Add `dangling_pointers_from_locals` lint to warn against dangling pointers from local variables](https://github.com/rust-lang/rust/pull/144322) +- [Upgrade `semicolon_in_expressions_from_macros` from warn to deny](https://github.com/rust-lang/rust/pull/144369) +- [Stabilize LoongArch32 inline assembly](https://github.com/rust-lang/rust/pull/144402) +- [Add warn-by-default `integer_to_ptr_transmutes` lint against integer-to-pointer transmutes](https://github.com/rust-lang/rust/pull/144531) +- [Stabilize `sse4a` and `tbm` target features](https://github.com/rust-lang/rust/pull/144542) +- [Add `target_env = "macabi"` and `target_env = "sim"` cfgs](https://github.com/rust-lang/rust/pull/139451) as replacements for the `target_abi` cfgs with the same values. + + + +Compiler +-------- + +- [Don't warn on never-to-any `as` casts as unreachable](https://github.com/rust-lang/rust/pull/144804) + + + +Platform Support +---------------- + +- [Promote `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/143031) + Note: llvm-tools and MSI installers are missing but will be added in future releases. +- [Promote `aarch64-pc-windows-msvc` to Tier 1](https://github.com/rust-lang/rust/pull/145682) + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + +[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html + + + +Libraries +--------- + +- [Print thread ID in panic message](https://github.com/rust-lang/rust/pull/115746) +- [Fix overly restrictive lifetime in `core::panic::Location::file` return type](https://github.com/rust-lang/rust/pull/132087) +- [Guarantee parameter order for `_by()` variants of `min` / `max`/ `minmax` in `std::cmp`](https://github.com/rust-lang/rust/pull/139357) +- [Document assumptions about `Clone` and `Eq` traits](https://github.com/rust-lang/rust/pull/144330/) +- [`std::thread`: Return error if setting thread stack size fails](https://github.com/rust-lang/rust/pull/144210) + This used to panic within the standard library. + + + +Stabilized APIs +--------------- + +- [`Path::file_prefix`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.file_prefix) +- [`AtomicPtr::fetch_ptr_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_add) +- [`AtomicPtr::fetch_ptr_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_ptr_sub) +- [`AtomicPtr::fetch_byte_add`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_add) +- [`AtomicPtr::fetch_byte_sub`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_byte_sub) +- [`AtomicPtr::fetch_or`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_or) +- [`AtomicPtr::fetch_and`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_and) +- [`AtomicPtr::fetch_xor`](https://doc.rust-lang.org/stable/std/sync/atomic/struct.AtomicPtr.html#method.fetch_xor) +- [`{integer}::strict_add`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add) +- [`{integer}::strict_sub`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub) +- [`{integer}::strict_mul`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_mul) +- [`{integer}::strict_div`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div) +- [`{integer}::strict_div_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_div_euclid) +- [`{integer}::strict_rem`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem) +- [`{integer}::strict_rem_euclid`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_rem_euclid) +- [`{integer}::strict_neg`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_neg) +- [`{integer}::strict_shl`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shl) +- [`{integer}::strict_shr`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_shr) +- [`{integer}::strict_pow`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_pow) +- [`i{N}::strict_add_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_add_unsigned) +- [`i{N}::strict_sub_unsigned`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_sub_unsigned) +- [`i{N}::strict_abs`](https://doc.rust-lang.org/stable/std/primitive.i32.html#method.strict_abs) +- [`u{N}::strict_add_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_add_signed) +- [`u{N}::strict_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.u32.html#method.strict_sub_signed) +- [`PanicHookInfo::payload_as_str`](https://doc.rust-lang.org/stable/std/panic/struct.PanicHookInfo.html#method.payload_as_str) +- [`core::iter::chain`](https://doc.rust-lang.org/stable/core/iter/fn.chain.html) +- [`u{N}::checked_signed_diff`](https://doc.rust-lang.org/stable/std/primitive.u16.html#method.checked_signed_diff) +- [`core::array::repeat`](https://doc.rust-lang.org/stable/core/array/fn.repeat.html) +- [`PathBuf::add_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.add_extension) +- [`PathBuf::with_added_extension`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.with_added_extension) +- [`Duration::from_mins`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_mins) +- [`Duration::from_hours`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_hours) +- [`impl PartialEq for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3Cstr%3E-for-PathBuf) +- [`impl PartialEq for PathBuf`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#impl-PartialEq%3CString%3E-for-PathBuf) +- [`impl PartialEq for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3Cstr%3E-for-Path) +- [`impl PartialEq for Path`](https://doc.rust-lang.org/stable/std/path/struct.Path.html#impl-PartialEq%3CString%3E-for-Path) +- [`impl PartialEq for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPathBuf%3E-for-String) +- [`impl PartialEq for String`](https://doc.rust-lang.org/stable/std/string/struct.String.html#impl-PartialEq%3CPath%3E-for-String) +- [`impl PartialEq for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPathBuf%3E-for-str) +- [`impl PartialEq for str`](https://doc.rust-lang.org/stable/std/primitive.str.html#impl-PartialEq%3CPath%3E-for-str) +- [`Ipv4Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv4Addr.html#method.from_octets) +- [`Ipv6Addr::from_octets`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_octets) +- [`Ipv6Addr::from_segments`](https://doc.rust-lang.org/stable/std/net/struct.Ipv6Addr.html#method.from_segments) +- [`impl Default for Pin> where Box: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CBox%3CT%3E%3E) +- [`impl Default for Pin> where Rc: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CRc%3CT%3E%3E) +- [`impl Default for Pin> where Arc: Default, T: ?Sized`](https://doc.rust-lang.org/stable/std/default/trait.Default.html#impl-Default-for-Pin%3CArc%3CT%3E%3E) +- [`Cell::as_array_of_cells`](https://doc.rust-lang.org/stable/std/cell/struct.Cell.html#method.as_array_of_cells) +- [`u{N}::carrying_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_add) +- [`u{N}::borrowing_sub`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.borrowing_sub) +- [`u{N}::carrying_mul`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul) +- [`u{N}::carrying_mul_add`](https://doc.rust-lang.org/stable/std/primitive.u64.html#method.carrying_mul_add) +- [`BTreeMap::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.extract_if) +- [`BTreeSet::extract_if`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.extract_if) +- [`impl Debug for windows::ffi::EncodeWide<'_>`](https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-Debug-for-EncodeWide%3C'_%3E) +- [`str::ceil_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.ceil_char_boundary) +- [`str::floor_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.floor_char_boundary) +- [`impl Sum for Saturating`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum-for-Saturating%3Cu32%3E) +- [`impl Sum<&Self> for Saturating`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Sum%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E) +- [`impl Product for Saturating`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product-for-Saturating%3Cu32%3E) +- [`impl Product<&Self> for Saturating`](https://doc.rust-lang.org/stable/std/num/struct.Saturating.html#impl-Product%3C%26Saturating%3Cu32%3E%3E-for-Saturating%3Cu32%3E) + +These previously stable APIs are now stable in const contexts: + +- [`<[T; N]>::each_ref`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_ref) +- [`<[T; N]>::each_mut`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut) +- [`OsString::new`](https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.new) +- [`PathBuf::new`](https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.new) +- [`TypeId::of`](https://doc.rust-lang.org/stable/std/any/struct.TypeId.html#method.of) +- [`ptr::with_exposed_provenance`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance.html) +- [`ptr::with_exposed_provenance_mut`](https://doc.rust-lang.org/stable/std/ptr/fn.with_exposed_provenance_mut.html) + + + +Cargo +----- + +- 🎉 Stabilize `build.build-dir`. + This config sets the directory where intermediate build artifacts are stored. + These artifacts are produced by Cargo and rustc during the build process. + End users usually won't need to interact with them, and the layout inside + `build-dir` is an implementation detail that may change without notice. + ([config doc](https://doc.rust-lang.org/stable/cargo/reference/config.html#buildbuild-dir)) + ([build cache doc](https://doc.rust-lang.org/stable/cargo/reference/build-cache.html)) + [#15833](https://github.com/rust-lang/cargo/pull/15833) + [#15840](https://github.com/rust-lang/cargo/pull/15840) +- The `--target` flag and the `build.target` configuration can now take literal + `"host-tuple"` string, which will internally be substituted by the host + machine's target triple. + [#15838](https://github.com/rust-lang/cargo/pull/15838) + [#16003](https://github.com/rust-lang/cargo/pull/16003) + [#16032](https://github.com/rust-lang/cargo/pull/16032) + + + +Rustdoc +----- +- [In search results, rank doc aliases lower than non-alias items with the same name](https://github.com/rust-lang/rust/pull/145100) +- [Raw pointers now work in type-based search like references](https://github.com/rust-lang/rust/pull/145731). This means you can now search for things like `*const u8 ->`, and additionally functions that take or return raw pointers will now display their signature properly in search results. + + + +Compatibility Notes +------------------- + +- [Always require coroutine captures to be drop-live](https://github.com/rust-lang/rust/pull/144156) +- [Apple: Always pass SDK root when linking with `cc`, and pass it via `SDKROOT` env var](https://github.com/rust-lang/rust/pull/131477). This should fix linking issues with `rustc` running inside Xcode. Libraries in `/usr/local/lib` may no longer be linked automatically, if you develop or use a crate that relies on this, you should explicitly set `cargo::rustc-link-search=/usr/local/lib` in a `build.rs` script. +- [Relaxed bounds in associated type bound position like in `TraitRef` are now correctly forbidden](https://github.com/rust-lang/rust/pull/135331) +- [Add unstable `#[sanitize(xyz = "on|off")]` built-in attribute that shadows procedural macros with the same name](https://github.com/rust-lang/rust/pull/142681) +- [Fix the drop checker being more permissive for bindings declared with let-else](https://github.com/rust-lang/rust/pull/143028) +- [Be more strict when parsing attributes, erroring on many invalid attributes](https://github.com/rust-lang/rust/pull/144689) + - [Error on invalid `#[should_panic]` attributes](https://github.com/rust-lang/rust/pull/143808) + - [Error on invalid `#[link]` attributes](https://github.com/rust-lang/rust/pull/143193) +- [Mark all deprecation lints in name resolution as deny-by-default and also report in dependencies](https://github.com/rust-lang/rust/pull/143929) +- The lint `semicolon_in_expressions_from_macros`, for `macro_rules!` macros in expression position that expand to end in a semicolon (`;`), is now deny-by-default. It was already warn-by-default, and a future compatibility warning (FCW) that warned even in dependencies. This lint will become a hard error in the future. +- [Trait impl modifiers (e.g., `unsafe`, `!`, `default`) in inherent impls are no longer syntactically valid](https://github.com/rust-lang/rust/pull/144386) +- [Start reporting future breakage for `ill_formed_attribute_input` in dependencies](https://github.com/rust-lang/rust/pull/144544) +- [Restrict the scope of temporaries created by the macros `pin!`, `format_args!`, `write!`, and `writeln!` in `if let` scrutinees in Rust Edition 2024.](https://github.com/rust-lang/rust/pull/145342) This applies [Rust Edition 2024's `if let` temporary scope rules](https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html) to these temporaries, which previously could live past the `if` expression regardless of Edition. +- [Invalid numeric literal suffixes in tuple indexing, tuple struct indexing, and struct field name positions are now correctly rejected](https://github.com/rust-lang/rust/pull/145463) +- [Closures marked with the keyword `static` are now syntactically invalid](https://github.com/rust-lang/rust/pull/145604) +- [Shebangs inside `--cfg` and `--check-cfg` arguments are no longer allowed](https://github.com/rust-lang/rust/pull/146211) +- [Add future incompatibility lint for temporary lifetime shortening in Rust 1.92](https://github.com/rust-lang/rust/pull/147056) + +Cargo compatibility notes: + +- `cargo publish` no longer keeps `.crate` tarballs as final build artifacts + when `build.build-dir` is set. These tarballs were previously included due to + an oversight and are now treated as intermediate artifacts. + To get `.crate` tarballs as final artifacts, use `cargo package`. + In a future version, this change will apply regardless of `build.build-dir`. + [#15910](https://github.com/rust-lang/cargo/pull/15910) +- Adjust Cargo messages to match rustc diagnostic style. + This changes some of the terminal colors used by Cargo messages. + [#15928](https://github.com/rust-lang/cargo/pull/15928) +- Tools and projects relying on the + [internal details of Cargo's `build-dir`](https://doc.rust-lang.org/cargo/reference/build-cache.html) + may not work for users changing their `build-dir` layout. + For those doing so, we'd recommend proactively testing these cases + particularly as we are considering changing the default location of the `build-dir` in the future + ([cargo#16147](https://github.com/rust-lang/cargo/issues/16147)). + If you can't migrate off of Cargo's internal details, + we'd like to learn more about your use case as we prepare to change the layout of the `build-dir` + ([cargo#15010](https://github.com/rust-lang/cargo/issues/15010)). + + + +Internal Changes +---------------- + +These changes do not affect any public interfaces of Rust, but they represent +significant improvements to the performance or internals of rustc and related +tools. + +- [Update to LLVM 21](https://github.com/rust-lang/rust/pull/143684) + +Version 1.90.0 (2025-09-18) +=========================== + + + +Language +-------- +- [Split up the `unknown_or_malformed_diagnostic_attributes` lint](https://github.com/rust-lang/rust/pull/140717). This lint has been split up into four finer-grained lints, with `unknown_or_malformed_diagnostic_attributes` now being the lint group that contains these lints: + 1. `unknown_diagnostic_attributes`: unknown to the current compiler + 2. `misplaced_diagnostic_attributes`: placed on the wrong item + 3. `malformed_diagnostic_attributes`: malformed attribute syntax or options + 4. `malformed_diagnostic_format_literals`: malformed format string literal +- [Allow constants whose final value has references to mutable/external memory, but reject such constants as patterns](https://github.com/rust-lang/rust/pull/140942) +- [Allow volatile access to non-Rust memory, including address 0](https://github.com/rust-lang/rust/pull/141260) + + + + +Compiler +-------- +- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525). +- [Tier 3 `musl` targets now link dynamically by default](https://github.com/rust-lang/rust/pull/144410). Affected targets: + - `mips64-unknown-linux-muslabi64` + - `powerpc64-unknown-linux-musl` + - `powerpc-unknown-linux-musl` + - `powerpc-unknown-linux-muslspe` + - `riscv32gc-unknown-linux-musl` + - `s390x-unknown-linux-musl` + - `thumbv7neon-unknown-linux-musleabihf` + + + + +Platform Support +---------------- +- [Demote `x86_64-apple-darwin` to Tier 2 with host tools](https://github.com/rust-lang/rust/pull/145252) + + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + +[platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html + + + +Libraries +--------- +- [Stabilize `u*::{checked,overflowing,saturating,wrapping}_sub_signed`](https://github.com/rust-lang/rust/issues/126043) +- [Allow comparisons between `CStr`, `CString`, and `Cow`](https://github.com/rust-lang/rust/pull/137268) +- [Remove some unsized tuple impls since unsized tuples can't be constructed](https://github.com/rust-lang/rust/pull/138340) +- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005) +- [`proc_macro::Ident::new` now supports `$crate`.](https://github.com/rust-lang/rust/pull/141996) +- [Guarantee the pointer returned from `Thread::into_raw` has at least 8 bytes of alignment](https://github.com/rust-lang/rust/pull/143859) + + + + +Stabilized APIs +--------------- + +- [`u{n}::checked_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.checked_sub_signed) +- [`u{n}::overflowing_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.overflowing_sub_signed) +- [`u{n}::saturating_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.saturating_sub_signed) +- [`u{n}::wrapping_sub_signed`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.wrapping_sub_signed) +- [`impl Copy for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Copy-for-IntErrorKind) +- [`impl Hash for IntErrorKind`](https://doc.rust-lang.org/stable/std/num/enum.IntErrorKind.html#impl-Hash-for-IntErrorKind) +- [`impl PartialEq<&CStr> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3C%26CStr%3E-for-CStr) +- [`impl PartialEq for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCString%3E-for-CStr) +- [`impl PartialEq> for CStr`](https://doc.rust-lang.org/stable/std/ffi/struct.CStr.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CStr) +- [`impl PartialEq<&CStr> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3C%26CStr%3E-for-CString) +- [`impl PartialEq for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCStr%3E-for-CString) +- [`impl PartialEq> for CString`](https://doc.rust-lang.org/stable/std/ffi/struct.CString.html#impl-PartialEq%3CCow%3C'_,+CStr%3E%3E-for-CString) +- [`impl PartialEq<&CStr> for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3C%26CStr%3E-for-Cow%3C'_,+CStr%3E) +- [`impl PartialEq for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCStr%3E-for-Cow%3C'_,+CStr%3E) +- [`impl PartialEq for Cow`](https://doc.rust-lang.org/stable/std/borrow/enum.Cow.html#impl-PartialEq%3CCString%3E-for-Cow%3C'_,+CStr%3E) + + +These previously stable APIs are now stable in const contexts: + +- [`<[T]>::reverse`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.reverse) +- [`f32::floor`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.floor) +- [`f32::ceil`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.ceil) +- [`f32::trunc`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.trunc) +- [`f32::fract`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.fract) +- [`f32::round`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round) +- [`f32::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.round_ties_even) +- [`f64::floor`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.floor) +- [`f64::ceil`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.ceil) +- [`f64::trunc`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.trunc) +- [`f64::fract`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.fract) +- [`f64::round`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round) +- [`f64::round_ties_even`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.round_ties_even) + + + + +Cargo +----- +- [Add `http.proxy-cainfo` config for proxy certs](https://github.com/rust-lang/cargo/pull/15374/) +- [Use `gix` for `cargo package`](https://github.com/rust-lang/cargo/pull/15534/) +- [feat(publish): Stabilize multi-package publishing](https://github.com/rust-lang/cargo/pull/15636/) + + + +Rustdoc +----- +- [Add ways to collapse all impl blocks](https://github.com/rust-lang/rust/pull/141663). Previously the "Summary" button and "-" keyboard shortcut would never collapse `impl` blocks, now they do when shift is held +- [Display unsafe attributes with `unsafe()` wrappers](https://github.com/rust-lang/rust/pull/143662) + + + + +Compatibility Notes +------------------- +- [Use `lld` by default on `x86_64-unknown-linux-gnu`](https://github.com/rust-lang/rust/pull/140525). + See also . +- [Make `core::iter::Fuse`'s `Default` impl construct `I::default()` internally as promised in the docs instead of always being empty](https://github.com/rust-lang/rust/pull/140985) +- [Set `MSG_NOSIGNAL` for `UnixStream`](https://github.com/rust-lang/rust/pull/140005) + This may change program behavior but results in the same behavior as other primitives (e.g., stdout, network sockets). + Programs relying on signals to terminate them should update handling of sockets to handle errors on write by exiting. +- [On Unix `std::env::home_dir` will use the fallback if the `HOME` environment variable is empty](https://github.com/rust-lang/rust/pull/141840) +- We now [reject unsupported `extern "{abi}"`s consistently in all positions](https://github.com/rust-lang/rust/pull/142134). This primarily affects the use of implementing traits on an `extern "{abi}"` function pointer, like `extern "stdcall" fn()`, on a platform that doesn't support that, like aarch64-unknown-linux-gnu. Direct usage of these unsupported ABI strings by declaring or defining functions was already rejected, so this is only a change for consistency. +- [const-eval: error when initializing a static writes to that static](https://github.com/rust-lang/rust/pull/143084) +- [Check that the `proc_macro_derive` macro has correct arguments when applied to the crate root](https://github.com/rust-lang/rust/pull/143607) + + Version 1.89.0 (2025-08-07) ========================== diff --git a/bootstrap.example.toml b/bootstrap.example.toml index eac9395779798..6f37e51a47de2 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -325,6 +325,9 @@ # Defaults to the Python interpreter used to execute x.py. #build.python = "python" +# The path to (or name of) the resource compiler executable to use on Windows. +#build.windows-rc = "rc.exe" + # The path to the REUSE executable to use. Note that REUSE is not required in # most cases, as our tooling relies on a cached (and shrunk) copy of the # REUSE output present in the git repository and in our source tarballs. @@ -473,9 +476,6 @@ # when the stage 0 compiler is actually built from in-tree sources. #build.compiletest-allow-stage0 = false -# Whether to use the precompiled stage0 libtest with compiletest. -#build.compiletest-use-stage0-libtest = true - # Default value for the `--extra-checks` flag of tidy. # # See `./x test tidy --help` for details. @@ -758,15 +758,10 @@ # Currently, the only standard options supported here are `"llvm"`, `"cranelift"` and `"gcc"`. #rust.codegen-backends = ["llvm"] -# Indicates whether LLD will be compiled and made available in the sysroot for rustc to execute, and -# whether to set it as rustc's default linker on `x86_64-unknown-linux-gnu`. This will also only be -# when *not* building an external LLVM (so only when using `download-ci-llvm` or building LLVM from -# the in-tree source): setting `llvm-config` in the `[target.x86_64-unknown-linux-gnu]` section will -# make this default to false. -#rust.lld = false in all cases, except on `x86_64-unknown-linux-gnu` as described above, where it is true +# Indicates whether LLD will be compiled and made available in the sysroot for rustc to execute, +#rust.lld = false, except for targets that opt into LLD (see `target.default-linker-linux-override`) -# Indicates whether LLD will be used to link Rust crates during bootstrap on -# supported platforms. +# Indicates if we should override the linker used to link Rust crates during bootstrap to be LLD. # If set to `true` or `"external"`, a global `lld` binary that has to be in $PATH # will be used. # If set to `"self-contained"`, rust-lld from the snapshot compiler will be used. @@ -774,7 +769,7 @@ # On MSVC, LLD will not be used if we're cross linking. # # Explicitly setting the linker for a target will override this option when targeting MSVC. -#rust.use-lld = false +#rust.bootstrap-override-lld = false # Indicates whether some LLVM tools, like llvm-objdump, will be made available in the # sysroot. @@ -859,6 +854,14 @@ # Trigger a `DebugBreak` after an internal compiler error during bootstrap on Windows #rust.break-on-ice = true +# Set the number of threads for the compiler frontend used during compilation of Rust code (passed to `-Zthreads`). +# The valid options are: +# 0 - Set the number of threads according to the detected number of threads of the host system +# 1 - Use a single thread for compilation of Rust code (the default) +# N - Number of threads used for compilation of Rust code +# +#rust.parallel-frontend-threads = 1 + # ============================================================================= # Distribution options # @@ -939,7 +942,7 @@ # Linker to be used to bootstrap Rust code. Note that the # default value is platform specific, and if not specified it may also depend on # what platform is crossing to what platform. -# Setting this will override the `use-lld` option for Rust code when targeting MSVC. +# Setting this will override the `bootstrap-override-lld` option for Rust code when targeting MSVC. #linker = "cc" (path) # Should rustc and the standard library be built with split debuginfo? Default @@ -1060,3 +1063,17 @@ # Link the compiler and LLVM against `jemalloc` instead of the default libc allocator. # This overrides the global `rust.jemalloc` option. See that option for more info. #jemalloc = rust.jemalloc (bool) + +# The linker configuration that will *override* the default linker used for Linux +# targets in the built compiler. +# +# The following values are supported: +# - `off` => do not apply any override and use the default linker. This can be used to opt out of +# linker overrides set by bootstrap for specific targets (see below). +# - `self-contained-lld-cc` => override the default linker to be self-contained LLD (`rust-lld`) +# that is invoked through `cc`. +# +# Currently, the following targets automatically opt into the self-contained LLD linker, unless you +# pass `off`: +# - x86_64-unknown-linux-gnu +#default-linker-linux-override = "off" (for most targets) diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index e3214d1ab9cec..9ef8fa75062a2 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -30,6 +30,7 @@ features = ['unprefixed_malloc_on_supported_platforms'] check_only = ['rustc_driver_impl/check_only'] jemalloc = ['dep:tikv-jemalloc-sys'] llvm = ['rustc_driver_impl/llvm'] +llvm_enzyme = ['rustc_driver_impl/llvm_enzyme'] max_level_info = ['rustc_driver_impl/max_level_info'] rustc_randomized_layouts = ['rustc_driver_impl/rustc_randomized_layouts'] # tidy-alphabetical-end diff --git a/compiler/rustc_abi/src/callconv/reg.rs b/compiler/rustc_abi/src/callconv/reg.rs index 8cf140dbaad4e..66c8056d0c2af 100644 --- a/compiler/rustc_abi/src/callconv/reg.rs +++ b/compiler/rustc_abi/src/callconv/reg.rs @@ -42,22 +42,22 @@ impl Reg { let dl = cx.data_layout(); match self.kind { RegKind::Integer => match self.size.bits() { - 1 => dl.i1_align.abi, - 2..=8 => dl.i8_align.abi, - 9..=16 => dl.i16_align.abi, - 17..=32 => dl.i32_align.abi, - 33..=64 => dl.i64_align.abi, - 65..=128 => dl.i128_align.abi, + 1 => dl.i1_align, + 2..=8 => dl.i8_align, + 9..=16 => dl.i16_align, + 17..=32 => dl.i32_align, + 33..=64 => dl.i64_align, + 65..=128 => dl.i128_align, _ => panic!("unsupported integer: {self:?}"), }, RegKind::Float => match self.size.bits() { - 16 => dl.f16_align.abi, - 32 => dl.f32_align.abi, - 64 => dl.f64_align.abi, - 128 => dl.f128_align.abi, + 16 => dl.f16_align, + 32 => dl.f32_align, + 64 => dl.f64_align, + 128 => dl.f128_align, _ => panic!("unsupported float: {self:?}"), }, - RegKind::Vector => dl.llvmlike_vector_align(self.size).abi, + RegKind::Vector => dl.llvmlike_vector_align(self.size), } } } diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 5004d0c80220f..14356813b7bb0 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -174,11 +174,11 @@ impl LayoutCalculator { // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close // to a vector as possible. - (BackendRepr::Memory { sized: true }, AbiAlign { abi: Align::max_aligned_factor(size) }) + (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size)) } else { (BackendRepr::SimdVector { element: e_repr, count }, dl.llvmlike_vector_align(size)) }; - let size = size.align_to(align.abi); + let size = size.align_to(align); Ok(LayoutData { variants: Variants::Single { index: VariantIdx::new(0) }, @@ -190,7 +190,7 @@ impl LayoutCalculator { largest_niche: elt.largest_niche, uninhabited: false, size, - align, + align: AbiAlign::new(align), max_repr_align: None, unadjusted_abi_align: elt.align.abi, randomization_seed: elt.randomization_seed.wrapping_add(Hash64::new(count)), @@ -388,7 +388,7 @@ impl LayoutCalculator { return Err(LayoutCalculatorError::UnexpectedUnsized(*field)); } - align = align.max(field.align); + align = align.max(field.align.abi); max_repr_align = max_repr_align.max(field.max_repr_align); size = cmp::max(size, field.size); @@ -423,13 +423,13 @@ impl LayoutCalculator { } if let Some(pack) = repr.pack { - align = align.min(AbiAlign::new(pack)); + align = align.min(pack); } // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). // See documentation on `LayoutData::unadjusted_abi_align`. - let unadjusted_abi_align = align.abi; + let unadjusted_abi_align = align; if let Some(repr_align) = repr.align { - align = align.max(AbiAlign::new(repr_align)); + align = align.max(repr_align); } // `align` must not be modified after this, or `unadjusted_abi_align` could be inaccurate. let align = align; @@ -441,14 +441,12 @@ impl LayoutCalculator { Ok(Some((repr, _))) => match repr { // Mismatched alignment (e.g. union is #[repr(packed)]): disable opt BackendRepr::Scalar(_) | BackendRepr::ScalarPair(_, _) - if repr.scalar_align(dl).unwrap() != align.abi => + if repr.scalar_align(dl).unwrap() != align => { BackendRepr::Memory { sized: true } } // Vectors require at least element alignment, else disable the opt - BackendRepr::SimdVector { element, count: _ } - if element.align(dl).abi > align.abi => - { + BackendRepr::SimdVector { element, count: _ } if element.align(dl).abi > align => { BackendRepr::Memory { sized: true } } // the alignment tests passed and we can use this @@ -474,8 +472,8 @@ impl LayoutCalculator { backend_repr, largest_niche: None, uninhabited: false, - align, - size: size.align_to(align.abi), + align: AbiAlign::new(align), + size: size.align_to(align), max_repr_align, unadjusted_abi_align, randomization_seed: combined_seed, @@ -611,7 +609,7 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; - let mut unadjusted_abi_align = align.abi; + let mut unadjusted_abi_align = align; let mut variant_layouts = variants .iter_enumerated() @@ -619,7 +617,7 @@ impl LayoutCalculator { let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; st.variants = Variants::Single { index: j }; - align = align.max(st.align); + align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); @@ -646,7 +644,7 @@ impl LayoutCalculator { let (niche_start, niche_scalar) = niche.reserve(dl, count)?; let niche_offset = niche.offset; let niche_size = niche.value.size(dl); - let size = variant_layouts[largest_variant_index].size.align_to(align.abi); + let size = variant_layouts[largest_variant_index].size.align_to(align); let all_variants_fit = variant_layouts.iter_enumerated_mut().all(|(i, layout)| { if i == largest_variant_index { @@ -699,7 +697,7 @@ impl LayoutCalculator { .iter_enumerated() .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO); let same_size = size == variant_layouts[largest_variant_index].size; - let same_align = align == variant_layouts[largest_variant_index].align; + let same_align = align == variant_layouts[largest_variant_index].align.abi; let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); let abi = if same_size && same_align && others_zst { @@ -746,7 +744,7 @@ impl LayoutCalculator { largest_niche, uninhabited, size, - align, + align: AbiAlign::new(align), max_repr_align, unadjusted_abi_align, randomization_seed: combined_seed, @@ -818,7 +816,7 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; - let mut unadjusted_abi_align = align.abi; + let mut unadjusted_abi_align = align; let mut size = Size::ZERO; @@ -860,7 +858,7 @@ impl LayoutCalculator { } } size = cmp::max(size, st.size); - align = align.max(st.align); + align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); Ok(st) @@ -868,7 +866,7 @@ impl LayoutCalculator { .collect::, _>>()?; // Align the maximum variant size to the largest alignment. - size = size.align_to(align.abi); + size = size.align_to(align); // FIXME(oli-obk): deduplicate and harden these checks if size.bytes() >= dl.obj_size_bound() { @@ -1042,7 +1040,7 @@ impl LayoutCalculator { }; if pair_offsets[FieldIdx::new(0)] == Size::ZERO && pair_offsets[FieldIdx::new(1)] == *offset - && align == pair.align + && align == pair.align.abi && size == pair.size { // We can use `ScalarPair` only when it matches our @@ -1066,7 +1064,7 @@ impl LayoutCalculator { // Also need to bump up the size and alignment, so that the entire value fits // in here. variant.size = cmp::max(variant.size, size); - variant.align.abi = cmp::max(variant.align.abi, align.abi); + variant.align.abi = cmp::max(variant.align.abi, align); } } } @@ -1092,7 +1090,7 @@ impl LayoutCalculator { largest_niche, uninhabited, backend_repr: abi, - align, + align: AbiAlign::new(align), size, max_repr_align, unadjusted_abi_align, @@ -1169,7 +1167,7 @@ impl LayoutCalculator { // To allow unsizing `&Foo` -> `&Foo`, the layout of the struct must // not depend on the layout of the tail. let max_field_align = - fields_excluding_tail.iter().map(|f| f.align.abi.bytes()).max().unwrap_or(1); + fields_excluding_tail.iter().map(|f| f.align.bytes()).max().unwrap_or(1); let largest_niche_size = fields_excluding_tail .iter() .filter_map(|f| f.largest_niche) @@ -1189,7 +1187,7 @@ impl LayoutCalculator { } else { // Returns `log2(effective-align)`. The calculation assumes that size is an // integer multiple of align, except for ZSTs. - let align = layout.align.abi.bytes(); + let align = layout.align.bytes(); let size = layout.size.bytes(); let niche_size = layout.largest_niche.map(|n| n.available(dl)).unwrap_or(0); // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields. @@ -1288,7 +1286,7 @@ impl LayoutCalculator { if let StructKind::Prefixed(prefix_size, prefix_align) = kind { let prefix_align = if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; - align = align.max(AbiAlign::new(prefix_align)); + align = align.max(prefix_align); offset = prefix_size.align_to(prefix_align); } for &i in &inverse_memory_index { @@ -1312,7 +1310,7 @@ impl LayoutCalculator { field.align }; offset = offset.align_to(field_align.abi); - align = align.max(field_align); + align = align.max(field_align.abi); max_repr_align = max_repr_align.max(field.max_repr_align); debug!("univariant offset: {:?} field: {:#?}", offset, field); @@ -1339,9 +1337,9 @@ impl LayoutCalculator { // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). // See documentation on `LayoutData::unadjusted_abi_align`. - let unadjusted_abi_align = align.abi; + let unadjusted_abi_align = align; if let Some(repr_align) = repr.align { - align = align.max(AbiAlign::new(repr_align)); + align = align.max(repr_align); } // `align` must not be modified after this point, or `unadjusted_abi_align` could be inaccurate. let align = align; @@ -1360,7 +1358,7 @@ impl LayoutCalculator { debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() }; - let size = min_size.align_to(align.abi); + let size = min_size.align_to(align); // FIXME(oli-obk): deduplicate and harden these checks if size.bytes() >= dl.obj_size_bound() { return Err(LayoutCalculatorError::SizeOverflow); @@ -1383,8 +1381,7 @@ impl LayoutCalculator { layout_of_single_non_zst_field = Some(field); // Field fills the struct and it has a scalar or scalar pair ABI. - if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size - { + if offsets[i].bytes() == 0 && align == field.align.abi && size == field.size { match field.backend_repr { // For plain scalars, or vectors of them, we can't unpack // newtypes for `#[repr(C)]`, as that affects C ABIs. @@ -1428,7 +1425,7 @@ impl LayoutCalculator { }; if offsets[i] == pair_offsets[FieldIdx::new(0)] && offsets[j] == pair_offsets[FieldIdx::new(1)] - && align == pair.align + && align == pair.align.abi && size == pair.size { // We can use `ScalarPair` only when it matches our @@ -1450,7 +1447,7 @@ impl LayoutCalculator { Some(l) => l.unadjusted_abi_align, None => { // `repr(transparent)` with all ZST fields. - align.abi + align } } } else { @@ -1465,7 +1462,7 @@ impl LayoutCalculator { backend_repr: abi, largest_niche, uninhabited, - align, + align: AbiAlign::new(align), size, max_repr_align, unadjusted_abi_align, @@ -1488,7 +1485,7 @@ impl LayoutCalculator { for i in layout.fields.index_by_increasing_offset() { let offset = layout.fields.offset(i); let f = &fields[FieldIdx::new(i)]; - write!(s, "[o{}a{}s{}", offset.bytes(), f.align.abi.bytes(), f.size.bytes()).unwrap(); + write!(s, "[o{}a{}s{}", offset.bytes(), f.align.bytes(), f.size.bytes()).unwrap(); if let Some(n) = f.largest_niche { write!( s, diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 0d0706defc2e5..b3807c8727396 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -4,7 +4,8 @@ use rustc_hashes::Hash64; use rustc_index::{Idx, IndexVec}; use crate::{ - BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size, Variants, + AbiAlign, BackendRepr, FieldsShape, HasDataLayout, LayoutData, Niche, Primitive, Scalar, Size, + Variants, }; /// "Simple" layout constructors that cannot fail. @@ -20,10 +21,10 @@ impl LayoutData { backend_repr: BackendRepr::Memory { sized }, largest_niche: None, uninhabited: false, - align: dl.i8_align, + align: AbiAlign::new(dl.i8_align), size: Size::ZERO, max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, + unadjusted_abi_align: dl.i8_align, randomization_seed: Hash64::new(0), } } @@ -37,10 +38,10 @@ impl LayoutData { backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, uninhabited: true, - align: dl.i8_align, + align: AbiAlign::new(dl.i8_align), size: Size::ZERO, max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, + unadjusted_abi_align: dl.i8_align, randomization_seed: Hash64::ZERO, } } @@ -89,10 +90,10 @@ impl LayoutData { pub fn scalar_pair(cx: &C, a: Scalar, b: Scalar) -> Self { let dl = cx.data_layout(); - let b_align = b.align(dl); - let align = a.align(dl).max(b_align).max(dl.aggregate_align); - let b_offset = a.size(dl).align_to(b_align.abi); - let size = (b_offset + b.size(dl)).align_to(align.abi); + let b_align = b.align(dl).abi; + let align = a.align(dl).abi.max(b_align).max(dl.aggregate_align); + let b_offset = a.size(dl).align_to(b_align); + let size = (b_offset + b.size(dl)).align_to(align); // HACK(nox): We iter on `b` and then `a` because `max_by_key` // returns the last maximum. @@ -112,10 +113,10 @@ impl LayoutData { backend_repr: BackendRepr::ScalarPair(a, b), largest_niche, uninhabited: false, - align, + align: AbiAlign::new(align), size, max_repr_align: None, - unadjusted_abi_align: align.abi, + unadjusted_abi_align: align, randomization_seed: Hash64::new(combined_seed), } } @@ -138,10 +139,10 @@ impl LayoutData { backend_repr: BackendRepr::Memory { sized: true }, largest_niche: None, uninhabited: true, - align: dl.i8_align, + align: AbiAlign::new(dl.i8_align), size: Size::ZERO, max_repr_align: None, - unadjusted_abi_align: dl.i8_align.abi, + unadjusted_abi_align: dl.i8_align, randomization_seed: Hash64::ZERO, } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 369874521e57e..de44c8755a078 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -229,7 +229,7 @@ pub struct PointerSpec { /// The size of the bitwise representation of the pointer. pointer_size: Size, /// The alignment of pointers for this address space - pointer_align: AbiAlign, + pointer_align: Align, /// The size of the value a pointer can be offset by in this address space. pointer_offset: Size, /// Pointers into this address space contain extra metadata @@ -242,20 +242,20 @@ pub struct PointerSpec { #[derive(Debug, PartialEq, Eq)] pub struct TargetDataLayout { pub endian: Endian, - pub i1_align: AbiAlign, - pub i8_align: AbiAlign, - pub i16_align: AbiAlign, - pub i32_align: AbiAlign, - pub i64_align: AbiAlign, - pub i128_align: AbiAlign, - pub f16_align: AbiAlign, - pub f32_align: AbiAlign, - pub f64_align: AbiAlign, - pub f128_align: AbiAlign, - pub aggregate_align: AbiAlign, + pub i1_align: Align, + pub i8_align: Align, + pub i16_align: Align, + pub i32_align: Align, + pub i64_align: Align, + pub i128_align: Align, + pub f16_align: Align, + pub f32_align: Align, + pub f64_align: Align, + pub f128_align: Align, + pub aggregate_align: Align, /// Alignments for vector types. - pub vector_align: Vec<(Size, AbiAlign)>, + pub vector_align: Vec<(Size, Align)>, pub default_address_space: AddressSpace, pub default_address_space_pointer_spec: PointerSpec, @@ -282,25 +282,25 @@ impl Default for TargetDataLayout { let align = |bits| Align::from_bits(bits).unwrap(); TargetDataLayout { endian: Endian::Big, - i1_align: AbiAlign::new(align(8)), - i8_align: AbiAlign::new(align(8)), - i16_align: AbiAlign::new(align(16)), - i32_align: AbiAlign::new(align(32)), - i64_align: AbiAlign::new(align(32)), - i128_align: AbiAlign::new(align(32)), - f16_align: AbiAlign::new(align(16)), - f32_align: AbiAlign::new(align(32)), - f64_align: AbiAlign::new(align(64)), - f128_align: AbiAlign::new(align(128)), - aggregate_align: AbiAlign { abi: align(8) }, + i1_align: align(8), + i8_align: align(8), + i16_align: align(16), + i32_align: align(32), + i64_align: align(32), + i128_align: align(32), + f16_align: align(16), + f32_align: align(32), + f64_align: align(64), + f128_align: align(128), + aggregate_align: align(8), vector_align: vec![ - (Size::from_bits(64), AbiAlign::new(align(64))), - (Size::from_bits(128), AbiAlign::new(align(128))), + (Size::from_bits(64), align(64)), + (Size::from_bits(128), align(128)), ], default_address_space: AddressSpace::ZERO, default_address_space_pointer_spec: PointerSpec { pointer_size: Size::from_bits(64), - pointer_align: AbiAlign::new(align(64)), + pointer_align: align(64), pointer_offset: Size::from_bits(64), _is_fat: false, }, @@ -360,7 +360,7 @@ impl TargetDataLayout { .map_err(|err| TargetDataLayoutErrors::InvalidAlignment { cause, err }) }; let abi = parse_bits(s, "alignment", cause)?; - Ok(AbiAlign::new(align_from_bits(abi)?)) + Ok(align_from_bits(abi)?) }; // Parse an alignment sequence, possibly in the form `[:]`, @@ -596,7 +596,7 @@ impl TargetDataLayout { /// psABI-mandated alignment for a vector type, if any #[inline] - fn cabi_vector_align(&self, vec_size: Size) -> Option { + fn cabi_vector_align(&self, vec_size: Size) -> Option { self.vector_align .iter() .find(|(size, _align)| *size == vec_size) @@ -605,10 +605,9 @@ impl TargetDataLayout { /// an alignment resembling the one LLVM would pick for a vector #[inline] - pub fn llvmlike_vector_align(&self, vec_size: Size) -> AbiAlign { - self.cabi_vector_align(vec_size).unwrap_or(AbiAlign::new( - Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap(), - )) + pub fn llvmlike_vector_align(&self, vec_size: Size) -> Align { + self.cabi_vector_align(vec_size) + .unwrap_or(Align::from_bytes(vec_size.bytes().next_power_of_two()).unwrap()) } /// Get the pointer size in the default data address space. @@ -654,21 +653,19 @@ impl TargetDataLayout { /// Get the pointer alignment in the default data address space. #[inline] pub fn pointer_align(&self) -> AbiAlign { - self.default_address_space_pointer_spec.pointer_align + AbiAlign::new(self.default_address_space_pointer_spec.pointer_align) } /// Get the pointer alignment in a specific address space. #[inline] pub fn pointer_align_in(&self, c: AddressSpace) -> AbiAlign { - if c == self.default_address_space { - return self.default_address_space_pointer_spec.pointer_align; - } - - if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) { + AbiAlign::new(if c == self.default_address_space { + self.default_address_space_pointer_spec.pointer_align + } else if let Some(e) = self.address_space_info.iter().find(|(a, _)| a == &c) { e.1.pointer_align } else { panic!("Use of unknown address space {c:?}"); - } + }) } } @@ -1185,13 +1182,13 @@ impl Integer { use Integer::*; let dl = cx.data_layout(); - match self { + AbiAlign::new(match self { I8 => dl.i8_align, I16 => dl.i16_align, I32 => dl.i32_align, I64 => dl.i64_align, I128 => dl.i128_align, - } + }) } /// Returns the largest signed value that can be represented by this Integer. @@ -1311,12 +1308,12 @@ impl Float { use Float::*; let dl = cx.data_layout(); - match self { + AbiAlign::new(match self { F16 => dl.f16_align, F32 => dl.f32_align, F64 => dl.f64_align, F128 => dl.f128_align, - } + }) } } @@ -2159,7 +2156,7 @@ impl LayoutData { /// Returns `true` if the type is sized and a 1-ZST (meaning it has size 0 and alignment 1). pub fn is_1zst(&self) -> bool { - self.is_sized() && self.size.bytes() == 0 && self.align.abi.bytes() == 1 + self.is_sized() && self.size.bytes() == 0 && self.align.bytes() == 1 } /// Returns `true` if the type is a ZST and not unsized. diff --git a/compiler/rustc_arena/src/tests.rs b/compiler/rustc_arena/src/tests.rs index bfde8abd5893a..eb9406d691b10 100644 --- a/compiler/rustc_arena/src/tests.rs +++ b/compiler/rustc_arena/src/tests.rs @@ -19,8 +19,8 @@ impl TypedArena { unsafe { // Clear the last chunk, which is partially filled. let mut chunks_borrow = self.chunks.borrow_mut(); - if let Some(mut last_chunk) = chunks_borrow.last_mut() { - self.clear_last_chunk(&mut last_chunk); + if let Some(last_chunk) = chunks_borrow.last_mut() { + self.clear_last_chunk(last_chunk); let len = chunks_borrow.len(); // If `T` is ZST, code below has no effect. for mut chunk in chunks_borrow.drain(..len - 1) { diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3e8fddd9954e2..94c15094f5251 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -114,8 +114,7 @@ impl PartialEq for Path { impl PartialEq<&[Symbol]> for Path { #[inline] fn eq(&self, names: &&[Symbol]) -> bool { - self.segments.len() == names.len() - && self.segments.iter().zip(names.iter()).all(|(s1, s2)| s1 == s2) + self.segments.iter().eq(*names) } } @@ -870,11 +869,11 @@ pub enum PatKind { Struct(Option>, Path, ThinVec, PatFieldsRest), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - TupleStruct(Option>, Path, ThinVec>), + TupleStruct(Option>, Path, ThinVec), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. - Or(ThinVec>), + Or(ThinVec), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants @@ -883,7 +882,7 @@ pub enum PatKind { Path(Option>, Path), /// A tuple pattern (`(a, b)`). - Tuple(ThinVec>), + Tuple(ThinVec), /// A `box` pattern. Box(Box), @@ -901,7 +900,7 @@ pub enum PatKind { Range(Option>, Option>, Spanned), /// A slice pattern `[a, b, c]`. - Slice(ThinVec>), + Slice(ThinVec), /// A rest pattern `..`. /// @@ -2580,7 +2579,10 @@ pub enum TyPatKind { /// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`). Range(Option>, Option>, Spanned), - Or(ThinVec>), + /// A `!null` pattern for raw pointers. + NotNull, + + Or(ThinVec), /// Placeholder for a pattern that wasn't syntactically well formed in some way. Err(ErrorGuaranteed), @@ -3634,49 +3636,26 @@ pub struct Trait { pub items: ThinVec>, } -/// The location of a where clause on a `TyAlias` (`Span`) and whether there was -/// a `where` keyword (`bool`). This is split out from `WhereClause`, since there -/// are two locations for where clause on type aliases, but their predicates -/// are concatenated together. -/// -/// Take this example: -/// ```ignore (only-for-syntax-highlight) -/// trait Foo { -/// type Assoc<'a, 'b> where Self: 'a, Self: 'b; -/// } -/// impl Foo for () { -/// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b; -/// // ^^^^^^^^^^^^^^ first where clause -/// // ^^^^^^^^^^^^^^ second where clause -/// } -/// ``` -/// -/// If there is no where clause, then this is `false` with `DUMMY_SP`. -#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)] -pub struct TyAliasWhereClause { - pub has_where_token: bool, - pub span: Span, -} - -/// The span information for the two where clauses on a `TyAlias`. -#[derive(Copy, Clone, Encodable, Decodable, Debug, Default, Walkable)] -pub struct TyAliasWhereClauses { - /// Before the equals sign. - pub before: TyAliasWhereClause, - /// After the equals sign. - pub after: TyAliasWhereClause, - /// The index in `TyAlias.generics.where_clause.predicates` that would split - /// into predicates from the where clause before the equals sign and the ones - /// from the where clause after the equals sign. - pub split: usize, -} - #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct TyAlias { pub defaultness: Defaultness, pub ident: Ident, pub generics: Generics, - pub where_clauses: TyAliasWhereClauses, + /// There are two locations for where clause on type aliases. This represents the second + /// where clause, before the semicolon. The first where clause is stored inside `generics`. + /// + /// Take this example: + /// ```ignore (only-for-syntax-highlight) + /// trait Foo { + /// type Assoc<'a, 'b> where Self: 'a, Self: 'b; + /// } + /// impl Foo for () { + /// type Assoc<'a, 'b> where Self: 'a = () where Self: 'b; + /// // ^^^^^^^^^^^^^^ before where clause + /// // ^^^^^^^^^^^^^^ after where clause + /// } + /// ``` + pub after_where_clause: WhereClause, #[visitable(extra = BoundKind::Bound)] pub bounds: GenericBounds, pub ty: Option>, diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 6ada93b4c89b9..901b645b8c4ef 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -86,10 +86,10 @@ impl AttributeExt for Attribute { /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not /// a doc comment) will return `false`. - fn is_doc_comment(&self) -> bool { + fn is_doc_comment(&self) -> Option { match self.kind { - AttrKind::Normal(..) => false, - AttrKind::DocComment(..) => true, + AttrKind::Normal(..) => None, + AttrKind::DocComment(..) => Some(self.span), } } @@ -776,7 +776,7 @@ pub trait AttributeExt: Debug { /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not /// a doc comment) will return `false`. - fn is_doc_comment(&self) -> bool; + fn is_doc_comment(&self) -> Option; #[inline] fn has_name(&self, name: Symbol) -> bool { @@ -863,8 +863,9 @@ impl Attribute { AttributeExt::path_matches(self, name) } + // on ast attributes we return a bool since that's what most code already expects pub fn is_doc_comment(&self) -> bool { - AttributeExt::is_doc_comment(self) + AttributeExt::is_doc_comment(self).is_some() } #[inline] diff --git a/compiler/rustc_ast/src/entry.rs b/compiler/rustc_ast/src/entry.rs index 12cbb3b2a15f7..ae0cc7350a78f 100644 --- a/compiler/rustc_ast/src/entry.rs +++ b/compiler/rustc_ast/src/entry.rs @@ -1,7 +1,5 @@ use rustc_span::{Symbol, sym}; -use crate::attr::{self, AttributeExt}; - #[derive(Debug)] pub enum EntryPointType { /// This function is not an entrypoint. @@ -30,11 +28,11 @@ pub enum EntryPointType { } pub fn entry_point_type( - attrs: &[impl AttributeExt], + has_rustc_main: bool, at_root: bool, name: Option, ) -> EntryPointType { - if attr::contains_name(attrs, sym::rustc_main) { + if has_rustc_main { EntryPointType::RustcMainAttr } else if let Some(name) = name && name == sym::main diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index 7dee2ed17b4be..332ad50d927fa 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -3,7 +3,9 @@ use rustc_span::{Symbol, sym}; #[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)] pub enum AllocatorKind { + /// Use `#[global_allocator]` as global allocator. Global, + /// Use the default implementation in libstd as global allocator. Default, } @@ -15,25 +17,37 @@ pub fn default_fn_name(base: Symbol) -> String { format!("__rdl_{base}") } -pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str { - match alloc_error_handler_kind { - AllocatorKind::Global => "__rg_oom", - AllocatorKind::Default => "__rdl_oom", - } -} - +pub const ALLOC_ERROR_HANDLER: Symbol = sym::alloc_error_handler; pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2"; +/// Argument or return type for methods in the allocator shim +#[derive(Copy, Clone)] pub enum AllocatorTy { Layout, + Never, Ptr, ResultPtr, Unit, Usize, } +/// Some allocator methods are known to the compiler: they act more like +/// intrinsics/language primitives than library-defined functions. +/// FIXME: ideally this would be derived from attributes like `#[rustc_allocator]`, +/// so we don't have two sources of truth. +#[derive(Copy, Clone, Debug)] +pub enum SpecialAllocatorMethod { + Alloc, + AllocZeroed, + Dealloc, + Realloc, +} + +/// A method that will be codegened in the allocator shim. +#[derive(Copy, Clone)] pub struct AllocatorMethod { pub name: Symbol, + pub special: Option, pub inputs: &'static [AllocatorMethodInput], pub output: AllocatorTy, } @@ -46,11 +60,13 @@ pub struct AllocatorMethodInput { pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ AllocatorMethod { name: sym::alloc, + special: Some(SpecialAllocatorMethod::Alloc), inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }], output: AllocatorTy::ResultPtr, }, AllocatorMethod { name: sym::dealloc, + special: Some(SpecialAllocatorMethod::Dealloc), inputs: &[ AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr }, AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }, @@ -59,6 +75,7 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ }, AllocatorMethod { name: sym::realloc, + special: Some(SpecialAllocatorMethod::Realloc), inputs: &[ AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr }, AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }, @@ -68,6 +85,7 @@ pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[ }, AllocatorMethod { name: sym::alloc_zeroed, + special: Some(SpecialAllocatorMethod::AllocZeroed), inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }], output: AllocatorTy::ResultPtr, }, diff --git a/compiler/rustc_ast/src/expand/autodiff_attrs.rs b/compiler/rustc_ast/src/expand/autodiff_attrs.rs index 33451f9974835..90f15753e99c9 100644 --- a/compiler/rustc_ast/src/expand/autodiff_attrs.rs +++ b/compiler/rustc_ast/src/expand/autodiff_attrs.rs @@ -6,6 +6,7 @@ use std::fmt::{self, Display, Formatter}; use std::str::FromStr; +use crate::expand::typetree::TypeTree; use crate::expand::{Decodable, Encodable, HashStable_Generic}; use crate::{Ty, TyKind}; @@ -84,6 +85,8 @@ pub struct AutoDiffItem { /// The name of the function being generated pub target: String, pub attrs: AutoDiffAttrs, + pub inputs: Vec, + pub output: TypeTree, } #[derive(Clone, Eq, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] @@ -275,14 +278,22 @@ impl AutoDiffAttrs { !matches!(self.mode, DiffMode::Error | DiffMode::Source) } - pub fn into_item(self, source: String, target: String) -> AutoDiffItem { - AutoDiffItem { source, target, attrs: self } + pub fn into_item( + self, + source: String, + target: String, + inputs: Vec, + output: TypeTree, + ) -> AutoDiffItem { + AutoDiffItem { source, target, inputs, output, attrs: self } } } impl fmt::Display for AutoDiffItem { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Differentiating {} -> {}", self.source, self.target)?; - write!(f, " with attributes: {:?}", self.attrs) + write!(f, " with attributes: {:?}", self.attrs)?; + write!(f, " with inputs: {:?}", self.inputs)?; + write!(f, " with output: {:?}", self.output) } } diff --git a/compiler/rustc_ast/src/expand/typetree.rs b/compiler/rustc_ast/src/expand/typetree.rs index 9a2dd2e85e0d6..e7b4f3aff413a 100644 --- a/compiler/rustc_ast/src/expand/typetree.rs +++ b/compiler/rustc_ast/src/expand/typetree.rs @@ -31,6 +31,7 @@ pub enum Kind { Half, Float, Double, + F128, Unknown, } diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index f1951049b4760..5fe218776e539 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -15,6 +15,7 @@ #![feature(associated_type_defaults)] #![feature(box_patterns)] #![feature(if_let_guard)] +#![feature(iter_order_by)] #![feature(macro_metavar_expr)] #![feature(rustdoc_internals)] #![recursion_limit = "256"] diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 6dc6d1026f621..e1231312a2afd 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -881,11 +881,11 @@ impl Token { } pub fn is_qpath_start(&self) -> bool { - self == &Lt || self == &Shl + matches!(self.kind, Lt | Shl) } pub fn is_path_start(&self) -> bool { - self == &PathSep + self.kind == PathSep || self.is_qpath_start() || matches!(self.is_metavar_seq(), Some(MetaVarKind::Path)) || self.is_path_segment_keyword() diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index a5d8fbfac612a..4111182c3b7dc 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -48,9 +48,7 @@ impl TokenTree { match (self, other) { (TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind, (TokenTree::Delimited(.., delim, tts), TokenTree::Delimited(.., delim2, tts2)) => { - delim == delim2 - && tts.len() == tts2.len() - && tts.iter().zip(tts2.iter()).all(|(a, b)| a.eq_unspanned(b)) + delim == delim2 && tts.iter().eq_by(tts2.iter(), |a, b| a.eq_unspanned(b)) } _ => false, } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 68b3d2b036865..03e5a6edeece5 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -389,9 +389,9 @@ macro_rules! common_visitor_and_walkers { ThinVec<(NodeId, Path)>, ThinVec, ThinVec, - ThinVec>, + ThinVec, ThinVec>, - ThinVec>, + ThinVec, ); // This macro generates `impl Visitable` and `impl MutVisitable` that forward to `Walkable` @@ -471,8 +471,6 @@ macro_rules! common_visitor_and_walkers { TraitBoundModifiers, TraitObjectSyntax, TyAlias, - TyAliasWhereClause, - TyAliasWhereClauses, TyKind, TyPatKind, UnOp, diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs new file mode 100644 index 0000000000000..2f1c3d66d4e70 --- /dev/null +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -0,0 +1,324 @@ +use thin_vec::thin_vec; + +use crate::LoweringContext; + +impl<'a, 'hir> LoweringContext<'a, 'hir> { + /// Lowered contracts are guarded with the `contract_checks` compiler flag, + /// i.e. the flag turns into a boolean guard in the lowered HIR. The reason + /// for not eliminating the contract code entirely when the `contract_checks` + /// flag is disabled is so that contracts can be type checked, even when + /// they are disabled, which avoids them becoming stale (i.e. out of sync + /// with the codebase) over time. + /// + /// The optimiser should be able to eliminate all contract code guarded + /// by `if false`, leaving the original body intact when runtime contract + /// checks are disabled. + pub(super) fn lower_contract( + &mut self, + body: impl FnOnce(&mut Self) -> rustc_hir::Expr<'hir>, + contract: &rustc_ast::FnContract, + ) -> rustc_hir::Expr<'hir> { + match (&contract.requires, &contract.ensures) { + (Some(req), Some(ens)) => { + // Lower the fn contract, which turns: + // + // { body } + // + // into: + // + // let __postcond = if contract_checks { + // contract_check_requires(PRECOND); + // Some(|ret_val| POSTCOND) + // } else { + // None + // }; + // { + // let ret = { body }; + // + // if contract_checks { + // contract_check_ensures(__postcond, ret) + // } else { + // ret + // } + // } + + let precond = self.lower_precond(req); + let postcond_checker = self.lower_postcond_checker(ens); + + let contract_check = + self.lower_contract_check_with_postcond(Some(precond), postcond_checker); + + let wrapped_body = + self.wrap_body_with_contract_check(body, contract_check, postcond_checker.span); + self.expr_block(wrapped_body) + } + (None, Some(ens)) => { + // Lower the fn contract, which turns: + // + // { body } + // + // into: + // + // let __postcond = if contract_checks { + // Some(|ret_val| POSTCOND) + // } else { + // None + // }; + // { + // let ret = { body }; + // + // if contract_checks { + // contract_check_ensures(__postcond, ret) + // } else { + // ret + // } + // } + + let postcond_checker = self.lower_postcond_checker(ens); + let contract_check = + self.lower_contract_check_with_postcond(None, postcond_checker); + + let wrapped_body = + self.wrap_body_with_contract_check(body, contract_check, postcond_checker.span); + self.expr_block(wrapped_body) + } + (Some(req), None) => { + // Lower the fn contract, which turns: + // + // { body } + // + // into: + // + // { + // if contracts_checks { + // contract_requires(PRECOND); + // } + // body + // } + let precond = self.lower_precond(req); + let precond_check = self.lower_contract_check_just_precond(precond); + + let body = self.arena.alloc(body(self)); + + // Flatten the body into precond check, then body. + let wrapped_body = self.block_all( + body.span, + self.arena.alloc_from_iter([precond_check].into_iter()), + Some(body), + ); + self.expr_block(wrapped_body) + } + (None, None) => body(self), + } + } + + /// Lower the precondition check intrinsic. + fn lower_precond(&mut self, req: &Box) -> rustc_hir::Stmt<'hir> { + let lowered_req = self.lower_expr_mut(&req); + let req_span = self.mark_span_with_reason( + rustc_span::DesugaringKind::Contract, + lowered_req.span, + None, + ); + let precond = self.expr_call_lang_item_fn_mut( + req_span, + rustc_hir::LangItem::ContractCheckRequires, + &*arena_vec![self; lowered_req], + ); + self.stmt_expr(req.span, precond) + } + + fn lower_postcond_checker( + &mut self, + ens: &Box, + ) -> &'hir rustc_hir::Expr<'hir> { + let ens_span = self.lower_span(ens.span); + let ens_span = + self.mark_span_with_reason(rustc_span::DesugaringKind::Contract, ens_span, None); + let lowered_ens = self.lower_expr_mut(&ens); + self.expr_call_lang_item_fn( + ens_span, + rustc_hir::LangItem::ContractBuildCheckEnsures, + &*arena_vec![self; lowered_ens], + ) + } + + fn lower_contract_check_just_precond( + &mut self, + precond: rustc_hir::Stmt<'hir>, + ) -> rustc_hir::Stmt<'hir> { + let stmts = self.arena.alloc_from_iter([precond].into_iter()); + + let then_block_stmts = self.block_all(precond.span, stmts, None); + let then_block = self.arena.alloc(self.expr_block(&then_block_stmts)); + + let precond_check = rustc_hir::ExprKind::If( + self.arena.alloc(self.expr_bool_literal(precond.span, self.tcx.sess.contract_checks())), + then_block, + None, + ); + + let precond_check = self.expr(precond.span, precond_check); + self.stmt_expr(precond.span, precond_check) + } + + fn lower_contract_check_with_postcond( + &mut self, + precond: Option>, + postcond_checker: &'hir rustc_hir::Expr<'hir>, + ) -> &'hir rustc_hir::Expr<'hir> { + let stmts = self.arena.alloc_from_iter(precond.into_iter()); + let span = match precond { + Some(precond) => precond.span, + None => postcond_checker.span, + }; + + let postcond_checker = self.arena.alloc(self.expr_enum_variant_lang_item( + postcond_checker.span, + rustc_hir::lang_items::LangItem::OptionSome, + &*arena_vec![self; *postcond_checker], + )); + let then_block_stmts = self.block_all(span, stmts, Some(postcond_checker)); + let then_block = self.arena.alloc(self.expr_block(&then_block_stmts)); + + let none_expr = self.arena.alloc(self.expr_enum_variant_lang_item( + postcond_checker.span, + rustc_hir::lang_items::LangItem::OptionNone, + Default::default(), + )); + let else_block = self.block_expr(none_expr); + let else_block = self.arena.alloc(self.expr_block(else_block)); + + let contract_check = rustc_hir::ExprKind::If( + self.arena.alloc(self.expr_bool_literal(span, self.tcx.sess.contract_checks())), + then_block, + Some(else_block), + ); + self.arena.alloc(self.expr(span, contract_check)) + } + + fn wrap_body_with_contract_check( + &mut self, + body: impl FnOnce(&mut Self) -> rustc_hir::Expr<'hir>, + contract_check: &'hir rustc_hir::Expr<'hir>, + postcond_span: rustc_span::Span, + ) -> &'hir rustc_hir::Block<'hir> { + let check_ident: rustc_span::Ident = + rustc_span::Ident::from_str_and_span("__ensures_checker", postcond_span); + let (check_hir_id, postcond_decl) = { + // Set up the postcondition `let` statement. + let (checker_pat, check_hir_id) = self.pat_ident_binding_mode_mut( + postcond_span, + check_ident, + rustc_hir::BindingMode::NONE, + ); + ( + check_hir_id, + self.stmt_let_pat( + None, + postcond_span, + Some(contract_check), + self.arena.alloc(checker_pat), + rustc_hir::LocalSource::Contract, + ), + ) + }; + + // Install contract_ensures so we will intercept `return` statements, + // then lower the body. + self.contract_ensures = Some((postcond_span, check_ident, check_hir_id)); + let body = self.arena.alloc(body(self)); + + // Finally, inject an ensures check on the implicit return of the body. + let body = self.inject_ensures_check(body, postcond_span, check_ident, check_hir_id); + + // Flatten the body into precond, then postcond, then wrapped body. + let wrapped_body = self.block_all( + body.span, + self.arena.alloc_from_iter([postcond_decl].into_iter()), + Some(body), + ); + wrapped_body + } + + /// Create an `ExprKind::Ret` that is optionally wrapped by a call to check + /// a contract ensures clause, if it exists. + pub(super) fn checked_return( + &mut self, + opt_expr: Option<&'hir rustc_hir::Expr<'hir>>, + ) -> rustc_hir::ExprKind<'hir> { + let checked_ret = + if let Some((check_span, check_ident, check_hir_id)) = self.contract_ensures { + let expr = opt_expr.unwrap_or_else(|| self.expr_unit(check_span)); + Some(self.inject_ensures_check(expr, check_span, check_ident, check_hir_id)) + } else { + opt_expr + }; + rustc_hir::ExprKind::Ret(checked_ret) + } + + /// Wraps an expression with a call to the ensures check before it gets returned. + pub(super) fn inject_ensures_check( + &mut self, + expr: &'hir rustc_hir::Expr<'hir>, + span: rustc_span::Span, + cond_ident: rustc_span::Ident, + cond_hir_id: rustc_hir::HirId, + ) -> &'hir rustc_hir::Expr<'hir> { + // { + // let ret = { body }; + // + // if contract_checks { + // contract_check_ensures(__postcond, ret) + // } else { + // ret + // } + // } + let ret_ident: rustc_span::Ident = rustc_span::Ident::from_str_and_span("__ret", span); + + // Set up the return `let` statement. + let (ret_pat, ret_hir_id) = + self.pat_ident_binding_mode_mut(span, ret_ident, rustc_hir::BindingMode::NONE); + + let ret_stmt = self.stmt_let_pat( + None, + span, + Some(expr), + self.arena.alloc(ret_pat), + rustc_hir::LocalSource::Contract, + ); + + let ret = self.expr_ident(span, ret_ident, ret_hir_id); + + let cond_fn = self.expr_ident(span, cond_ident, cond_hir_id); + let contract_check = self.expr_call_lang_item_fn_mut( + span, + rustc_hir::LangItem::ContractCheckEnsures, + arena_vec![self; *cond_fn, *ret], + ); + let contract_check = self.arena.alloc(contract_check); + let call_expr = self.block_expr_block(contract_check); + + // same ident can't be used in 2 places, so we create a new one for the + // else branch + let ret = self.expr_ident(span, ret_ident, ret_hir_id); + let ret_block = self.block_expr_block(ret); + + let contracts_enabled: rustc_hir::Expr<'_> = + self.expr_bool_literal(span, self.tcx.sess.contract_checks()); + let contract_check = self.arena.alloc(self.expr( + span, + rustc_hir::ExprKind::If( + self.arena.alloc(contracts_enabled), + call_expr, + Some(ret_block), + ), + )); + + let attrs: rustc_ast::AttrVec = thin_vec![self.unreachable_code_attr(span)]; + self.lower_attrs(contract_check.hir_id, &attrs, span, rustc_hir::Target::Expression); + + let ret_block = self.block_all(span, arena_vec![self; ret_stmt], Some(contract_check)); + self.arena.alloc(self.expr_block(self.arena.alloc(ret_block))) + } +} diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index bb6b25baf013d..4a9b9f544b53d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -383,36 +383,6 @@ impl<'hir> LoweringContext<'_, 'hir> { }) } - /// Create an `ExprKind::Ret` that is optionally wrapped by a call to check - /// a contract ensures clause, if it exists. - fn checked_return(&mut self, opt_expr: Option<&'hir hir::Expr<'hir>>) -> hir::ExprKind<'hir> { - let checked_ret = - if let Some((check_span, check_ident, check_hir_id)) = self.contract_ensures { - let expr = opt_expr.unwrap_or_else(|| self.expr_unit(check_span)); - Some(self.inject_ensures_check(expr, check_span, check_ident, check_hir_id)) - } else { - opt_expr - }; - hir::ExprKind::Ret(checked_ret) - } - - /// Wraps an expression with a call to the ensures check before it gets returned. - pub(crate) fn inject_ensures_check( - &mut self, - expr: &'hir hir::Expr<'hir>, - span: Span, - cond_ident: Ident, - cond_hir_id: HirId, - ) -> &'hir hir::Expr<'hir> { - let cond_fn = self.expr_ident(span, cond_ident, cond_hir_id); - let call_expr = self.expr_call_lang_item_fn_mut( - span, - hir::LangItem::ContractCheckEnsures, - arena_vec![self; *cond_fn, *expr], - ); - self.arena.alloc(call_expr) - } - pub(crate) fn lower_const_block(&mut self, c: &AnonConst) -> hir::ConstBlock { self.with_new_scopes(c.value.span, |this| { let def_id = this.local_def_id(c.id); @@ -1971,16 +1941,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }; - // `#[allow(unreachable_code)]` - let attr = attr::mk_attr_nested_word( - &self.tcx.sess.psess.attr_id_generator, - AttrStyle::Outer, - Safety::Default, - sym::allow, - sym::unreachable_code, - try_span, - ); - let attrs: AttrVec = thin_vec![attr]; + let attrs: AttrVec = thin_vec![self.unreachable_code_attr(try_span)]; // `ControlFlow::Continue(val) => #[allow(unreachable_code)] val,` let continue_arm = { @@ -2120,7 +2081,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e)) } - fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { + pub(super) fn expr_unit(&mut self, sp: Span) -> &'hir hir::Expr<'hir> { self.arena.alloc(self.expr(sp, hir::ExprKind::Tup(&[]))) } @@ -2161,6 +2122,43 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Call(e, args)) } + pub(super) fn expr_struct( + &mut self, + span: Span, + path: &'hir hir::QPath<'hir>, + fields: &'hir [hir::ExprField<'hir>], + ) -> hir::Expr<'hir> { + self.expr(span, hir::ExprKind::Struct(path, fields, rustc_hir::StructTailExpr::None)) + } + + pub(super) fn expr_enum_variant( + &mut self, + span: Span, + path: &'hir hir::QPath<'hir>, + fields: &'hir [hir::Expr<'hir>], + ) -> hir::Expr<'hir> { + let fields = self.arena.alloc_from_iter(fields.into_iter().enumerate().map(|(i, f)| { + hir::ExprField { + hir_id: self.next_id(), + ident: Ident::from_str(&i.to_string()), + expr: f, + span: f.span, + is_shorthand: false, + } + })); + self.expr_struct(span, path, fields) + } + + pub(super) fn expr_enum_variant_lang_item( + &mut self, + span: Span, + lang_item: hir::LangItem, + fields: &'hir [hir::Expr<'hir>], + ) -> hir::Expr<'hir> { + let path = self.arena.alloc(self.lang_item_path(span, lang_item)); + self.expr_enum_variant(span, path, fields) + } + pub(super) fn expr_call( &mut self, span: Span, @@ -2189,8 +2187,21 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(self.expr_call_lang_item_fn_mut(span, lang_item, args)) } - fn expr_lang_item_path(&mut self, span: Span, lang_item: hir::LangItem) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Path(hir::QPath::LangItem(lang_item, self.lower_span(span)))) + pub(super) fn expr_lang_item_path( + &mut self, + span: Span, + lang_item: hir::LangItem, + ) -> hir::Expr<'hir> { + let path = self.lang_item_path(span, lang_item); + self.expr(span, hir::ExprKind::Path(path)) + } + + pub(super) fn lang_item_path( + &mut self, + span: Span, + lang_item: hir::LangItem, + ) -> hir::QPath<'hir> { + hir::QPath::LangItem(lang_item, self.lower_span(span)) } /// `::name` @@ -2270,6 +2281,17 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(b.span, hir::ExprKind::Block(b, None)) } + /// Wrap an expression in a block, and wrap that block in an expression again. + /// Useful for constructing if-expressions, which require expressions of + /// kind block. + pub(super) fn block_expr_block( + &mut self, + expr: &'hir hir::Expr<'hir>, + ) -> &'hir hir::Expr<'hir> { + let b = self.block_expr(expr); + self.arena.alloc(self.expr_block(b)) + } + pub(super) fn expr_array_ref( &mut self, span: Span, @@ -2283,6 +2305,10 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, expr)) } + pub(super) fn expr_bool_literal(&mut self, span: Span, val: bool) -> hir::Expr<'hir> { + self.expr(span, hir::ExprKind::Lit(Spanned { node: LitKind::Bool(val), span })) + } + pub(super) fn expr(&mut self, span: Span, kind: hir::ExprKind<'hir>) -> hir::Expr<'hir> { let hir_id = self.next_id(); hir::Expr { hir_id, kind, span: self.lower_span(span) } @@ -2316,6 +2342,19 @@ impl<'hir> LoweringContext<'_, 'hir> { body: expr, } } + + /// `#[allow(unreachable_code)]` + pub(super) fn unreachable_code_attr(&mut self, span: Span) -> Attribute { + let attr = attr::mk_attr_nested_word( + &self.tcx.sess.psess.attr_id_generator, + AttrStyle::Outer, + Safety::Default, + sym::allow, + sym::unreachable_code, + span, + ); + attr + } } /// Used by [`LoweringContext::make_lowered_await`] to customize the desugaring based on what kind diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index ec9d26eb33f48..2871430030c45 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -487,26 +487,6 @@ fn expand_format_args<'hir>( // Generate: // [] (vec![], ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(&[])))) - } else if argmap.len() == 1 && arguments.len() == 1 { - // Only one argument, so we don't need to make the `args` tuple. - // - // Generate: - // super let args = [::new_display(&arg)]; - let args = ctx.arena.alloc_from_iter(argmap.iter().map( - |(&(arg_index, ty), &placeholder_span)| { - let arg = &arguments[arg_index]; - let placeholder_span = - placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt()); - let arg = ctx.lower_expr(&arg.expr); - let ref_arg = ctx.arena.alloc(ctx.expr_ref(arg.span.with_ctxt(macsp.ctxt()), arg)); - make_argument(ctx, placeholder_span, ref_arg, ty) - }, - )); - let args = ctx.arena.alloc(ctx.expr(macsp, hir::ExprKind::Array(args))); - let args_ident = Ident::new(sym::args, macsp); - let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident); - let let_statement = ctx.stmt_super_let_pat(macsp, args_pat, Some(args)); - (vec![let_statement], ctx.arena.alloc(ctx.expr_ident_mut(macsp, args_ident, args_hir_id))) } else { // Generate: // super let args = (&arg0, &arg1, &…); diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 53351f91c46bc..8527108f70419 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -36,20 +36,18 @@ pub(super) struct ItemLowerer<'a, 'hir> { /// clause if it exists. fn add_ty_alias_where_clause( generics: &mut ast::Generics, - mut where_clauses: TyAliasWhereClauses, + after_where_clause: &ast::WhereClause, prefer_first: bool, ) { + generics.where_clause.predicates.extend_from_slice(&after_where_clause.predicates); + + let mut before = (generics.where_clause.has_where_token, generics.where_clause.span); + let mut after = (after_where_clause.has_where_token, after_where_clause.span); if !prefer_first { - (where_clauses.before, where_clauses.after) = (where_clauses.after, where_clauses.before); + (before, after) = (after, before); } - let where_clause = - if where_clauses.before.has_where_token || !where_clauses.after.has_where_token { - where_clauses.before - } else { - where_clauses.after - }; - generics.where_clause.has_where_token = where_clause.has_where_token; - generics.where_clause.span = where_clause.span; + (generics.where_clause.has_where_token, generics.where_clause.span) = + if before.0 || !after.0 { before } else { after }; } impl<'a, 'hir> ItemLowerer<'a, 'hir> { @@ -271,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_body(|this| (&[], this.expr(span, hir::ExprKind::InlineAsm(asm)))); hir::ItemKind::GlobalAsm { asm, fake_body } } - ItemKind::TyAlias(box TyAlias { ident, generics, where_clauses, ty, .. }) => { + ItemKind::TyAlias(box TyAlias { ident, generics, after_where_clause, ty, .. }) => { // We lower // // type Foo = impl Trait @@ -282,7 +280,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // opaque type Foo1: Trait let ident = self.lower_ident(*ident); let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, true); + add_ty_alias_where_clause(&mut generics, after_where_clause, true); let (generics, ty) = self.lower_generics( &generics, id, @@ -426,7 +424,7 @@ impl<'hir> LoweringContext<'_, 'hir> { |this| { this.lower_param_bounds( bounds, - RelaxedBoundPolicy::Allowed, + RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitAlias), ImplTraitContext::Disallowed(ImplTraitPosition::Bound), ) }, @@ -901,10 +899,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } AssocItemKind::Type(box TyAlias { - ident, generics, where_clauses, bounds, ty, .. + ident, + generics, + after_where_clause, + bounds, + ty, + .. }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, false); + add_ty_alias_where_clause(&mut generics, after_where_clause, false); let (generics, kind) = self.lower_generics( &generics, i.id, @@ -1070,9 +1073,11 @@ impl<'hir> LoweringContext<'_, 'hir> { (*ident, (generics, hir::ImplItemKind::Fn(sig, body_id))) } - AssocItemKind::Type(box TyAlias { ident, generics, where_clauses, ty, .. }) => { + AssocItemKind::Type(box TyAlias { + ident, generics, after_where_clause, ty, .. + }) => { let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, false); + add_ty_alias_where_clause(&mut generics, after_where_clause, false); ( *ident, self.lower_generics( @@ -1214,76 +1219,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let params = this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))); - // Optionally lower the fn contract, which turns: - // - // { body } - // - // into: - // - // { contract_requires(PRECOND); let __postcond = |ret_val| POSTCOND; postcond({ body }) } + // Optionally lower the fn contract if let Some(contract) = contract { - let precond = if let Some(req) = &contract.requires { - // Lower the precondition check intrinsic. - let lowered_req = this.lower_expr_mut(&req); - let req_span = this.mark_span_with_reason( - DesugaringKind::Contract, - lowered_req.span, - None, - ); - let precond = this.expr_call_lang_item_fn_mut( - req_span, - hir::LangItem::ContractCheckRequires, - &*arena_vec![this; lowered_req], - ); - Some(this.stmt_expr(req.span, precond)) - } else { - None - }; - let (postcond, body) = if let Some(ens) = &contract.ensures { - let ens_span = this.lower_span(ens.span); - let ens_span = - this.mark_span_with_reason(DesugaringKind::Contract, ens_span, None); - // Set up the postcondition `let` statement. - let check_ident: Ident = - Ident::from_str_and_span("__ensures_checker", ens_span); - let (checker_pat, check_hir_id) = this.pat_ident_binding_mode_mut( - ens_span, - check_ident, - hir::BindingMode::NONE, - ); - let lowered_ens = this.lower_expr_mut(&ens); - let postcond_checker = this.expr_call_lang_item_fn( - ens_span, - hir::LangItem::ContractBuildCheckEnsures, - &*arena_vec![this; lowered_ens], - ); - let postcond = this.stmt_let_pat( - None, - ens_span, - Some(postcond_checker), - this.arena.alloc(checker_pat), - hir::LocalSource::Contract, - ); - - // Install contract_ensures so we will intercept `return` statements, - // then lower the body. - this.contract_ensures = Some((ens_span, check_ident, check_hir_id)); - let body = this.arena.alloc(body(this)); - - // Finally, inject an ensures check on the implicit return of the body. - let body = this.inject_ensures_check(body, ens_span, check_ident, check_hir_id); - (Some(postcond), body) - } else { - let body = &*this.arena.alloc(body(this)); - (None, body) - }; - // Flatten the body into precond, then postcond, then wrapped body. - let wrapped_body = this.block_all( - body.span, - this.arena.alloc_from_iter([precond, postcond].into_iter().flatten()), - Some(body), - ); - (params, this.expr_block(wrapped_body)) + (params, this.lower_contract(body, contract)) } else { (params, body(this)) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 4e2243e87873c..d959657e7fe57 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -77,6 +77,7 @@ macro_rules! arena_vec { mod asm; mod block; +mod contract; mod delegation; mod errors; mod expr; @@ -296,6 +297,7 @@ enum RelaxedBoundPolicy<'a> { enum RelaxedBoundForbiddenReason { TraitObjectTy, SuperTrait, + TraitAlias, AssocTyBounds, LateBoundVarsInScope, } @@ -2085,12 +2087,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, rbp: RelaxedBoundPolicy<'_>, ) { - // Even though feature `more_maybe_bounds` bypasses the given policy and (currently) enables - // relaxed bounds in every conceivable position[^1], we don't want to advertise it to the user - // (via a feature gate) since it's super internal. Besides this, it'd be quite distracting. + // Even though feature `more_maybe_bounds` enables the user to relax all default bounds + // other than `Sized` in a lot more positions (thereby bypassing the given policy), we don't + // want to advertise it to the user (via a feature gate error) since it's super internal. // - // [^1]: Strictly speaking, this is incorrect (at the very least for `Sized`) because it's - // no longer fully consistent with default trait elaboration in HIR ty lowering. + // FIXME(more_maybe_bounds): Moreover, if we actually were to add proper default traits + // (like a hypothetical `Move` or `Leak`) we would want to validate the location according + // to default trait elaboration in HIR ty lowering (which depends on the specific trait in + // question: E.g., `?Sized` & `?Move` most likely won't be allowed in all the same places). match rbp { RelaxedBoundPolicy::Allowed => return, @@ -2103,33 +2107,41 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } RelaxedBoundPolicy::Forbidden(reason) => { + let gate = |context, subject| { + let extended = self.tcx.features().more_maybe_bounds(); + let is_sized = trait_ref + .trait_def_id() + .is_some_and(|def_id| self.tcx.is_lang_item(def_id, hir::LangItem::Sized)); + + if extended && !is_sized { + return; + } + + let prefix = if extended { "`Sized` " } else { "" }; + let mut diag = self.dcx().struct_span_err( + span, + format!("relaxed {prefix}bounds are not permitted in {context}"), + ); + if is_sized { + diag.note(format!( + "{subject} are not implicitly bounded by `Sized`, \ + so there is nothing to relax" + )); + } + diag.emit(); + }; + match reason { RelaxedBoundForbiddenReason::TraitObjectTy => { - if self.tcx.features().more_maybe_bounds() { - return; - } - - self.dcx().span_err( - span, - "relaxed bounds are not permitted in trait object types", - ); + gate("trait object types", "trait object types"); return; } RelaxedBoundForbiddenReason::SuperTrait => { - if self.tcx.features().more_maybe_bounds() { - return; - } - - let mut diag = self.dcx().struct_span_err( - span, - "relaxed bounds are not permitted in supertrait bounds", - ); - if let Some(def_id) = trait_ref.trait_def_id() - && self.tcx.is_lang_item(def_id, hir::LangItem::Sized) - { - diag.note("traits are `?Sized` by default"); - } - diag.emit(); + gate("supertrait bounds", "traits"); + return; + } + RelaxedBoundForbiddenReason::TraitAlias => { + gate("trait alias bounds", "trait aliases"); return; } RelaxedBoundForbiddenReason::AssocTyBounds @@ -2142,7 +2154,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .struct_span_err(span, "this relaxed bound is not permitted here") .with_note( "in this context, relaxed bounds are only allowed on \ - type parameters defined by the closest item", + type parameters defined on the closest item", ) .emit(); } diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index ed159f37051c1..7e4fa840f2523 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -143,7 +143,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } // return inner to be processed in next loop PatKind::Paren(inner) => pattern = inner, - PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span), + PatKind::MacCall(_) => { + panic!("{pattern:#?} shouldn't exist here") + } PatKind::Err(guar) => break hir::PatKind::Err(*guar), } }; @@ -154,7 +156,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_pat_tuple( &mut self, - pats: &[Box], + pats: &[Pat], ctx: &str, ) -> (&'hir [hir::Pat<'hir>], hir::DotDotPos) { let mut elems = Vec::with_capacity(pats.len()); @@ -209,7 +211,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// When encountering `($binding_mode $ident @)? ..` (`slice`), /// this is interpreted as a sub-slice pattern semantically. /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`. - fn lower_pat_slice(&mut self, pats: &[Box]) -> hir::PatKind<'hir> { + fn lower_pat_slice(&mut self, pats: &[Pat]) -> hir::PatKind<'hir> { let mut before = Vec::new(); let mut after = Vec::new(); let mut slice = None; @@ -460,6 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) }), ), + TyPatKind::NotNull => hir::TyPatKind::NotNull, TyPatKind::Or(variants) => { hir::TyPatKind::Or(self.arena.alloc_from_iter( variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)), diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index 8dcf3e3aa3882..5e10c5a77d97d 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -64,8 +64,6 @@ ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect -ast_passes_c_variadic_associated_function = associated functions cannot have a C variable argument list - ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions .label = `extern "{$abi}"` because of this .help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list @@ -216,6 +214,10 @@ ast_passes_match_arm_with_no_body = .suggestion = add a body after the pattern ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe + .suggestion = needs `unsafe` before the extern keyword + +ast_passes_missing_unsafe_on_extern_lint = extern blocks should be unsafe + .suggestion = needs `unsafe` before the extern keyword ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name .help = consider using the `#[path]` attribute to specify filesystem path diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index a6ef89b553db4..93f8b74ad561f 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -145,25 +145,24 @@ impl<'a> AstValidator<'a> { &mut self, ty_alias: &TyAlias, ) -> Result<(), errors::WhereClauseBeforeTypeAlias> { - if ty_alias.ty.is_none() || !ty_alias.where_clauses.before.has_where_token { + if ty_alias.ty.is_none() || !ty_alias.generics.where_clause.has_where_token { return Ok(()); } - let (before_predicates, after_predicates) = - ty_alias.generics.where_clause.predicates.split_at(ty_alias.where_clauses.split); - let span = ty_alias.where_clauses.before.span; + let span = ty_alias.generics.where_clause.span; - let sugg = if !before_predicates.is_empty() || !ty_alias.where_clauses.after.has_where_token + let sugg = if !ty_alias.generics.where_clause.predicates.is_empty() + || !ty_alias.after_where_clause.has_where_token { let mut state = State::new(); - if !ty_alias.where_clauses.after.has_where_token { + if !ty_alias.after_where_clause.has_where_token { state.space(); state.word_space("where"); } - let mut first = after_predicates.is_empty(); - for p in before_predicates { + let mut first = ty_alias.after_where_clause.predicates.is_empty(); + for p in &ty_alias.generics.where_clause.predicates { if !first { state.word_space(","); } @@ -174,7 +173,7 @@ impl<'a> AstValidator<'a> { errors::WhereClauseBeforeTypeAliasSugg::Move { left: span, snippet: state.s.eof(), - right: ty_alias.where_clauses.after.span.shrink_to_hi(), + right: ty_alias.after_where_clause.span.shrink_to_hi(), } } else { errors::WhereClauseBeforeTypeAliasSugg::Remove { span } @@ -566,11 +565,7 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(errors::BoundInContext { span, ctx }); } - fn check_foreign_ty_genericless( - &self, - generics: &Generics, - where_clauses: &TyAliasWhereClauses, - ) { + fn check_foreign_ty_genericless(&self, generics: &Generics, after_where_clause: &WhereClause) { let cannot_have = |span, descr, remove_descr| { self.dcx().emit_err(errors::ExternTypesCannotHave { span, @@ -584,14 +579,14 @@ impl<'a> AstValidator<'a> { cannot_have(generics.span, "generic parameters", "generic parameters"); } - let check_where_clause = |where_clause: TyAliasWhereClause| { + let check_where_clause = |where_clause: &WhereClause| { if where_clause.has_where_token { cannot_have(where_clause.span, "`where` clauses", "`where` clause"); } }; - check_where_clause(where_clauses.before); - check_where_clause(where_clauses.after); + check_where_clause(&generics.where_clause); + check_where_clause(&after_where_clause); } fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body_span: Option) { @@ -696,7 +691,7 @@ impl<'a> AstValidator<'a> { match fn_ctxt { FnCtxt::Foreign => return, - FnCtxt::Free => match sig.header.ext { + FnCtxt::Free | FnCtxt::Assoc(_) => match sig.header.ext { Extern::Implicit(_) => { if !matches!(sig.header.safety, Safety::Unsafe(_)) { self.dcx().emit_err(errors::CVariadicMustBeUnsafe { @@ -726,11 +721,6 @@ impl<'a> AstValidator<'a> { self.dcx().emit_err(err); } }, - FnCtxt::Assoc(_) => { - // For now, C variable argument lists are unsupported in associated functions. - let err = errors::CVariadicAssociatedFunction { span: variadic_param.span }; - self.dcx().emit_err(err); - } } } @@ -1131,7 +1121,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { MISSING_UNSAFE_ON_EXTERN, item.id, item.span, - BuiltinLintDiag::MissingUnsafeOnExtern { + errors::MissingUnsafeOnExternLint { suggestion: item.span.shrink_to_lo(), }, ); @@ -1266,7 +1256,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_item(self, item); } ItemKind::TyAlias( - ty_alias @ box TyAlias { defaultness, bounds, where_clauses, ty, .. }, + ty_alias @ box TyAlias { defaultness, bounds, after_where_clause, ty, .. }, ) => { self.check_defaultness(item.span, *defaultness); if ty.is_none() { @@ -1281,9 +1271,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let Err(err) = self.check_type_alias_where_clause_location(ty_alias) { self.dcx().emit_err(err); } - } else if where_clauses.after.has_where_token { + } else if after_where_clause.has_where_token { self.dcx().emit_err(errors::WhereClauseAfterTypeAlias { - span: where_clauses.after.span, + span: after_where_clause.span, help: self.sess.is_nightly_build(), }); } @@ -1313,7 +1303,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, .. @@ -1321,7 +1311,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(fi.span, *defaultness); self.check_foreign_kind_bodyless(*ident, "type", ty.as_ref().map(|b| b.span)); self.check_type_no_bounds(bounds, "`extern` blocks"); - self.check_foreign_ty_genericless(generics, where_clauses); + self.check_foreign_ty_genericless(generics, after_where_clause); self.check_foreign_item_ascii_only(*ident); } ForeignItemKind::Static(box StaticItem { ident, safety, expr, .. }) => { diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index ae805042c549f..fd75e999d1381 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -318,13 +318,6 @@ pub(crate) struct ExternItemAscii { pub block: Span, } -#[derive(Diagnostic)] -#[diag(ast_passes_c_variadic_associated_function)] -pub(crate) struct CVariadicAssociatedFunction { - #[primary_span] - pub span: Span, -} - #[derive(Diagnostic)] #[diag(ast_passes_c_variadic_no_extern)] #[help] @@ -523,6 +516,13 @@ pub(crate) struct MissingUnsafeOnExtern { pub span: Span, } +#[derive(LintDiagnostic)] +#[diag(ast_passes_missing_unsafe_on_extern_lint)] +pub(crate) struct MissingUnsafeOnExternLint { + #[suggestion(code = "unsafe ", applicability = "machine-applicable")] + pub suggestion: Span, +} + #[derive(Diagnostic)] #[diag(ast_passes_fieldless_union)] pub(crate) struct FieldlessUnion { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 9ab5b0b354726..b8a29a9a08f43 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -183,7 +183,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_doc!( "experimental" { cfg => doc_cfg - cfg_hide => doc_cfg_hide + auto_cfg => doc_cfg masked => doc_masked notable_trait => doc_notable_trait } @@ -622,11 +622,7 @@ fn maybe_stage_features(sess: &Session, features: &Features, krate: &ast::Crate) } fn check_incompatible_features(sess: &Session, features: &Features) { - let enabled_lang_features = - features.enabled_lang_features().iter().map(|feat| (feat.gate_name, feat.attr_sp)); - let enabled_lib_features = - features.enabled_lib_features().iter().map(|feat| (feat.gate_name, feat.attr_sp)); - let enabled_features = enabled_lang_features.chain(enabled_lib_features); + let enabled_features = features.enabled_features_iter_stable_order(); for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES .iter() diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 41b520b04c993..a5e2bcaa3bd06 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1232,6 +1232,7 @@ impl<'a> State<'a> { self.print_expr_anon_const(end, &[]); } } + rustc_ast::TyPatKind::NotNull => self.word("!null"), rustc_ast::TyPatKind::Or(variants) => { let mut first = true; for pat in variants { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index ab402cbb8dc12..3412660863407 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -59,14 +59,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), vis, @@ -127,14 +127,12 @@ impl<'a> State<'a> { &mut self, ident: Ident, generics: &ast::Generics, - where_clauses: ast::TyAliasWhereClauses, + after_where_clause: &ast::WhereClause, bounds: &ast::GenericBounds, ty: Option<&ast::Ty>, vis: &ast::Visibility, defaultness: ast::Defaultness, ) { - let (before_predicates, after_predicates) = - generics.where_clause.predicates.split_at(where_clauses.split); let (cb, ib) = self.head(""); self.print_visibility(vis); self.print_defaultness(defaultness); @@ -145,13 +143,13 @@ impl<'a> State<'a> { self.word_nbsp(":"); self.print_type_bounds(bounds); } - self.print_where_clause_parts(where_clauses.before.has_where_token, before_predicates); + self.print_where_clause(&generics.where_clause); if let Some(ty) = ty { self.space(); self.word_space("="); self.print_type(ty); } - self.print_where_clause_parts(where_clauses.after.has_where_token, after_predicates); + self.print_where_clause(&after_where_clause); self.word(";"); self.end(ib); self.end(cb); @@ -283,14 +281,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), &item.vis, @@ -585,14 +583,14 @@ impl<'a> State<'a> { defaultness, ident, generics, - where_clauses, + after_where_clause, bounds, ty, }) => { self.print_associated_type( *ident, generics, - *where_clauses, + after_where_clause, bounds, ty.as_deref(), vis, @@ -759,14 +757,7 @@ impl<'a> State<'a> { } fn print_where_clause(&mut self, where_clause: &ast::WhereClause) { - self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates); - } - - fn print_where_clause_parts( - &mut self, - has_where_token: bool, - predicates: &[ast::WherePredicate], - ) { + let ast::WhereClause { has_where_token, ref predicates, span: _ } = *where_clause; if predicates.is_empty() && !has_where_token { return; } diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl index 839a5d23c3b4d..a2a5f8ab14236 100644 --- a/compiler/rustc_attr_parsing/messages.ftl +++ b/compiler/rustc_attr_parsing/messages.ftl @@ -1,3 +1,11 @@ +attr_parsing_as_needed_compatibility = + linking modifier `as-needed` is only compatible with `dylib`, `framework` and `raw-dylib` linking kinds + +attr_parsing_bundle_needs_static = + linking modifier `bundle` is only compatible with `static` linking kind + +attr_parsing_cfg_attr_bad_delim = wrong `cfg_attr` delimiters + attr_parsing_cfg_predicate_identifier = `cfg` predicate key must be an identifier @@ -8,18 +16,22 @@ attr_parsing_deprecated_item_suggestion = attr_parsing_empty_attribute = unused attribute - .suggestion = remove this attribute + .suggestion = {$valid_without_list -> + [true] remove these parentheses + *[other] remove this attribute + } + .note = {$valid_without_list -> + [true] using `{$attr_path}` with an empty list is equivalent to not using a list at all + *[other] using `{$attr_path}` with an empty list has no effect + } -attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target} - .help = `#[{$name}]` can {$only}be applied to {$applied} - .suggestion = remove the attribute -attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target} - .warn = {-attr_parsing_previously_accepted} - .help = `#[{$name}]` can {$only}be applied to {$applied} - .suggestion = remove the attribute attr_parsing_empty_confusables = expected at least one confusable name +attr_parsing_empty_link_name = + link name must not be empty + .label = empty link name + attr_parsing_expected_one_cfg_pattern = expected 1 cfg-pattern @@ -40,6 +52,15 @@ attr_parsing_ill_formed_attribute_input = {$num_suggestions -> *[other] valid forms for the attribute are {$suggestions} } +attr_parsing_import_name_type_raw = + import name type can only be used with link kind `raw-dylib` + +attr_parsing_import_name_type_x86 = + import name type is only supported on x86 + +attr_parsing_incompatible_wasm_link = + `wasm_import_module` is incompatible with other arguments in `#[link]` attributes + attr_parsing_incorrect_repr_format_align_one_arg = incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses @@ -59,6 +80,11 @@ attr_parsing_incorrect_repr_format_packed_one_or_zero_arg = attr_parsing_invalid_alignment_value = invalid alignment value: {$error_part} +attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute + .label = this is not an unsafe attribute + .suggestion = remove the `unsafe(...)` + .note = extraneous unsafe is not allowed in attributes + attr_parsing_invalid_issue_string = `issue` must be a non-zero numeric string or "none" .must_not_be_zero = `issue` must not be "0", use "none" instead @@ -67,6 +93,13 @@ attr_parsing_invalid_issue_string = .pos_overflow = number too large to fit in target type .neg_overflow = number too small to fit in target type +attr_parsing_invalid_link_modifier = + invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed + +attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} + .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign + .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal + attr_parsing_invalid_predicate = invalid predicate `{$predicate}` @@ -92,9 +125,36 @@ attr_parsing_invalid_style = {$is_used_as_inner -> } .note = This attribute does not have an `!`, which means it is applied to this {$target} +attr_parsing_invalid_target = `#[{$name}]` attribute cannot be used on {$target} + .help = `#[{$name}]` can {$only}be applied to {$applied} + .suggestion = remove the attribute +attr_parsing_invalid_target_lint = `#[{$name}]` attribute cannot be used on {$target} + .warn = {-attr_parsing_previously_accepted} + .help = `#[{$name}]` can {$only}be applied to {$applied} + .suggestion = remove the attribute + +attr_parsing_limit_invalid = + `limit` must be a non-negative integer + .label = {$error_str} +attr_parsing_link_arg_unstable = + link kind `link-arg` is unstable + +attr_parsing_link_cfg_unstable = + link cfg is unstable + +attr_parsing_link_framework_apple = + link kind `framework` is only supported on Apple targets + attr_parsing_link_ordinal_out_of_range = ordinal value in `link_ordinal` is too large: `{$ordinal}` .note = the value may not exceed `u16::MAX` +attr_parsing_link_requires_name = + `#[link]` attribute requires a `name = "string"` argument + .label = missing `name` argument + +attr_parsing_meta_bad_delim = wrong meta list delimiters +attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)` + attr_parsing_missing_feature = missing 'feature' @@ -107,6 +167,9 @@ attr_parsing_missing_note = attr_parsing_missing_since = missing 'since' +attr_parsing_multiple_modifiers = + multiple `{$modifier}` modifiers in a single `modifiers` argument + attr_parsing_multiple_stability_levels = multiple stability levels @@ -122,6 +185,23 @@ attr_parsing_null_on_export = `export_name` may not contain null characters attr_parsing_null_on_link_section = `link_section` may not contain null characters +attr_parsing_null_on_objc_class = `objc::class!` may not contain null characters + +attr_parsing_null_on_objc_selector = `objc::selector!` may not contain null characters + +attr_parsing_objc_class_expected_string_literal = `objc::class!` expected a string literal + +attr_parsing_objc_selector_expected_string_literal = `objc::selector!` expected a string literal + +attr_parsing_raw_dylib_elf_unstable = + link kind `raw-dylib` is unstable on ELF platforms + +attr_parsing_raw_dylib_no_nul = + link name must not contain NUL characters if link kind is `raw-dylib` + +attr_parsing_raw_dylib_only_windows = + link kind `raw-dylib` is only supported on Windows targets + attr_parsing_repr_ident = meta item in `repr` must be an identifier @@ -136,6 +216,9 @@ attr_parsing_soft_no_args = attr_parsing_stability_outside_std = stability attributes may not be used outside of the standard library +attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes + .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) + attr_parsing_unknown_meta_item = unknown meta item '{$item}' .label = expected one of {$expected} @@ -148,6 +231,10 @@ attr_parsing_unrecognized_repr_hint = .help = valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` .note = for more information, visit +attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe + .label = usage of unsafe attribute +attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` + attr_parsing_unstable_cfg_target_compact = compact `cfg(target(..))` is experimental and subject to change @@ -177,77 +264,5 @@ attr_parsing_unused_multiple = -attr_parsing_previously_accepted = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -attr_parsing_meta_bad_delim = wrong meta list delimiters -attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)` - -attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe - .label = usage of unsafe attribute -attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)` - -attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute - .label = this is not an unsafe attribute - .suggestion = remove the `unsafe(...)` - .note = extraneous unsafe is not allowed in attributes - -attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr} - .remove_neg_sugg = negative numbers are not literals, try removing the `-` sign - .quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal - -attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes - .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) - -attr_parsing_as_needed_compatibility = - linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds - -attr_parsing_bundle_needs_static = - linking modifier `bundle` is only compatible with `static` linking kind - -attr_parsing_empty_link_name = - link name must not be empty - .label = empty link name - -attr_parsing_import_name_type_raw = - import name type can only be used with link kind `raw-dylib` - -attr_parsing_import_name_type_x86 = - import name type is only supported on x86 - -attr_parsing_incompatible_wasm_link = - `wasm_import_module` is incompatible with other arguments in `#[link]` attributes - -attr_parsing_invalid_link_modifier = - invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed - -attr_parsing_link_arg_unstable = - link kind `link-arg` is unstable - -attr_parsing_link_cfg_unstable = - link cfg is unstable - -attr_parsing_link_framework_apple = - link kind `framework` is only supported on Apple targets - -attr_parsing_link_requires_name = - `#[link]` attribute requires a `name = "string"` argument - .label = missing `name` argument - -attr_parsing_multiple_modifiers = - multiple `{$modifier}` modifiers in a single `modifiers` argument - -attr_parsing_multiple_renamings = - multiple renamings were specified for library `{$lib_name}` -attr_parsing_raw_dylib_no_nul = - link name must not contain NUL characters if link kind is `raw-dylib` - -attr_parsing_raw_dylib_elf_unstable = - link kind `raw-dylib` is unstable on ELF platforms - -attr_parsing_raw_dylib_only_windows = - link kind `raw-dylib` is only supported on Windows targets - attr_parsing_whole_archive_needs_static = linking modifier `whole-archive` is only compatible with `static` linking kind - -attr_parsing_limit_invalid = - `limit` must be a non-negative integer - .label = {$error_str} diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 7085561107978..af94e8acaf68e 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -1,19 +1,28 @@ -use rustc_ast::{LitKind, NodeId}; +use rustc_ast::token::Delimiter; +use rustc_ast::tokenstream::DelimSpan; +use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token}; +use rustc_errors::{Applicability, PResult}; use rustc_feature::{AttributeTemplate, Features, template}; -use rustc_hir::RustcVersion; use rustc_hir::attrs::CfgEntry; +use rustc_hir::{AttrPath, RustcVersion}; +use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_parse::{exp, parse_in}; use rustc_session::Session; use rustc_session::config::ExpectedValues; use rustc_session::lint::BuiltinLintDiag; use rustc_session::lint::builtin::UNEXPECTED_CFGS; -use rustc_session::parse::feature_err; +use rustc_session::parse::{ParseSess, feature_err}; use rustc_span::{Span, Symbol, sym}; use thin_vec::ThinVec; use crate::context::{AcceptContext, ShouldEmit, Stage}; use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, NameValueParser}; +use crate::session_diagnostics::{ + AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg, +}; use crate::{ - CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, try_gate_cfg, + AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics, + try_gate_cfg, }; pub const CFG_TEMPLATE: AttributeTemplate = template!( @@ -21,7 +30,12 @@ pub const CFG_TEMPLATE: AttributeTemplate = template!( "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg-attribute" ); -pub fn parse_cfg_attr<'c, S: Stage>( +const CFG_ATTR_TEMPLATE: AttributeTemplate = template!( + List: &["predicate, attr1, attr2, ..."], + "https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute" +); + +pub fn parse_cfg<'c, S: Stage>( cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser<'_>, ) -> Option { @@ -70,9 +84,7 @@ pub(crate) fn parse_cfg_entry( }, a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => { let Some(name) = meta.path().word_sym() else { - cx.emit_err(session_diagnostics::CfgPredicateIdentifier { - span: meta.path().span(), - }); + cx.expected_identifier(meta.path().span()); return None; }; parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)? @@ -81,7 +93,7 @@ pub(crate) fn parse_cfg_entry( MetaItemOrLitParser::Lit(lit) => match lit.kind { LitKind::Bool(b) => CfgEntry::Bool(b, lit.span), _ => { - cx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: lit.span }); + cx.expected_identifier(lit.span); return None; } }, @@ -149,9 +161,7 @@ fn parse_cfg_entry_target( // Then, parse it as a name-value item let Some(name) = sub_item.path().word_sym() else { - cx.emit_err(session_diagnostics::CfgPredicateIdentifier { - span: sub_item.path().span(), - }); + cx.expected_identifier(sub_item.path().span()); return None; }; let name = Symbol::intern(&format!("target_{name}")); @@ -300,3 +310,120 @@ impl EvalConfigResult { } } } + +pub fn parse_cfg_attr( + cfg_attr: &Attribute, + sess: &Session, + features: Option<&Features>, +) -> Option<(CfgEntry, Vec<(AttrItem, Span)>)> { + match cfg_attr.get_normal_item().args { + ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens }) + if !tokens.is_empty() => + { + check_cfg_attr_bad_delim(&sess.psess, dspan, delim); + match parse_in(&sess.psess, tokens.clone(), "`cfg_attr` input", |p| { + parse_cfg_attr_internal(p, sess, features, cfg_attr) + }) { + Ok(r) => return Some(r), + Err(e) => { + let suggestions = CFG_ATTR_TEMPLATE.suggestions(cfg_attr.style, sym::cfg_attr); + e.with_span_suggestions( + cfg_attr.span, + "must be of the form", + suggestions, + Applicability::HasPlaceholders, + ) + .with_note(format!( + "for more information, visit <{}>", + CFG_ATTR_TEMPLATE.docs.expect("cfg_attr has docs") + )) + .emit(); + } + } + } + _ => { + let (span, reason) = if let ast::AttrArgs::Delimited(ast::DelimArgs { dspan, .. }) = + cfg_attr.get_normal_item().args + { + (dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument) + } else { + (cfg_attr.span, AttributeParseErrorReason::ExpectedList) + }; + + sess.dcx().emit_err(AttributeParseError { + span, + attr_span: cfg_attr.span, + template: CFG_ATTR_TEMPLATE, + attribute: AttrPath::from_ast(&cfg_attr.get_normal_item().path), + reason, + attr_style: cfg_attr.style, + }); + } + } + None +} + +fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim: Delimiter) { + if let Delimiter::Parenthesis = delim { + return; + } + psess.dcx().emit_err(CfgAttrBadDelim { + span: span.entire(), + sugg: MetaBadDelimSugg { open: span.open, close: span.close }, + }); +} + +/// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited. +fn parse_cfg_attr_internal<'a>( + parser: &mut Parser<'a>, + sess: &'a Session, + features: Option<&Features>, + attribute: &Attribute, +) -> PResult<'a, (CfgEntry, Vec<(ast::AttrItem, Span)>)> { + // Parse cfg predicate + let pred_start = parser.token.span; + let meta = MetaItemOrLitParser::parse_single(parser, ShouldEmit::ErrorsAndLints)?; + let pred_span = pred_start.with_hi(parser.token.span.hi()); + + let cfg_predicate = AttributeParser::parse_single_args( + sess, + attribute.span, + attribute.style, + AttrPath { + segments: attribute + .ident_path() + .expect("cfg_attr is not a doc comment") + .into_boxed_slice(), + span: attribute.span, + }, + pred_span, + CRATE_NODE_ID, + features, + ShouldEmit::ErrorsAndLints, + &meta, + parse_cfg_entry, + &CFG_ATTR_TEMPLATE, + ) + .ok_or_else(|| { + let mut diag = sess.dcx().struct_err( + "cfg_entry parsing failing with `ShouldEmit::ErrorsAndLints` should emit a error.", + ); + diag.downgrade_to_delayed_bug(); + diag + })?; + + parser.expect(exp!(Comma))?; + + // Presumably, the majority of the time there will only be one attr. + let mut expanded_attrs = Vec::with_capacity(1); + while parser.token != token::Eof { + let lo = parser.token.span; + let item = parser.parse_attr_item(ForceCollect::Yes)?; + expanded_attrs.push((item, lo.to(parser.prev_token.span))); + if !parser.eat(exp!(Comma)) { + break; + } + } + + Ok((cfg_predicate, expanded_attrs)) +} diff --git a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs index d5d51f2e79ab8..f09b02251e4d0 100644 --- a/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs @@ -2,7 +2,11 @@ use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy}; use rustc_session::parse::feature_err; use super::prelude::*; -use crate::session_diagnostics::{NakedFunctionIncompatibleAttribute, NullOnExport}; +use crate::session_diagnostics::{ + NakedFunctionIncompatibleAttribute, NullOnExport, NullOnObjcClass, NullOnObjcSelector, + ObjcClassExpectedStringLiteral, ObjcSelectorExpectedStringLiteral, +}; +use crate::target_checking::Policy::AllowSilent; pub(crate) struct OptimizeParser; @@ -150,6 +154,70 @@ impl SingleAttributeParser for ExportNameParser { } } +pub(crate) struct ObjcClassParser; + +impl SingleAttributeParser for ObjcClassParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_class]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + let Some(classname) = nv.value_as_str() else { + // `#[rustc_objc_class = ...]` is expected to be used as an implementatioin detail + // inside a standard library macro, but `cx.expected_string_literal` exposes too much. + // Use a custom error message instead. + cx.emit_err(ObjcClassExpectedStringLiteral { span: nv.value_span }); + return None; + }; + if classname.as_str().contains('\0') { + // `#[rustc_objc_class = ...]` will be converted to a null-terminated string, + // so it may not contain any null characters. + cx.emit_err(NullOnObjcClass { span: nv.value_span }); + return None; + } + Some(AttributeKind::ObjcClass { classname, span: cx.attr_span }) + } +} + +pub(crate) struct ObjcSelectorParser; + +impl SingleAttributeParser for ObjcSelectorParser { + const PATH: &[rustc_span::Symbol] = &[sym::rustc_objc_selector]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::ForeignStatic)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let Some(nv) = args.name_value() else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + let Some(methname) = nv.value_as_str() else { + // `#[rustc_objc_selector = ...]` is expected to be used as an implementatioin detail + // inside a standard library macro, but `cx.expected_string_literal` exposes too much. + // Use a custom error message instead. + cx.emit_err(ObjcSelectorExpectedStringLiteral { span: nv.value_span }); + return None; + }; + if methname.as_str().contains('\0') { + // `#[rustc_objc_selector = ...]` will be converted to a null-terminated string, + // so it may not contain any null characters. + cx.emit_err(NullOnObjcSelector { span: nv.value_span }); + return None; + } + Some(AttributeKind::ObjcSelector { methname, span: cx.attr_span }) + } +} + #[derive(Default)] pub(crate) struct NakedParser { span: Option, @@ -295,6 +363,8 @@ impl NoArgsAttributeParser for NoMangleParser { Allow(Target::Static), Allow(Target::Method(MethodKind::Inherent)), Allow(Target::Method(MethodKind::TraitImpl)), + AllowSilent(Target::Const), // Handled in the `InvalidNoMangleItems` pass + Error(Target::Closure), ]); const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoMangle; } @@ -303,6 +373,7 @@ impl NoArgsAttributeParser for NoMangleParser { pub(crate) struct UsedParser { first_compiler: Option, first_linker: Option, + first_default: Option, } // A custom `AttributeParser` is used rather than a Simple attribute parser because @@ -315,7 +386,7 @@ impl AttributeParser for UsedParser { template!(Word, List: &["compiler", "linker"]), |group: &mut Self, cx, args| { let used_by = match args { - ArgParser::NoArgs => UsedBy::Linker, + ArgParser::NoArgs => UsedBy::Default, ArgParser::List(list) => { let Some(l) = list.single() else { cx.expected_single_argument(list.span); @@ -356,12 +427,29 @@ impl AttributeParser for UsedParser { ArgParser::NameValue(_) => return, }; + let attr_span = cx.attr_span; + + // `#[used]` is interpreted as `#[used(linker)]` (though depending on target OS the + // circumstances are more complicated). While we're checking `used_by`, also report + // these cross-`UsedBy` duplicates to warn. let target = match used_by { UsedBy::Compiler => &mut group.first_compiler, - UsedBy::Linker => &mut group.first_linker, + UsedBy::Linker => { + if let Some(prev) = group.first_default { + cx.warn_unused_duplicate(prev, attr_span); + return; + } + &mut group.first_linker + } + UsedBy::Default => { + if let Some(prev) = group.first_linker { + cx.warn_unused_duplicate(prev, attr_span); + return; + } + &mut group.first_default + } }; - let attr_span = cx.attr_span; if let Some(prev) = *target { cx.warn_unused_duplicate(prev, attr_span); } else { @@ -373,11 +461,13 @@ impl AttributeParser for UsedParser { AllowedTargets::AllowList(&[Allow(Target::Static), Warn(Target::MacroCall)]); fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { - // Ratcheting behaviour, if both `linker` and `compiler` are specified, use `linker` - Some(match (self.first_compiler, self.first_linker) { - (_, Some(span)) => AttributeKind::Used { used_by: UsedBy::Linker, span }, - (Some(span), _) => AttributeKind::Used { used_by: UsedBy::Compiler, span }, - (None, None) => return None, + // If a specific form of `used` is specified, it takes precedence over generic `#[used]`. + // If both `linker` and `compiler` are specified, use `linker`. + Some(match (self.first_compiler, self.first_linker, self.first_default) { + (_, Some(span), _) => AttributeKind::Used { used_by: UsedBy::Linker, span }, + (Some(span), _, _) => AttributeKind::Used { used_by: UsedBy::Compiler, span }, + (_, _, Some(span)) => AttributeKind::Used { used_by: UsedBy::Default, span }, + (None, None, None) => return None, }) } } diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 0b2c05482bfaa..1d3ab76e14990 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -1,40 +1,4 @@ -use std::num::IntErrorKind; - -use rustc_hir::limit::Limit; - use super::prelude::*; -use crate::session_diagnostics::LimitInvalid; - -impl AcceptContext<'_, '_, S> { - fn parse_limit_int(&self, nv: &NameValueParser) -> Option { - let Some(limit) = nv.value_as_str() else { - self.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); - return None; - }; - - let error_str = match limit.as_str().parse() { - Ok(i) => return Some(Limit::new(i)), - Err(e) => match e.kind() { - IntErrorKind::PosOverflow => "`limit` is too large", - IntErrorKind::Empty => "`limit` must be a non-negative integer", - IntErrorKind::InvalidDigit => "not a valid integer", - IntErrorKind::NegOverflow => { - panic!( - "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead" - ) - } - IntErrorKind::Zero => { - panic!("zero is a valid `limit` so should have returned Ok() when parsing") - } - kind => panic!("unimplemented IntErrorKind variant: {:?}", kind), - }, - }; - - self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str }); - - None - } -} pub(crate) struct CrateNameParser; @@ -43,11 +7,7 @@ impl SingleAttributeParser for CrateNameParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name"); - const TYPE: AttributeType = AttributeType::CrateLevel; - - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(n) = args else { @@ -60,12 +20,7 @@ impl SingleAttributeParser for CrateNameParser { return None; }; - Some(AttributeKind::CrateName { - name, - name_span: n.value_span, - attr_span: cx.attr_span, - style: cx.attr_style, - }) + Some(AttributeKind::CrateName { name, name_span: n.value_span, attr_span: cx.attr_span }) } } @@ -76,11 +31,7 @@ impl SingleAttributeParser for RecursionLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute"); - const TYPE: AttributeType = AttributeType::CrateLevel; - - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -103,11 +54,7 @@ impl SingleAttributeParser for MoveSizeLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const TYPE: AttributeType = AttributeType::CrateLevel; - - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -130,11 +77,7 @@ impl SingleAttributeParser for TypeLengthLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const TYPE: AttributeType = AttributeType::CrateLevel; - - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -157,11 +100,7 @@ impl SingleAttributeParser for PatternComplexityLimitParser { const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); - const TYPE: AttributeType = AttributeType::CrateLevel; - - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { let ArgParser::NameValue(nv) = args else { @@ -182,11 +121,8 @@ pub(crate) struct NoCoreParser; impl NoArgsAttributeParser for NoCoreParser { const PATH: &[Symbol] = &[sym::no_core]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore; - const TYPE: AttributeType = AttributeType::CrateLevel; } pub(crate) struct NoStdParser; @@ -194,9 +130,15 @@ pub(crate) struct NoStdParser; impl NoArgsAttributeParser for NoStdParser { const PATH: &[Symbol] = &[sym::no_std]; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; - // because it's a crate-level attribute, we already warn about it. - // Putting target limitations here would give duplicate warnings - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd; - const TYPE: AttributeType = AttributeType::CrateLevel; +} + +pub(crate) struct RustcCoherenceIsCoreParser; + +impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { + const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcCoherenceIsCore; } diff --git a/compiler/rustc_attr_parsing/src/attributes/debugger.rs b/compiler/rustc_attr_parsing/src/attributes/debugger.rs new file mode 100644 index 0000000000000..56ff10be42640 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/debugger.rs @@ -0,0 +1,60 @@ +use rustc_hir::attrs::{DebugVisualizer, DebuggerVisualizerType}; + +use super::prelude::*; + +pub(crate) struct DebuggerViualizerParser; + +impl CombineAttributeParser for DebuggerViualizerParser { + const PATH: &[Symbol] = &[sym::debugger_visualizer]; + const ALLOWED_TARGETS: AllowedTargets = + AllowedTargets::AllowList(&[Allow(Target::Mod), Allow(Target::Crate)]); + const TEMPLATE: AttributeTemplate = template!( + List: &[r#"natvis_file = "...", gdb_script_file = "...""#], + "https://doc.rust-lang.org/reference/attributes/debugger.html#the-debugger_visualizer-attribute" + ); + + type Item = DebugVisualizer; + const CONVERT: ConvertFn = |v, _| AttributeKind::DebuggerVisualizer(v); + + fn extend<'c>( + cx: &'c mut AcceptContext<'_, '_, S>, + args: &'c ArgParser<'_>, + ) -> impl IntoIterator + 'c { + let Some(l) = args.list() else { + cx.expected_list(args.span().unwrap_or(cx.attr_span)); + return None; + }; + let Some(single) = l.single() else { + cx.expected_single_argument(l.span); + return None; + }; + let Some(mi) = single.meta_item() else { + cx.expected_name_value(single.span(), None); + return None; + }; + let path = mi.path().word_sym(); + let visualizer_type = match path { + Some(sym::natvis_file) => DebuggerVisualizerType::Natvis, + Some(sym::gdb_script_file) => DebuggerVisualizerType::GdbPrettyPrinter, + _ => { + cx.expected_specific_argument( + mi.path().span(), + &[sym::natvis_file, sym::gdb_script_file], + ); + return None; + } + }; + + let Some(path) = mi.args().name_value() else { + cx.expected_name_value(single.span(), path); + return None; + }; + + let Some(path) = path.value_as_str() else { + cx.expected_string_literal(path.value_span, Some(path.value_as_lit())); + return None; + }; + + Some(DebugVisualizer { span: mi.span(), visualizer_type, path }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/inline.rs b/compiler/rustc_attr_parsing/src/attributes/inline.rs index a73430c9d0096..a10ad27fcc68b 100644 --- a/compiler/rustc_attr_parsing/src/attributes/inline.rs +++ b/compiler/rustc_attr_parsing/src/attributes/inline.rs @@ -72,7 +72,11 @@ impl SingleAttributeParser for RustcForceInlineParser { const PATH: &'static [Symbol] = &[sym::rustc_force_inline]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + ]); + const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason"); fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index d4942e56f429d..40ecd91e5cfc1 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -65,10 +65,22 @@ impl CombineAttributeParser for LinkParser { cx: &'c mut AcceptContext<'_, '_, S>, args: &'c ArgParser<'_>, ) -> impl IntoIterator + 'c { - let mut result = None; - let Some(items) = args.list() else { - cx.expected_list(cx.attr_span); - return result; + let items = match args { + ArgParser::List(list) => list, + // This is an edgecase added because making this a hard error would break too many crates + // Specifically `#[link = "dl"]` is accepted with a FCW + // For more information, see https://github.com/rust-lang/rust/pull/143193 + ArgParser::NameValue(nv) if nv.value_as_str().is_some_and(|v| v == sym::dl) => { + let suggestions = >::TEMPLATE + .suggestions(cx.attr_style, "link"); + let span = cx.attr_span; + cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + return None; + } + _ => { + cx.expected_list(cx.attr_span); + return None; + } }; let sess = cx.sess(); @@ -113,7 +125,7 @@ impl CombineAttributeParser for LinkParser { } }; if !cont { - return result; + return None; } } @@ -168,7 +180,8 @@ impl CombineAttributeParser for LinkParser { } (sym::as_dash_needed, Some(NativeLibKind::Dylib { as_needed })) - | (sym::as_dash_needed, Some(NativeLibKind::Framework { as_needed })) => { + | (sym::as_dash_needed, Some(NativeLibKind::Framework { as_needed })) + | (sym::as_dash_needed, Some(NativeLibKind::RawDylib { as_needed })) => { report_unstable_modifier!(native_link_modifiers_as_needed); assign_modifier(as_needed) } @@ -202,31 +215,30 @@ impl CombineAttributeParser for LinkParser { } let Some((name, name_span)) = name else { cx.emit_err(LinkRequiresName { span: cx.attr_span }); - return result; + return None; }; // Do this outside of the loop so that `import_name_type` can be specified before `kind`. if let Some((_, span)) = import_name_type { - if kind != Some(NativeLibKind::RawDylib) { + if !matches!(kind, Some(NativeLibKind::RawDylib { .. })) { cx.emit_err(ImportNameTypeRaw { span }); } } - if let Some(NativeLibKind::RawDylib) = kind + if let Some(NativeLibKind::RawDylib { .. }) = kind && name.as_str().contains('\0') { cx.emit_err(RawDylibNoNul { span: name_span }); } - result = Some(LinkEntry { + Some(LinkEntry { span: cx.attr_span, kind: kind.unwrap_or(NativeLibKind::Unspecified), name, cfg, verbatim, import_name_type, - }); - result + }) } } @@ -304,7 +316,7 @@ impl LinkParser { cx.emit_err(RawDylibOnlyWindows { span: nv.value_span }); } - NativeLibKind::RawDylib + NativeLibKind::RawDylib { as_needed: None } } sym::link_dash_arg => { if !features.link_arg_attribute() { @@ -455,8 +467,14 @@ impl SingleAttributeParser for LinkSectionParser { const PATH: &[Symbol] = &[sym::link_section]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError; - const ALLOWED_TARGETS: AllowedTargets = - AllowedTargets::AllowListWarnRest(&[Allow(Target::Static), Allow(Target::Fn)]); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + Allow(Target::Static), + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + Allow(Target::Method(MethodKind::TraitImpl)), + ]); const TEMPLATE: AttributeTemplate = template!( NameValueStr: "name", "https://doc.rust-lang.org/reference/abi.html#the-link_section-attribute" diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs index 180130c7be4fc..849141c34f7d9 100644 --- a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -1,3 +1,4 @@ +use rustc_ast::AttrStyle; use rustc_errors::DiagArgValue; use rustc_hir::attrs::MacroUseArgs; @@ -133,3 +134,65 @@ impl NoArgsAttributeParser for AllowInternalUnsafeParser { ]); const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span); } + +pub(crate) struct MacroExportParser; + +impl SingleAttributeParser for MacroExportParser { + const PATH: &[Symbol] = &[sym::macro_export]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]); + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[ + Allow(Target::MacroDef), + Error(Target::WherePredicate), + Error(Target::Crate), + ]); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let suggestions = || { + >::TEMPLATE + .suggestions(AttrStyle::Inner, "macro_export") + }; + let local_inner_macros = match args { + ArgParser::NoArgs => false, + ArgParser::List(list) => { + let Some(l) = list.single() else { + let span = cx.attr_span; + cx.emit_lint( + AttributeLintKind::InvalidMacroExportArguments { + suggestions: suggestions(), + }, + span, + ); + return None; + }; + match l.meta_item().and_then(|i| i.path().word_sym()) { + Some(sym::local_inner_macros) => true, + _ => { + let span = cx.attr_span; + cx.emit_lint( + AttributeLintKind::InvalidMacroExportArguments { + suggestions: suggestions(), + }, + span, + ); + return None; + } + } + } + ArgParser::NameValue(_) => { + let span = cx.attr_span; + let suggestions = suggestions(); + cx.emit_err(IllFormedAttributeInputLint { + num_suggestions: suggestions.len(), + suggestions: DiagArgValue::StrListSepByAnd( + suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), + ), + span, + }); + return None; + } + }; + Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 043bc925eac9f..639c75d7c5e47 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -12,15 +12,11 @@ //! - [`CombineAttributeParser`](crate::attributes::CombineAttributeParser): makes it easy to implement an attribute which should combine the //! contents of attributes, if an attribute appear multiple times in a list //! -//! By default, attributes are allowed anywhere. When adding an attribute that should only be used -//! at the crate root, consider setting the `TYPE` in the parser trait to -//! [`AttributeType::CrateLevel`](rustc_feature::AttributeType::CrateLevel). -//! //! Attributes should be added to `crate::context::ATTRIBUTE_PARSERS` to be parsed. use std::marker::PhantomData; -use rustc_feature::{AttributeTemplate, AttributeType, template}; +use rustc_feature::{AttributeTemplate, template}; use rustc_hir::attrs::AttributeKind; use rustc_span::{Span, Symbol}; use thin_vec::ThinVec; @@ -40,6 +36,7 @@ pub(crate) mod cfg_old; pub(crate) mod codegen_attrs; pub(crate) mod confusables; pub(crate) mod crate_level; +pub(crate) mod debugger; pub(crate) mod deprecation; pub(crate) mod dummy; pub(crate) mod inline; @@ -89,11 +86,8 @@ pub(crate) trait AttributeParser: Default + 'static { /// /// If an attribute has this symbol, the `accept` function will be called on it. const ATTRIBUTES: AcceptMapping; - const ALLOWED_TARGETS: AllowedTargets; - const TYPE: AttributeType = AttributeType::Normal; - /// The parser has gotten a chance to accept the attributes on an item, /// here it can produce an attribute. /// @@ -135,8 +129,6 @@ pub(crate) trait SingleAttributeParser: 'static { /// The template this attribute parser should implement. Used for diagnostics. const TEMPLATE: AttributeTemplate; - const TYPE: AttributeType = AttributeType::Normal; - /// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`] fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option; } @@ -183,8 +175,6 @@ impl, S: Stage> AttributeParser for Single )]; const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; - const TYPE: AttributeType = T::TYPE; - fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option { Some(self.1?.0) } @@ -269,7 +259,6 @@ pub(crate) trait NoArgsAttributeParser: 'static { const PATH: &[Symbol]; const ON_DUPLICATE: OnDuplicate; const ALLOWED_TARGETS: AllowedTargets; - const TYPE: AttributeType = AttributeType::Normal; /// Create the [`AttributeKind`] given attribute's [`Span`]. const CREATE: fn(Span) -> AttributeKind; @@ -289,7 +278,6 @@ impl, S: Stage> SingleAttributeParser for Without const ON_DUPLICATE: OnDuplicate = T::ON_DUPLICATE; const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS; const TEMPLATE: AttributeTemplate = template!(Word); - const TYPE: AttributeType = T::TYPE; fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { if let Err(span) = args.no_args() { @@ -314,7 +302,7 @@ pub(crate) trait CombineAttributeParser: 'static { type Item; /// A function that converts individual items (of type [`Item`](Self::Item)) into the final attribute. /// - /// For example, individual representations fomr `#[repr(...)]` attributes into an `AttributeKind::Repr(x)`, + /// For example, individual representations from `#[repr(...)]` attributes into an `AttributeKind::Repr(x)`, /// where `x` is a vec of these individual reprs. const CONVERT: ConvertFn; @@ -323,8 +311,6 @@ pub(crate) trait CombineAttributeParser: 'static { /// The template this attribute parser should implement. Used for diagnostics. const TEMPLATE: AttributeTemplate; - const TYPE: AttributeType = AttributeType::Normal; - /// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`] fn extend<'c>( cx: &'c mut AcceptContext<'_, '_, S>, @@ -360,7 +346,6 @@ impl, S: Stage> AttributeParser for Combine) -> Option { if let Some(first_span) = self.first_span { diff --git a/compiler/rustc_attr_parsing/src/attributes/prelude.rs b/compiler/rustc_attr_parsing/src/attributes/prelude.rs index 8f040ffb9d41c..980366b5c372f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/prelude.rs +++ b/compiler/rustc_attr_parsing/src/attributes/prelude.rs @@ -1,6 +1,6 @@ // data structures #[doc(hidden)] -pub(super) use rustc_feature::{AttributeTemplate, AttributeType, template}; +pub(super) use rustc_feature::{AttributeTemplate, template}; #[doc(hidden)] pub(super) use rustc_hir::attrs::AttributeKind; #[doc(hidden)] diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index a995549fc7c83..455c61097d78d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1,9 +1,18 @@ use super::prelude::*; use super::util::parse_single_integer; -pub(crate) struct RustcLayoutScalarValidRangeStart; +pub(crate) struct RustcMainParser; -impl SingleAttributeParser for RustcLayoutScalarValidRangeStart { +impl NoArgsAttributeParser for RustcMainParser { + const PATH: &'static [Symbol] = &[sym::rustc_main]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain; +} + +pub(crate) struct RustcLayoutScalarValidRangeStartParser; + +impl SingleAttributeParser for RustcLayoutScalarValidRangeStartParser { const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; @@ -16,9 +25,9 @@ impl SingleAttributeParser for RustcLayoutScalarValidRangeStart { } } -pub(crate) struct RustcLayoutScalarValidRangeEnd; +pub(crate) struct RustcLayoutScalarValidRangeEndParser; -impl SingleAttributeParser for RustcLayoutScalarValidRangeEnd { +impl SingleAttributeParser for RustcLayoutScalarValidRangeEndParser { const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end]; const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; @@ -49,3 +58,21 @@ impl SingleAttributeParser for RustcObjectLifetimeDefaultParser { Some(AttributeKind::RustcObjectLifetimeDefault) } } + +pub(crate) struct RustcSimdMonomorphizeLaneLimitParser; + +impl SingleAttributeParser for RustcSimdMonomorphizeLaneLimitParser { + const PATH: &[Symbol] = &[sym::rustc_simd_monomorphize_lane_limit]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let ArgParser::NameValue(nv) = args else { + cx.expected_name_value(cx.attr_span, None); + return None; + }; + Some(AttributeKind::RustcSimdMonomorphizeLaneLimit(cx.parse_limit_int(nv)?)) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/traits.rs b/compiler/rustc_attr_parsing/src/attributes/traits.rs index fbd9a480fbb6e..ced3bcad2293a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/traits.rs +++ b/compiler/rustc_attr_parsing/src/attributes/traits.rs @@ -1,7 +1,5 @@ use std::mem; -use rustc_feature::AttributeType; - use super::prelude::*; use crate::attributes::{ AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser, @@ -151,15 +149,6 @@ impl NoArgsAttributeParser for AllowIncoherentImplParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::AllowIncoherentImpl; } -pub(crate) struct CoherenceIsCoreParser; -impl NoArgsAttributeParser for CoherenceIsCoreParser { - const PATH: &[Symbol] = &[sym::rustc_coherence_is_core]; - const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; - const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); - const TYPE: AttributeType = AttributeType::CrateLevel; - const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore; -} - pub(crate) struct FundamentalParser; impl NoArgsAttributeParser for FundamentalParser { const PATH: &[Symbol] = &[sym::fundamental]; diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 77e8c32e59d73..520fd9da7c2ab 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -1,11 +1,15 @@ +use std::num::IntErrorKind; + use rustc_ast::LitKind; use rustc_ast::attr::AttributeExt; use rustc_feature::is_builtin_attr_name; use rustc_hir::RustcVersion; +use rustc_hir::limit::Limit; use rustc_span::{Symbol, sym}; use crate::context::{AcceptContext, Stage}; -use crate::parser::ArgParser; +use crate::parser::{ArgParser, NameValueParser}; +use crate::session_diagnostics::LimitInvalid; /// Parse a rustc version number written inside string literal in an attribute, /// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are @@ -24,7 +28,8 @@ pub fn parse_version(s: Symbol) -> Option { } pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { - attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) + attr.is_doc_comment().is_some() + || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name)) } pub fn is_doc_alias_attrs_contain_symbol<'tcx, T: AttributeExt + 'tcx>( @@ -85,3 +90,34 @@ pub(crate) fn parse_single_integer( }; Some(num.0) } + +impl AcceptContext<'_, '_, S> { + pub(crate) fn parse_limit_int(&self, nv: &NameValueParser) -> Option { + let Some(limit) = nv.value_as_str() else { + self.expected_string_literal(nv.value_span, Some(nv.value_as_lit())); + return None; + }; + + let error_str = match limit.as_str().parse() { + Ok(i) => return Some(Limit::new(i)), + Err(e) => match e.kind() { + IntErrorKind::PosOverflow => "`limit` is too large", + IntErrorKind::Empty => "`limit` must be a non-negative integer", + IntErrorKind::InvalidDigit => "not a valid integer", + IntErrorKind::NegOverflow => { + panic!( + "`limit` should never negatively overflow since we're parsing into a usize and we'd get Empty instead" + ) + } + IntErrorKind::Zero => { + panic!("zero is a valid `limit` so should have returned Ok() when parsing") + } + kind => panic!("unimplemented IntErrorKind variant: {:?}", kind), + }, + }; + + self.emit_err(LimitInvalid { span: self.attr_span, value_span: nv.value_span, error_str }); + + None + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index b3ab1d3edd6d2..6749bdfb1a672 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -6,7 +6,7 @@ use std::sync::LazyLock; use private::Sealed; use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId}; use rustc_errors::{Diag, Diagnostic, Level}; -use rustc_feature::{AttributeTemplate, AttributeType}; +use rustc_feature::AttributeTemplate; use rustc_hir::attrs::AttributeKind; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId}; @@ -20,14 +20,15 @@ use crate::attributes::allow_unstable::{ use crate::attributes::body::CoroutineParser; use crate::attributes::codegen_attrs::{ ColdParser, CoverageParser, ExportNameParser, ForceTargetFeatureParser, NakedParser, - NoMangleParser, OptimizeParser, SanitizeParser, TargetFeatureParser, TrackCallerParser, - UsedParser, + NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser, SanitizeParser, + TargetFeatureParser, TrackCallerParser, UsedParser, }; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::crate_level::{ CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser, - RecursionLimitParser, TypeLengthLimitParser, + RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser, }; +use crate::attributes::debugger::DebuggerViualizerParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::dummy::DummyParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; @@ -40,7 +41,7 @@ use crate::attributes::lint_helpers::{ }; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::macro_attrs::{ - AllowInternalUnsafeParser, MacroEscapeParser, MacroUseParser, + AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser, }; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; @@ -52,8 +53,8 @@ use crate::attributes::proc_macro_attrs::{ use crate::attributes::prototype::CustomMirParser; use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser}; use crate::attributes::rustc_internal::{ - RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, - RustcObjectLifetimeDefaultParser, + RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser, + RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser, }; use crate::attributes::semantics::MayDangleParser; use crate::attributes::stability::{ @@ -61,10 +62,10 @@ use crate::attributes::stability::{ }; use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser}; use crate::attributes::traits::{ - AllowIncoherentImplParser, CoherenceIsCoreParser, CoinductiveParser, ConstTraitParser, - DenyExplicitImplParser, DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, - ParenSugarParser, PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, - TypeConstParser, UnsafeSpecializationMarkerParser, + AllowIncoherentImplParser, CoinductiveParser, ConstTraitParser, DenyExplicitImplParser, + DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser, + PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser, + UnsafeSpecializationMarkerParser, }; use crate::attributes::transparency::TransparencyParser; use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs}; @@ -83,7 +84,6 @@ pub(super) struct GroupTypeInnerAccept { pub(super) template: AttributeTemplate, pub(super) accept_fn: AcceptFn, pub(super) allowed_targets: AllowedTargets, - pub(super) attribute_type: AttributeType, } type AcceptFn = @@ -133,7 +133,6 @@ macro_rules! attribute_parsers { }) }), allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS, - attribute_type: <$names as crate::attributes::AttributeParser<$stage>>::TYPE, }); } @@ -165,6 +164,7 @@ attribute_parsers!( // tidy-alphabetical-start Combine, Combine, + Combine, Combine, Combine, Combine, @@ -185,8 +185,11 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, + Single, + Single, Single, Single, Single, @@ -194,9 +197,10 @@ attribute_parsers!( Single, Single, Single, - Single, - Single, + Single, + Single, Single, + Single, Single, Single, Single, @@ -206,7 +210,6 @@ attribute_parsers!( Single>, Single>, Single>, - Single>, Single>, Single>, Single>, @@ -234,6 +237,8 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, + Single>, Single>, Single>, Single>, @@ -593,7 +598,12 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> { } pub(crate) fn warn_empty_attribute(&mut self, span: Span) { - self.emit_lint(AttributeLintKind::EmptyAttribute { first_span: span }, span); + let attr_path = self.attr_path.clone(); + let valid_without_list = self.template.word; + self.emit_lint( + AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list }, + span, + ); } } diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index 0fe3c209421fd..b8ef11c26d80e 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use rustc_ast as ast; -use rustc_ast::NodeId; +use rustc_ast::{AttrStyle, NodeId}; use rustc_errors::DiagCtxtHandle; use rustc_feature::{AttributeTemplate, Features}; use rustc_hir::attrs::AttributeKind; @@ -62,7 +62,8 @@ impl<'sess> AttributeParser<'sess, Early> { ) } - /// Usually you want `parse_limited`, which defaults to no errors. + /// This does the same as `parse_limited`, except it has a `should_emit` parameter which allows it to emit errors. + /// Usually you want `parse_limited`, which emits no errors. pub fn parse_limited_should_emit( sess: &'sess Session, attrs: &[ast::Attribute], @@ -86,6 +87,13 @@ impl<'sess> AttributeParser<'sess, Early> { parsed.pop() } + /// This method allows you to parse a list of attributes *before* `rustc_ast_lowering`. + /// This can be used for attributes that would be removed before `rustc_ast_lowering`, such as attributes on macro calls. + /// + /// Try to use this as little as possible. Attributes *should* be lowered during + /// `rustc_ast_lowering`. Some attributes require access to features to parse, which would + /// crash if you tried to do so through [`parse_limited_all`](Self::parse_limited_all). + /// Therefore, if `parse_only` is None, then features *must* be provided. pub fn parse_limited_all( sess: &'sess Session, attrs: &[ast::Attribute], @@ -111,6 +119,8 @@ impl<'sess> AttributeParser<'sess, Early> { ) } + /// This method parses a single attribute, using `parse_fn`. + /// This is useful if you already know what exact attribute this is, and want to parse it. pub fn parse_single( sess: &'sess Session, attr: &ast::Attribute, @@ -121,13 +131,6 @@ impl<'sess> AttributeParser<'sess, Early> { parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> Option, template: &AttributeTemplate, ) -> Option { - let mut parser = Self { - features, - tools: Vec::new(), - parse_only: None, - sess, - stage: Early { emit_errors }, - }; let ast::AttrKind::Normal(normal_attr) = &attr.kind else { panic!("parse_single called on a doc attr") }; @@ -136,6 +139,43 @@ impl<'sess> AttributeParser<'sess, Early> { let meta_parser = MetaItemParser::from_attr(normal_attr, &parts, &sess.psess, emit_errors)?; let path = meta_parser.path(); let args = meta_parser.args(); + Self::parse_single_args( + sess, + attr.span, + attr.style, + path.get_attribute_path(), + target_span, + target_node_id, + features, + emit_errors, + args, + parse_fn, + template, + ) + } + + /// This method is equivalent to `parse_single`, but parses arguments using `parse_fn` using manually created `args`. + /// This is useful when you want to parse other things than attributes using attribute parsers. + pub fn parse_single_args( + sess: &'sess Session, + attr_span: Span, + attr_style: AttrStyle, + attr_path: AttrPath, + target_span: Span, + target_node_id: NodeId, + features: Option<&'sess Features>, + emit_errors: ShouldEmit, + args: &I, + parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &I) -> Option, + template: &AttributeTemplate, + ) -> Option { + let mut parser = Self { + features, + tools: Vec::new(), + parse_only: None, + sess, + stage: Early { emit_errors }, + }; let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext { shared: SharedContext { cx: &mut parser, @@ -145,10 +185,10 @@ impl<'sess> AttributeParser<'sess, Early> { crate::lints::emit_attribute_lint(&lint, sess); }, }, - attr_span: attr.span, - attr_style: attr.style, + attr_span, + attr_style, template, - attr_path: path.get_attribute_path(), + attr_path, }; parse_fn(&mut cx, args) } @@ -272,7 +312,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { (accept.accept_fn)(&mut cx, args); if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) { - Self::check_type(accept.attribute_type, target, &mut cx); Self::check_target(&accept.allowed_targets, target, &mut cx); } } diff --git a/compiler/rustc_attr_parsing/src/lib.rs b/compiler/rustc_attr_parsing/src/lib.rs index f51cc8c4e8be7..bcd0d674c75f1 100644 --- a/compiler/rustc_attr_parsing/src/lib.rs +++ b/compiler/rustc_attr_parsing/src/lib.rs @@ -105,7 +105,9 @@ mod session_diagnostics; mod target_checking; pub mod validate_attr; -pub use attributes::cfg::{CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg_attr}; +pub use attributes::cfg::{ + CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg, parse_cfg_attr, +}; pub use attributes::cfg_old::*; pub use attributes::util::{is_builtin_attr, is_doc_alias_attrs_contain_symbol, parse_version}; pub use context::{Early, Late, OmitDoc, ShouldEmit}; diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs index b1a971eec3245..3a2a370466961 100644 --- a/compiler/rustc_attr_parsing/src/lints.rs +++ b/compiler/rustc_attr_parsing/src/lints.rs @@ -31,12 +31,30 @@ pub fn emit_attribute_lint(lint: &AttributeLint, lint_emi }, ); } - AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint( - rustc_session::lint::builtin::UNUSED_ATTRIBUTES, - *id, - *first_span, - session_diagnostics::EmptyAttributeList { attr_span: *first_span }, - ), + AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter + .emit_node_span_lint( + rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS, + *id, + *span, + session_diagnostics::IllFormedAttributeInput { + num_suggestions: suggestions.len(), + suggestions: DiagArgValue::StrListSepByAnd( + suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), + ), + }, + ), + AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => { + lint_emitter.emit_node_span_lint( + rustc_session::lint::builtin::UNUSED_ATTRIBUTES, + *id, + *first_span, + session_diagnostics::EmptyAttributeList { + attr_span: *first_span, + attr_path: attr_path.clone(), + valid_without_list: *valid_without_list, + }, + ) + } AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter .emit_node_span_lint( // This check is here because `deprecated` had its own lint group and removing this would be a breaking change diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 4f903594225e0..7474471f2fe0f 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -8,7 +8,7 @@ use std::fmt::{Debug, Display}; use rustc_ast::token::{self, Delimiter, MetaVarKind}; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::{AttrArgs, DelimArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path}; +use rustc_ast::{AttrArgs, Expr, ExprKind, LitKind, MetaItemLit, NormalAttr, Path}; use rustc_ast_pretty::pprust; use rustc_errors::{Diag, PResult}; use rustc_hir::{self as hir, AttrPath}; @@ -49,7 +49,7 @@ impl<'a> PathParser<'a> { } pub fn segments_is(&self, segments: &[Symbol]) -> bool { - self.len() == segments.len() && self.segments().zip(segments).all(|(a, b)| a.name == *b) + self.segments().map(|segment| &segment.name).eq(segments) } pub fn word(&self) -> Option { @@ -124,7 +124,11 @@ impl<'a> ArgParser<'a> { return None; } - Self::List(MetaItemListParser::new(args, psess, should_emit)?) + Self::List( + MetaItemListParser::new(&args.tokens, args.dspan.entire(), psess, should_emit) + .map_err(|e| should_emit.emit_err(e)) + .ok()?, + ) } AttrArgs::Eq { eq_span, expr } => Self::NameValue(NameValueParser { eq_span: *eq_span, @@ -186,7 +190,15 @@ pub enum MetaItemOrLitParser<'a> { Err(Span, ErrorGuaranteed), } -impl<'a> MetaItemOrLitParser<'a> { +impl<'sess> MetaItemOrLitParser<'sess> { + pub fn parse_single( + parser: &mut Parser<'sess>, + should_emit: ShouldEmit, + ) -> PResult<'sess, MetaItemOrLitParser<'static>> { + let mut this = MetaItemListParserContext { parser, should_emit }; + this.parse_meta_item_inner() + } + pub fn span(&self) -> Span { match self { MetaItemOrLitParser::MetaItemParser(generic_meta_item_parser) => { @@ -204,7 +216,7 @@ impl<'a> MetaItemOrLitParser<'a> { } } - pub fn meta_item(&self) -> Option<&MetaItemParser<'a>> { + pub fn meta_item(&self) -> Option<&MetaItemParser<'sess>> { match self { MetaItemOrLitParser::MetaItemParser(parser) => Some(parser), _ => None, @@ -542,23 +554,13 @@ pub struct MetaItemListParser<'a> { } impl<'a> MetaItemListParser<'a> { - fn new<'sess>( - delim: &'a DelimArgs, + pub(crate) fn new<'sess>( + tokens: &'a TokenStream, + span: Span, psess: &'sess ParseSess, should_emit: ShouldEmit, - ) -> Option { - match MetaItemListParserContext::parse( - delim.tokens.clone(), - psess, - delim.dspan.entire(), - should_emit, - ) { - Ok(s) => Some(s), - Err(e) => { - should_emit.emit_err(e); - None - } - } + ) -> Result> { + MetaItemListParserContext::parse(tokens.clone(), psess, span, should_emit) } /// Lets you pick and choose as what you want to parse each element in the list diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 32ea9005a97d0..7b82f3baec093 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -459,6 +459,34 @@ pub(crate) struct NullOnLinkSection { pub span: Span, } +#[derive(Diagnostic)] +#[diag(attr_parsing_null_on_objc_class)] +pub(crate) struct NullOnObjcClass { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_null_on_objc_selector)] +pub(crate) struct NullOnObjcSelector { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_objc_class_expected_string_literal)] +pub(crate) struct ObjcClassExpectedStringLiteral { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(attr_parsing_objc_selector_expected_string_literal)] +pub(crate) struct ObjcSelectorExpectedStringLiteral { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(attr_parsing_stability_outside_std, code = E0734)] pub(crate) struct StabilityOutsideStd { @@ -475,9 +503,12 @@ pub(crate) struct EmptyConfusables { #[derive(LintDiagnostic)] #[diag(attr_parsing_empty_attribute)] +#[note] pub(crate) struct EmptyAttributeList { #[suggestion(code = "", applicability = "machine-applicable")] pub attr_span: Span, + pub attr_path: AttrPath, + pub valid_without_list: bool, } #[derive(LintDiagnostic)] @@ -940,3 +971,12 @@ pub(crate) struct LimitInvalid<'a> { pub value_span: Span, pub error_str: &'a str, } + +#[derive(Diagnostic)] +#[diag(attr_parsing_cfg_attr_bad_delim)] +pub(crate) struct CfgAttrBadDelim { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub sugg: MetaBadDelimSugg, +} diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index edc496b460cf8..fabd364d3d7f8 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use rustc_ast::AttrStyle; use rustc_errors::DiagArgValue; -use rustc_feature::{AttributeType, Features}; +use rustc_feature::Features; use rustc_hir::lints::AttributeLintKind; use rustc_hir::{MethodKind, Target}; @@ -14,6 +14,11 @@ use crate::session_diagnostics::InvalidTarget; pub(crate) enum AllowedTargets { AllowList(&'static [Policy]), AllowListWarnRest(&'static [Policy]), + /// Special, and not the same as `AllowList(&[Allow(Target::Crate)])`. + /// For crate-level attributes we emit a specific set of lints to warn + /// people about accidentally not using them on the crate. + /// Only use this for attributes that are *exclusively* valid at the crate level. + CrateLevel, } pub(crate) enum AllowedResult { @@ -26,7 +31,9 @@ impl AllowedTargets { pub(crate) fn is_allowed(&self, target: Target) -> AllowedResult { match self { AllowedTargets::AllowList(list) => { - if list.contains(&Policy::Allow(target)) { + if list.contains(&Policy::Allow(target)) + || list.contains(&Policy::AllowSilent(target)) + { AllowedResult::Allowed } else if list.contains(&Policy::Warn(target)) { AllowedResult::Warn @@ -35,7 +42,9 @@ impl AllowedTargets { } } AllowedTargets::AllowListWarnRest(list) => { - if list.contains(&Policy::Allow(target)) { + if list.contains(&Policy::Allow(target)) + || list.contains(&Policy::AllowSilent(target)) + { AllowedResult::Allowed } else if list.contains(&Policy::Error(target)) { AllowedResult::Error @@ -43,6 +52,7 @@ impl AllowedTargets { AllowedResult::Warn } } + AllowedTargets::CrateLevel => AllowedResult::Allowed, } } @@ -50,10 +60,12 @@ impl AllowedTargets { match self { AllowedTargets::AllowList(list) => list, AllowedTargets::AllowListWarnRest(list) => list, + AllowedTargets::CrateLevel => ALL_TARGETS, } .iter() .filter_map(|target| match target { Policy::Allow(target) => Some(*target), + Policy::AllowSilent(_) => None, // Not listed in possible targets Policy::Warn(_) => None, Policy::Error(_) => None, }) @@ -61,10 +73,18 @@ impl AllowedTargets { } } +/// This policy determines what diagnostics should be emitted based on the `Target` of the attribute. #[derive(Debug, Eq, PartialEq)] pub(crate) enum Policy { + /// A target that is allowed. Allow(Target), + /// A target that is allowed and not listed in the possible targets. + /// This is useful if the target is checked elsewhere. + AllowSilent(Target), + /// Emits a FCW on this target. + /// This is useful if the target was previously allowed but should not be. Warn(Target), + /// Emits an error on this target. Error(Target), } @@ -74,6 +94,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { target: Target, cx: &mut AcceptContext<'_, 'sess, S>, ) { + Self::check_type(matches!(allowed_targets, AllowedTargets::CrateLevel), target, cx); + match allowed_targets.is_allowed(target) { AllowedResult::Allowed => {} AllowedResult::Warn => { @@ -109,7 +131,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { } pub(crate) fn check_type( - attribute_type: AttributeType, + crate_level: bool, target: Target, cx: &mut AcceptContext<'_, 'sess, S>, ) { @@ -119,7 +141,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { return; } - if attribute_type != AttributeType::CrateLevel { + if !crate_level { return; } @@ -189,16 +211,20 @@ pub(crate) fn allowed_targets_applied( filter_targets(&mut allowed_targets, IMPL_LIKE, "impl blocks", target, &mut added_fake_targets); filter_targets(&mut allowed_targets, ADT_LIKE, "data types", target, &mut added_fake_targets); + let mut target_strings: Vec<_> = added_fake_targets + .iter() + .copied() + .chain(allowed_targets.iter().map(|t| t.plural_name())) + .map(|i| i.to_string()) + .collect(); + + // ensure a consistent order + target_strings.sort(); + // If there is now only 1 target left, show that as the only possible target - ( - added_fake_targets - .iter() - .copied() - .chain(allowed_targets.iter().map(|t| t.plural_name())) - .map(|i| i.to_string()) - .collect(), - allowed_targets.len() + added_fake_targets.len() == 1, - ) + let only_target = target_strings.len() == 1; + + (target_strings, only_target) } fn filter_targets( diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index 7a7624893bd21..927417f89f8c0 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -207,10 +207,9 @@ pub fn check_attribute_safety( } } - // - Normal builtin attribute, or any non-builtin attribute - // - All non-builtin attributes are currently considered safe; writing `#[unsafe(..)]` is - // not permitted on non-builtin attributes or normal builtin attributes - (Some(AttributeSafety::Normal) | None, Safety::Unsafe(unsafe_span)) => { + // - Normal builtin attribute + // - Writing `#[unsafe(..)]` is not permitted on normal builtin attributes + (Some(AttributeSafety::Normal), Safety::Unsafe(unsafe_span)) => { psess.dcx().emit_err(errors::InvalidAttrUnsafe { span: unsafe_span, name: attr_item.path.clone(), @@ -224,9 +223,8 @@ pub fn check_attribute_safety( } // - Non-builtin attribute - // - No explicit `#[unsafe(..)]` written. - (None, Safety::Default) => { - // OK + (None, Safety::Unsafe(_) | Safety::Default) => { + // OK (not checked here) } ( diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index c9be5575da5ce..7c9011505d64c 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -426,7 +426,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { } pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> { - struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,) + struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path) } pub(crate) fn cannot_return_reference_to_local( @@ -480,7 +480,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> { } pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> { - struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",) + struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed") } } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index d3f6c01ab8c3a..84d5ffb947914 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -577,7 +577,6 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { mir::StatementKind::FakeRead(..) | mir::StatementKind::SetDiscriminant { .. } - | mir::StatementKind::Deinit(..) | mir::StatementKind::StorageLive(..) | mir::StatementKind::Retag { .. } | mir::StatementKind::PlaceMention(..) diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index b9ced81c46c19..502265a83523e 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -80,7 +80,7 @@ pub(crate) fn categorize(context: PlaceContext) -> Option { // Backwards incompatible drop hint is not a use, just a marker for linting. PlaceContext::NonUse(NonUseContext::BackwardIncompatibleDropHint) => None, - PlaceContext::MutatingUse(MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant) => { + PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant) => { bug!("These statements are not allowed in this MIR phase") } } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 76da9dc883231..15b2a5ef2e213 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -420,7 +420,7 @@ fn try_extract_error_from_fulfill_cx<'a, 'tcx>( // We generally shouldn't have errors here because the query was // already run, but there's no point using `span_delayed_bug` // when we're going to emit an error here anyway. - let _errors = ocx.select_all_or_error(); + let _errors = ocx.evaluate_obligations_error_on_ambiguity(); let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone()); try_extract_error_from_region_constraints( ocx.infcx, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7e20a5133e07f..47a1ad0d9489a 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1313,7 +1313,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let ocx = ObligationCtxt::new_with_diagnostics(self.infcx); let cause = ObligationCause::misc(expr.span, self.mir_def_id()); ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait); - let errors = ocx.select_all_or_error(); + let errors = ocx.evaluate_obligations_error_on_ambiguity(); if errors.iter().all(|error| { match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) { Some(clause) => match clause.self_ty().skip_binder().kind() { @@ -1497,7 +1497,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let cause = ObligationCause::misc(span, self.mir_def_id()); ocx.register_bound(cause, self.infcx.param_env, ty, def_id); - let errors = ocx.select_all_or_error(); + let errors = ocx.evaluate_obligations_error_on_ambiguity(); // Only emit suggestion if all required predicates are on generic let predicates: Result, _> = errors @@ -2992,6 +2992,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { self.buffer_error(err); } + #[tracing::instrument(level = "debug", skip(self, explanation))] fn report_local_value_does_not_live_long_enough( &self, location: Location, @@ -3001,13 +3002,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { borrow_spans: UseSpans<'tcx>, explanation: BorrowExplanation<'tcx>, ) -> Diag<'infcx> { - debug!( - "report_local_value_does_not_live_long_enough(\ - {:?}, {:?}, {:?}, {:?}, {:?}\ - )", - location, name, borrow, drop_span, borrow_spans - ); - let borrow_span = borrow_spans.var_or_use_path_span(); if let BorrowExplanation::MustBeValidFor { category, @@ -3974,7 +3968,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { } ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } - | ProjectionElem::Subtype(_) | ProjectionElem::Index(_) | ProjectionElem::UnwrapUnsafeBinder(_) => kind, }, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index fda96dde8269d..6bcfa9d8bf9a7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -416,6 +416,26 @@ impl<'tcx> BorrowExplanation<'tcx> { { self.add_object_lifetime_default_note(tcx, err, unsize_ty); } + + let mut preds = path + .iter() + .filter_map(|constraint| match constraint.category { + ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred), + _ => None, + }) + .collect::>(); + preds.sort(); + preds.dedup(); + if !preds.is_empty() { + let s = if preds.len() == 1 { "" } else { "s" }; + err.span_note( + preds, + format!( + "requirement{s} that the value outlives `{region_name}` introduced here" + ), + ); + } + self.add_lifetime_bound_suggestion_to_diagnostic(err, &category, span, region_name); } _ => {} @@ -438,7 +458,7 @@ impl<'tcx> BorrowExplanation<'tcx> { let elaborated_args = std::iter::zip(*args, &generics.own_params).map(|(arg, param)| { - if let Some(ty::Dynamic(obj, _, ty::Dyn)) = arg.as_type().map(Ty::kind) { + if let Some(ty::Dynamic(obj, _)) = arg.as_type().map(Ty::kind) { let default = tcx.object_lifetime_default(param.def_id); let re_static = tcx.lifetimes.re_static; @@ -464,7 +484,7 @@ impl<'tcx> BorrowExplanation<'tcx> { has_dyn = true; - Ty::new_dynamic(tcx, obj, implied_region, ty::Dyn).into() + Ty::new_dynamic(tcx, obj, implied_region).into() } else { arg } @@ -667,7 +687,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } } - Some(Cause::DropVar(local, location)) => { + Some(Cause::DropVar(local, location)) if !is_local_boring(local) => { let mut should_note_order = false; if self.local_name(local).is_some() && let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place @@ -685,7 +705,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> { } } - Some(Cause::LiveVar(..)) | None => { + Some(Cause::LiveVar(..) | Cause::DropVar(..)) | None => { // Here, under NLL: no cause was found. Under polonius: no cause was found, or a // boring local was found, which we ignore like NLLs do to match its diagnostics. if let Some(region) = self.to_error_region_vid(borrow_region_vid) { diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 5642cdf87fded..e13c1c712d8d7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -402,7 +402,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ProjectionElem::Downcast(..) if opt.including_downcast => return None, ProjectionElem::Downcast(..) => (), ProjectionElem::OpaqueCast(..) => (), - ProjectionElem::Subtype(..) => (), ProjectionElem::UnwrapUnsafeBinder(_) => (), ProjectionElem::Field(field, _ty) => { // FIXME(project-rfc_2229#36): print capture precisely here. @@ -484,9 +483,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx) } ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx), - ProjectionElem::Subtype(ty) - | ProjectionElem::OpaqueCast(ty) - | ProjectionElem::UnwrapUnsafeBinder(ty) => PlaceTy::from_ty(*ty), + ProjectionElem::OpaqueCast(ty) | ProjectionElem::UnwrapUnsafeBinder(ty) => { + PlaceTy::from_ty(*ty) + } ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type), }, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 0b3151fd8b82d..be2a5b1ebe22d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -139,9 +139,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { // whether or not the right-hand side is a place expression if let LocalInfo::User(BindingForm::Var(VarBindingForm { opt_match_place: Some((opt_match_place, match_span)), - binding_mode: _, - opt_ty_info: _, - pat_span: _, + .. })) = *local_decl.local_info() { let stmt_source_info = self.body.source_info(location); diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6d69040c711d9..b4990ffc7739c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -192,7 +192,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { [ .., ProjectionElem::Index(_) - | ProjectionElem::Subtype(_) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } @@ -336,8 +335,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { LocalInfo::User(BindingForm::Var(mir::VarBindingForm { binding_mode: BindingMode(ByRef::No, Mutability::Not), opt_ty_info: Some(sp), - opt_match_place: _, - pat_span: _, + .. })) => { if suggest { err.span_note(sp, "the binding is already a mutable borrow"); @@ -710,8 +708,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { return (false, false, None); } let my_def = self.body.source.def_id(); - let Some(td) = - tcx.trait_impl_of_assoc(my_def).and_then(|id| self.infcx.tcx.trait_id_of_impl(id)) + let Some(td) = tcx.trait_impl_of_assoc(my_def).map(|id| self.infcx.tcx.impl_trait_id(id)) else { return (false, false, None); }; @@ -751,6 +748,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { opt_ty_info: _, opt_match_place: _, pat_span, + introductions: _, })) => pat_span, _ => local_decl.source_info.span, }; diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index bec4c934502d8..bad5f03e41274 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1134,7 +1134,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred) })); - if ocx.select_all_or_error().is_empty() && count > 0 { + if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 { diag.span_suggestion_verbose( tcx.hir_body(*body).value.peel_blocks().span.shrink_to_lo(), fluent::borrowck_dereference_suggestion, diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index 94379cdebf730..d23ecf6c70796 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -166,13 +166,9 @@ impl RegionTracker { } } - /// Determine if the tracked universes of the two SCCs are compatible. - pub(crate) fn universe_compatible_with(&self, other: Self) -> bool { - // HACK: We first check whether we can name the highest existential universe - // of `other`. This only exists to avoid errors in case that scc already - // depends on a placeholder it cannot name itself. - self.max_nameable_universe().can_name(other.max_nameable_universe()) - || other.reachable_placeholders.can_be_named_by(self.max_nameable_universe()) + /// Determine if we can name all the placeholders in `other`. + pub(crate) fn can_name_all_placeholders(&self, other: Self) -> bool { + other.reachable_placeholders.can_be_named_by(self.max_nameable_universe.0) } /// If this SCC reaches a placeholder it can't name, return it. @@ -348,7 +344,7 @@ pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>( } } -fn rewrite_placeholder_outlives<'tcx>( +pub(crate) fn rewrite_placeholder_outlives<'tcx>( sccs: &Sccs, annotations: &SccAnnotations<'_, '_, RegionTracker>, fr_static: RegionVid, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 5d2dda8b0e7cc..a57689a45b67b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -119,7 +119,7 @@ pub fn provide(providers: &mut Providers) { fn mir_borrowck( tcx: TyCtxt<'_>, def: LocalDefId, -) -> Result<&ConcreteOpaqueTypes<'_>, ErrorGuaranteed> { +) -> Result<&DefinitionSiteHiddenTypes<'_>, ErrorGuaranteed> { assert!(!tcx.is_typeck_child(def.to_def_id())); let (input_body, _) = tcx.mir_promoted(def); debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); @@ -130,7 +130,7 @@ fn mir_borrowck( Err(guar) } else if input_body.should_skip() { debug!("Skipping borrowck because of injected body"); - let opaque_types = ConcreteOpaqueTypes(Default::default()); + let opaque_types = DefinitionSiteHiddenTypes(Default::default()); Ok(tcx.arena.alloc(opaque_types)) } else { let mut root_cx = BorrowCheckRootCtxt::new(tcx, def, None); @@ -278,7 +278,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> { mut map: impl FnMut(ty::RegionVid) -> ty::Region<'tcx>, ) -> Ty<'tcx> { fold_regions(tcx, self.inner, |r, depth| match r.kind() { - ty::ReBound(debruijn, br) => { + ty::ReBound(ty::BoundVarIndexKind::Bound(debruijn), br) => { debug_assert_eq!(debruijn, depth); map(ty::RegionVid::from_usize(br.var.index())) } @@ -857,7 +857,6 @@ impl<'a, 'tcx> ResultsVisitor<'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<'a, } StatementKind::Nop | StatementKind::Retag { .. } - | StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } @@ -1539,27 +1538,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { self.consume_operand(location, (operand, span), state) } - &Rvalue::CopyForDeref(place) => { - self.access_place( - location, - (place, span), - (Deep, Read(ReadKind::Copy)), - LocalMutationIsAllowed::No, - state, - ); - - // Finally, check if path was already moved. - self.check_if_path_or_subpath_is_moved( - location, - InitializationRequiringAction::Use, - (place.as_ref(), span), - state, - ); - } - - &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { + &Rvalue::Discriminant(place) => { let af = match *rvalue { - Rvalue::Len(..) => Some(ArtificialField::ArrayLength), Rvalue::Discriminant(..) => None, _ => unreachable!(), }; @@ -1619,6 +1599,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { Rvalue::WrapUnsafeBinder(op, _) => { self.consume_operand(location, (op, span), state); } + + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"), } } @@ -1904,7 +1886,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::Slice(_) | ty::FnDef(_, _) | ty::FnPtr(..) - | ty::Dynamic(_, _, _) + | ty::Dynamic(_, _) | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) @@ -1950,7 +1932,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ty::Ref(_, _, _) | ty::FnDef(_, _) | ty::FnPtr(..) - | ty::Dynamic(_, _, _) + | ty::Dynamic(_, _) | ty::CoroutineWitness(..) | ty::Never | ty::UnsafeBinder(_) @@ -1990,10 +1972,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { }, // `OpaqueCast`: only transmutes the type, so no moves there. // `Downcast` : only changes information about a `Place` without moving. - // `Subtype` : only transmutes the type, so no moves. // So it's safe to skip these. ProjectionElem::OpaqueCast(_) - | ProjectionElem::Subtype(_) | ProjectionElem::Downcast(_, _) | ProjectionElem::UnwrapUnsafeBinder(_) => (), } @@ -2219,7 +2199,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { for (place_base, elem) in place.iter_projections().rev() { match elem { ProjectionElem::Index(_/*operand*/) | - ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } | // assigning to P[i] requires P to be valid. @@ -2611,7 +2590,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } - | ProjectionElem::Subtype(..) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Downcast(..) | ProjectionElem::UnwrapUnsafeBinder(_) => { diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs index cf3e82426e8a0..60676ac6b8644 100644 --- a/compiler/rustc_borrowck/src/places_conflict.rs +++ b/compiler/rustc_borrowck/src/places_conflict.rs @@ -249,7 +249,6 @@ fn place_components_conflict<'tcx>( | (ProjectionElem::ConstantIndex { .. }, _, _) | (ProjectionElem::Subslice { .. }, _, _) | (ProjectionElem::OpaqueCast { .. }, _, _) - | (ProjectionElem::Subtype(_), _, _) | (ProjectionElem::Downcast { .. }, _, _) | (ProjectionElem::UnwrapUnsafeBinder(_), _, _) => { // Recursive case. This can still be disjoint on a @@ -510,7 +509,6 @@ fn place_projection_conflict<'tcx>( | ProjectionElem::Field(..) | ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } - | ProjectionElem::Subtype(_) | ProjectionElem::OpaqueCast { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Downcast(..), diff --git a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs index 99dd0b2dd4664..722b59f145d9d 100644 --- a/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs +++ b/compiler/rustc_borrowck/src/polonius/legacy/loan_invalidations.rs @@ -84,7 +84,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> { StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::Retag { .. } - | StatementKind::Deinit(..) | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") @@ -301,21 +300,11 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { | Rvalue::Cast(_ /*cast_kind*/, operand, _ /*ty*/) | Rvalue::ShallowInitBox(operand, _ /*ty*/) => self.consume_operand(location, operand), - &Rvalue::CopyForDeref(place) => { - let op = &Operand::Copy(place); - self.consume_operand(location, op); - } - - &(Rvalue::Len(place) | Rvalue::Discriminant(place)) => { - let af = match rvalue { - Rvalue::Len(..) => Some(ArtificialField::ArrayLength), - Rvalue::Discriminant(..) => None, - _ => unreachable!(), - }; + &Rvalue::Discriminant(place) => { self.access_place( location, place, - (Shallow(af), Read(ReadKind::Copy)), + (Shallow(None), Read(ReadKind::Copy)), LocalMutationIsAllowed::No, ); } @@ -336,6 +325,8 @@ impl<'a, 'tcx> LoanInvalidationsGenerator<'a, 'tcx> { Rvalue::WrapUnsafeBinder(op, _) => { self.consume_operand(location, op); } + + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in borrowck"), } } diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs index 83cca38a5c090..9e51264d8edcb 100644 --- a/compiler/rustc_borrowck/src/prefixes.rs +++ b/compiler/rustc_borrowck/src/prefixes.rs @@ -77,9 +77,6 @@ impl<'tcx> Iterator for Prefixes<'tcx> { | ProjectionElem::Index(_) => { cursor = cursor_base; } - ProjectionElem::Subtype(..) => { - panic!("Subtype projection is not allowed before borrow check") - } ProjectionElem::Deref => { match self.kind { PrefixSet::Shallow => { diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index f57456949bb5e..e98c60e633805 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -571,11 +571,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Returns `true` if all the elements in the value of `scc_b` are nameable + /// Returns `true` if all the placeholders in the value of `scc_b` are nameable /// in `scc_a`. Used during constraint propagation, and only once /// the value of `scc_b` has been computed. - fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool { - self.scc_annotations[scc_a].universe_compatible_with(self.scc_annotations[scc_b]) + fn can_name_all_placeholders( + &self, + scc_a: ConstraintSccIndex, + scc_b: ConstraintSccIndex, + ) -> bool { + self.scc_annotations[scc_a].can_name_all_placeholders(self.scc_annotations[scc_b]) } /// Once regions have been propagated, this method is used to see @@ -964,16 +968,22 @@ impl<'tcx> RegionInferenceContext<'tcx> { return true; } + let fr_static = self.universal_regions().fr_static; + // If we are checking that `'sup: 'sub`, and `'sub` contains // some placeholder that `'sup` cannot name, then this is only // true if `'sup` outlives static. - if !self.universe_compatible(sub_region_scc, sup_region_scc) { + // + // Avoid infinite recursion if `sub_region` is already `'static` + if sub_region != fr_static + && !self.can_name_all_placeholders(sup_region_scc, sub_region_scc) + { debug!( "sub universe `{sub_region_scc:?}` is not nameable \ by super `{sup_region_scc:?}`, promoting to static", ); - return self.eval_outlives(sup_region, self.universal_regions().fr_static); + return self.eval_outlives(sup_region, fr_static); } // Both the `sub_region` and `sup_region` consist of the union @@ -1372,10 +1382,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// The constraints we get from equating the hidden type of each use of an opaque - /// with its final concrete type may end up getting preferred over other, potentially + /// with its final hidden type may end up getting preferred over other, potentially /// longer constraint paths. /// - /// Given that we compute the final concrete type by relying on this existing constraint + /// Given that we compute the final hidden type by relying on this existing constraint /// path, this can easily end up hiding the actual reason for why we require these regions /// to be equal. /// @@ -1726,9 +1736,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { // `BoringNoLocation` constraints can point to user-written code, but are less // specific, and are not used for relations that would make sense to blame. ConstraintCategory::BoringNoLocation => 6, - // Do not blame internal constraints. - ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 7, - ConstraintCategory::Internal => 8, + // Do not blame internal constraints if we can avoid it. Never blame + // the `'region: 'static` constraints introduced by placeholder outlives. + ConstraintCategory::Internal => 7, + ConstraintCategory::OutlivesUnnameablePlaceholder(_) => 8, }; debug!("constraint {constraint:?} category: {category:?}, interest: {interest:?}"); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs index 667fc440ac002..a2e2b61ae2d35 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs @@ -39,7 +39,7 @@ pub(super) fn apply_member_constraints<'tcx>( debug!(?member_constraints); for scc_a in rcx.constraint_sccs.all_sccs() { debug!(?scc_a); - // Start by adding the region values required by outlives constraints. This + // Start by adding the region values required by outlives constraints. This // matches how we compute the final region values in `fn compute_regions`. // // We need to do this here to get a lower bound when applying member constraints. @@ -64,6 +64,7 @@ fn apply_member_constraint<'tcx>( // If the member region lives in a higher universe, we currently choose // the most conservative option by leaving it unchanged. if !rcx.max_placeholder_universe_reached(member).is_root() { + debug!("member region reached non root universe, bailing"); return; } diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 0af636aa734ca..67d1d44b1e1f8 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -8,7 +8,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, OpaqueTypeStorageEntries}; use rustc_infer::traits::ObligationCause; use rustc_macros::extension; -use rustc_middle::mir::{Body, ConcreteOpaqueTypes, ConstraintCategory}; +use rustc_middle::mir::{Body, ConstraintCategory, DefinitionSiteHiddenTypes}; use rustc_middle::ty::{ self, DefiningScopeKind, EarlyBinder, FallibleTypeFolder, GenericArg, GenericArgsRef, OpaqueHiddenType, OpaqueTypeKey, Region, RegionVid, Ty, TyCtxt, TypeFoldable, @@ -129,9 +129,9 @@ fn nll_var_to_universal_region<'tcx>( /// Collect all defining uses of opaque types inside of this typeck root. This /// expects the hidden type to be mapped to the definition parameters of the opaque /// and errors if we end up with distinct hidden types. -fn add_concrete_opaque_type<'tcx>( +fn add_hidden_type<'tcx>( tcx: TyCtxt<'tcx>, - concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, def_id: LocalDefId, hidden_ty: OpaqueHiddenType<'tcx>, ) { @@ -139,7 +139,7 @@ fn add_concrete_opaque_type<'tcx>( // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to // `(X, Y)` and `OpaqueType` mapped to `(Y, X)`, and those are the same, but we // only know that once we convert the generic parameters to those of the opaque type. - if let Some(prev) = concrete_opaque_types.0.get_mut(&def_id) { + if let Some(prev) = hidden_types.0.get_mut(&def_id) { if prev.ty != hidden_ty.ty { let guar = hidden_ty.ty.error_reported().err().unwrap_or_else(|| { let (Ok(e) | Err(e)) = prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); @@ -151,17 +151,10 @@ fn add_concrete_opaque_type<'tcx>( // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. prev.span = prev.span.substitute_dummy(hidden_ty.span); } else { - concrete_opaque_types.0.insert(def_id, hidden_ty); + hidden_types.0.insert(def_id, hidden_ty); } } -fn get_concrete_opaque_type<'tcx>( - concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>, - def_id: LocalDefId, -) -> Option>> { - concrete_opaque_types.0.get(&def_id).map(|ty| EarlyBinder::bind(*ty)) -} - #[derive(Debug)] struct DefiningUse<'tcx> { /// The opaque type using non NLL vars. This uses the actual @@ -173,22 +166,22 @@ struct DefiningUse<'tcx> { } /// This computes the actual hidden types of the opaque types and maps them to their -/// definition sites. Outside of registering the computed concrete types this function +/// definition sites. Outside of registering the computed hidden types this function /// does not mutate the current borrowck state. /// /// While it may fail to infer the hidden type and return errors, we always apply -/// the computed concrete hidden type to all opaque type uses to check whether they +/// the computed hidden type to all opaque type uses to check whether they /// are correct. This is necessary to support non-defining uses of opaques in their /// defining scope. /// /// It also means that this whole function is not really soundness critical as we /// recheck all uses of the opaques regardless. -pub(crate) fn compute_concrete_opaque_types<'tcx>( +pub(crate) fn compute_definition_site_hidden_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, universal_region_relations: &Frozen>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, - concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], ) -> Vec> { let mut errors = Vec::new(); @@ -201,8 +194,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>( // We start by checking each use of an opaque type during type check and // check whether the generic arguments of the opaque type are fully // universal, if so, it's a defining use. - let defining_uses = - collect_defining_uses(&mut rcx, concrete_opaque_types, opaque_types, &mut errors); + let defining_uses = collect_defining_uses(&mut rcx, hidden_types, opaque_types, &mut errors); // We now compute and apply member constraints for all regions in the hidden // types of each defining use. This mutates the region values of the `rcx` which @@ -210,11 +202,11 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>( apply_member_constraints(&mut rcx, &defining_uses); // After applying member constraints, we now check whether all member regions ended - // up equal to one of their choice regions and compute the actual concrete type of + // up equal to one of their choice regions and compute the actual hidden type of // the opaque type definition. This is stored in the `root_cx`. - compute_concrete_types_from_defining_uses( + compute_definition_site_hidden_types_from_defining_uses( &rcx, - concrete_opaque_types, + hidden_types, &defining_uses, &mut errors, ); @@ -224,7 +216,7 @@ pub(crate) fn compute_concrete_opaque_types<'tcx>( #[instrument(level = "debug", skip_all, ret)] fn collect_defining_uses<'tcx>( rcx: &mut RegionCtxt<'_, 'tcx>, - concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], errors: &mut Vec>, ) -> Vec> { @@ -244,9 +236,9 @@ fn collect_defining_uses<'tcx>( // with `TypingMode::Borrowck`. if infcx.tcx.use_typing_mode_borrowck() { match err { - NonDefiningUseReason::Tainted(guar) => add_concrete_opaque_type( + NonDefiningUseReason::Tainted(guar) => add_hidden_type( infcx.tcx, - concrete_opaque_types, + hidden_types, opaque_type_key.def_id, OpaqueHiddenType::new_error(infcx.tcx, guar), ), @@ -254,6 +246,10 @@ fn collect_defining_uses<'tcx>( } } else { errors.push(DeferredOpaqueTypeError::InvalidOpaqueTypeArgs(err)); + debug!( + "collect_defining_uses: InvalidOpaqueTypeArgs for {:?} := {:?}", + non_nll_opaque_type_key, hidden_type + ); } continue; } @@ -277,9 +273,10 @@ fn collect_defining_uses<'tcx>( defining_uses } -fn compute_concrete_types_from_defining_uses<'tcx>( +#[instrument(level = "debug", skip(rcx, hidden_types, defining_uses, errors))] +fn compute_definition_site_hidden_types_from_defining_uses<'tcx>( rcx: &RegionCtxt<'_, 'tcx>, - concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, defining_uses: &[DefiningUse<'tcx>], errors: &mut Vec>, ) { @@ -288,6 +285,7 @@ fn compute_concrete_types_from_defining_uses<'tcx>( let mut decls_modulo_regions: FxIndexMap, (OpaqueTypeKey<'tcx>, Span)> = FxIndexMap::default(); for &DefiningUse { opaque_type_key, ref arg_regions, hidden_type } in defining_uses { + debug!(?opaque_type_key, ?arg_regions, ?hidden_type); // After applying member constraints, we now map all regions in the hidden type // to the `arg_regions` of this defining use. In case a region in the hidden type // ended up not being equal to any such region, we error. @@ -295,6 +293,7 @@ fn compute_concrete_types_from_defining_uses<'tcx>( match hidden_type.try_fold_with(&mut ToArgRegionsFolder::new(rcx, arg_regions)) { Ok(hidden_type) => hidden_type, Err(r) => { + debug!("UnexpectedHiddenRegion: {:?}", r); errors.push(DeferredOpaqueTypeError::UnexpectedHiddenRegion { hidden_type, opaque_type_key, @@ -358,9 +357,9 @@ fn compute_concrete_types_from_defining_uses<'tcx>( }, )); } - add_concrete_opaque_type( + add_hidden_type( tcx, - concrete_opaque_types, + hidden_types, opaque_type_key.def_id, OpaqueHiddenType { span: hidden_type.span, ty }, ); @@ -489,20 +488,21 @@ impl<'tcx> FallibleTypeFolder> for ToArgRegionsFolder<'_, 'tcx> { /// /// It does this by equating the hidden type of each use with the instantiated final /// hidden type of the opaque. -pub(crate) fn apply_computed_concrete_opaque_types<'tcx>( +pub(crate) fn apply_definition_site_hidden_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, universal_regions: &UniversalRegions<'tcx>, region_bound_pairs: &RegionBoundPairs<'tcx>, known_type_outlives_obligations: &[ty::PolyTypeOutlivesPredicate<'tcx>], constraints: &mut MirTypeckRegionConstraints<'tcx>, - concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + hidden_types: &mut DefinitionSiteHiddenTypes<'tcx>, opaque_types: &[(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)], ) -> Vec> { let tcx = infcx.tcx; let mut errors = Vec::new(); for &(key, hidden_type) in opaque_types { - let Some(expected) = get_concrete_opaque_type(concrete_opaque_types, key.def_id) else { + let Some(expected) = hidden_types.0.get(&key.def_id).map(|ty| EarlyBinder::bind(*ty)) + else { if !tcx.use_typing_mode_borrowck() { if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() && alias_ty.def_id == key.def_id.to_def_id() @@ -521,12 +521,7 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>( hidden_type.span, "non-defining use in the defining scope with no defining uses", ); - add_concrete_opaque_type( - tcx, - concrete_opaque_types, - key.def_id, - OpaqueHiddenType::new_error(tcx, guar), - ); + add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); continue; }; @@ -566,18 +561,13 @@ pub(crate) fn apply_computed_concrete_opaque_types<'tcx>( "equating opaque types", ), ) { - add_concrete_opaque_type( - tcx, - concrete_opaque_types, - key.def_id, - OpaqueHiddenType::new_error(tcx, guar), - ); + add_hidden_type(tcx, hidden_types, key.def_id, OpaqueHiddenType::new_error(tcx, guar)); } } errors } -/// In theory `apply_concrete_opaque_types` could introduce new uses of opaque types. +/// In theory `apply_definition_site_hidden_types` could introduce new uses of opaque types. /// We do not check these new uses so this could be unsound. /// /// We detect any new uses and simply delay a bug if they occur. If this results in @@ -682,13 +672,6 @@ impl<'tcx> InferCtxt<'tcx> { /// /// (*) C1 and C2 were introduced in the comments on /// `register_member_constraints`. Read that comment for more context. - /// - /// # Parameters - /// - /// - `def_id`, the `impl Trait` type - /// - `args`, the args used to instantiate this opaque type - /// - `instantiated_ty`, the inferred type C1 -- fully resolved, lifted version of - /// `opaque_defn.concrete_ty` #[instrument(level = "debug", skip(self))] fn infer_opaque_definition_from_instantiation( &self, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs index 88326e4eebfc2..90b15cbdd2cc8 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs @@ -11,7 +11,9 @@ use crate::constraints::ConstraintSccIndex; use crate::handle_placeholders::{SccAnnotations, region_definitions}; use crate::region_infer::reverse_sccs::ReverseSccGraph; use crate::region_infer::values::RegionValues; -use crate::region_infer::{ConstraintSccs, RegionDefinition, RegionTracker, Representative}; +use crate::region_infer::{ + ConstraintSccs, OutlivesConstraintSet, RegionDefinition, RegionTracker, Representative, +}; use crate::type_check::MirTypeckRegionConstraints; use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::universal_regions::UniversalRegions; @@ -39,16 +41,36 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { location_map: Rc, constraints: &MirTypeckRegionConstraints<'tcx>, ) -> RegionCtxt<'a, 'tcx> { + let mut outlives_constraints = constraints.outlives_constraints.clone(); let universal_regions = &universal_region_relations.universal_regions; let (definitions, _has_placeholders) = region_definitions(infcx, universal_regions); + + let compute_sccs = + |outlives_constraints: &OutlivesConstraintSet<'tcx>, + annotations: &mut SccAnnotations<'_, 'tcx, RegionTracker>| { + ConstraintSccs::new_with_annotation( + &outlives_constraints + .graph(definitions.len()) + .region_graph(outlives_constraints, universal_regions.fr_static), + annotations, + ) + }; + let mut scc_annotations = SccAnnotations::init(&definitions); - let constraint_sccs = ConstraintSccs::new_with_annotation( - &constraints - .outlives_constraints - .graph(definitions.len()) - .region_graph(&constraints.outlives_constraints, universal_regions.fr_static), - &mut scc_annotations, + let mut constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations); + + let added_constraints = crate::handle_placeholders::rewrite_placeholder_outlives( + &constraint_sccs, + &scc_annotations, + universal_regions.fr_static, + &mut outlives_constraints, ); + + if added_constraints { + scc_annotations = SccAnnotations::init(&definitions); + constraint_sccs = compute_sccs(&outlives_constraints, &mut scc_annotations); + } + let scc_annotations = scc_annotations.scc_to_annotation; // Unlike the `RegionInferenceContext`, we only care about free regions diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index fa3064afee81c..d6dbc7dd831fb 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -21,10 +21,10 @@ pub(crate) fn renumber_mir<'tcx>( let mut renumberer = RegionRenumberer { infcx }; for body in promoted.iter_mut() { - renumberer.visit_body(body); + renumberer.visit_body_preserves_cfg(body); } - renumberer.visit_body(body); + renumberer.visit_body_preserves_cfg(body); } // The fields are used only for debugging output in `sccs_info`. diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index cd4e9683f2d87..21c11e1287353 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -12,12 +12,12 @@ use smallvec::SmallVec; use crate::consumers::BorrowckConsumer; use crate::nll::compute_closure_requirements_modulo_opaques; use crate::region_infer::opaque_types::{ - apply_computed_concrete_opaque_types, clone_and_resolve_opaque_types, - compute_concrete_opaque_types, detect_opaque_types_added_while_handling_opaque_types, + apply_definition_site_hidden_types, clone_and_resolve_opaque_types, + compute_definition_site_hidden_types, detect_opaque_types_added_while_handling_opaque_types, }; use crate::type_check::{Locations, constraint_conversion}; use crate::{ - ClosureRegionRequirements, CollectRegionConstraintsResult, ConcreteOpaqueTypes, + ClosureRegionRequirements, CollectRegionConstraintsResult, DefinitionSiteHiddenTypes, PropagatedBorrowCheckResults, borrowck_check_region_constraints, borrowck_collect_region_constraints, }; @@ -27,7 +27,7 @@ use crate::{ pub(super) struct BorrowCheckRootCtxt<'tcx> { pub tcx: TyCtxt<'tcx>, root_def_id: LocalDefId, - concrete_opaque_types: ConcreteOpaqueTypes<'tcx>, + hidden_types: DefinitionSiteHiddenTypes<'tcx>, /// The region constraints computed by [borrowck_collect_region_constraints]. This uses /// an [FxIndexMap] to guarantee that iterating over it visits nested bodies before /// their parents. @@ -49,7 +49,7 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { BorrowCheckRootCtxt { tcx, root_def_id, - concrete_opaque_types: Default::default(), + hidden_types: Default::default(), collect_region_constraints_results: Default::default(), propagated_borrowck_results: Default::default(), tainted_by_errors: None, @@ -72,11 +72,11 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { &self.propagated_borrowck_results[&nested_body_def_id].used_mut_upvars } - pub(super) fn finalize(self) -> Result<&'tcx ConcreteOpaqueTypes<'tcx>, ErrorGuaranteed> { + pub(super) fn finalize(self) -> Result<&'tcx DefinitionSiteHiddenTypes<'tcx>, ErrorGuaranteed> { if let Some(guar) = self.tainted_by_errors { Err(guar) } else { - Ok(self.tcx.arena.alloc(self.concrete_opaque_types)) + Ok(self.tcx.arena.alloc(self.hidden_types)) } } @@ -88,12 +88,12 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { &input.universal_region_relations, &mut input.constraints, ); - input.deferred_opaque_type_errors = compute_concrete_opaque_types( + input.deferred_opaque_type_errors = compute_definition_site_hidden_types( &input.infcx, &input.universal_region_relations, &input.constraints, Rc::clone(&input.location_map), - &mut self.concrete_opaque_types, + &mut self.hidden_types, &opaque_types, ); per_body_info.push((num_entries, opaque_types)); @@ -103,14 +103,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { self.collect_region_constraints_results.values_mut().zip(per_body_info) { if input.deferred_opaque_type_errors.is_empty() { - input.deferred_opaque_type_errors = apply_computed_concrete_opaque_types( + input.deferred_opaque_type_errors = apply_definition_site_hidden_types( &input.infcx, &input.body_owned, &input.universal_region_relations.universal_regions, &input.region_bound_pairs, &input.known_type_outlives_obligations, &mut input.constraints, - &mut self.concrete_opaque_types, + &mut self.hidden_types, &opaque_types, ); } diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 2627ed899a933..aece0bda34692 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -230,8 +230,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { location: impl NormalizeLocation, ) -> Ty<'tcx> { let tcx = self.tcx(); + let body = self.body; + + let cause = ObligationCause::misc( + location.to_locations().span(body), + body.source.def_id().expect_local(), + ); + if self.infcx.next_trait_solver() { - let body = self.body; let param_env = self.infcx.param_env; // FIXME: Make this into a real type op? self.fully_perform_op( @@ -241,10 +247,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { |ocx| { let structurally_normalize = |ty| { ocx.structurally_normalize_ty( - &ObligationCause::misc( - location.to_locations().span(body), - body.source.def_id().expect_local(), - ), + &cause, param_env, ty, ) @@ -253,6 +256,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tail = tcx.struct_tail_raw( ty, + &cause, structurally_normalize, || {}, ); @@ -265,7 +269,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .unwrap_or_else(|guar| Ty::new_error(tcx, guar)) } else { let mut normalize = |ty| self.normalize(ty, location); - let tail = tcx.struct_tail_raw(ty, &mut normalize, || {}); + let tail = tcx.struct_tail_raw(ty, &cause, &mut normalize, || {}); normalize(tail) } } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index b704d8f0a7692..7ac94020de03b 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -657,7 +657,7 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> { let errors = match dropck_outlives::compute_dropck_outlives_with_errors( &ocx, op, span, ) { - Ok(_) => ocx.select_all_or_error(), + Ok(_) => ocx.evaluate_obligations_error_on_ambiguity(), Err(e) => e, }; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 8c5447fe1e9e7..984a154853a98 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -505,6 +505,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let mut constraints = Default::default(); let mut liveness_constraints = LivenessValues::without_specific_points(Rc::new(DenseLocationMap::new(promoted_body))); + let mut deferred_closure_requirements = Default::default(); // Don't try to add borrow_region facts for the promoted MIR as they refer // to the wrong locations. @@ -512,6 +513,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { mem::swap(this.polonius_facts, polonius_facts); mem::swap(&mut this.constraints.outlives_constraints, &mut constraints); mem::swap(&mut this.constraints.liveness_constraints, &mut liveness_constraints); + mem::swap(this.deferred_closure_requirements, &mut deferred_closure_requirements); }; swap_constraints(self); @@ -536,6 +538,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } self.constraints.outlives_constraints.push(constraint) } + + // If there are nested bodies in promoteds, we also need to update their + // location to something in the actual body, not the promoted. + // + // We don't update the constraint categories of the resulting constraints + // as returns in nested bodies are a proper return, even if that nested body + // is in a promoted. + for (closure_def_id, args, _locations) in deferred_closure_requirements { + self.deferred_closure_requirements.push((closure_def_id, args, locations)); + } + // If the region is live at least one location in the promoted MIR, // then add a liveness constraint to the main MIR for this region // at the location provided as an argument to this method @@ -735,7 +748,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { | StatementKind::BackwardIncompatibleDropHint { .. } | StatementKind::Nop => {} StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(..)) - | StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => { bug!("Statement not allowed in this MIR phase") } @@ -1487,9 +1499,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { unsize_to: None, }, ); - } else if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = + } else if let ty::Dynamic(src_tty, _src_lt) = *self.struct_tail(src.ty, location).kind() - && let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = + && let ty::Dynamic(dst_tty, dst_lt) = *self.struct_tail(dst.ty, location).kind() && src_tty.principal().is_some() && dst_tty.principal().is_some() @@ -1511,7 +1523,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { // FIXME: Once we disallow casting `*const dyn Trait + 'short` // to `*const dyn Trait + 'long`, then this can just be `src_lt`. dst_lt, - ty::Dyn, ); let dst_obj = Ty::new_dynamic( tcx, @@ -1519,7 +1530,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { &dst_tty.without_auto_traits().collect::>(), ), dst_lt, - ty::Dyn, ); debug!(?src_tty, ?dst_tty, ?src_obj, ?dst_obj); @@ -1547,6 +1557,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ), } } + CastKind::Subtype => { + bug!("CastKind::Subtype shouldn't exist in borrowck") + } } } @@ -1631,7 +1644,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { | Rvalue::BinaryOp(..) | Rvalue::RawPtr(..) | Rvalue::ThreadLocalRef(..) - | Rvalue::Len(..) | Rvalue::Discriminant(..) | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} } @@ -1872,9 +1884,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ) .unwrap(); } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } } } } @@ -2201,7 +2210,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::Repeat(..) | Rvalue::Ref(..) | Rvalue::RawPtr(..) - | Rvalue::Len(..) | Rvalue::Cast(..) | Rvalue::ShallowInitBox(..) | Rvalue::BinaryOp(..) @@ -2403,9 +2411,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | ProjectionElem::UnwrapUnsafeBinder(_) => { // other field access } - ProjectionElem::Subtype(_) => { - bug!("ProjectionElem::Subtype shouldn't exist in borrowck") - } } } } diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index e56b9e641a10b..ce9a3ce3f248e 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -33,3 +33,8 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" tracing = "0.1" # tidy-alphabetical-end + +[features] +# tidy-alphabetical-start +llvm_enzyme = [] +# tidy-alphabetical-end diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 358c0d3db460f..5e498bf98fb55 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -64,6 +64,11 @@ builtin_macros_autodiff_ty_activity = {$act} can not be used for this type builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}` builtin_macros_autodiff_width = autodiff width must fit u32, but is {$width} + +builtin_macros_avoid_att_syntax = avoid using `.att_syntax`, prefer using `options(att_syntax)` instead + +builtin_macros_avoid_intel_syntax = avoid using `.intel_syntax`, Intel syntax is the default + builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s .label = not applicable here .label2 = not a `struct`, `enum` or `union` @@ -130,6 +135,15 @@ builtin_macros_concat_missing_literal = expected a literal builtin_macros_default_arg = `#[default]` attribute does not accept a value .suggestion = try using `#[default]` +builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field + +builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields -> + [true] multiple fields + *[false] no fields +} + +builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind} + builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept arguments @@ -138,6 +152,8 @@ builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept a builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values .suggestion = remove the value +builtin_macros_duplicate_macro_attribute = duplicated attribute + builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time .cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead .custom = use `std::env::var({$var_expr})` to read the variable at run time @@ -222,14 +238,7 @@ builtin_macros_format_unused_args = multiple unused formatting arguments builtin_macros_format_use_positional = consider using a positional formatting argument instead -builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind} - -builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields -> - [true] multiple fields - *[false] no fields -} - -builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field +builtin_macros_incomplete_include = include macro expected single expression in source builtin_macros_multiple_default_attrs = multiple `#[default]` attributes .note = only one `#[default]` attribute is needed @@ -274,7 +283,7 @@ builtin_macros_requires_cfg_pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required -builtin_macros_source_uitls_expected_item = expected item, found `{$token}` +builtin_macros_source_utils_expected_item = expected item, found `{$token}` builtin_macros_takes_no_arguments = {$name} takes no arguments @@ -294,3 +303,5 @@ builtin_macros_unexpected_lit = expected path to a trait, found literal .label = not a trait .str_lit = try using `#[derive({$sym})]` .other = for example, write `#[derive(Debug)]` for `Debug` + +builtin_macros_unnameable_test_items = cannot test inner items diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index 35ef6be095e9c..40946f3b2791a 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -1,3 +1,4 @@ +use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, global_fn_name}; use rustc_ast::{ self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind, }; @@ -55,7 +56,7 @@ pub(crate) fn expand( } // #[rustc_std_internal_symbol] -// unsafe fn __rg_oom(size: usize, align: usize) -> ! { +// unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! { // handler(core::alloc::Layout::from_size_align_unchecked(size, align)) // } fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { @@ -84,7 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let kind = ItemKind::Fn(Box::new(Fn { defaultness: ast::Defaultness::Final, sig, - ident: Ident::from_str_and_span("__rg_oom", span), + ident: Ident::from_str_and_span(&global_fn_name(ALLOC_ERROR_HANDLER), span), generics: Generics::default(), contract: None, body, diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 86b8e1ff8dbb4..971b68d14757a 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -1,4 +1,3 @@ -use lint::BuiltinLintDiag; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{AsmMacro, token}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; @@ -352,7 +351,7 @@ fn expand_preparsed_asm( lint::builtin::BAD_ASM_STYLE, find_span(".intel_syntax"), ecx.current_expansion.lint_node_id, - BuiltinLintDiag::AvoidUsingIntelSyntax, + errors::AvoidIntelSyntax, ); } if template_str.contains(".att_syntax") { @@ -360,7 +359,7 @@ fn expand_preparsed_asm( lint::builtin::BAD_ASM_STYLE, find_span(".att_syntax"), ecx.current_expansion.lint_node_id, - BuiltinLintDiag::AvoidUsingAttSyntax, + errors::AvoidAttSyntax, ); } } @@ -369,7 +368,7 @@ fn expand_preparsed_asm( if args.options.contains(ast::InlineAsmOptions::RAW) { template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string().into())); let template_num_lines = 1 + template_str.matches('\n').count(); - line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines)); + line_spans.extend(std::iter::repeat_n(template_sp, template_num_lines)); continue; } @@ -524,7 +523,7 @@ fn expand_preparsed_asm( if parser.line_spans.is_empty() { let template_num_lines = 1 + template_str.matches('\n').count(); - line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines)); + line_spans.extend(std::iter::repeat_n(template_sp, template_num_lines)); } else { line_spans.extend( parser diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 48d0795af5ee2..ddc59bfe1414a 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -209,7 +209,8 @@ mod llvm_enzyme { mut item: Annotatable, mode: DiffMode, ) -> Vec { - if cfg!(not(llvm_enzyme)) { + // FIXME(bjorn3) maybe have the backend directly tell if autodiff is supported? + if cfg!(not(feature = "llvm_enzyme")) { ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span }); return vec![item]; } @@ -376,8 +377,7 @@ mod llvm_enzyme { (ast::AttrKind::Normal(a), ast::AttrKind::Normal(b)) => { let a = &a.item.path; let b = &b.item.path; - a.segments.len() == b.segments.len() - && a.segments.iter().zip(b.segments.iter()).all(|(a, b)| a.ident == b.ident) + a.segments.iter().eq_by(&b.segments, |a, b| a.ident == b.ident) } _ => false, } diff --git a/compiler/rustc_builtin_macros/src/contracts.rs b/compiler/rustc_builtin_macros/src/contracts.rs index 6a24af361fe78..118efd15412e6 100644 --- a/compiler/rustc_builtin_macros/src/contracts.rs +++ b/compiler/rustc_builtin_macros/src/contracts.rs @@ -71,6 +71,14 @@ fn expand_contract_clause( .span_err(attr_span, "contract annotations can only be used on functions")); } + // Contracts are not yet supported on async/gen functions + if new_tts.iter().any(|tt| is_kw(tt, kw::Async) || is_kw(tt, kw::Gen)) { + return Err(ecx.sess.dcx().span_err( + attr_span, + "contract annotations are not yet supported on async or gen functions", + )); + } + // Found the `fn` keyword, now find either the `where` token or the function body. let next_tt = loop { let Some(tt) = cursor.next() else { @@ -141,7 +149,7 @@ fn expand_requires_tts( new_tts.push_tree(TokenTree::Delimited( DelimSpan::from_single(attr_span), DelimSpacing::new(Spacing::JointHidden, Spacing::JointHidden), - token::Delimiter::Parenthesis, + token::Delimiter::Brace, annotation, )); Ok(()) @@ -163,7 +171,7 @@ fn expand_ensures_tts( new_tts.push_tree(TokenTree::Delimited( DelimSpan::from_single(attr_span), DelimSpacing::new(Spacing::JointHidden, Spacing::JointHidden), - token::Delimiter::Parenthesis, + token::Delimiter::Brace, annotation, )); Ok(()) diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index dd8f0e46a0e03..63342880b0941 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -51,43 +51,4 @@ pub(crate) fn expand_deriving_const_param_ty( }; trait_def.expand(cx, mitem, item, push); - - let trait_def = TraitDef { - span, - path: path_std!(marker::UnsizedConstParamTy), - skip_path_as_bound: false, - needs_copy_as_bound_if_packed: false, - additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))], - supports_unions: false, - methods: Vec::new(), - associated_types: Vec::new(), - is_const, - is_staged_api_crate: cx.ecfg.features.staged_api(), - }; - - trait_def.expand(cx, mitem, item, push); -} - -pub(crate) fn expand_deriving_unsized_const_param_ty( - cx: &ExtCtxt<'_>, - span: Span, - mitem: &MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable), - is_const: bool, -) { - let trait_def = TraitDef { - span, - path: path_std!(marker::UnsizedConstParamTy), - skip_path_as_bound: false, - needs_copy_as_bound_if_packed: false, - additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))], - supports_unions: false, - methods: Vec::new(), - associated_types: Vec::new(), - is_const, - is_staged_api_crate: cx.ecfg.features.staged_api(), - }; - - trait_def.expand(cx, mitem, item, push); } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 75db5d77783eb..5b378de8bbddc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -356,21 +356,14 @@ fn contains_maybe_sized_bound(bounds: &[GenericBound]) -> bool { bounds.iter().any(is_maybe_sized_bound) } -fn path_segment_is_exact_match(path_segments: &[ast::PathSegment], syms: &[Symbol]) -> bool { - path_segments.iter().zip(syms).all(|(segment, &symbol)| segment.ident.name == symbol) -} - fn is_sized_marker(path: &ast::Path) -> bool { const CORE_UNSIZE: [Symbol; 3] = [sym::core, sym::marker, sym::Sized]; const STD_UNSIZE: [Symbol; 3] = [sym::std, sym::marker, sym::Sized]; - if path.segments.len() == 4 && path.is_global() { - path_segment_is_exact_match(&path.segments[1..], &CORE_UNSIZE) - || path_segment_is_exact_match(&path.segments[1..], &STD_UNSIZE) - } else if path.segments.len() == 3 { - path_segment_is_exact_match(&path.segments, &CORE_UNSIZE) - || path_segment_is_exact_match(&path.segments, &STD_UNSIZE) + let segments = || path.segments.iter().map(|segment| segment.ident.name); + if path.is_global() { + segments().skip(1).eq(CORE_UNSIZE) || segments().skip(1).eq(STD_UNSIZE) } else { - *path == sym::Sized + segments().eq(CORE_UNSIZE) || segments().eq(STD_UNSIZE) || *path == sym::Sized } } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 3fcf9da945070..24a71ae943899 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -610,7 +610,7 @@ impl<'a> TraitDef<'a> { defaultness: ast::Defaultness::Final, ident, generics: Generics::default(), - where_clauses: ast::TyAliasWhereClauses::default(), + after_where_clause: ast::WhereClause::default(), bounds: Vec::new(), ty: Some(type_def.to_ty(cx, self.span, type_ident, generics)), })), @@ -1507,7 +1507,7 @@ impl<'a> TraitDef<'a> { struct_def: &'a VariantData, prefixes: &[String], by_ref: ByRef, - ) -> ThinVec> { + ) -> ThinVec { prefixes .iter() .map(|prefix| { @@ -1543,7 +1543,7 @@ impl<'a> TraitDef<'a> { attrs: ast::AttrVec::new(), id: ast::DUMMY_NODE_ID, span: pat.span.with_ctxt(self.span.ctxt()), - pat, + pat: Box::new(pat), is_placeholder: false, } }) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 54e8f7503377f..d6ffbb5a4101d 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -3,9 +3,29 @@ use rustc_errors::{ Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, MultiSpan, SingleLabelManySpans, Subdiagnostic, }; -use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Ident, Span, Symbol}; +#[derive(LintDiagnostic)] +#[diag(builtin_macros_avoid_intel_syntax)] +pub(crate) struct AvoidIntelSyntax; + +#[derive(LintDiagnostic)] +#[diag(builtin_macros_avoid_att_syntax)] +pub(crate) struct AvoidAttSyntax; + +#[derive(LintDiagnostic)] +#[diag(builtin_macros_incomplete_include)] +pub(crate) struct IncompleteInclude; + +#[derive(LintDiagnostic)] +#[diag(builtin_macros_unnameable_test_items)] +pub(crate) struct UnnameableTestItems; + +#[derive(LintDiagnostic)] +#[diag(builtin_macros_duplicate_macro_attribute)] +pub(crate) struct DuplicateMacroAttribute; + #[derive(Diagnostic)] #[diag(builtin_macros_requires_cfg_pattern)] pub(crate) struct RequiresCfgPattern { @@ -932,7 +952,7 @@ pub(crate) struct AttributeOnlyUsableWithCrateType<'a> { } #[derive(Diagnostic)] -#[diag(builtin_macros_source_uitls_expected_item)] +#[diag(builtin_macros_source_utils_expected_item)] pub(crate) struct ExpectedItem<'a> { #[primary_span] pub span: Span, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index d70888205a51b..a0ee7ac19899b 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -69,35 +69,26 @@ struct MacroInput { /// Ok((fmtstr, parsed arguments)) /// ``` fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, MacroInput> { - let mut args = FormatArguments::new(); - let mut p = ecx.new_parser_from_tts(tts); - if p.token == token::Eof { - return Err(ecx.dcx().create_err(errors::FormatRequiresString { span: sp })); - } - - let first_token = &p.token; - - let fmtstr = if let token::Literal(lit) = first_token.kind - && matches!(lit.kind, token::Str | token::StrRaw(_)) - { + // parse the format string + let fmtstr = match p.token.kind { + token::Eof => return Err(ecx.dcx().create_err(errors::FormatRequiresString { span: sp })), // This allows us to properly handle cases when the first comma // after the format string is mistakenly replaced with any operator, // which cause the expression parser to eat too much tokens. - p.parse_literal_maybe_minus()? - } else { + token::Literal(token::Lit { kind: token::Str | token::StrRaw(_), .. }) => { + p.parse_literal_maybe_minus()? + } // Otherwise, we fall back to the expression parser. - p.parse_expr()? + _ => p.parse_expr()?, }; - // Only allow implicit captures to be used when the argument is a direct literal - // instead of a macro expanding to one. - let is_direct_literal = matches!(fmtstr.kind, ExprKind::Lit(_)); - + // parse comma FormatArgument pairs + let mut args = FormatArguments::new(); let mut first = true; - while p.token != token::Eof { + // parse a comma, or else report an error if !p.eat(exp!(Comma)) { if first { p.clear_expected_token_types(); @@ -120,9 +111,11 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, } } first = false; + // accept a trailing comma if p.token == token::Eof { break; - } // accept trailing commas + } + // parse a FormatArgument match p.token.ident() { Some((ident, _)) if p.look_ahead(1, |t| *t == token::Eq) => { p.bump(); @@ -156,6 +149,10 @@ fn parse_args<'a>(ecx: &ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, } } } + + // Only allow implicit captures for direct literals + let is_direct_literal = matches!(fmtstr.kind, ExprKind::Lit(_)); + Ok(MacroInput { fmtstr, args, is_direct_literal }) } @@ -768,7 +765,7 @@ fn report_missing_placeholders( if !found_foreign && invalid_refs.is_empty() { // Show example if user didn't use any format specifiers - let show_example = used.iter().all(|used| !used); + let show_example = !used.contains(&true); if !show_example { if unused.len() > 1 { diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index f14b1920722f4..c968353504e15 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -85,7 +85,7 @@ impl AllocFnFactory<'_, '_> { body, define_opaque: None, })); - let item = self.cx.item(self.span, self.attrs(), kind); + let item = self.cx.item(self.span, self.attrs(method), kind); self.cx.stmt_item(self.ty_span, item) } @@ -100,8 +100,18 @@ impl AllocFnFactory<'_, '_> { self.cx.expr_call(self.ty_span, method, args) } - fn attrs(&self) -> AttrVec { - thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)] + fn attrs(&self, method: &AllocatorMethod) -> AttrVec { + let alloc_attr = match method.name { + sym::alloc => sym::rustc_allocator, + sym::dealloc => sym::rustc_deallocator, + sym::realloc => sym::rustc_reallocator, + sym::alloc_zeroed => sym::rustc_allocator_zeroed, + _ => unreachable!("Unknown allocator method!"), + }; + thin_vec![ + self.cx.attr_word(sym::rustc_std_internal_symbol, self.span), + self.cx.attr_word(alloc_attr, self.span) + ] } fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec) -> Box { @@ -141,7 +151,7 @@ impl AllocFnFactory<'_, '_> { self.cx.expr_ident(self.span, ident) } - AllocatorTy::ResultPtr | AllocatorTy::Unit => { + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { panic!("can't convert AllocatorTy to an argument") } } @@ -153,7 +163,7 @@ impl AllocFnFactory<'_, '_> { AllocatorTy::Unit => self.cx.ty(self.span, TyKind::Tup(ThinVec::new())), - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + AllocatorTy::Layout | AllocatorTy::Never | AllocatorTy::Usize | AllocatorTy::Ptr => { panic!("can't convert `AllocatorTy` to an output") } } diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 1bcea95fbb7b0..57cf62ea61212 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -11,6 +11,7 @@ #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] +#![feature(iter_order_by)] #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustdoc_internals)] @@ -129,7 +130,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { Clone: clone::expand_deriving_clone, Copy: bounds::expand_deriving_copy, ConstParamTy: bounds::expand_deriving_const_param_ty, - UnsizedConstParamTy: bounds::expand_deriving_unsized_const_param_ty, Debug: debug::expand_deriving_debug, Default: default::expand_deriving_default, Eq: eq::expand_deriving_eq, diff --git a/compiler/rustc_builtin_macros/src/pattern_type.rs b/compiler/rustc_builtin_macros/src/pattern_type.rs index 34faafdc07c61..87a5a440140e0 100644 --- a/compiler/rustc_builtin_macros/src/pattern_type.rs +++ b/compiler/rustc_builtin_macros/src/pattern_type.rs @@ -30,28 +30,34 @@ fn parse_pat_ty<'a>( let ty = parser.parse_ty()?; parser.expect_keyword(exp!(Is))?; - let pat = pat_to_ty_pat( - cx, - *parser.parse_pat_no_top_guard( - None, - RecoverComma::No, - RecoverColon::No, - CommaRecoveryMode::EitherTupleOrPipe, - )?, - ); + let start = parser.token.span; + let pat = if parser.eat(exp!(Bang)) { + parser.expect_keyword(exp!(Null))?; + ty_pat(TyPatKind::NotNull, start.to(parser.token.span)) + } else { + pat_to_ty_pat( + cx, + parser.parse_pat_no_top_guard( + None, + RecoverComma::No, + RecoverColon::No, + CommaRecoveryMode::EitherTupleOrPipe, + )?, + ) + }; if parser.token != token::Eof { parser.unexpected()?; } - Ok((ty, pat)) + Ok((ty, Box::new(pat))) } -fn ty_pat(kind: TyPatKind, span: Span) -> Box { - Box::new(TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None }) +fn ty_pat(kind: TyPatKind, span: Span) -> TyPat { + TyPat { id: DUMMY_NODE_ID, kind, span, tokens: None } } -fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> Box { +fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> TyPat { let kind = match pat.kind { ast::PatKind::Range(start, end, include_end) => TyPatKind::Range( start.map(|value| Box::new(AnonConst { id: DUMMY_NODE_ID, value })), @@ -59,7 +65,7 @@ fn pat_to_ty_pat(cx: &mut ExtCtxt<'_>, pat: ast::Pat) -> Box { include_end, ), ast::PatKind::Or(variants) => { - TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, *pat)).collect()) + TyPatKind::Or(variants.into_iter().map(|pat| pat_to_ty_pat(cx, pat)).collect()) } ast::PatKind::Err(guar) => TyPatKind::Err(guar), _ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")), diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 11b868f81a976..16adaab15c525 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -12,7 +12,6 @@ use rustc_expand::base::{ DummyResult, ExpandResult, ExtCtxt, MacEager, MacResult, MacroExpanderResult, resolve_path, }; use rustc_expand::module::DirOwnership; -use rustc_lint_defs::BuiltinLintDiag; use rustc_parse::lexer::StripTokens; use rustc_parse::parser::ForceCollect; use rustc_parse::{new_parser_from_file, unwrap_or_emit_fatal, utf8_error}; @@ -159,7 +158,7 @@ pub(crate) fn expand_include<'cx>( INCOMPLETE_INCLUDE, p.token.span, self.node_id, - BuiltinLintDiag::IncompleteInclude, + errors::IncompleteInclude, ); } Some(expr) diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index a9d91f77560a7..2a6ac5754bfaf 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -3,6 +3,7 @@ use std::mem; use rustc_ast as ast; +use rustc_ast::attr::contains_name; use rustc_ast::entry::EntryPointType; use rustc_ast::mut_visit::*; use rustc_ast::visit::Visitor; @@ -11,7 +12,6 @@ use rustc_errors::DiagCtxtHandle; use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; -use rustc_lint_defs::BuiltinLintDiag; use rustc_session::Session; use rustc_session::lint::builtin::UNNAMEABLE_TEST_ITEMS; use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; @@ -64,8 +64,8 @@ pub fn inject( if sess.is_test_crate() { let panic_strategy = match (panic_strategy, sess.opts.unstable_opts.panic_abort_tests) { - (PanicStrategy::Abort, true) => PanicStrategy::Abort, - (PanicStrategy::Abort, false) => { + (PanicStrategy::Abort | PanicStrategy::ImmediateAbort, true) => panic_strategy, + (PanicStrategy::Abort | PanicStrategy::ImmediateAbort, false) => { if panic_strategy == platform_panic_strategy { // Silently allow compiling with panic=abort on these platforms, // but with old behavior (abort if a test fails). @@ -165,7 +165,7 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> { UNNAMEABLE_TEST_ITEMS, attr.span, i.id, - BuiltinLintDiag::UnnameableTestItems, + errors::UnnameableTestItems, ); } } @@ -173,9 +173,11 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> { fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType { match &item.kind { - ast::ItemKind::Fn(fn_) => { - rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name)) - } + ast::ItemKind::Fn(fn_) => rustc_ast::entry::entry_point_type( + contains_name(&item.attrs, sym::rustc_main), + at_root, + Some(fn_.ident.name), + ), _ => EntryPointType::None, } } @@ -288,10 +290,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> Box { let ecx = &cx.ext_cx; let test_ident = Ident::new(sym::test, sp); - let runner_name = match cx.panic_strategy { - PanicStrategy::Unwind => "test_main_static", - PanicStrategy::Abort => "test_main_static_abort", - }; + let runner_name = + if cx.panic_strategy.unwinds() { "test_main_static" } else { "test_main_static_abort" }; // test::test_main_static(...) let mut test_runner = cx.test_runner.clone().unwrap_or_else(|| { diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index 3a4585d5be9d1..e26f31dce67bd 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -5,7 +5,6 @@ use rustc_errors::{Applicability, Diag, ErrorGuaranteed}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt}; use rustc_expand::expand::AstFragment; use rustc_feature::AttributeTemplate; -use rustc_lint_defs::BuiltinLintDiag; use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES; use rustc_parse::{exp, parser}; use rustc_session::errors::report_lit_error; @@ -49,7 +48,7 @@ pub(crate) fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, DUPLICATE_MACRO_ATTRIBUTES, attr.span, ecx.current_expansion.lint_node_id, - BuiltinLintDiag::DuplicateMacroAttribute, + errors::DuplicateMacroAttribute, ); } } diff --git a/compiler/rustc_codegen_cranelift/src/abi/comments.rs b/compiler/rustc_codegen_cranelift/src/abi/comments.rs index c74efeb59f3fc..d1b2b9a502ac2 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/comments.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/comments.rs @@ -89,7 +89,7 @@ pub(super) fn add_local_place_comments<'tcx>( format!("{:?}", local), format!("{:?}", ty), size.bytes(), - align.abi.bytes(), + align.bytes(), if extra.is_empty() { "" } else { " " }, extra, )); diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 7d0731c77bdc4..9a9a1f4a2c0f8 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -467,7 +467,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( true } else { instance.is_some_and(|inst| { - fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD) + fx.tcx.codegen_instance_attrs(inst.def).flags.contains(CodegenFnAttrFlags::COLD) }) }; if is_cold { @@ -715,7 +715,7 @@ pub(crate) fn codegen_drop<'tcx>( fx.bcx.ins().jump(ret_block, &[]); } else { match ty.kind() { - ty::Dynamic(_, _, ty::Dyn) => { + ty::Dynamic(_, _) => { // IN THIS ARM, WE HAVE: // ty = *mut (dyn Trait) // which is: exists ( *mut T, Vtable ) diff --git a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index 2031842062d97..7a909a740b054 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs @@ -233,7 +233,7 @@ pub(super) fn from_casted_value<'tcx>( // It may also be smaller for example when the type is a wrapper around an integer with a // larger alignment than the integer. std::cmp::max(abi_param_size, layout_size), - u32::try_from(layout.align.abi.bytes()).unwrap(), + u32::try_from(layout.align.bytes()).unwrap(), ); let mut block_params_iter = block_params.iter().copied(); for (offset, _) in abi_params { diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 04f1129d87c1f..67b89114356b5 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -3,10 +3,9 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; -use rustc_codegen_ssa::base::allocator_kind_for_codegen; +use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents}; use rustc_session::config::OomStrategy; use rustc_symbol_mangling::mangle_internal_symbol; @@ -15,75 +14,57 @@ use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - tcx, - module, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + let methods = allocator_shim_contents(tcx, kind); + codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom); true } fn codegen_inner( tcx: TyCtxt<'_>, module: &mut dyn Module, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - arg_tys.push(usize_ty); // size - arg_tys.push(usize_ty); // align - } - AllocatorTy::Ptr => arg_tys.push(usize_ty), - AllocatorTy::Usize => arg_tys.push(usize_ty), + for method in methods { + let mut arg_tys = Vec::with_capacity(method.inputs.len()); + for input in method.inputs.iter() { + match input.ty { + AllocatorTy::Layout => { + arg_tys.push(usize_ty); // size + arg_tys.push(usize_ty); // align + } + AllocatorTy::Ptr => arg_tys.push(usize_ty), + AllocatorTy::Usize => arg_tys.push(usize_ty), - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { + panic!("invalid allocator arg") } } - let output = match method.output { - AllocatorTy::ResultPtr => Some(usize_ty), - AllocatorTy::Unit => None, + } + let output = match method.output { + AllocatorTy::ResultPtr => Some(usize_ty), + AllocatorTy::Never | AllocatorTy::Unit => None, - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: arg_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output.into_iter().map(AbiParam::new).collect(), - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, &global_fn_name(method.name)), - &mangle_internal_symbol(tcx, &default_fn_name(method.name)), - ); - } + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: arg_tys.iter().cloned().map(AbiParam::new).collect(), + returns: output.into_iter().map(AbiParam::new).collect(), + }; + crate::common::create_wrapper_function( + module, + sig, + &mangle_internal_symbol(tcx, &global_fn_name(method.name)), + &mangle_internal_symbol(tcx, &default_fn_name(method.name)), + ); } - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - sig, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), - ); - { let sig = Signature { call_conv: module.target_config().default_call_conv, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 3a28dd7e73cb3..c97218797107b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -600,11 +600,6 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let val = codegen_operand(fx, operand); lval.write_cvalue(fx, val); } - Rvalue::CopyForDeref(place) => { - let cplace = codegen_place(fx, place); - let val = cplace.to_cvalue(fx); - lval.write_cvalue(fx, val) - } Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => { let place = codegen_place(fx, place); let ref_ = place.place_ref(fx, lval.layout()); @@ -789,7 +784,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); crate::unsize::coerce_unsized_into(fx, operand, lval); } - Rvalue::Cast(CastKind::Transmute, ref operand, _to_ty) => { + Rvalue::Cast(CastKind::Transmute | CastKind::Subtype, ref operand, _to_ty) => { let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); } @@ -834,25 +829,12 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: fx.bcx.ins().nop(); } } - Rvalue::Len(place) => { - let place = codegen_place(fx, place); - let usize_layout = fx.layout_of(fx.tcx.types.usize); - let len = codegen_array_len(fx, place); - lval.write_cvalue(fx, CValue::by_val(len, usize_layout)); - } - Rvalue::ShallowInitBox(ref operand, content_ty) => { - let content_ty = fx.monomorphize(content_ty); - let box_layout = fx.layout_of(Ty::new_box(fx.tcx, content_ty)); - let operand = codegen_operand(fx, operand); - let operand = operand.load_scalar(fx); - lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); - } Rvalue::NullaryOp(ref null_op, ty) => { assert!(lval.layout().ty.is_sized(fx.tcx, fx.typing_env())); let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { NullOp::SizeOf => layout.size.bytes(), - NullOp::AlignOf => layout.align.abi.bytes(), + NullOp::AlignOf => layout.align.bytes(), NullOp::OffsetOf(fields) => fx .tcx .offset_of_subfield( @@ -934,11 +916,12 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt: let operand = codegen_operand(fx, operand); lval.write_cvalue_transmute(fx, operand); } + Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), + Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } StatementKind::StorageLive(_) | StatementKind::StorageDead(_) - | StatementKind::Deinit(_) | StatementKind::ConstEvalCounter | StatementKind::Nop | StatementKind::FakeRead(..) @@ -1002,7 +985,7 @@ pub(crate) fn codegen_place<'tcx>( cplace = cplace.place_deref(fx); } PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"), - PlaceElem::Subtype(ty) | PlaceElem::UnwrapUnsafeBinder(ty) => { + PlaceElem::UnwrapUnsafeBinder(ty) => { cplace = cplace.place_transmute_type(fx, fx.monomorphize(ty)); } PlaceElem::Field(field, _ty) => { diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 2fbe5c02802ab..81b1814605a12 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -439,7 +439,10 @@ pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); impl<'tcx> LayoutOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::InvalidSimd { .. } + | LayoutError::ReferencesError(_) = err + { self.0.sess.dcx().span_fatal(span, err.to_string()) } else { self.0 @@ -458,7 +461,9 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FullyMonomorphizedLayoutCx<'tcx> { span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { - if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { + if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) = + err + { self.0.sess.dcx().emit_fatal(Spanned { span, node: err }) } else { match fn_abi_request { diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index a56466750e75c..3243e12e69999 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -5,7 +5,9 @@ use std::cmp::Ordering; use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use rustc_middle::mir::interpret::{AllocId, GlobalAlloc, Scalar, read_target_uint}; +use rustc_middle::mir::interpret::{ + AllocId, GlobalAlloc, PointerArithmetic, Scalar, read_target_uint, +}; use rustc_middle::ty::{ExistentialTraitRef, ScalarInt}; use crate::prelude::*; @@ -138,8 +140,11 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match fx.tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { if alloc.inner().len() == 0 { - assert_eq!(offset, Size::ZERO); - fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64) + let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); + fx.bcx.ins().iconst( + fx.pointer_type, + fx.tcx.truncate_to_target_usize(val) as i64, + ) } else { let data_id = data_id_for_alloc_id( &mut fx.constants_cx, @@ -318,7 +323,7 @@ fn data_id_for_static( let mut data = DataDescription::new(); data.set_align(align); let data_gv = module.declare_data_in_data(data_id, &mut data); - data.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect()); + data.define(std::iter::repeat_n(0, pointer_ty(tcx).bytes() as usize).collect()); data.write_data_addr(0, data_gv, 0); match module.define_data(ref_data_id, &data) { // Every time the static is referenced there will be another definition of this global, @@ -597,7 +602,6 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( StatementKind::Assign(_) | StatementKind::FakeRead(_) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(_) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) | StatementKind::Retag(_, _) diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 286e02b986b3c..4c438742f3d22 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -304,7 +304,7 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); - entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.abi.bytes())); + entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.bytes())); let mut expr = Expression::new(); expr.op_addr(address_for_data(data_id)); diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index 25b922c8be4c7..0d49f32373caa 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs @@ -166,7 +166,7 @@ impl DebugContext { let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id); tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); - tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.abi.bytes())); + tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.bytes())); for (i, (ty, dw_ty)) in components.into_iter().enumerate() { let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member); @@ -178,9 +178,7 @@ impl DebugContext { member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); member_entry.set( gimli::DW_AT_alignment, - AttributeValue::Udata( - FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.abi.bytes(), - ), + AttributeValue::Udata(FullyMonomorphizedLayoutCx(tcx).layout_of(ty).align.bytes()), ); member_entry.set( gimli::DW_AT_data_member_location, diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 203b443269fa7..1306c6aa5179c 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -42,7 +42,10 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> { impl<'tcx> LayoutOfHelpers<'tcx> for GlobalAsmContext<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::InvalidSimd { .. } + | LayoutError::ReferencesError(_) = err + { self.tcx.sess.dcx().span_fatal(span, err.to_string()) } else { self.tcx diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 8e34436fb5e0a..5d48d0c94c581 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -26,13 +26,12 @@ extern crate rustc_fs_util; extern crate rustc_hir; extern crate rustc_incremental; extern crate rustc_index; +extern crate rustc_log; extern crate rustc_metadata; extern crate rustc_session; extern crate rustc_span; extern crate rustc_symbol_mangling; extern crate rustc_target; -#[macro_use] -extern crate tracing; // This prevents duplicating functions and statics that are already part of the host rustc process. #[allow(unused_extern_crates)] @@ -46,6 +45,7 @@ use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::settings::{self, Configurable}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::{CodegenResults, TargetConfig}; +use rustc_log::tracing::info; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_session::Session; use rustc_session::config::OutputFilenames; @@ -165,6 +165,10 @@ impl CodegenBackend for CraneliftCodegenBackend { "" } + fn name(&self) -> &'static str { + "cranelift" + } + fn init(&self, sess: &Session) { use rustc_session::config::{InstrumentCoverage, Lto}; match sess.lto() { diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 2aee0b2e97424..c97eb3874b02c 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -30,9 +30,7 @@ pub(crate) fn unsized_info<'tcx>( fx.pointer_type, len.try_to_target_usize(fx.tcx).expect("expected monomorphic const in codegen") as i64, ), - (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind)) - if src_dyn_kind == target_dyn_kind => - { + (&ty::Dynamic(data_a, _), &ty::Dynamic(data_b, _)) => { let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); let b_principal_def_id = data_b.principal_def_id(); @@ -133,6 +131,11 @@ pub(crate) fn coerce_unsized_into<'tcx>( dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout())); }; match (&src_ty.kind(), &dst_ty.kind()) { + (ty::Pat(a, _), ty::Pat(b, _)) => { + let src = src.cast_pat_ty_to_base(fx.layout_of(*a)); + let dst = dst.place_transmute_type(fx, *b); + return coerce_unsized_into(fx, src, dst); + } (&ty::Ref(..), &ty::Ref(..)) | (&ty::Ref(..), &ty::RawPtr(..)) | (&ty::RawPtr(..), &ty::RawPtr(..)) => coerce_ptr(), @@ -169,7 +172,7 @@ pub(crate) fn size_and_align_of<'tcx>( if layout.is_sized() { return ( fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64), - fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, layout.align.bytes() as i64), ); } @@ -188,7 +191,7 @@ pub(crate) fn size_and_align_of<'tcx>( // times the unit size. ( fx.bcx.ins().imul_imm(info.unwrap(), unit.size.bytes() as i64), - fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, unit.align.bytes() as i64), ) } ty::Foreign(_) => { @@ -226,7 +229,7 @@ pub(crate) fn size_and_align_of<'tcx>( let unsized_offset_unadjusted = layout.fields.offset(i).bytes(); let unsized_offset_unadjusted = fx.bcx.ins().iconst(fx.pointer_type, unsized_offset_unadjusted as i64); - let sized_align = layout.align.abi.bytes(); + let sized_align = layout.align.bytes(); let sized_align = fx.bcx.ins().iconst(fx.pointer_type, sized_align as i64); // Recurse to get the size of the dynamically sized field (must be diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 9d73f200afe2b..9dcd4a33d44f6 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -342,6 +342,14 @@ impl<'tcx> CValue<'tcx> { assert_eq!(self.layout().backend_repr, layout.backend_repr); CValue(self.0, layout) } + + pub(crate) fn cast_pat_ty_to_base(self, layout: TyAndLayout<'tcx>) -> Self { + let ty::Pat(base, _) = *self.layout().ty.kind() else { + panic!("not a pattern type: {:#?}", self.layout()) + }; + assert_eq!(layout.ty, base); + CValue(self.0, layout) + } } /// A place where you can write a value to or read a value from @@ -383,7 +391,7 @@ impl<'tcx> CPlace<'tcx> { let stack_slot = fx.create_stack_slot( u32::try_from(layout.size.bytes()).unwrap(), - u32::try_from(layout.align.abi.bytes()).unwrap(), + u32::try_from(layout.align.bytes()).unwrap(), ); CPlace { inner: CPlaceInner::Addr(stack_slot, None), layout } } @@ -641,8 +649,8 @@ impl<'tcx> CPlace<'tcx> { let size = dst_layout.size.bytes(); // `emit_small_memory_copy` uses `u8` for alignments, just use the maximum // alignment that fits in a `u8` if the actual alignment is larger. - let src_align = src_layout.align.abi.bytes().try_into().unwrap_or(128); - let dst_align = dst_layout.align.abi.bytes().try_into().unwrap_or(128); + let src_align = src_layout.align.bytes().try_into().unwrap_or(128); + let dst_align = dst_layout.align.bytes().try_into().unwrap_or(128); fx.bcx.emit_small_memory_copy( fx.target_config, to_addr, @@ -660,7 +668,7 @@ impl<'tcx> CPlace<'tcx> { } } - /// Used for `ProjectionElem::Subtype`, `ty` has to be monomorphized before + /// Used for `ProjectionElem::UnwrapUnsafeBinder`, `ty` has to be monomorphized before /// passed on. pub(crate) fn place_transmute_type( self, @@ -909,8 +917,7 @@ pub(crate) fn assert_assignable<'tcx>( ); // fn(&T) -> for<'l> fn(&'l T) is allowed } - (&ty::Dynamic(from_traits, _, _from_kind), &ty::Dynamic(to_traits, _, _to_kind)) => { - // FIXME(dyn-star): Do the right thing with DynKinds + (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => { for (from, to) in from_traits.iter().zip(to_traits) { let from = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), from); let to = fx.tcx.normalize_erasing_late_bound_regions(fx.typing_env(), to); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 2a95a7368aac6..647569694b04d 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -2,8 +2,7 @@ use gccjit::FnAttribute; use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -18,8 +17,7 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) { let context = &mods.context; let usize = match tcx.sess.target.pointer_width { @@ -31,45 +29,35 @@ pub(crate) unsafe fn codegen( let i8 = context.new_type::(); let i8p = i8.make_pointer(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut types = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - types.push(usize); - types.push(usize); - } - AllocatorTy::Ptr => types.push(i8p), - AllocatorTy::Usize => types.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), + for method in methods { + let mut types = Vec::with_capacity(method.inputs.len()); + for input in method.inputs.iter() { + match input.ty { + AllocatorTy::Layout => { + types.push(usize); + types.push(usize); } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, + AllocatorTy::Ptr => types.push(i8p), + AllocatorTy::Usize => types.push(usize), - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { + panic!("invalid allocator arg") } - }; - let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); - let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - - create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); + } } - } + let output = match method.output { + AllocatorTy::ResultPtr => Some(i8p), + AllocatorTy::Never | AllocatorTy::Unit => None, - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), - &[usize, usize], - None, - ); + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); + + create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); + } create_const_value_function( tcx, diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 17e2e028b16fa..f237861b1595a 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -546,9 +546,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { } if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) { - // TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient - // on all architectures. For instance, what about FP stack? - extended_asm.add_clobber("cc"); + match asm_arch { + InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => { + // "cc" is cr0 on powerpc. + } + // TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient + // on all architectures. For instance, what about FP stack? + _ => { + extended_asm.add_clobber("cc"); + } + } } if !options.contains(InlineAsmOptions::NOMEM) { extended_asm.add_clobber("memory"); @@ -698,8 +705,13 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str { InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => "wa", + InlineAsmRegClass::PowerPC( + PowerPCInlineAsmRegClass::cr + | PowerPCInlineAsmRegClass::ctr + | PowerPCInlineAsmRegClass::lr + | PowerPCInlineAsmRegClass::xer, + ) => { unreachable!("clobber-only") } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r", @@ -774,11 +786,15 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { - cx.type_vector(cx.type_i32(), 4) - } - InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) - | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => { + InlineAsmRegClass::PowerPC( + PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg, + ) => cx.type_vector(cx.type_i32(), 4), + InlineAsmRegClass::PowerPC( + PowerPCInlineAsmRegClass::cr + | PowerPCInlineAsmRegClass::ctr + | PowerPCInlineAsmRegClass::lr + | PowerPCInlineAsmRegClass::xer, + ) => { unreachable!("clobber-only") } InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), @@ -949,6 +965,13 @@ fn modifier_to_gcc( InlineAsmRegClass::LoongArch(_) => None, InlineAsmRegClass::Mips(_) => None, InlineAsmRegClass::Nvptx(_) => None, + InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => { + if modifier.is_none() { + Some('x') + } else { + modifier + } + } InlineAsmRegClass::PowerPC(_) => None, InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) | InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None, diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs index d29bba2570f67..598bbe74007d0 100644 --- a/compiler/rustc_codegen_gcc/src/back/lto.rs +++ b/compiler/rustc_codegen_gcc/src/back/lto.rs @@ -30,6 +30,7 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file}; use rustc_data_structures::memmap::Mmap; use rustc_errors::DiagCtxtHandle; +use rustc_log::tracing::info; use rustc_middle::bug; use rustc_middle::dep_graph::WorkProduct; use rustc_session::config::Lto; diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index 84bc70162719f..8ba730e325029 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -5,6 +5,7 @@ use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; use rustc_fs_util::link_or_copy; +use rustc_log::tracing::debug; use rustc_session::config::OutputType; use rustc_target::spec::SplitDebuginfo; diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index e9d72e457a086..e8672f49580b6 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility; use rustc_middle::ty::TyCtxt; use rustc_session::config::DebugInfo; use rustc_span::Symbol; +use rustc_target::spec::RelocModel; #[cfg(feature = "master")] use rustc_target::spec::SymbolVisibility; -use rustc_target::spec::{PanicStrategy, RelocModel}; use crate::builder::Builder; use crate::context::CodegenCx; @@ -101,7 +101,7 @@ pub fn compile_codegen_unit( // Instantiate monomorphizations without filling out definitions yet... let context = new_context(tcx); - if tcx.sess.panic_strategy() == PanicStrategy::Unwind { + if tcx.sess.panic_strategy().unwinds() { context.add_command_line_option("-fexceptions"); context.add_driver_option("-fexceptions"); } diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index f7a7a3f8c7e35..5657620879ca1 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1383,6 +1383,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { _src_align: Align, size: RValue<'gcc>, flags: MemFlags, + _tt: Option, // Autodiff TypeTrees are LLVM-only, ignored in GCC backend ) { assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memcpy not supported"); let size = self.intcast(size, self.type_size_t(), false); diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 28848ca61845c..7c2969e587186 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{ BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods, }; use rustc_middle::mir::Mutability; -use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; +use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::layout::LayoutOf; use crate::context::CodegenCx; @@ -247,8 +247,8 @@ impl<'gcc, 'tcx> ConstCodegenMethods for CodegenCx<'gcc, 'tcx> { // This avoids generating a zero-sized constant value and actually needing a // real address at runtime. if alloc.inner().len() == 0 { - assert_eq!(offset.bytes(), 0); - let val = self.const_usize(alloc.inner().align.bytes()); + let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); + let val = self.const_usize(self.tcx.truncate_to_target_usize(val)); return if matches!(layout.primitive(), Pointer(_)) { self.context.new_cast(None, val, ty) } else { diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 7fe8fc122b3cc..ec7d4b285a3fd 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::{ use rustc_hir::attrs::Linkage; use rustc_hir::def::DefKind; use rustc_hir::def_id::LOCAL_CRATE; +use rustc_log::tracing::trace; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::interpret::{ self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint, diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 665cf22ddbaee..c9ae96777de44 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -147,7 +147,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let layout = tcx .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type)) .unwrap(); - let align = layout.align.abi.bytes(); + let align = layout.align.bytes(); // For types with size 1, the alignment can be 1 and only 1 // So, we can skip the call to ``get_aligned`. // In the future, we can add a GCC API to query the type align, @@ -186,9 +186,9 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { (i128_type, u128_type) } else { /*let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.i128)).unwrap(); - let i128_align = layout.align.abi.bytes(); + let i128_align = layout.align.bytes(); let layout = tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.u128)).unwrap(); - let u128_align = layout.align.abi.bytes();*/ + let u128_align = layout.align.bytes();*/ // TODO(antoyo): re-enable the alignment when libgccjit fixed the issue in // gcc_jit_context_new_array_constructor (it should not use reinterpret_cast). @@ -529,7 +529,10 @@ impl<'gcc, 'tcx> HasX86AbiOpt for CodegenCx<'gcc, 'tcx> { impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::InvalidSimd { .. } + | LayoutError::ReferencesError(_) = err + { self.tcx.dcx().emit_fatal(respan(span, err.into_diagnostic())) } else { self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err }) @@ -545,7 +548,9 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { - if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { + if let FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) = + err + { self.tcx.dcx().emit_fatal(respan(span, err)) } else { match fn_abi_request { diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs index 4c8585192a1b1..0f015cc23f52f 100644 --- a/compiler/rustc_codegen_gcc/src/debuginfo.rs +++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs @@ -29,13 +29,24 @@ impl<'a, 'gcc, 'tcx> DebugInfoBuilderMethods for Builder<'a, 'gcc, 'tcx> { _variable_alloca: Self::Value, _direct_offset: Size, _indirect_offsets: &[Size], - _fragment: Option>, + _fragment: &Option>, ) { // FIXME(tempdragon): Not sure if this is correct, probably wrong but still keep it here. #[cfg(feature = "master")] _variable_alloca.set_location(_dbg_loc); } + fn dbg_var_value( + &mut self, + _dbg_var: Self::DIVariable, + _dbg_loc: Self::DILocation, + _value: Self::Value, + _direct_offset: Size, + _indirect_offsets: &[Size], + _fragment: &Option>, + ) { + } + fn insert_reference_to_gdb_debug_scripts_section_global(&mut self) { // TODO(antoyo): insert reference to gdb debug scripts section global. } diff --git a/compiler/rustc_codegen_gcc/src/gcc_util.rs b/compiler/rustc_codegen_gcc/src/gcc_util.rs index 42ba40692b75c..702704ddf1369 100644 --- a/compiler/rustc_codegen_gcc/src/gcc_util.rs +++ b/compiler/rustc_codegen_gcc/src/gcc_util.rs @@ -1,8 +1,8 @@ #[cfg(feature = "master")] use gccjit::Context; use rustc_codegen_ssa::target_features; +use rustc_data_structures::smallvec::{SmallVec, smallvec}; use rustc_session::Session; -use smallvec::{SmallVec, smallvec}; fn gcc_features_by_flags(sess: &Session, features: &mut Vec) { target_features::retpoline_features_by_flags(sess, features); diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index eb0a5336a1f13..99a4f9b9f7e7e 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -29,7 +29,6 @@ use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Instance, Ty}; use rustc_span::{Span, Symbol, sym}; use rustc_target::callconv::{ArgAbi, PassMode}; -use rustc_target::spec::PanicStrategy; #[cfg(feature = "master")] use crate::abi::FnAbiGccExt; @@ -730,7 +729,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { if self.is_sized_indirect() { OperandValue::Ref(PlaceValue::new_sized(val, self.layout.align.abi)).store(bx, dst) } else if self.is_unsized_indirect() { - bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); + bug!("unsized `ArgAbi` cannot be stored"); } else if let PassMode::Cast { ref cast, .. } = self.mode { // FIXME(eddyb): Figure out when the simpler Store is safe, clang // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}. @@ -771,6 +770,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { scratch_align, bx.const_usize(self.layout.size.bytes()), MemFlags::empty(), + None, ); bx.lifetime_end(scratch, scratch_size); @@ -797,12 +797,7 @@ impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Indirect { meta_attrs: Some(_), .. } => { - let place_val = PlaceValue { - llval: next(), - llextra: Some(next()), - align: self.layout.align.abi, - }; - OperandValue::Ref(place_val).store(bx, dst); + bug!("unsized `ArgAbi` cannot be stored"); } PassMode::Direct(_) | PassMode::Indirect { meta_attrs: None, .. } @@ -1339,7 +1334,7 @@ fn try_intrinsic<'a, 'b, 'gcc, 'tcx>( _catch_func: RValue<'gcc>, dest: PlaceRef<'tcx, RValue<'gcc>>, ) { - if bx.sess().panic_strategy() == PanicStrategy::Abort { + if !bx.sess().panic_strategy().unwinds() { bx.call(bx.type_void(), None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f76f933cad4a5..71500ded02038 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -1,7 +1,5 @@ /* * TODO(antoyo): implement equality in libgccjit based on https://zpz.github.io/blog/overloading-equality-operator-in-cpp-class-hierarchy/ (for type equality?) - * TODO(antoyo): support #[inline] attributes. - * TODO(antoyo): support LTO (gcc's equivalent to Full LTO is -flto -flto-partition=one — https://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html). * For Thin LTO, this might be helpful: // cspell:disable-next-line * In gcc 4.6 -fwhopr was removed and became default with -flto. The non-whopr path can still be executed via -flto-partition=none. @@ -25,12 +23,6 @@ #![deny(clippy::pattern_type_mismatch)] #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)] -// These crates are pulled from the sysroot because they are part of -// rustc's public API, so we need to ensure version compatibility. -extern crate smallvec; -#[macro_use] -extern crate tracing; - // The rustc crates we need extern crate rustc_abi; extern crate rustc_apfloat; @@ -44,6 +36,7 @@ extern crate rustc_hir; extern crate rustc_index; #[cfg(feature = "master")] extern crate rustc_interface; +extern crate rustc_log; extern crate rustc_macros; extern crate rustc_middle; extern crate rustc_session; @@ -92,7 +85,7 @@ use back::lto::{ThinBuffer, ThinData}; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn, @@ -184,6 +177,10 @@ impl CodegenBackend for GccCodegenBackend { crate::DEFAULT_LOCALE_RESOURCE } + fn name(&self) -> &'static str { + "gcc" + } + fn init(&self, _sess: &Session) { #[cfg(feature = "master")] { @@ -280,8 +277,7 @@ impl ExtraBackendMethods for GccCodegenBackend { &self, tcx: TyCtxt<'_>, module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) -> Self::Module { let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), @@ -291,7 +287,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name, methods); } mods } diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 2d11628250cd2..67bd1e59bb0c2 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -46,5 +46,6 @@ tracing = "0.1" [features] # tidy-alphabetical-start check_only = ["rustc_llvm/check_only"] +llvm_enzyme = [] # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index ac7583f566687..680ad98593e7e 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -1,4 +1,3 @@ -use std::borrow::Borrow; use std::cmp; use libc::c_uint; @@ -13,7 +12,7 @@ use rustc_codegen_ssa::traits::*; use rustc_middle::ty::Ty; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::{bug, ty}; -use rustc_session::config; +use rustc_session::{Session, config}; use rustc_target::callconv::{ ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode, }; @@ -23,11 +22,9 @@ use smallvec::SmallVec; use crate::attributes::{self, llfn_attrs_from_instance}; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::llvm::{self, Attribute, AttributePlace}; +use crate::llvm::{self, Attribute, AttributePlace, Type, Value}; use crate::llvm_util; -use crate::type_::Type; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; trait ArgAttributesExt { fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value); @@ -215,9 +212,9 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { let align = attrs.pointee_align.unwrap_or(self.layout.align.abi); OperandValue::Ref(PlaceValue::new_sized(val, align)).store(bx, dst); } - // Unsized indirect qrguments + // Unsized indirect arguments cannot be stored PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { - bug!("unsized `ArgAbi` must be handled through `store_fn_arg`"); + bug!("unsized `ArgAbi` cannot be stored"); } PassMode::Cast { cast, pad_i32: _ } => { // The ABI mandates that the value is passed as a different struct representation. @@ -246,6 +243,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { scratch_align, bx.const_usize(copy_bytes), MemFlags::empty(), + None, ); bx.lifetime_end(llscratch, scratch_size); } @@ -272,12 +270,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> { OperandValue::Pair(next(), next()).store(bx, dst); } PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { - let place_val = PlaceValue { - llval: next(), - llextra: Some(next()), - align: self.layout.align.abi, - }; - OperandValue::Ref(place_val).store(bx, dst); + bug!("unsized `ArgAbi` cannot be stored"); } PassMode::Direct(_) | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } @@ -404,7 +397,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv { - llvm::CallConv::from_conv(self.conv, cx.tcx.sess.target.arch.borrow()) + to_llvm_calling_convention(cx.tcx.sess, self.conv) } fn apply_attrs_llfn( @@ -543,7 +536,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { // If the declaration has an associated instance, compute extra attributes based on that. if let Some(instance) = instance { - llfn_attrs_from_instance(cx, llfn, instance); + llfn_attrs_from_instance( + cx, + cx.tcx, + llfn, + &cx.tcx.codegen_instance_attrs(instance.def), + Some(instance), + ); } } @@ -661,43 +660,44 @@ impl AbiBuilderMethods for Builder<'_, '_, '_> { } } -impl llvm::CallConv { - pub(crate) fn from_conv(conv: CanonAbi, arch: &str) -> Self { - match conv { - CanonAbi::C | CanonAbi::Rust => llvm::CCallConv, - CanonAbi::RustCold => llvm::PreserveMost, - // Functions with this calling convention can only be called from assembly, but it is - // possible to declare an `extern "custom"` block, so the backend still needs a calling - // convention for declaring foreign functions. - CanonAbi::Custom => llvm::CCallConv, - CanonAbi::GpuKernel => { - if arch == "amdgpu" { - llvm::AmdgpuKernel - } else if arch == "nvptx64" { - llvm::PtxKernel - } else { - panic!("Architecture {arch} does not support GpuKernel calling convention"); - } +/// Determines the appropriate [`llvm::CallConv`] to use for a given function +/// ABI, for the current target. +pub(crate) fn to_llvm_calling_convention(sess: &Session, abi: CanonAbi) -> llvm::CallConv { + match abi { + CanonAbi::C | CanonAbi::Rust => llvm::CCallConv, + CanonAbi::RustCold => llvm::PreserveMost, + // Functions with this calling convention can only be called from assembly, but it is + // possible to declare an `extern "custom"` block, so the backend still needs a calling + // convention for declaring foreign functions. + CanonAbi::Custom => llvm::CCallConv, + CanonAbi::GpuKernel => { + let arch = sess.target.arch.as_ref(); + if arch == "amdgpu" { + llvm::AmdgpuKernel + } else if arch == "nvptx64" { + llvm::PtxKernel + } else { + panic!("Architecture {arch} does not support GpuKernel calling convention"); } - CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { - InterruptKind::Avr => llvm::AvrInterrupt, - InterruptKind::AvrNonBlocking => llvm::AvrNonBlockingInterrupt, - InterruptKind::Msp430 => llvm::Msp430Intr, - InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => llvm::CCallConv, - InterruptKind::X86 => llvm::X86_Intr, - }, - CanonAbi::Arm(arm_call) => match arm_call { - ArmCall::Aapcs => llvm::ArmAapcsCallConv, - ArmCall::CCmseNonSecureCall | ArmCall::CCmseNonSecureEntry => llvm::CCallConv, - }, - CanonAbi::X86(x86_call) => match x86_call { - X86Call::Fastcall => llvm::X86FastcallCallConv, - X86Call::Stdcall => llvm::X86StdcallCallConv, - X86Call::SysV64 => llvm::X86_64_SysV, - X86Call::Thiscall => llvm::X86_ThisCall, - X86Call::Vectorcall => llvm::X86_VectorCall, - X86Call::Win64 => llvm::X86_64_Win64, - }, } + CanonAbi::Interrupt(interrupt_kind) => match interrupt_kind { + InterruptKind::Avr => llvm::AvrInterrupt, + InterruptKind::AvrNonBlocking => llvm::AvrNonBlockingInterrupt, + InterruptKind::Msp430 => llvm::Msp430Intr, + InterruptKind::RiscvMachine | InterruptKind::RiscvSupervisor => llvm::CCallConv, + InterruptKind::X86 => llvm::X86_Intr, + }, + CanonAbi::Arm(arm_call) => match arm_call { + ArmCall::Aapcs => llvm::ArmAapcsCallConv, + ArmCall::CCmseNonSecureCall | ArmCall::CCmseNonSecureEntry => llvm::CCallConv, + }, + CanonAbi::X86(x86_call) => match x86_call { + X86Call::Fastcall => llvm::X86FastcallCallConv, + X86Call::Stdcall => llvm::X86StdcallCallConv, + X86Call::SysV64 => llvm::X86_64_SysV, + X86Call::Thiscall => llvm::X86_ThisCall, + X86Call::Vectorcall => llvm::X86_VectorCall, + X86Call::Win64 => llvm::X86_64_Win64, + }, } } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index df3e49279d976..de0b85ebb63b8 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,26 +1,26 @@ use libc::c_uint; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, SpecialAllocatorMethod, + default_fn_name, global_fn_name, }; use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _; use rustc_middle::bug; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; use rustc_symbol_mangling::mangle_internal_symbol; -use smallvec::SmallVec; +use crate::attributes::llfn_attrs_from_instance; use crate::builder::SBuilder; use crate::declare::declare_simple_fn; -use crate::llvm::{self, FALSE, TRUE, Type, Value}; -use crate::{SimpleCx, attributes, debuginfo, llvm_util}; +use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value}; +use crate::{SimpleCx, attributes, debuginfo}; pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, cx: SimpleCx<'_>, module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) { let usize = match tcx.sess.target.pointer_width { 16 => cx.type_i16(), @@ -31,70 +31,85 @@ pub(crate) unsafe fn codegen( let i8 = cx.type_i8(); let i8p = cx.type_ptr(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut args = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - args.push(usize); // size - args.push(usize); // align - } - AllocatorTy::Ptr => args.push(i8p), - AllocatorTy::Usize => args.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), + for method in methods { + let mut args = Vec::with_capacity(method.inputs.len()); + for input in method.inputs.iter() { + match input.ty { + AllocatorTy::Layout => { + args.push(usize); // size + args.push(usize); // align } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, + AllocatorTy::Ptr => args.push(i8p), + AllocatorTy::Usize => args.push(usize), - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") + AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => { + panic!("invalid allocator arg") } - }; + } + } - let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); - let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); + let mut no_return = false; + let output = match method.output { + AllocatorTy::ResultPtr => Some(i8p), + AllocatorTy::Unit => None, + AllocatorTy::Never => { + no_return = true; + None + } - create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false); - } - } + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; - // rust alloc error handler - create_wrapper_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), - &[usize, usize], // size, align - None, - true, - ); + let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); + let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - unsafe { - // __rust_alloc_error_handler_should_panic_v2 - create_const_value_function( - tcx, - &cx, - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - &i8, - &llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE), - ); + let alloc_attr_flag = match method.special { + Some(SpecialAllocatorMethod::Alloc) => CodegenFnAttrFlags::ALLOCATOR, + Some(SpecialAllocatorMethod::Dealloc) => CodegenFnAttrFlags::DEALLOCATOR, + Some(SpecialAllocatorMethod::Realloc) => CodegenFnAttrFlags::REALLOCATOR, + Some(SpecialAllocatorMethod::AllocZeroed) => CodegenFnAttrFlags::ALLOCATOR_ZEROED, + None => CodegenFnAttrFlags::empty(), + }; - // __rust_no_alloc_shim_is_unstable_v2 + let mut attrs = CodegenFnAttrs::new(); + attrs.flags |= alloc_attr_flag; create_wrapper_function( tcx, &cx, - &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), - None, - &[], - None, - false, + &from_name, + Some(&to_name), + &args, + output, + no_return, + &attrs, ); } + // __rust_alloc_error_handler_should_panic_v2 + create_const_value_function( + tcx, + &cx, + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + &i8, + unsafe { + llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE) + }, + ); + + // __rust_no_alloc_shim_is_unstable_v2 + create_wrapper_function( + tcx, + &cx, + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + None, + &[], + None, + false, + &CodegenFnAttrs::new(), + ); + if tcx.sess.opts.debuginfo != DebugInfo::None { let dbg_cx = debuginfo::CodegenUnitDebugContext::new(cx.llmod); debuginfo::metadata::build_compile_unit_di_node(tcx, module_name, &dbg_cx); @@ -138,6 +153,7 @@ fn create_wrapper_function( args: &[&Type], output: Option<&Type>, no_return: bool, + attrs: &CodegenFnAttrs, ) { let ty = cx.type_func(args, output.unwrap_or_else(|| cx.type_void())); let llfn = declare_simple_fn( @@ -149,18 +165,7 @@ fn create_wrapper_function( ty, ); - let mut attrs = SmallVec::<[_; 2]>::new(); - - let target_cpu = llvm_util::target_cpu(tcx.sess); - let target_cpu_attr = llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu); - - let tune_cpu_attr = llvm_util::tune_cpu(tcx.sess) - .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu)); - - attrs.push(target_cpu_attr); - attrs.extend(tune_cpu_attr); - - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &attrs); + llfn_attrs_from_instance(cx, tcx, llfn, attrs, None); let no_return = if no_return { // -> ! DIFlagNoReturn @@ -171,12 +176,6 @@ fn create_wrapper_function( None }; - if tcx.sess.must_emit_unwind_tables() { - let uwtable = - attributes::uwtable_attr(cx.llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } - let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; let mut bx = SBuilder::build(&cx, llbb); diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 38c1d3b53e87c..8cd4bdc372789 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -13,14 +13,12 @@ use rustc_target::asm::*; use smallvec::SmallVec; use tracing::debug; +use crate::attributes; use crate::builder::Builder; use crate::common::Funclet; use crate::context::CodegenCx; -use crate::llvm::ToLlvmBool; -use crate::type_::Type; +use crate::llvm::{self, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; -use crate::{attributes, llvm}; impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn codegen_inline_asm( @@ -240,6 +238,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { } InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => { constraints.extend_from_slice(&[ + "~{fflags}".to_string(), "~{vtype}".to_string(), "~{vl}".to_string(), "~{vxsat}".to_string(), @@ -339,8 +338,8 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { attrs.push(llvm::AttributeKind::WillReturn.create_attr(self.cx.llcx)); } else if options.contains(InlineAsmOptions::NOMEM) { attrs.push(llvm::MemoryEffects::InaccessibleMemOnly.create_attr(self.cx.llcx)); - } else { - // LLVM doesn't have an attribute to represent ReadOnly + SideEffect + } else if options.contains(InlineAsmOptions::READONLY) { + attrs.push(llvm::MemoryEffects::ReadOnlyNotPure.create_attr(self.cx.llcx)); } attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs }); @@ -537,9 +536,7 @@ pub(crate) fn inline_asm_call<'ll>( bx.const_u64(u64::from(span.lo().to_u32()) | (u64::from(span.hi().to_u32()) << 32)), ) })); - let md = unsafe { llvm::LLVMMDNodeInContext2(bx.llcx, srcloc.as_ptr(), srcloc.len()) }; - let md = bx.get_metadata_value(md); - llvm::LLVMSetMetadata(call, kind, md); + bx.cx.set_metadata_node(call, kind, &srcloc); Some(call) } @@ -661,7 +658,13 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", PowerPC(PowerPCInlineAsmRegClass::freg) => "f", PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", - PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => { + PowerPC(PowerPCInlineAsmRegClass::vsreg) => "^wa", + PowerPC( + PowerPCInlineAsmRegClass::cr + | PowerPCInlineAsmRegClass::ctr + | PowerPCInlineAsmRegClass::lr + | PowerPCInlineAsmRegClass::xer, + ) => { unreachable!("clobber-only") } RiscV(RiscVInlineAsmRegClass::reg) => "r", @@ -746,6 +749,12 @@ fn modifier_to_llvm( LoongArch(_) => None, Mips(_) => None, Nvptx(_) => None, + PowerPC(PowerPCInlineAsmRegClass::vsreg) => { + // The documentation for the 'x' modifier is missing for llvm, and the gcc + // documentation is simply "use this for any vsx argument". It is needed + // to ensure the correct vsx register number is used. + if modifier.is_none() { Some('x') } else { modifier } + } PowerPC(_) => None, RiscV(RiscVInlineAsmRegClass::reg) | RiscV(RiscVInlineAsmRegClass::freg) => None, RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"), @@ -829,7 +838,13 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), PowerPC(PowerPCInlineAsmRegClass::vreg) => cx.type_vector(cx.type_i32(), 4), - PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => { + PowerPC(PowerPCInlineAsmRegClass::vsreg) => cx.type_vector(cx.type_i32(), 4), + PowerPC( + PowerPCInlineAsmRegClass::cr + | PowerPCInlineAsmRegClass::ctr + | PowerPCInlineAsmRegClass::lr + | PowerPCInlineAsmRegClass::xer, + ) => { unreachable!("clobber-only") } RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(), @@ -1054,9 +1069,10 @@ fn llvm_fixup_input<'ll, 'tcx>( let value = bx.or(value, bx.const_u32(0xFFFF_0000)); bx.bitcast(value, bx.type_f32()) } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F32) => - { + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F32) => { let value = bx.insert_element( bx.const_undef(bx.type_vector(bx.type_f32(), 4)), value, @@ -1064,9 +1080,10 @@ fn llvm_fixup_input<'ll, 'tcx>( ); bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)) } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F64) => - { + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F64) => { let value = bx.insert_element( bx.const_undef(bx.type_vector(bx.type_f64(), 2)), value, @@ -1217,15 +1234,17 @@ fn llvm_fixup_output<'ll, 'tcx>( let value = bx.trunc(value, bx.type_i16()); bx.bitcast(value, bx.type_f16()) } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F32) => - { + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F32) => { let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4)); bx.extract_element(value, bx.const_usize(0)) } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F64) => - { + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F64) => { let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2)); bx.extract_element(value, bx.const_usize(0)) } @@ -1359,16 +1378,14 @@ fn llvm_fixup_output_type<'ll, 'tcx>( { cx.type_f32() } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F32) => - { - cx.type_vector(cx.type_f32(), 4) - } - (PowerPC(PowerPCInlineAsmRegClass::vreg), BackendRepr::Scalar(s)) - if s.primitive() == Primitive::Float(Float::F64) => - { - cx.type_vector(cx.type_f64(), 2) - } + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F32) => cx.type_vector(cx.type_f32(), 4), + ( + PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg), + BackendRepr::Scalar(s), + ) if s.primitive() == Primitive::Float(Float::F64) => cx.type_vector(cx.type_f64(), 2), _ => layout.llvm_type(cx), } } diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 573c51a95398b..209b8efa2c3b3 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -1,20 +1,22 @@ //! Set and unset common attributes on LLVM values. -use rustc_codegen_ssa::traits::*; use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_hir::def_id::DefId; -use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; +use rustc_middle::middle::codegen_fn_attrs::{ + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, +}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{BranchProtection, FunctionReturn, OptLevel, PAuthKey, PacRet}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{FramePointer, SanitizerSet, StackProbeType, StackProtector}; use smallvec::SmallVec; -use crate::context::CodegenCx; +use crate::context::SimpleCx; use crate::errors::SanitizerMemtagRequiresMte; use crate::llvm::AttributePlace::Function; -use crate::llvm::{self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects}; -use crate::value::Value; -use crate::{attributes, llvm_util}; +use crate::llvm::{ + self, AllocKindFlags, Attribute, AttributeKind, AttributePlace, MemoryEffects, Value, +}; +use crate::{Session, attributes, llvm_util}; pub(crate) fn apply_to_llfn(llfn: &Value, idx: AttributePlace, attrs: &[&Attribute]) { if !attrs.is_empty() { @@ -30,18 +32,19 @@ pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[ /// Get LLVM attribute for the provided inline heuristic. pub(crate) fn inline_attr<'ll, 'tcx>( - cx: &CodegenCx<'ll, 'tcx>, + cx: &SimpleCx<'ll>, + tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>, ) -> Option<&'ll Attribute> { // `optnone` requires `noinline` - let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id()); + let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id()); let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) { (_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never, - (InlineAttr::None, _) if instance.def.requires_inline(cx.tcx) => InlineAttr::Hint, + (InlineAttr::None, _) if instance.def.requires_inline(tcx) => InlineAttr::Hint, (inline, _) => inline, }; - if !cx.tcx.sess.opts.unstable_opts.inline_llvm { + if !tcx.sess.opts.unstable_opts.inline_llvm { // disable LLVM inlining return Some(AttributeKind::NoInline.create_attr(cx.llcx)); } @@ -51,7 +54,7 @@ pub(crate) fn inline_attr<'ll, 'tcx>( Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)) } InlineAttr::Never => { - if cx.sess().target.arch != "amdgpu" { + if tcx.sess.target.arch != "amdgpu" { Some(AttributeKind::NoInline.create_attr(cx.llcx)) } else { None @@ -63,12 +66,13 @@ pub(crate) fn inline_attr<'ll, 'tcx>( #[inline] fn patchable_function_entry_attrs<'ll>( - cx: &CodegenCx<'ll, '_>, + cx: &SimpleCx<'ll>, + sess: &Session, attr: Option, ) -> SmallVec<[&'ll Attribute; 2]> { let mut attrs = SmallVec::new(); let patchable_spec = attr.unwrap_or_else(|| { - PatchableFunctionEntry::from_config(cx.tcx.sess.opts.unstable_opts.patchable_function_entry) + PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry) }); let entry = patchable_spec.entry(); let prefix = patchable_spec.prefix(); @@ -91,12 +95,13 @@ fn patchable_function_entry_attrs<'ll>( /// Get LLVM sanitize attributes. #[inline] -pub(crate) fn sanitize_attrs<'ll>( - cx: &CodegenCx<'ll, '_>, +pub(crate) fn sanitize_attrs<'ll, 'tcx>( + cx: &SimpleCx<'ll>, + tcx: TyCtxt<'tcx>, no_sanitize: SanitizerSet, ) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); - let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize; + let enabled = tcx.sess.opts.unstable_opts.sanitizer - no_sanitize; if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) { attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx)); } @@ -114,11 +119,11 @@ pub(crate) fn sanitize_attrs<'ll>( } if enabled.contains(SanitizerSet::MEMTAG) { // Check to make sure the mte target feature is actually enabled. - let features = cx.tcx.global_backend_features(()); + let features = tcx.global_backend_features(()); let mte_feature = features.iter().map(|s| &s[..]).rfind(|n| ["+mte", "-mte"].contains(&&n[..])); if let None | Some("-mte") = mte_feature { - cx.tcx.dcx().emit_err(SanitizerMemtagRequiresMte); + tcx.dcx().emit_err(SanitizerMemtagRequiresMte); } attrs.push(llvm::AttributeKind::SanitizeMemTag.create_attr(cx.llcx)); @@ -139,9 +144,12 @@ pub(crate) fn uwtable_attr(llcx: &llvm::Context, use_sync_unwind: Option) llvm::CreateUWTableAttr(llcx, async_unwind) } -pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - let mut fp = cx.sess().target.frame_pointer; - let opts = &cx.sess().opts; +pub(crate) fn frame_pointer_type_attr<'ll>( + cx: &SimpleCx<'ll>, + sess: &Session, +) -> Option<&'ll Attribute> { + let mut fp = sess.target.frame_pointer; + let opts = &sess.opts; // "mcount" function relies on stack pointer. // See . if opts.unstable_opts.instrument_mcount { @@ -156,8 +164,8 @@ pub(crate) fn frame_pointer_type_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&' Some(llvm::CreateAttrStringValue(cx.llcx, "frame-pointer", attr_value)) } -fn function_return_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - let function_return_attr = match cx.sess().opts.unstable_opts.function_return { +fn function_return_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { + let function_return_attr = match sess.opts.unstable_opts.function_return { FunctionReturn::Keep => return None, FunctionReturn::ThunkExtern => AttributeKind::FnRetThunkExtern, }; @@ -167,17 +175,20 @@ fn function_return_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> /// Tell LLVM what instrument function to insert. #[inline] -fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'ll Attribute; 4]> { +fn instrument_function_attr<'ll>( + cx: &SimpleCx<'ll>, + sess: &Session, +) -> SmallVec<[&'ll Attribute; 4]> { let mut attrs = SmallVec::new(); - if cx.sess().opts.unstable_opts.instrument_mcount { + if sess.opts.unstable_opts.instrument_mcount { // Similar to `clang -pg` behavior. Handled by the // `post-inline-ee-instrument` LLVM pass. // The function name varies on platforms. // See test/CodeGen/mcount.c in clang. - let mcount_name = match &cx.sess().target.llvm_mcount_intrinsic { + let mcount_name = match &sess.target.llvm_mcount_intrinsic { Some(llvm_mcount_intrinsic) => llvm_mcount_intrinsic.as_ref(), - None => cx.sess().target.mcount.as_ref(), + None => sess.target.mcount.as_ref(), }; attrs.push(llvm::CreateAttrStringValue( @@ -186,7 +197,7 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'ll Attr mcount_name, )); } - if let Some(options) = &cx.sess().opts.unstable_opts.instrument_xray { + if let Some(options) = &sess.opts.unstable_opts.instrument_xray { // XRay instrumentation is similar to __cyg_profile_func_{enter,exit}. // Function prologue and epilogue are instrumented with NOP sleds, // a runtime library later replaces them with detours into tracing code. @@ -217,20 +228,20 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'ll Attr attrs } -fn nojumptables_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - if !cx.sess().opts.unstable_opts.no_jump_tables { +fn nojumptables_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { + if !sess.opts.unstable_opts.no_jump_tables { return None; } Some(llvm::CreateAttrStringValue(cx.llcx, "no-jump-tables", "true")) } -fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +fn probestack_attr<'ll, 'tcx>(cx: &SimpleCx<'ll>, tcx: TyCtxt<'tcx>) -> Option<&'ll Attribute> { // Currently stack probes seem somewhat incompatible with the address // sanitizer and thread sanitizer. With asan we're already protected from // stack overflow anyway so we don't really need stack probes regardless. - if cx - .sess() + if tcx + .sess .opts .unstable_opts .sanitizer @@ -240,22 +251,22 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { } // probestack doesn't play nice either with `-C profile-generate`. - if cx.sess().opts.cg.profile_generate.enabled() { + if tcx.sess.opts.cg.profile_generate.enabled() { return None; } - let attr_value = match cx.sess().target.stack_probes { + let attr_value = match tcx.sess.target.stack_probes { StackProbeType::None => return None, // Request LLVM to generate the probes inline. If the given LLVM version does not support // this, no probe is generated at all (even if the attribute is specified). StackProbeType::Inline => "inline-asm", // Flag our internal `__rust_probestack` function as the stack probe symbol. // This is defined in the `compiler-builtins` crate for each architecture. - StackProbeType::Call => &mangle_internal_symbol(cx.tcx, "__rust_probestack"), + StackProbeType::Call => &mangle_internal_symbol(tcx, "__rust_probestack"), // Pick from the two above based on the LLVM version. StackProbeType::InlineOrCall { min_llvm_version_for_inline } => { if llvm_util::get_version() < min_llvm_version_for_inline { - &mangle_internal_symbol(cx.tcx, "__rust_probestack") + &mangle_internal_symbol(tcx, "__rust_probestack") } else { "inline-asm" } @@ -264,8 +275,8 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { Some(llvm::CreateAttrStringValue(cx.llcx, "probe-stack", attr_value)) } -fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - let sspattr = match cx.sess().stack_protector() { +fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { + let sspattr = match sess.stack_protector() { StackProtector::None => return None, StackProtector::All => AttributeKind::StackProtectReq, StackProtector::Strong => AttributeKind::StackProtectStrong, @@ -275,33 +286,34 @@ fn stackprotector_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { Some(sspattr.create_attr(cx.llcx)) } -fn backchain_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - if cx.sess().target.arch != "s390x" { +fn backchain_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { + if sess.target.arch != "s390x" { return None; } - let requested_features = cx.sess().opts.cg.target_feature.split(','); + let requested_features = sess.opts.cg.target_feature.split(','); let found_positive = requested_features.clone().any(|r| r == "+backchain"); if found_positive { Some(llvm::CreateAttrString(cx.llcx, "backchain")) } else { None } } -pub(crate) fn target_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll Attribute { - let target_cpu = llvm_util::target_cpu(cx.tcx.sess); +pub(crate) fn target_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> &'ll Attribute { + let target_cpu = llvm_util::target_cpu(sess); llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu) } -pub(crate) fn tune_cpu_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { - llvm_util::tune_cpu(cx.tcx.sess) +pub(crate) fn tune_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> { + llvm_util::tune_cpu(sess) .map(|tune_cpu| llvm::CreateAttrStringValue(cx.llcx, "tune-cpu", tune_cpu)) } /// Get the `target-features` LLVM attribute. -pub(crate) fn target_features_attr<'ll>( - cx: &CodegenCx<'ll, '_>, +pub(crate) fn target_features_attr<'ll, 'tcx>( + cx: &SimpleCx<'ll>, + tcx: TyCtxt<'tcx>, function_features: Vec, ) -> Option<&'ll Attribute> { - let global_features = cx.tcx.global_backend_features(()).iter().map(String::as_str); + let global_features = tcx.global_backend_features(()).iter().map(String::as_str); let function_features = function_features.iter().map(String::as_str); let target_features = global_features.chain(function_features).intersperse(",").collect::(); @@ -311,22 +323,22 @@ pub(crate) fn target_features_attr<'ll>( /// Get the `NonLazyBind` LLVM attribute, /// if the codegen options allow skipping the PLT. -pub(crate) fn non_lazy_bind_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { +pub(crate) fn non_lazy_bind_attr<'ll>( + cx: &SimpleCx<'ll>, + sess: &Session, +) -> Option<&'ll Attribute> { // Don't generate calls through PLT if it's not necessary - if !cx.sess().needs_plt() { - Some(AttributeKind::NonLazyBind.create_attr(cx.llcx)) - } else { - None - } + if !sess.needs_plt() { Some(AttributeKind::NonLazyBind.create_attr(cx.llcx)) } else { None } } /// Get the default optimizations attrs for a function. #[inline] pub(crate) fn default_optimisation_attrs<'ll>( - cx: &CodegenCx<'ll, '_>, + cx: &SimpleCx<'ll>, + sess: &Session, ) -> SmallVec<[&'ll Attribute; 2]> { let mut attrs = SmallVec::new(); - match cx.sess().opts.optimize { + match sess.opts.optimize { OptLevel::Size => { attrs.push(llvm::AttributeKind::OptimizeForSize.create_attr(cx.llcx)); } @@ -347,17 +359,18 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute { /// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`) /// attributes. pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( - cx: &CodegenCx<'ll, 'tcx>, + cx: &SimpleCx<'ll>, + tcx: TyCtxt<'tcx>, llfn: &'ll Value, - instance: ty::Instance<'tcx>, + codegen_fn_attrs: &CodegenFnAttrs, + instance: Option>, ) { - let codegen_fn_attrs = cx.tcx.codegen_instance_attrs(instance.def); - + let sess = tcx.sess; let mut to_add = SmallVec::<[_; 16]>::new(); match codegen_fn_attrs.optimize { OptimizeAttr::Default => { - to_add.extend(default_optimisation_attrs(cx)); + to_add.extend(default_optimisation_attrs(cx, sess)); } OptimizeAttr::DoNotOptimize => { to_add.push(llvm::AttributeKind::OptimizeNone.create_attr(cx.llcx)); @@ -369,21 +382,21 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( OptimizeAttr::Speed => {} } - if cx.sess().must_emit_unwind_tables() { - to_add.push(uwtable_attr(cx.llcx, cx.sess().opts.unstable_opts.use_sync_unwind)); + if sess.must_emit_unwind_tables() { + to_add.push(uwtable_attr(cx.llcx, sess.opts.unstable_opts.use_sync_unwind)); } - if cx.sess().opts.unstable_opts.profile_sample_use.is_some() { + if sess.opts.unstable_opts.profile_sample_use.is_some() { to_add.push(llvm::CreateAttrString(cx.llcx, "use-sample-profile")); } // FIXME: none of these functions interact with source level attributes. - to_add.extend(frame_pointer_type_attr(cx)); - to_add.extend(function_return_attr(cx)); - to_add.extend(instrument_function_attr(cx)); - to_add.extend(nojumptables_attr(cx)); - to_add.extend(probestack_attr(cx)); - to_add.extend(stackprotector_attr(cx)); + to_add.extend(frame_pointer_type_attr(cx, sess)); + to_add.extend(function_return_attr(cx, sess)); + to_add.extend(instrument_function_attr(cx, sess)); + to_add.extend(nojumptables_attr(cx, sess)); + to_add.extend(probestack_attr(cx, tcx)); + to_add.extend(stackprotector_attr(cx, sess)); if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_BUILTINS) { to_add.push(llvm::CreateAttrString(cx.llcx, "no-builtins")); @@ -404,16 +417,19 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( // not used. } else { // Do not set sanitizer attributes for naked functions. - to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); + to_add.extend(sanitize_attrs(cx, tcx, codegen_fn_attrs.no_sanitize)); // For non-naked functions, set branch protection attributes on aarch64. - if let Some(BranchProtection { bti, pac_ret }) = - cx.sess().opts.unstable_opts.branch_protection + if let Some(BranchProtection { bti, pac_ret, gcs }) = + sess.opts.unstable_opts.branch_protection { - assert!(cx.sess().target.arch == "aarch64"); + assert!(sess.target.arch == "aarch64"); if bti { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement")); } + if gcs { + to_add.push(llvm::CreateAttrString(cx.llcx, "guarded-control-stack")); + } if let Some(PacRet { leaf, pc, key }) = pac_ret { if pc { to_add.push(llvm::CreateAttrString(cx.llcx, "branch-protection-pauth-lr")); @@ -435,14 +451,15 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR_ZEROED) { to_add.push(create_alloc_family_attr(cx.llcx)); - if let Some(zv) = - cx.tcx.get_attr(instance.def_id(), rustc_span::sym::rustc_allocator_zeroed_variant) + if let Some(instance) = instance + && let Some(zv) = + tcx.get_attr(instance.def_id(), rustc_span::sym::rustc_allocator_zeroed_variant) && let Some(name) = zv.value_str() { to_add.push(llvm::CreateAttrStringValue( cx.llcx, "alloc-variant-zeroed", - &mangle_internal_symbol(cx.tcx, name.as_str()), + &mangle_internal_symbol(tcx, name.as_str()), )); } // apply to argument place instead of function @@ -487,18 +504,22 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( if let Some(align) = codegen_fn_attrs.alignment { llvm::set_alignment(llfn, align); } - if let Some(backchain) = backchain_attr(cx) { + if let Some(backchain) = backchain_attr(cx, sess) { to_add.push(backchain); } - to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); + to_add.extend(patchable_function_entry_attrs( + cx, + sess, + codegen_fn_attrs.patchable_function_entry, + )); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated // functions (because Clang annotates functions this way too). - to_add.push(target_cpu_attr(cx)); + to_add.push(target_cpu_attr(cx, sess)); // tune-cpu is only conveyed through the attribute for our purpose. // The target doesn't care; the subtarget reads our attribute. - to_add.extend(tune_cpu_attr(cx)); + to_add.extend(tune_cpu_attr(cx, sess)); let function_features = codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::>(); @@ -506,7 +527,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( // Apply function attributes as per usual if there are no user defined // target features otherwise this will get applied at the callsite. if function_features.is_empty() { - if let Some(inline_attr) = inline_attr(cx, instance) { + if let Some(instance) = instance + && let Some(inline_attr) = inline_attr(cx, tcx, instance) + { to_add.push(inline_attr); } } @@ -514,7 +537,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( let function_features = function_features .iter() // Convert to LLVMFeatures and filter out unavailable ones - .flat_map(|feat| llvm_util::to_llvm_features(cx.tcx.sess, feat)) + .flat_map(|feat| llvm_util::to_llvm_features(sess, feat)) // Convert LLVMFeatures & dependencies to +s .flat_map(|feat| feat.into_iter().map(|f| format!("+{f}"))) .chain(codegen_fn_attrs.instruction_set.iter().map(|x| match x { @@ -523,20 +546,22 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>( })) .collect::>(); - if cx.tcx.sess.target.is_like_wasm { + if sess.target.is_like_wasm { // If this function is an import from the environment but the wasm // import has a specific module/name, apply them here. - if let Some(module) = wasm_import_module(cx.tcx, instance.def_id()) { + if let Some(instance) = instance + && let Some(module) = wasm_import_module(tcx, instance.def_id()) + { to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-module", module)); let name = - codegen_fn_attrs.symbol_name.unwrap_or_else(|| cx.tcx.item_name(instance.def_id())); + codegen_fn_attrs.symbol_name.unwrap_or_else(|| tcx.item_name(instance.def_id())); let name = name.as_str(); to_add.push(llvm::CreateAttrStringValue(cx.llcx, "wasm-import-name", name)); } } - to_add.extend(target_features_attr(cx, function_features)); + to_add.extend(target_features_attr(cx, tcx, function_features)); attributes::apply_to_llfn(llfn, Function, &to_add); } diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index f571716d9dd9f..5ac3a87c158e6 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -563,6 +563,8 @@ fn enable_autodiff_settings(ad: &[config::AutoDiff]) { config::AutoDiff::Enable => {} // We handle this below config::AutoDiff::NoPostopt => {} + // Disables TypeTree generation + config::AutoDiff::NoTT => {} } } // This helps with handling enums for now. @@ -617,7 +619,7 @@ pub(crate) fn run_pass_manager( crate::builder::gpu_offload::handle_gpu_code(cgcx, &cx); } - if cfg!(llvm_enzyme) && enable_ad && !thin { + if cfg!(feature = "llvm_enzyme") && enable_ad && !thin { let opt_stage = llvm::OptStage::FatLTO; let stage = write::AutodiffStage::PostAD; if !config.autodiff.contains(&config::AutoDiff::NoPostopt) { diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs index 6d8178320febd..2972f3d5201ed 100644 --- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs +++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs @@ -1,4 +1,3 @@ -use std::assert_matches::assert_matches; use std::ffi::CStr; use std::marker::PhantomData; use std::ptr::NonNull; @@ -39,13 +38,8 @@ impl OwnedTargetMachine { output_obj_file: &CStr, debug_info_compression: &CStr, use_emulated_tls: bool, - args_cstr_buff: &[u8], use_wasm_eh: bool, ) -> Result> { - // The argument list is passed as the concatenation of one or more C strings. - // This implies that there must be a last byte, and it must be 0. - assert_matches!(args_cstr_buff, [.., b'\0'], "the last byte must be a NUL terminator"); - // SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data let tm_ptr = unsafe { llvm::LLVMRustCreateTargetMachine( @@ -70,8 +64,6 @@ impl OwnedTargetMachine { output_obj_file.as_ptr(), debug_info_compression.as_ptr(), use_emulated_tls, - args_cstr_buff.as_ptr(), - args_cstr_buff.len(), use_wasm_eh, ) }; @@ -97,8 +89,6 @@ impl Drop for OwnedTargetMachine { // SAFETY: constructing ensures we have a valid pointer created by // llvm::LLVMRustCreateTargetMachine OwnedTargetMachine is not copyable so there is no // double free or use after free. - unsafe { - llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_ptr()); - } + unsafe { llvm::LLVMDisposeTargetMachine(self.tm_unique) }; } } diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 423f0da48781a..d18030b1574c5 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -43,7 +43,7 @@ use crate::errors::{ }; use crate::llvm::diagnostic::OptimizationDiagnosticKind::*; use crate::llvm::{self, DiagnosticInfo}; -use crate::type_::Type; +use crate::type_::llvm_type_ptr; use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util}; pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> ! { @@ -203,6 +203,9 @@ pub(crate) fn target_machine_factory( optlvl: config::OptLevel, target_features: &[String], ) -> TargetMachineFactoryFn { + // Self-profile timer for creating a _factory_. + let _prof_timer = sess.prof.generic_activity("target_machine_factory"); + let reloc_model = to_llvm_relocation_model(sess.relocation_model()); let (opt_level, _) = to_llvm_opt_settings(optlvl); @@ -249,24 +252,6 @@ pub(crate) fn target_machine_factory( let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated); - // copy the exe path, followed by path all into one buffer - // null terminating them so we can use them as null terminated strings - let args_cstr_buff = { - let mut args_cstr_buff: Vec = Vec::new(); - let exe_path = std::env::current_exe().unwrap_or_default(); - let exe_path_str = exe_path.into_os_string().into_string().unwrap_or_default(); - - args_cstr_buff.extend_from_slice(exe_path_str.as_bytes()); - args_cstr_buff.push(0); - - for arg in sess.expanded_args.iter() { - args_cstr_buff.extend_from_slice(arg.as_bytes()); - args_cstr_buff.push(0); - } - - args_cstr_buff - }; - let debuginfo_compression = sess.opts.debuginfo_compression.to_string(); match sess.opts.debuginfo_compression { rustc_session::config::DebugInfoCompression::Zlib => { @@ -288,7 +273,11 @@ pub(crate) fn target_machine_factory( let use_wasm_eh = wants_wasm_eh(sess); + let prof = SelfProfilerRef::clone(&sess.prof); Arc::new(move |config: TargetMachineFactoryConfig| { + // Self-profile timer for invoking a factory to create a target machine. + let _prof_timer = prof.generic_activity("target_machine_factory_inner"); + let path_to_cstring_helper = |path: Option| -> CString { let path = path.unwrap_or_default(); let path = path_mapping @@ -323,7 +312,6 @@ pub(crate) fn target_machine_factory( &output_obj_file, &debuginfo_compression, use_emulated_tls, - &args_cstr_buff, use_wasm_eh, ) }) @@ -354,7 +342,7 @@ fn write_bitcode_to_file(module: &ModuleCodegen, path: &Path) { } } -/// In what context is a dignostic handler being attached to a codegen unit? +/// In what context is a diagnostic handler being attached to a codegen unit? pub(crate) enum CodegenDiagnosticsStage { /// Prelink optimization stage. Opt, @@ -574,7 +562,8 @@ pub(crate) unsafe fn llvm_optimize( // FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting // differentiated. - let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = + cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); let run_enzyme = autodiff_stage == AutodiffStage::DuringAD; let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore); let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter); @@ -740,7 +729,8 @@ pub(crate) fn optimize( // If we know that we will later run AD, then we disable vectorization and loop unrolling. // Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD). - let consider_ad = cfg!(llvm_enzyme) && config.autodiff.contains(&config::AutoDiff::Enable); + let consider_ad = + cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable); let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD }; // The embedded bitcode is used to run LTO/ThinLTO. // The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO. @@ -1154,7 +1144,7 @@ fn create_msvc_imps( // underscores added in front). let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" }; - let ptr_ty = Type::ptr_llcx(llcx); + let ptr_ty = llvm_type_ptr(llcx); let globals = base::iter_globals(llmod) .filter(|&val| { llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage && !llvm::is_declaration(val) diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 9cc5d8dbc21cf..4523d629b1ef6 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -28,10 +28,10 @@ use rustc_span::Symbol; use rustc_target::spec::SanitizerSet; use super::ModuleLlvm; +use crate::attributes; use crate::builder::Builder; use crate::context::CodegenCx; -use crate::value::Value; -use crate::{attributes, llvm}; +use crate::llvm::{self, Value}; pub(crate) struct ValueIter<'ll> { cur: Option<&'ll Value>, @@ -105,22 +105,40 @@ pub(crate) fn compile_codegen_unit( if let Some(entry) = maybe_create_entry_wrapper::>(&cx, cx.codegen_unit) { - let attrs = attributes::sanitize_attrs(&cx, SanitizerSet::empty()); + let attrs = attributes::sanitize_attrs(&cx, tcx, SanitizerSet::empty()); attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs); } + // Define Objective-C module info and module flags. Note, the module info will + // also be added to the `llvm.compiler.used` variable, created later. + // + // These are only necessary when we need the linker to do its Objective-C-specific + // magic. We could theoretically do it unconditionally, but at a slight cost to linker + // performance in the common case where it's unnecessary. + if !cx.objc_classrefs.borrow().is_empty() || !cx.objc_selrefs.borrow().is_empty() { + if cx.objc_abi_version() == 1 { + cx.define_objc_module_info(); + } + cx.add_objc_module_flags(); + } + // Finalize code coverage by injecting the coverage map. Note, the coverage map will // also be added to the `llvm.compiler.used` variable, created next. if cx.sess().instrument_coverage() { cx.coverageinfo_finalize(); } - // Create the llvm.used and llvm.compiler.used variables. + // Create the llvm.used variable. if !cx.used_statics.is_empty() { cx.create_used_variable_impl(c"llvm.used", &cx.used_statics); } - if !cx.compiler_used_statics.is_empty() { - cx.create_used_variable_impl(c"llvm.compiler.used", &cx.compiler_used_statics); + + // Create the llvm.compiler.used variable. + { + let compiler_used_statics = cx.compiler_used_statics.borrow(); + if !compiler_used_statics.is_empty() { + cx.create_used_variable_impl(c"llvm.compiler.used", &compiler_used_statics); + } } // Run replace-all-uses-with for statics that need it. This must diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 7d0691366e602..c082a82306848 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1,11 +1,12 @@ use std::borrow::{Borrow, Cow}; +use std::iter; use std::ops::Deref; -use std::{iter, ptr}; +use rustc_ast::expand::typetree::FncTree; pub(crate) mod autodiff; pub(crate) mod gpu_offload; -use libc::{c_char, c_uint, size_t}; +use libc::{c_char, c_uint}; use rustc_abi as abi; use rustc_abi::{Align, Size, WrappingRange}; use rustc_codegen_ssa::MemFlags; @@ -35,11 +36,10 @@ use crate::attributes; use crate::common::Funclet; use crate::context::{CodegenCx, FullCx, GenericCx, SCx}; use crate::llvm::{ - self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, GEPNoWrapFlags, Metadata, TRUE, ToLlvmBool, + self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, FromGeneric, GEPNoWrapFlags, Metadata, TRUE, + ToLlvmBool, Type, Value, }; -use crate::type_::Type; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; #[must_use] pub(crate) struct GenericBuilder<'a, 'll, CX: Borrow>> { @@ -395,10 +395,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { md.push(weight(is_cold)); } - unsafe { - let md_node = llvm::LLVMMDNodeInContext2(self.cx.llcx, md.as_ptr(), md.len() as size_t); - self.cx.set_metadata(switch, llvm::MD_prof, md_node); - } + self.cx.set_metadata_node(switch, llvm::MD_prof, &md); } fn invoke( @@ -642,13 +639,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { size: Size, ) -> &'ll Value { unsafe { - let load = llvm::LLVMRustBuildAtomicLoad( - self.llbuilder, - ty, - ptr, - UNNAMED, - AtomicOrdering::from_generic(order), - ); + let load = llvm::LLVMBuildLoad2(self.llbuilder, ty, ptr, UNNAMED); + // Set atomic ordering + llvm::LLVMSetOrdering(load, AtomicOrdering::from_generic(order)); // LLVM requires the alignment of atomic loads to be at least the size of the type. llvm::LLVMSetAlignment(load, size.bytes() as c_uint); load @@ -800,22 +793,16 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { return; } - unsafe { - let llty = self.cx.val_ty(load); - let md = [ - llvm::LLVMValueAsMetadata(self.cx.const_uint_big(llty, range.start)), - llvm::LLVMValueAsMetadata(self.cx.const_uint_big(llty, range.end.wrapping_add(1))), - ]; - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, md.as_ptr(), md.len()); - self.set_metadata(load, llvm::MD_range, md); - } + let llty = self.cx.val_ty(load); + let md = [ + llvm::LLVMValueAsMetadata(self.cx.const_uint_big(llty, range.start)), + llvm::LLVMValueAsMetadata(self.cx.const_uint_big(llty, range.end.wrapping_add(1))), + ]; + self.set_metadata_node(load, llvm::MD_range, &md); } fn nonnull_metadata(&mut self, load: &'ll Value) { - unsafe { - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, ptr::null(), 0); - self.set_metadata(load, llvm::MD_nonnull, md); - } + self.set_metadata_node(load, llvm::MD_nonnull, &[]); } fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value { @@ -864,8 +851,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // // [1]: https://llvm.org/docs/LangRef.html#store-instruction let one = llvm::LLVMValueAsMetadata(self.cx.const_i32(1)); - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, &one, 1); - self.set_metadata(store, llvm::MD_nontemporal, md); + self.set_metadata_node(store, llvm::MD_nontemporal, &[one]); } } store @@ -882,12 +868,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { debug!("Store {:?} -> {:?}", val, ptr); assert_eq!(self.cx.type_kind(self.cx.val_ty(ptr)), TypeKind::Pointer); unsafe { - let store = llvm::LLVMRustBuildAtomicStore( - self.llbuilder, - val, - ptr, - AtomicOrdering::from_generic(order), - ); + let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr); + // Set atomic ordering + llvm::LLVMSetOrdering(store, AtomicOrdering::from_generic(order)); // LLVM requires the alignment of atomic stores to be at least the size of the type. llvm::LLVMSetAlignment(store, size.bytes() as c_uint); } @@ -1091,16 +1074,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { ty: Ty<'tcx>, lhs: Self::Value, rhs: Self::Value, - ) -> Option { - // FIXME: See comment on the definition of `three_way_compare`. - if crate::llvm_util::get_version() < (20, 0, 0) { - return None; - } - + ) -> Self::Value { let size = ty.primitive_size(self.tcx); let name = if ty.is_signed() { "llvm.scmp" } else { "llvm.ucmp" }; - Some(self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs])) + self.call_intrinsic(name, &[self.type_i8(), self.type_ix(size.bits())], &[lhs, rhs]) } /* Miscellaneous instructions */ @@ -1112,11 +1090,12 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { src_align: Align, size: &'ll Value, flags: MemFlags, + tt: Option, ) { assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memcpy not supported"); let size = self.intcast(size, self.type_isize(), false); let is_volatile = flags.contains(MemFlags::VOLATILE); - unsafe { + let memcpy = unsafe { llvm::LLVMRustBuildMemCpy( self.llbuilder, dst, @@ -1125,7 +1104,16 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { src_align.bytes() as c_uint, size, is_volatile, - ); + ) + }; + + // TypeTree metadata for memcpy is especially important: when Enzyme encounters + // a memcpy during autodiff, it needs to know the structure of the data being + // copied to properly track derivatives. For example, copying an array of floats + // vs. copying a struct with mixed types requires different derivative handling. + // The TypeTree tells Enzyme exactly what memory layout to expect. + if let Some(tt) = tt { + crate::typetree::add_tt(self.cx().llmod, self.cx().llcx, memcpy, tt); } } @@ -1375,10 +1363,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } fn set_invariant_load(&mut self, load: &'ll Value) { - unsafe { - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, ptr::null(), 0); - self.set_metadata(load, llvm::MD_invariant_load, md); - } + self.set_metadata_node(load, llvm::MD_invariant_load, &[]); } fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) { @@ -1438,7 +1423,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // If there is an inline attribute and a target feature that matches // we will add the attribute to the callsite otherwise we'll omit // this and not add the attribute to prevent soundness issues. - && let Some(inlining_rule) = attributes::inline_attr(&self.cx, instance) + && let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, instance) && self.cx.tcx.is_target_feature_call_safe( &fn_call_attrs.target_features, &fn_defn_attrs.target_features, @@ -1522,34 +1507,24 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { } impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { fn align_metadata(&mut self, load: &'ll Value, align: Align) { - unsafe { - let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))]; - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, md.as_ptr(), md.len()); - self.set_metadata(load, llvm::MD_align, md); - } + let md = [llvm::LLVMValueAsMetadata(self.cx.const_u64(align.bytes()))]; + self.set_metadata_node(load, llvm::MD_align, &md); } fn noundef_metadata(&mut self, load: &'ll Value) { - unsafe { - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, ptr::null(), 0); - self.set_metadata(load, llvm::MD_noundef, md); - } + self.set_metadata_node(load, llvm::MD_noundef, &[]); } pub(crate) fn set_unpredictable(&mut self, inst: &'ll Value) { - unsafe { - let md = llvm::LLVMMDNodeInContext2(self.cx.llcx, ptr::null(), 0); - self.set_metadata(inst, llvm::MD_unpredictable, md); - } + self.set_metadata_node(inst, llvm::MD_unpredictable, &[]); } -} -impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { + pub(crate) fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) } + self.call_intrinsic("llvm.minnum", &[self.val_ty(lhs)], &[lhs, rhs]) } pub(crate) fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) } + self.call_intrinsic("llvm.maxnum", &[self.val_ty(lhs)], &[lhs, rhs]) } pub(crate) fn insert_element( @@ -1571,10 +1546,10 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { } pub(crate) fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) } + self.call_intrinsic("llvm.vector.reduce.fadd", &[self.val_ty(src)], &[acc, src]) } pub(crate) fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) } + self.call_intrinsic("llvm.vector.reduce.fmul", &[self.val_ty(src)], &[acc, src]) } pub(crate) fn vector_reduce_fadd_reassoc( &mut self, @@ -1582,7 +1557,8 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { src: &'ll Value, ) -> &'ll Value { unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); + let instr = + self.call_intrinsic("llvm.vector.reduce.fadd", &[self.val_ty(src)], &[acc, src]); llvm::LLVMRustSetAllowReassoc(instr); instr } @@ -1593,43 +1569,49 @@ impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { src: &'ll Value, ) -> &'ll Value { unsafe { - let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); + let instr = + self.call_intrinsic("llvm.vector.reduce.fmul", &[self.val_ty(src)], &[acc, src]); llvm::LLVMRustSetAllowReassoc(instr); instr } } pub(crate) fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) } + self.call_intrinsic("llvm.vector.reduce.add", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) } + self.call_intrinsic("llvm.vector.reduce.mul", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) } + self.call_intrinsic("llvm.vector.reduce.and", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) } + self.call_intrinsic("llvm.vector.reduce.or", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) } + self.call_intrinsic("llvm.vector.reduce.xor", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { - llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) - } + self.call_intrinsic("llvm.vector.reduce.fmin", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value { - unsafe { - llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) - } + self.call_intrinsic("llvm.vector.reduce.fmax", &[self.val_ty(src)], &[src]) } pub(crate) fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) } + self.call_intrinsic( + if is_signed { "llvm.vector.reduce.smin" } else { "llvm.vector.reduce.umin" }, + &[self.val_ty(src)], + &[src], + ) } pub(crate) fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value { - unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) } + self.call_intrinsic( + if is_signed { "llvm.vector.reduce.smax" } else { "llvm.vector.reduce.umax" }, + &[self.val_ty(src)], + &[src], + ) } - +} +impl<'a, 'll, CX: Borrow>> GenericBuilder<'a, 'll, CX> { pub(crate) fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) { unsafe { llvm::LLVMAddClause(landing_pad, clause); diff --git a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs index 6ddf53cdc87f0..4b433e2b63616 100644 --- a/compiler/rustc_codegen_llvm/src/builder/autodiff.rs +++ b/compiler/rustc_codegen_llvm/src/builder/autodiff.rs @@ -1,24 +1,27 @@ use std::ptr; use rustc_ast::expand::autodiff_attrs::{AutoDiffAttrs, DiffActivity, DiffMode}; +use rustc_ast::expand::typetree::FncTree; use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods}; -use rustc_middle::ty::{PseudoCanonicalInput, Ty, TyCtxt, TypingEnv}; +use rustc_middle::ty::{Instance, PseudoCanonicalInput, TyCtxt, TypingEnv}; use rustc_middle::{bug, ty}; +use rustc_target::callconv::PassMode; use tracing::debug; use crate::builder::{Builder, PlaceRef, UNNAMED}; use crate::context::SimpleCx; use crate::declare::declare_simple_fn; -use crate::llvm; -use crate::llvm::{Metadata, TRUE, Type}; -use crate::value::Value; +use crate::llvm::{self, TRUE, Type, Value}; pub(crate) fn adjust_activity_to_abi<'tcx>( tcx: TyCtxt<'tcx>, - fn_ty: Ty<'tcx>, + instance: Instance<'tcx>, + typing_env: TypingEnv<'tcx>, da: &mut Vec, ) { + let fn_ty = instance.ty(tcx, typing_env); + if !matches!(fn_ty.kind(), ty::FnDef(..)) { bug!("expected fn def for autodiff, got {:?}", fn_ty); } @@ -27,8 +30,16 @@ pub(crate) fn adjust_activity_to_abi<'tcx>( // All we do is decide how to handle the arguments. let sig = fn_ty.fn_sig(tcx).skip_binder(); + // FIXME(Sa4dUs): pass proper varargs once we have support for differentiating variadic functions + let Ok(fn_abi) = + tcx.fn_abi_of_instance(typing_env.as_query_input((instance, ty::List::empty()))) + else { + bug!("failed to get fn_abi of instance with empty varargs"); + }; + let mut new_activities = vec![]; let mut new_positions = vec![]; + let mut del_activities = 0; for (i, ty) in sig.inputs().iter().enumerate() { if let Some(inner_ty) = ty.builtin_deref(true) { if inner_ty.is_slice() { @@ -80,6 +91,34 @@ pub(crate) fn adjust_activity_to_abi<'tcx>( continue; } } + + let pci = PseudoCanonicalInput { typing_env: TypingEnv::fully_monomorphized(), value: *ty }; + + let layout = match tcx.layout_of(pci) { + Ok(layout) => layout.layout, + Err(_) => { + bug!("failed to compute layout for type {:?}", ty); + } + }; + + let pass_mode = &fn_abi.args[i].mode; + + // For ZST, just ignore and don't add its activity, as this arg won't be present + // in the LLVM passed to Enzyme. + // Some targets pass ZST indirectly in the C ABI, in that case, handle it as a normal arg + // FIXME(Sa4dUs): Enforce ZST corresponding diff activity be `Const` + if *pass_mode == PassMode::Ignore { + del_activities += 1; + da.remove(i); + } + + // If the argument is lowered as a `ScalarPair`, we need to duplicate its activity. + // Otherwise, the number of activities won't match the number of LLVM arguments and + // this will lead to errors when verifying the Enzyme call. + if let rustc_abi::BackendRepr::ScalarPair(_, _) = layout.backend_repr() { + new_activities.push(da[i].clone()); + new_positions.push(i + 1 - del_activities); + } } // now add the extra activities coming from slices // Reverse order to not invalidate the indices @@ -104,9 +143,9 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( cx: &SimpleCx<'ll>, builder: &mut Builder<'_, 'll, 'tcx>, width: u32, - args: &mut Vec<&'ll llvm::Value>, + args: &mut Vec<&'ll Value>, inputs: &[DiffActivity], - outer_args: &[&'ll llvm::Value], + outer_args: &[&'ll Value], ) { debug!("matching autodiff arguments"); // We now handle the issue that Rust level arguments not always match the llvm-ir level @@ -118,32 +157,36 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( let mut outer_pos: usize = 0; let mut activity_pos = 0; - let enzyme_const = cx.create_metadata(b"enzyme_const"); - let enzyme_out = cx.create_metadata(b"enzyme_out"); - let enzyme_dup = cx.create_metadata(b"enzyme_dup"); - let enzyme_dupv = cx.create_metadata(b"enzyme_dupv"); - let enzyme_dupnoneed = cx.create_metadata(b"enzyme_dupnoneed"); - let enzyme_dupnoneedv = cx.create_metadata(b"enzyme_dupnoneedv"); + // We used to use llvm's metadata to instruct enzyme how to differentiate a function. + // In debug mode we would use incremental compilation which caused the metadata to be + // dropped. This is prevented by now using named globals, which are also understood + // by Enzyme. + let global_const = cx.declare_global("enzyme_const", cx.type_ptr()); + let global_out = cx.declare_global("enzyme_out", cx.type_ptr()); + let global_dup = cx.declare_global("enzyme_dup", cx.type_ptr()); + let global_dupv = cx.declare_global("enzyme_dupv", cx.type_ptr()); + let global_dupnoneed = cx.declare_global("enzyme_dupnoneed", cx.type_ptr()); + let global_dupnoneedv = cx.declare_global("enzyme_dupnoneedv", cx.type_ptr()); while activity_pos < inputs.len() { let diff_activity = inputs[activity_pos as usize]; // Duplicated arguments received a shadow argument, into which enzyme will write the // gradient. - let (activity, duplicated): (&Metadata, bool) = match diff_activity { + let (activity, duplicated): (&Value, bool) = match diff_activity { DiffActivity::None => panic!("not a valid input activity"), - DiffActivity::Const => (enzyme_const, false), - DiffActivity::Active => (enzyme_out, false), - DiffActivity::ActiveOnly => (enzyme_out, false), - DiffActivity::Dual => (enzyme_dup, true), - DiffActivity::Dualv => (enzyme_dupv, true), - DiffActivity::DualOnly => (enzyme_dupnoneed, true), - DiffActivity::DualvOnly => (enzyme_dupnoneedv, true), - DiffActivity::Duplicated => (enzyme_dup, true), - DiffActivity::DuplicatedOnly => (enzyme_dupnoneed, true), - DiffActivity::FakeActivitySize(_) => (enzyme_const, false), + DiffActivity::Const => (global_const, false), + DiffActivity::Active => (global_out, false), + DiffActivity::ActiveOnly => (global_out, false), + DiffActivity::Dual => (global_dup, true), + DiffActivity::Dualv => (global_dupv, true), + DiffActivity::DualOnly => (global_dupnoneed, true), + DiffActivity::DualvOnly => (global_dupnoneedv, true), + DiffActivity::Duplicated => (global_dup, true), + DiffActivity::DuplicatedOnly => (global_dupnoneed, true), + DiffActivity::FakeActivitySize(_) => (global_const, false), }; let outer_arg = outer_args[outer_pos]; - args.push(cx.get_metadata_value(activity)); + args.push(activity); if matches!(diff_activity, DiffActivity::Dualv) { let next_outer_arg = outer_args[outer_pos + 1]; let elem_bytes_size: u64 = match inputs[activity_pos + 1] { @@ -203,7 +246,7 @@ fn match_args_from_caller_to_enzyme<'ll, 'tcx>( assert_eq!(cx.type_kind(next_outer_ty3), TypeKind::Integer); args.push(next_outer_arg2); } - args.push(cx.get_metadata_value(enzyme_const)); + args.push(global_const); args.push(next_outer_arg); outer_pos += 2 + 2 * iterations; activity_pos += 2; @@ -254,6 +297,7 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( fn_args: &[&'ll Value], attrs: AutoDiffAttrs, dest: PlaceRef<'tcx, &'ll Value>, + fnc_tree: FncTree, ) { // We have to pick the name depending on whether we want forward or reverse mode autodiff. let mut ad_name: String = match attrs.mode { @@ -311,13 +355,13 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( let mut args = Vec::with_capacity(num_args as usize + 1); args.push(fn_to_diff); - let enzyme_primal_ret = cx.create_metadata(b"enzyme_primal_return"); + let global_primal_ret = cx.declare_global("enzyme_primal_return", cx.type_ptr()); if matches!(attrs.ret_activity, DiffActivity::Dual | DiffActivity::Active) { - args.push(cx.get_metadata_value(enzyme_primal_ret)); + args.push(global_primal_ret); } if attrs.width > 1 { - let enzyme_width = cx.create_metadata(b"enzyme_width"); - args.push(cx.get_metadata_value(enzyme_width)); + let global_width = cx.declare_global("enzyme_width", cx.type_ptr()); + args.push(global_width); args.push(cx.get_const_int(cx.type_i64(), attrs.width as u64)); } @@ -330,7 +374,18 @@ pub(crate) fn generate_enzyme_call<'ll, 'tcx>( fn_args, ); + if !fnc_tree.args.is_empty() || !fnc_tree.ret.0.is_empty() { + crate::typetree::add_tt(cx.llmod, cx.llcx, fn_to_diff, fnc_tree); + } + let call = builder.call(enzyme_ty, None, None, ad_fn, &args, None, None); - builder.store_to_place(call, dest.val); + let fn_ret_ty = builder.cx.val_ty(call); + if fn_ret_ty != builder.cx.type_void() && fn_ret_ty != builder.cx.type_struct(&[], false) { + // If we return void or an empty struct, then our caller (due to how we generated it) + // does not expect a return value. As such, we have no pointer (or place) into which + // we could store our value, and would store into an undef, which would cause UB. + // As such, we just ignore the return value in those cases. + builder.store_to_place(call, dest.val); + } } diff --git a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs index 0737a18384bd4..3d55064ea1304 100644 --- a/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs +++ b/compiler/rustc_codegen_llvm/src/builder/gpu_offload.rs @@ -16,25 +16,42 @@ pub(crate) fn handle_gpu_code<'ll>( cx: &'ll SimpleCx<'_>, ) { // The offload memory transfer type for each kernel - let mut o_types = vec![]; - let mut kernels = vec![]; - let offload_entry_ty = add_tgt_offload_entry(&cx); + let mut memtransfer_types = vec![]; + let mut region_ids = vec![]; + let offload_entry_ty = TgtOffloadEntry::new_decl(&cx); for num in 0..9 { let kernel = cx.get_function(&format!("kernel_{num}")); if let Some(kernel) = kernel { - o_types.push(gen_define_handling(&cx, kernel, offload_entry_ty, num)); - kernels.push(kernel); + let (o, k) = gen_define_handling(&cx, kernel, offload_entry_ty, num); + memtransfer_types.push(o); + region_ids.push(k); } } - gen_call_handling(&cx, &kernels, &o_types); + gen_call_handling(&cx, &memtransfer_types, ®ion_ids); +} + +// ; Function Attrs: nounwind +// declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) #2 +fn generate_launcher<'ll>(cx: &'ll SimpleCx<'_>) -> (&'ll llvm::Value, &'ll llvm::Type) { + let tptr = cx.type_ptr(); + let ti64 = cx.type_i64(); + let ti32 = cx.type_i32(); + let args = vec![tptr, ti64, ti32, ti32, tptr, tptr]; + let tgt_fn_ty = cx.type_func(&args, ti32); + let name = "__tgt_target_kernel"; + let tgt_decl = declare_offload_fn(&cx, name, tgt_fn_ty); + let nounwind = llvm::AttributeKind::NoUnwind.create_attr(cx.llcx); + attributes::apply_to_llfn(tgt_decl, Function, &[nounwind]); + (tgt_decl, tgt_fn_ty) } // What is our @1 here? A magic global, used in our data_{begin/update/end}_mapper: // @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 // @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8 +// FIXME(offload): @0 should include the file name (e.g. lib.rs) in which the function to be +// offloaded was defined. fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value { - // @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 let unknown_txt = ";unknown;unknown;0;0;;"; let c_entry_name = CString::new(unknown_txt).unwrap(); let c_val = c_entry_name.as_bytes_with_nul(); @@ -59,15 +76,7 @@ fn generate_at_one<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Value { at_one } -pub(crate) fn add_tgt_offload_entry<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type { - let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry"); - let tptr = cx.type_ptr(); - let ti64 = cx.type_i64(); - let ti32 = cx.type_i32(); - let ti16 = cx.type_i16(); - // For each kernel to run on the gpu, we will later generate one entry of this type. - // copied from LLVM - // typedef struct { +struct TgtOffloadEntry { // uint64_t Reserved; // uint16_t Version; // uint16_t Kind; @@ -77,21 +86,40 @@ pub(crate) fn add_tgt_offload_entry<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Ty // uint64_t Size; Size of the entry info (0 if it is a function) // uint64_t Data; // void *AuxAddr; - // } __tgt_offload_entry; - let entry_elements = vec![ti64, ti16, ti16, ti32, tptr, tptr, ti64, ti64, tptr]; - cx.set_struct_body(offload_entry_ty, &entry_elements, false); - offload_entry_ty } -fn gen_tgt_kernel_global<'ll>(cx: &'ll SimpleCx<'_>) { - let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments"); - let tptr = cx.type_ptr(); - let ti64 = cx.type_i64(); - let ti32 = cx.type_i32(); - let tarr = cx.type_array(ti32, 3); +impl TgtOffloadEntry { + pub(crate) fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll llvm::Type { + let offload_entry_ty = cx.type_named_struct("struct.__tgt_offload_entry"); + let tptr = cx.type_ptr(); + let ti64 = cx.type_i64(); + let ti32 = cx.type_i32(); + let ti16 = cx.type_i16(); + // For each kernel to run on the gpu, we will later generate one entry of this type. + // copied from LLVM + let entry_elements = vec![ti64, ti16, ti16, ti32, tptr, tptr, ti64, ti64, tptr]; + cx.set_struct_body(offload_entry_ty, &entry_elements, false); + offload_entry_ty + } + + fn new<'ll>( + cx: &'ll SimpleCx<'_>, + region_id: &'ll Value, + llglobal: &'ll Value, + ) -> [&'ll Value; 9] { + let reserved = cx.get_const_i64(0); + let version = cx.get_const_i16(1); + let kind = cx.get_const_i16(1); + let flags = cx.get_const_i32(0); + let size = cx.get_const_i64(0); + let data = cx.get_const_i64(0); + let aux_addr = cx.const_null(cx.type_ptr()); + [reserved, version, kind, flags, region_id, llglobal, size, data, aux_addr] + } +} - // Taken from the LLVM APITypes.h declaration: - //struct KernelArgsTy { +// Taken from the LLVM APITypes.h declaration: +struct KernelArgsTy { // uint32_t Version = 0; // Version of this struct for ABI compatibility. // uint32_t NumArgs = 0; // Number of arguments in each input pointer. // void **ArgBasePtrs = @@ -102,25 +130,65 @@ fn gen_tgt_kernel_global<'ll>(cx: &'ll SimpleCx<'_>) { // void **ArgNames = nullptr; // Name of the data for debugging, possibly null. // void **ArgMappers = nullptr; // User-defined mappers, possibly null. // uint64_t Tripcount = - // 0; // Tripcount for the teams / distribute loop, 0 otherwise. - // struct { + // 0; // Tripcount for the teams / distribute loop, 0 otherwise. + // struct { // uint64_t NoWait : 1; // Was this kernel spawned with a `nowait` clause. // uint64_t IsCUDA : 1; // Was this kernel spawned via CUDA. // uint64_t Unused : 62; - // } Flags = {0, 0, 0}; + // } Flags = {0, 0, 0}; // totals to 64 Bit, 8 Byte // // The number of teams (for x,y,z dimension). // uint32_t NumTeams[3] = {0, 0, 0}; // // The number of threads (for x,y,z dimension). // uint32_t ThreadLimit[3] = {0, 0, 0}; // uint32_t DynCGroupMem = 0; // Amount of dynamic cgroup memory requested. - //}; - let kernel_elements = - vec![ti32, ti32, tptr, tptr, tptr, tptr, tptr, tptr, ti64, ti64, tarr, tarr, ti32]; - - cx.set_struct_body(kernel_arguments_ty, &kernel_elements, false); - // For now we don't handle kernels, so for now we just add a global dummy - // to make sure that the __tgt_offload_entry is defined and handled correctly. - cx.declare_global("my_struct_global2", kernel_arguments_ty); +} + +impl KernelArgsTy { + const OFFLOAD_VERSION: u64 = 3; + const FLAGS: u64 = 0; + const TRIPCOUNT: u64 = 0; + fn new_decl<'ll>(cx: &'ll SimpleCx<'_>) -> &'ll Type { + let kernel_arguments_ty = cx.type_named_struct("struct.__tgt_kernel_arguments"); + let tptr = cx.type_ptr(); + let ti64 = cx.type_i64(); + let ti32 = cx.type_i32(); + let tarr = cx.type_array(ti32, 3); + + let kernel_elements = + vec![ti32, ti32, tptr, tptr, tptr, tptr, tptr, tptr, ti64, ti64, tarr, tarr, ti32]; + + cx.set_struct_body(kernel_arguments_ty, &kernel_elements, false); + kernel_arguments_ty + } + + fn new<'ll>( + cx: &'ll SimpleCx<'_>, + num_args: u64, + memtransfer_types: &[&'ll Value], + geps: [&'ll Value; 3], + ) -> [(Align, &'ll Value); 13] { + let four = Align::from_bytes(4).expect("4 Byte alignment should work"); + let eight = Align::EIGHT; + + let ti32 = cx.type_i32(); + let ci32_0 = cx.get_const_i32(0); + [ + (four, cx.get_const_i32(KernelArgsTy::OFFLOAD_VERSION)), + (four, cx.get_const_i32(num_args)), + (eight, geps[0]), + (eight, geps[1]), + (eight, geps[2]), + (eight, memtransfer_types[0]), + // The next two are debug infos. FIXME(offload): set them + (eight, cx.const_null(cx.type_ptr())), // dbg + (eight, cx.const_null(cx.type_ptr())), // dbg + (eight, cx.get_const_i64(KernelArgsTy::TRIPCOUNT)), + (eight, cx.get_const_i64(KernelArgsTy::FLAGS)), + (four, cx.const_array(ti32, &[cx.get_const_i32(2097152), ci32_0, ci32_0])), + (four, cx.const_array(ti32, &[cx.get_const_i32(256), ci32_0, ci32_0])), + (four, cx.get_const_i32(0)), + ] + } } fn gen_tgt_data_mappers<'ll>( @@ -182,12 +250,15 @@ pub(crate) fn add_global<'ll>( llglobal } +// This function returns a memtransfer value which encodes how arguments to this kernel shall be +// mapped to/from the gpu. It also returns a region_id with the name of this kernel, to be +// concatenated into the list of region_ids. fn gen_define_handling<'ll>( cx: &'ll SimpleCx<'_>, kernel: &'ll llvm::Value, offload_entry_ty: &'ll llvm::Type, num: i64, -) -> &'ll llvm::Value { +) -> (&'ll llvm::Value, &'ll llvm::Value) { let types = cx.func_params_types(cx.get_type_of_global(kernel)); // It seems like non-pointer values are automatically mapped. So here, we focus on pointer (or // reference) types. @@ -205,10 +276,14 @@ fn gen_define_handling<'ll>( // or both to and from the gpu (=3). Other values shouldn't affect us for now. // A non-mutable reference or pointer will be 1, an array that's not read, but fully overwritten // will be 2. For now, everything is 3, until we have our frontend set up. - let o_types = - add_priv_unnamed_arr(&cx, &format!(".offload_maptypes.{num}"), &vec![3; num_ptr_types]); + // 1+2+32: 1 (MapTo), 2 (MapFrom), 32 (Add one extra input ptr per function, to be used later). + let memtransfer_types = add_priv_unnamed_arr( + &cx, + &format!(".offload_maptypes.{num}"), + &vec![1 + 2 + 32; num_ptr_types], + ); // Next: For each function, generate these three entries. A weak constant, - // the llvm.rodata entry name, and the omp_offloading_entries value + // the llvm.rodata entry name, and the llvm_offload_entries value let name = format!(".kernel_{num}.region_id"); let initializer = cx.get_const_i8(0); @@ -222,19 +297,10 @@ fn gen_define_handling<'ll>( let llglobal = add_unnamed_global(&cx, &offload_entry_name, initializer, InternalLinkage); llvm::set_alignment(llglobal, Align::ONE); llvm::set_section(llglobal, c".llvm.rodata.offloading"); - - // Not actively used yet, for calling real kernels let name = format!(".offloading.entry.kernel_{num}"); // See the __tgt_offload_entry documentation above. - let reserved = cx.get_const_i64(0); - let version = cx.get_const_i16(1); - let kind = cx.get_const_i16(1); - let flags = cx.get_const_i32(0); - let size = cx.get_const_i64(0); - let data = cx.get_const_i64(0); - let aux_addr = cx.const_null(cx.type_ptr()); - let elems = vec![reserved, version, kind, flags, region_id, llglobal, size, data, aux_addr]; + let elems = TgtOffloadEntry::new(&cx, region_id, llglobal); let initializer = crate::common::named_struct(offload_entry_ty, &elems); let c_name = CString::new(name).unwrap(); @@ -242,13 +308,13 @@ fn gen_define_handling<'ll>( llvm::set_global_constant(llglobal, true); llvm::set_linkage(llglobal, WeakAnyLinkage); llvm::set_initializer(llglobal, initializer); - llvm::set_alignment(llglobal, Align::ONE); - let c_section_name = CString::new(".omp_offloading_entries").unwrap(); + llvm::set_alignment(llglobal, Align::EIGHT); + let c_section_name = CString::new("llvm_offload_entries").unwrap(); llvm::set_section(llglobal, &c_section_name); - o_types + (memtransfer_types, region_id) } -fn declare_offload_fn<'ll>( +pub(crate) fn declare_offload_fn<'ll>( cx: &'ll SimpleCx<'_>, name: &str, ty: &'ll llvm::Type, @@ -285,9 +351,10 @@ fn declare_offload_fn<'ll>( // 6. generate __tgt_target_data_end calls to move data from the GPU fn gen_call_handling<'ll>( cx: &'ll SimpleCx<'_>, - _kernels: &[&'ll llvm::Value], - o_types: &[&'ll llvm::Value], + memtransfer_types: &[&'ll llvm::Value], + region_ids: &[&'ll llvm::Value], ) { + let (tgt_decl, tgt_target_kernel_ty) = generate_launcher(&cx); // %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } let tptr = cx.type_ptr(); let ti32 = cx.type_i32(); @@ -295,7 +362,7 @@ fn gen_call_handling<'ll>( let tgt_bin_desc = cx.type_named_struct("struct.__tgt_bin_desc"); cx.set_struct_body(tgt_bin_desc, &tgt_bin_desc_ty, false); - gen_tgt_kernel_global(&cx); + let tgt_kernel_decl = KernelArgsTy::new_decl(&cx); let (begin_mapper_decl, _, end_mapper_decl, fn_ty) = gen_tgt_data_mappers(&cx); let main_fn = cx.get_function("main"); @@ -329,35 +396,32 @@ fn gen_call_handling<'ll>( // These represent the sizes in bytes, e.g. the entry for `&[f64; 16]` will be 8*16. let ty2 = cx.type_array(cx.type_i64(), num_args); let a4 = builder.direct_alloca(ty2, Align::EIGHT, ".offload_sizes"); + + //%kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 + let a5 = builder.direct_alloca(tgt_kernel_decl, Align::EIGHT, "kernel_args"); + + // Step 1) + unsafe { llvm::LLVMRustPositionBefore(builder.llbuilder, kernel_call) }; + builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT); + // Now we allocate once per function param, a copy to be passed to one of our maps. let mut vals = vec![]; let mut geps = vec![]; let i32_0 = cx.get_const_i32(0); - for (index, in_ty) in types.iter().enumerate() { - // get function arg, store it into the alloca, and read it. - let p = llvm::get_param(called, index as u32); - let name = llvm::get_value_name(p); - let name = str::from_utf8(&name).unwrap(); - let arg_name = format!("{name}.addr"); - let alloca = builder.direct_alloca(in_ty, Align::EIGHT, &arg_name); - - builder.store(p, alloca, Align::EIGHT); - let val = builder.load(in_ty, alloca, Align::EIGHT); - let gep = builder.inbounds_gep(cx.type_f32(), val, &[i32_0]); - vals.push(val); + for index in 0..types.len() { + let v = unsafe { llvm::LLVMGetOperand(kernel_call, index as u32).unwrap() }; + let gep = builder.inbounds_gep(cx.type_f32(), v, &[i32_0]); + vals.push(v); geps.push(gep); } - // Step 1) - unsafe { llvm::LLVMRustPositionBefore(builder.llbuilder, kernel_call) }; - builder.memset(tgt_bin_desc_alloca, cx.get_const_i8(0), cx.get_const_i64(32), Align::EIGHT); - let mapper_fn_ty = cx.type_func(&[cx.type_ptr()], cx.type_void()); let register_lib_decl = declare_offload_fn(&cx, "__tgt_register_lib", mapper_fn_ty); let unregister_lib_decl = declare_offload_fn(&cx, "__tgt_unregister_lib", mapper_fn_ty); let init_ty = cx.type_func(&[], cx.type_void()); let init_rtls_decl = declare_offload_fn(cx, "__tgt_init_all_rtls", init_ty); + // FIXME(offload): Later we want to add them to the wrapper code, rather than our main function. // call void @__tgt_register_lib(ptr noundef %6) builder.call(mapper_fn_ty, register_lib_decl, &[tgt_bin_desc_alloca], None); // call void @__tgt_init_all_rtls() @@ -386,19 +450,19 @@ fn gen_call_handling<'ll>( a1: &'ll Value, a2: &'ll Value, a4: &'ll Value, - ) -> (&'ll Value, &'ll Value, &'ll Value) { + ) -> [&'ll Value; 3] { let i32_0 = cx.get_const_i32(0); let gep1 = builder.inbounds_gep(ty, a1, &[i32_0, i32_0]); let gep2 = builder.inbounds_gep(ty, a2, &[i32_0, i32_0]); let gep3 = builder.inbounds_gep(ty2, a4, &[i32_0, i32_0]); - (gep1, gep2, gep3) + [gep1, gep2, gep3] } fn generate_mapper_call<'a, 'll>( builder: &mut SBuilder<'a, 'll>, cx: &'ll SimpleCx<'ll>, - geps: (&'ll Value, &'ll Value, &'ll Value), + geps: [&'ll Value; 3], o_type: &'ll Value, fn_to_call: &'ll Value, fn_ty: &'ll Type, @@ -409,31 +473,51 @@ fn gen_call_handling<'ll>( let i64_max = cx.get_const_i64(u64::MAX); let num_args = cx.get_const_i32(num_args); let args = - vec![s_ident_t, i64_max, num_args, geps.0, geps.1, geps.2, o_type, nullptr, nullptr]; + vec![s_ident_t, i64_max, num_args, geps[0], geps[1], geps[2], o_type, nullptr, nullptr]; builder.call(fn_ty, fn_to_call, &args, None); } // Step 2) let s_ident_t = generate_at_one(&cx); - let o = o_types[0]; + let o = memtransfer_types[0]; let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); generate_mapper_call(&mut builder, &cx, geps, o, begin_mapper_decl, fn_ty, num_args, s_ident_t); + let values = KernelArgsTy::new(&cx, num_args, memtransfer_types, geps); // Step 3) - // Here we will add code for the actual kernel launches in a follow-up PR. - // FIXME(offload): launch kernels + // Here we fill the KernelArgsTy, see the documentation above + for (i, value) in values.iter().enumerate() { + let ptr = builder.inbounds_gep(tgt_kernel_decl, a5, &[i32_0, cx.get_const_i32(i as u64)]); + builder.store(value.1, ptr, value.0); + } - // Step 4) - unsafe { llvm::LLVMRustPositionAfter(builder.llbuilder, kernel_call) }; + let args = vec![ + s_ident_t, + // FIXME(offload) give users a way to select which GPU to use. + cx.get_const_i64(u64::MAX), // MAX == -1. + // FIXME(offload): Don't hardcode the numbers of threads in the future. + cx.get_const_i32(2097152), + cx.get_const_i32(256), + region_ids[0], + a5, + ]; + let offload_success = builder.call(tgt_target_kernel_ty, tgt_decl, &args, None); + // %41 = call i32 @__tgt_target_kernel(ptr @1, i64 -1, i32 2097152, i32 256, ptr @.kernel_1.region_id, ptr %kernel_args) + unsafe { + let next = llvm::LLVMGetNextInstruction(offload_success).unwrap(); + llvm::LLVMRustPositionAfter(builder.llbuilder, next); + llvm::LLVMInstructionEraseFromParent(next); + } + // Step 4) let geps = get_geps(&mut builder, &cx, ty, ty2, a1, a2, a4); generate_mapper_call(&mut builder, &cx, geps, o, end_mapper_decl, fn_ty, num_args, s_ident_t); builder.call(mapper_fn_ty, unregister_lib_decl, &[tgt_bin_desc_alloca], None); - // With this we generated the following begin and end mappers. We could easily generate the - // update mapper in an update. - // call void @__tgt_target_data_begin_mapper(ptr @1, i64 -1, i32 3, ptr %27, ptr %28, ptr %29, ptr @.offload_maptypes, ptr null, ptr null) - // call void @__tgt_target_data_update_mapper(ptr @1, i64 -1, i32 2, ptr %46, ptr %47, ptr %48, ptr @.offload_maptypes.1, ptr null, ptr null) - // call void @__tgt_target_data_end_mapper(ptr @1, i64 -1, i32 3, ptr %49, ptr %50, ptr %51, ptr @.offload_maptypes, ptr null, ptr null) + drop(builder); + // FIXME(offload) The issue is that we right now add a call to the gpu version of the function, + // and then delete the call to the CPU version. In the future, we should use an intrinsic which + // directly resolves to a call to the GPU version. + unsafe { llvm::LLVMDeleteFunction(called) }; } diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 791a71d73ae58..b86b32b92df04 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -10,8 +10,7 @@ use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use tracing::debug; use crate::context::CodegenCx; -use crate::llvm; -use crate::value::Value; +use crate::llvm::{self, Value}; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 11b79a7fe68c6..b0cf9925019d2 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -12,7 +12,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hashes::Hash128; use rustc_hir::def_id::DefId; use rustc_middle::bug; -use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; +use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, PointerArithmetic, Scalar}; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::DllImport; use tracing::debug; @@ -20,9 +20,7 @@ use tracing::debug; use crate::consts::const_alloc_to_llvm; pub(crate) use crate::context::CodegenCx; use crate::context::{GenericCx, SCx}; -use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool}; -use crate::type_::Type; -use crate::value::Value; +use crate::llvm::{self, BasicBlock, ConstantInt, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value}; /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". @@ -108,6 +106,10 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { bytes_in_context(self.llcx(), bytes) } + pub(crate) fn null_terminate_const_bytes(&self, bytes: &[u8]) -> &'ll Value { + null_terminate_bytes_in_context(self.llcx(), bytes) + } + pub(crate) fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value { unsafe { let idx = c_uint::try_from(idx).expect("LLVMGetAggregateElement index overflow"); @@ -279,8 +281,8 @@ impl<'ll, 'tcx> ConstCodegenMethods for CodegenCx<'ll, 'tcx> { // This avoids generating a zero-sized constant value and actually needing a // real address at runtime. if alloc.inner().len() == 0 { - assert_eq!(offset.bytes(), 0); - let llval = self.const_usize(alloc.inner().align.bytes()); + let val = alloc.inner().align.bytes().wrapping_add(offset.bytes()); + let llval = self.const_usize(self.tcx.truncate_to_target_usize(val)); return if matches!(layout.primitive(), Pointer(_)) { unsafe { llvm::LLVMConstIntToPtr(llval, llty) } } else { @@ -381,6 +383,16 @@ pub(crate) fn bytes_in_context<'ll>(llcx: &'ll llvm::Context, bytes: &[u8]) -> & } } +pub(crate) fn null_terminate_bytes_in_context<'ll>( + llcx: &'ll llvm::Context, + bytes: &[u8], +) -> &'ll Value { + unsafe { + let ptr = bytes.as_ptr() as *const c_char; + llvm::LLVMConstStringInContext2(llcx, ptr, bytes.len(), FALSE) + } +} + pub(crate) fn named_struct<'ll>(ty: &'ll Type, elts: &[&'ll Value]) -> &'ll Value { let len = c_uint::try_from(elts.len()).expect("LLVMConstStructInContext elements len overflow"); unsafe { llvm::LLVMConstNamedStruct(ty, elts.as_ptr(), len) } diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index dc9bb743560dd..9844c9444b3d0 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -16,14 +16,14 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::ty::layout::{HasTypingEnv, LayoutOf}; use rustc_middle::ty::{self, Instance}; use rustc_middle::{bug, span_bug}; +use rustc_span::Symbol; use tracing::{debug, instrument, trace}; use crate::common::CodegenCx; use crate::errors::SymbolAlreadyDefined; -use crate::type_::Type; +use crate::llvm::{self, Type, Value}; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; -use crate::{base, debuginfo, llvm}; +use crate::{base, debuginfo}; pub(crate) fn const_alloc_to_llvm<'ll>( cx: &CodegenCx<'ll, '_>, @@ -240,11 +240,13 @@ impl<'ll> CodegenCx<'ll, '_> { let gv = self.define_global(&name, self.val_ty(cv)).unwrap_or_else(|| { bug!("symbol `{}` is already defined", name); }); - llvm::set_linkage(gv, llvm::Linkage::PrivateLinkage); gv } - _ => self.define_private_global(self.val_ty(cv)), + _ => self.define_global("", self.val_ty(cv)).unwrap_or_else(|| { + bug!("anonymous global symbol is already defined"); + }), }; + llvm::set_linkage(gv, llvm::Linkage::PrivateLinkage); llvm::set_initializer(gv, cv); set_global_alignment(self, gv, align); llvm::set_unnamed_address(gv, llvm::UnnamedAddr::Global); @@ -331,6 +333,10 @@ impl<'ll> CodegenCx<'ll, '_> { } g + } else if let Some(classname) = fn_attrs.objc_class { + self.get_objc_classref(classname) + } else if let Some(methname) = fn_attrs.objc_selector { + self.get_objc_selref(methname) } else { check_and_apply_linkage(self, fn_attrs, llty, sym, def_id) }; @@ -489,16 +495,7 @@ impl<'ll> CodegenCx<'ll, '_> { let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()); let alloc = self.create_metadata(bytes); let data = [section, alloc]; - let meta = - unsafe { llvm::LLVMMDNodeInContext2(self.llcx, data.as_ptr(), data.len()) }; - let val = self.get_metadata_value(meta); - unsafe { - llvm::LLVMAddNamedMetadataOperand( - self.llmod, - c"wasm.custom_sections".as_ptr(), - val, - ) - }; + self.module_add_named_metadata_node(self.llmod(), c"wasm.custom_sections", &data); } } else { base::set_link_section(g, attrs); @@ -543,8 +540,225 @@ impl<'ll> CodegenCx<'ll, '_> { /// Add a global value to a list to be stored in the `llvm.compiler.used` variable, /// an array of ptr. - pub(crate) fn add_compiler_used_global(&mut self, global: &'ll Value) { - self.compiler_used_statics.push(global); + pub(crate) fn add_compiler_used_global(&self, global: &'ll Value) { + self.compiler_used_statics.borrow_mut().push(global); + } + + // We do our best here to match what Clang does when compiling Objective-C natively. + // See Clang's `CGObjCCommonMac::CreateCStringLiteral`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L4134 + fn define_objc_classname(&self, classname: &str) -> &'ll Value { + assert_eq!(self.objc_abi_version(), 1); + + let llval = self.null_terminate_const_bytes(classname.as_bytes()); + let llty = self.val_ty(llval); + let sym = self.generate_local_symbol_name("OBJC_CLASS_NAME_"); + let g = self.define_global(&sym, llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", sym); + }); + set_global_alignment(self, g, self.tcx.data_layout.i8_align); + llvm::set_initializer(g, llval); + llvm::set_linkage(g, llvm::Linkage::PrivateLinkage); + llvm::set_section(g, c"__TEXT,__cstring,cstring_literals"); + llvm::LLVMSetGlobalConstant(g, llvm::TRUE); + llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global); + self.add_compiler_used_global(g); + + g + } + + // We do our best here to match what Clang does when compiling Objective-C natively. + // See Clang's `ObjCNonFragileABITypesHelper`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L6052 + fn get_objc_class_t(&self) -> &'ll Type { + if let Some(class_t) = self.objc_class_t.get() { + return class_t; + } + + assert_eq!(self.objc_abi_version(), 2); + + // struct _class_t { + // struct _class_t* isa; + // struct _class_t* const superclass; + // void* cache; + // IMP* vtable; + // struct class_ro_t* ro; + // } + + let class_t = self.type_named_struct("struct._class_t"); + let els = [self.type_ptr(); 5]; + let packed = false; + self.set_struct_body(class_t, &els, packed); + + self.objc_class_t.set(Some(class_t)); + class_t + } + + // We do our best here to match what Clang does when compiling Objective-C natively. We + // deduplicate references within a CGU, but we need a reference definition in each referencing + // CGU. All attempts at using external references to a single reference definition result in + // linker errors. + fn get_objc_classref(&self, classname: Symbol) -> &'ll Value { + let mut classrefs = self.objc_classrefs.borrow_mut(); + if let Some(classref) = classrefs.get(&classname).copied() { + return classref; + } + + let g = match self.objc_abi_version() { + 1 => { + // See Clang's `CGObjCMac::EmitClassRefFromId`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5205 + let llval = self.define_objc_classname(classname.as_str()); + let llty = self.type_ptr(); + let sym = self.generate_local_symbol_name("OBJC_CLASS_REFERENCES_"); + let g = self.define_global(&sym, llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", sym); + }); + set_global_alignment(self, g, self.tcx.data_layout.pointer_align().abi); + llvm::set_initializer(g, llval); + llvm::set_linkage(g, llvm::Linkage::PrivateLinkage); + llvm::set_section(g, c"__OBJC,__cls_refs,literal_pointers,no_dead_strip"); + self.add_compiler_used_global(g); + g + } + 2 => { + // See Clang's `CGObjCNonFragileABIMac::EmitClassRefFromId`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L7423 + let llval = { + let extern_sym = format!("OBJC_CLASS_$_{}", classname.as_str()); + let extern_llty = self.get_objc_class_t(); + self.declare_global(&extern_sym, extern_llty) + }; + let llty = self.type_ptr(); + let sym = self.generate_local_symbol_name("OBJC_CLASSLIST_REFERENCES_$_"); + let g = self.define_global(&sym, llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", sym); + }); + set_global_alignment(self, g, self.tcx.data_layout.pointer_align().abi); + llvm::set_initializer(g, llval); + llvm::set_linkage(g, llvm::Linkage::InternalLinkage); + llvm::set_section(g, c"__DATA,__objc_classrefs,regular,no_dead_strip"); + self.add_compiler_used_global(g); + g + } + _ => unreachable!(), + }; + + classrefs.insert(classname, g); + g + } + + // We do our best here to match what Clang does when compiling Objective-C natively. We + // deduplicate references within a CGU, but we need a reference definition in each referencing + // CGU. All attempts at using external references to a single reference definition result in + // linker errors. + // + // Newer versions of Apple Clang generate calls to `@"objc_msgSend$methname"` selector stub + // functions. We don't currently do that. The code we generate is closer to what Apple Clang + // generates with the `-fno-objc-msgsend-selector-stubs` option. + fn get_objc_selref(&self, methname: Symbol) -> &'ll Value { + let mut selrefs = self.objc_selrefs.borrow_mut(); + if let Some(selref) = selrefs.get(&methname).copied() { + return selref; + } + + let abi_version = self.objc_abi_version(); + + // See Clang's `CGObjCCommonMac::CreateCStringLiteral`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L4134 + let methname_llval = self.null_terminate_const_bytes(methname.as_str().as_bytes()); + let methname_llty = self.val_ty(methname_llval); + let methname_sym = self.generate_local_symbol_name("OBJC_METH_VAR_NAME_"); + let methname_g = self.define_global(&methname_sym, methname_llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", methname_sym); + }); + set_global_alignment(self, methname_g, self.tcx.data_layout.i8_align); + llvm::set_initializer(methname_g, methname_llval); + llvm::set_linkage(methname_g, llvm::Linkage::PrivateLinkage); + llvm::set_section( + methname_g, + match abi_version { + 1 => c"__TEXT,__cstring,cstring_literals", + 2 => c"__TEXT,__objc_methname,cstring_literals", + _ => unreachable!(), + }, + ); + llvm::LLVMSetGlobalConstant(methname_g, llvm::TRUE); + llvm::LLVMSetUnnamedAddress(methname_g, llvm::UnnamedAddr::Global); + self.add_compiler_used_global(methname_g); + + // See Clang's `CGObjCMac::EmitSelectorAddr`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5243 + // And Clang's `CGObjCNonFragileABIMac::EmitSelectorAddr`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L7586 + let selref_llval = methname_g; + let selref_llty = self.type_ptr(); + let selref_sym = self.generate_local_symbol_name("OBJC_SELECTOR_REFERENCES_"); + let selref_g = self.define_global(&selref_sym, selref_llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", selref_sym); + }); + set_global_alignment(self, selref_g, self.tcx.data_layout.pointer_align().abi); + llvm::set_initializer(selref_g, selref_llval); + llvm::set_externally_initialized(selref_g, true); + llvm::set_linkage( + selref_g, + match abi_version { + 1 => llvm::Linkage::PrivateLinkage, + 2 => llvm::Linkage::InternalLinkage, + _ => unreachable!(), + }, + ); + llvm::set_section( + selref_g, + match abi_version { + 1 => c"__OBJC,__message_refs,literal_pointers,no_dead_strip", + 2 => c"__DATA,__objc_selrefs,literal_pointers,no_dead_strip", + _ => unreachable!(), + }, + ); + self.add_compiler_used_global(selref_g); + + selrefs.insert(methname, selref_g); + selref_g + } + + // We do our best here to match what Clang does when compiling Objective-C natively. + // See Clang's `ObjCTypesHelper`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5936 + // And Clang's `CGObjCMac::EmitModuleInfo`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5151 + pub(crate) fn define_objc_module_info(&mut self) { + assert_eq!(self.objc_abi_version(), 1); + + // struct _objc_module { + // long version; // Hardcoded to 7 in Clang. + // long size; // sizeof(struct _objc_module) + // char* name; // Hardcoded to classname "" in Clang. + // struct _objc_symtab* symtab; // Null without class or category definitions. + // } + + let llty = self.type_named_struct("struct._objc_module"); + let i32_llty = self.type_i32(); + let ptr_llty = self.type_ptr(); + let packed = false; + self.set_struct_body(llty, &[i32_llty, i32_llty, ptr_llty, ptr_llty], packed); + + let version = self.const_uint(i32_llty, 7); + let size = self.const_uint(i32_llty, 16); + let name = self.define_objc_classname(""); + let symtab = self.const_null(ptr_llty); + let llval = crate::common::named_struct(llty, &[version, size, name, symtab]); + + let sym = "OBJC_MODULES"; + let g = self.define_global(&sym, llty).unwrap_or_else(|| { + bug!("symbol `{}` is already defined", sym); + }); + set_global_alignment(self, g, self.tcx.data_layout.pointer_align().abi); + llvm::set_initializer(g, llval); + llvm::set_linkage(g, llvm::Linkage::PrivateLinkage); + llvm::set_section(g, c"__OBJC,__module_info,regular,no_dead_strip"); + + self.add_compiler_used_global(g); } } diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index a69fa54a54a4d..808aaceab4d20 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -26,18 +26,17 @@ use rustc_session::config::{ BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, FunctionReturn, PAuthKey, PacRet, }; use rustc_span::source_map::Spanned; -use rustc_span::{DUMMY_SP, Span}; +use rustc_span::{DUMMY_SP, Span, Symbol}; use rustc_symbol_mangling::mangle_internal_symbol; use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel}; use smallvec::SmallVec; +use crate::abi::to_llvm_calling_convention; use crate::back::write::to_llvm_code_model; use crate::callee::get_fn; use crate::debuginfo::metadata::apply_vcall_visibility_metadata; -use crate::llvm::Metadata; -use crate::type_::Type; -use crate::value::Value; -use crate::{attributes, common, coverageinfo, debuginfo, llvm, llvm_util}; +use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value}; +use crate::{attributes, common, coverageinfo, debuginfo, llvm_util}; /// `TyCtxt` (and related cache datastructures) can't be move between threads. /// However, there are various cx related functions which we want to be available to the builder and @@ -119,7 +118,7 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// Statics that will be placed in the llvm.compiler.used variable /// See for details - pub compiler_used_statics: Vec<&'ll Value>, + pub compiler_used_statics: RefCell>, /// Mapping of non-scalar types to llvm types. pub type_lowering: RefCell, Option), &'ll Type>>, @@ -146,6 +145,15 @@ pub(crate) struct FullCx<'ll, 'tcx> { /// `global_asm!` needs to be able to find this new global so that it can /// compute the correct mangled symbol name to insert into the asm. pub renamed_statics: RefCell>, + + /// Cached Objective-C class type + pub objc_class_t: Cell>, + + /// Cache of Objective-C class references + pub objc_classrefs: RefCell>, + + /// Cache of Objective-C selector references + pub objc_selrefs: RefCell>, } fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode { @@ -172,35 +180,6 @@ pub(crate) unsafe fn create_module<'ll>( let mut target_data_layout = sess.target.data_layout.to_string(); let llvm_version = llvm_util::get_version(); - if llvm_version < (20, 0, 0) { - if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") { - // LLVM 20 defines three additional address spaces for alternate - // pointer kinds used in Windows. - // See https://github.com/llvm/llvm-project/pull/111879 - target_data_layout = - target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", ""); - } - if sess.target.arch.starts_with("sparc") { - // LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit. - // See https://github.com/llvm/llvm-project/pull/106951 - target_data_layout = target_data_layout.replace("-i128:128", ""); - } - if sess.target.arch.starts_with("mips64") { - // LLVM 20 updates the mips64 layout to correctly align 128 bit integers to 128 bit. - // See https://github.com/llvm/llvm-project/pull/112084 - target_data_layout = target_data_layout.replace("-i128:128", ""); - } - if sess.target.arch.starts_with("powerpc64") { - // LLVM 20 updates the powerpc64 layout to correctly align 128 bit integers to 128 bit. - // See https://github.com/llvm/llvm-project/pull/118004 - target_data_layout = target_data_layout.replace("-i128:128", ""); - } - if sess.target.arch.starts_with("wasm32") || sess.target.arch.starts_with("wasm64") { - // LLVM 20 updates the wasm(32|64) layout to correctly align 128 bit integers to 128 bit. - // See https://github.com/llvm/llvm-project/pull/119204 - target_data_layout = target_data_layout.replace("-i128:128", ""); - } - } if llvm_version < (21, 0, 0) { if sess.target.arch == "nvptx64" { // LLVM 21 updated the default layout on nvptx: https://github.com/llvm/llvm-project/pull/124961 @@ -390,7 +369,8 @@ pub(crate) unsafe fn create_module<'ll>( ); } - if let Some(BranchProtection { bti, pac_ret }) = sess.opts.unstable_opts.branch_protection { + if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection + { if sess.target.arch == "aarch64" { llvm::add_module_flag_u32( llmod, @@ -423,6 +403,12 @@ pub(crate) unsafe fn create_module<'ll>( "sign-return-address-with-bkey", u32::from(pac_opts.key == PAuthKey::B), ); + llvm::add_module_flag_u32( + llmod, + llvm::ModuleFlagMergeBehavior::Min, + "guarded-control-stack", + gcs.into(), + ); } else { bug!( "branch-protection used on non-AArch64 target; \ @@ -508,14 +494,7 @@ pub(crate) unsafe fn create_module<'ll>( format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION")); let name_metadata = cx.create_metadata(rustc_producer.as_bytes()); - - unsafe { - llvm::LLVMAddNamedMetadataOperand( - llmod, - c"llvm.ident".as_ptr(), - &cx.get_metadata_value(llvm::LLVMMDNodeInContext2(llcx, &name_metadata, 1)), - ); - } + cx.module_add_named_metadata_node(llmod, c"llvm.ident", &[name_metadata]); // Emit RISC-V specific target-abi metadata // to workaround lld as the LTO plugin not @@ -644,7 +623,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { const_globals: Default::default(), statics_to_rauw: RefCell::new(Vec::new()), used_statics: Vec::new(), - compiler_used_statics: Vec::new(), + compiler_used_statics: Default::default(), type_lowering: Default::default(), scalar_lltypes: Default::default(), coverage_cx, @@ -655,6 +634,9 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { intrinsics: Default::default(), local_gen_sym_counter: Cell::new(0), renamed_statics: Default::default(), + objc_class_t: Cell::new(None), + objc_classrefs: Default::default(), + objc_selrefs: Default::default(), }, PhantomData, ) @@ -679,6 +661,69 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { llvm::set_linkage(g, llvm::Linkage::AppendingLinkage); llvm::set_section(g, c"llvm.metadata"); } + + /// The Objective-C ABI that is used. + /// + /// This corresponds to the `-fobjc-abi-version=` flag in Clang / GCC. + pub(crate) fn objc_abi_version(&self) -> u32 { + assert!(self.tcx.sess.target.is_like_darwin); + if self.tcx.sess.target.arch == "x86" && self.tcx.sess.target.os == "macos" { + // 32-bit x86 macOS uses ABI version 1 (a.k.a. the "fragile ABI"). + 1 + } else { + // All other Darwin-like targets we support use ABI version 2 + // (a.k.a the "non-fragile ABI"). + 2 + } + } + + // We do our best here to match what Clang does when compiling Objective-C natively. + // See Clang's `CGObjCCommonMac::EmitImageInfo`: + // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5085 + pub(crate) fn add_objc_module_flags(&self) { + let abi_version = self.objc_abi_version(); + + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Error, + "Objective-C Version", + abi_version, + ); + + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Error, + "Objective-C Image Info Version", + 0, + ); + + llvm::add_module_flag_str( + self.llmod, + llvm::ModuleFlagMergeBehavior::Error, + "Objective-C Image Info Section", + match abi_version { + 1 => "__OBJC,__image_info,regular", + 2 => "__DATA,__objc_imageinfo,regular,no_dead_strip", + _ => unreachable!(), + }, + ); + + if self.tcx.sess.target.env == "sim" { + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Error, + "Objective-C Is Simulated", + 1 << 5, + ); + } + + llvm::add_module_flag_u32( + self.llmod, + llvm::ModuleFlagMergeBehavior::Error, + "Objective-C Class Properties", + 1 << 6, + ); + } } impl<'ll> SimpleCx<'ll> { pub(crate) fn get_type_of_global(&self, val: &'ll Value) -> &'ll Type { @@ -694,7 +739,7 @@ impl<'ll> SimpleCx<'ll> { llcx: &'ll llvm::Context, pointer_size: Size, ) -> Self { - let isize_ty = llvm::Type::ix_llcx(llcx, pointer_size.bits()); + let isize_ty = llvm::LLVMIntTypeInContext(llcx, pointer_size.bits() as c_uint); Self(SCx { llmod, llcx, isize_ty }, PhantomData) } } @@ -823,7 +868,7 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } else { let fty = self.type_variadic_func(&[], self.type_i32()); let llfn = self.declare_cfn(name, llvm::UnnamedAddr::Global, fty); - let target_cpu = attributes::target_cpu_attr(self); + let target_cpu = attributes::target_cpu_attr(self, self.sess()); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]); llfn } @@ -838,15 +883,15 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn set_frame_pointer_type(&self, llfn: &'ll Value) { - if let Some(attr) = attributes::frame_pointer_type_attr(self) { + if let Some(attr) = attributes::frame_pointer_type_attr(self, self.sess()) { attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]); } } fn apply_target_cpu_attr(&self, llfn: &'ll Value) { let mut attrs = SmallVec::<[_; 2]>::new(); - attrs.push(attributes::target_cpu_attr(self)); - attrs.extend(attributes::tune_cpu_attr(self)); + attrs.push(attributes::target_cpu_attr(self, self.sess())); + attrs.extend(attributes::tune_cpu_attr(self, self.sess())); attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &attrs); } @@ -855,17 +900,14 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { if self.get_declared_value(entry_name).is_none() { let llfn = self.declare_entry_fn( entry_name, - llvm::CallConv::from_conv( - self.sess().target.entry_abi, - self.sess().target.arch.borrow(), - ), + to_llvm_calling_convention(self.sess(), self.sess().target.entry_abi), llvm::UnnamedAddr::Global, fn_type, ); attributes::apply_to_llfn( llfn, llvm::AttributePlace::Function, - attributes::target_features_attr(self, vec![]).as_slice(), + attributes::target_features_attr(self, self.tcx, vec![]).as_slice(), ); Some(llfn) } else { @@ -949,15 +991,75 @@ impl CodegenCx<'_, '_> { } impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { + /// Wrapper for `LLVMMDNodeInContext2`, i.e. `llvm::MDNode::get`. + pub(crate) fn md_node_in_context(&self, md_list: &[&'ll Metadata]) -> &'ll Metadata { + unsafe { llvm::LLVMMDNodeInContext2(self.llcx(), md_list.as_ptr(), md_list.len()) } + } + /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`. pub(crate) fn set_metadata<'a>( &self, val: &'a Value, - kind_id: impl Into, + kind_id: MetadataKindId, md: &'ll Metadata, ) { let node = self.get_metadata_value(md); - llvm::LLVMSetMetadata(val, kind_id.into(), node); + llvm::LLVMSetMetadata(val, kind_id, node); + } + + /// Helper method for the sequence of calls: + /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata) + /// - `LLVMMetadataAsValue` (to adapt that node to an `llvm::Value`) + /// - `LLVMSetMetadata` (to set that node as metadata of `kind_id` for `instruction`) + pub(crate) fn set_metadata_node( + &self, + instruction: &'ll Value, + kind_id: MetadataKindId, + md_list: &[&'ll Metadata], + ) { + let md = self.md_node_in_context(md_list); + self.set_metadata(instruction, kind_id, md); + } + + /// Helper method for the sequence of calls: + /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata) + /// - `LLVMMetadataAsValue` (to adapt that node to an `llvm::Value`) + /// - `LLVMAddNamedMetadataOperand` (to set that node as metadata of `kind_name` for `module`) + pub(crate) fn module_add_named_metadata_node( + &self, + module: &'ll Module, + kind_name: &CStr, + md_list: &[&'ll Metadata], + ) { + let md = self.md_node_in_context(md_list); + let md_as_val = self.get_metadata_value(md); + unsafe { llvm::LLVMAddNamedMetadataOperand(module, kind_name.as_ptr(), md_as_val) }; + } + + /// Helper method for the sequence of calls: + /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata) + /// - `LLVMRustGlobalAddMetadata` (to set that node as metadata of `kind_id` for `global`) + pub(crate) fn global_add_metadata_node( + &self, + global: &'ll Value, + kind_id: MetadataKindId, + md_list: &[&'ll Metadata], + ) { + let md = self.md_node_in_context(md_list); + unsafe { llvm::LLVMRustGlobalAddMetadata(global, kind_id, md) }; + } + + /// Helper method for the sequence of calls: + /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata) + /// - `LLVMGlobalSetMetadata` (to set that node as metadata of `kind_id` for `global`) + pub(crate) fn global_set_metadata_node( + &self, + global: &'ll Value, + kind_id: MetadataKindId, + md_list: &[&'ll Metadata], + ) { + let md = self.md_node_in_context(md_list); + unsafe { llvm::LLVMGlobalSetMetadata(global, kind_id, md) }; } } @@ -991,7 +1093,10 @@ impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> { impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { - if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err { + if let LayoutError::SizeOverflow(_) + | LayoutError::ReferencesError(_) + | LayoutError::InvalidSimd { .. } = err + { self.tcx.dcx().emit_fatal(Spanned { span, node: err.into_diagnostic() }) } else { self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err }) @@ -1008,7 +1113,11 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { match err { - FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::Cycle(_)) => { + FnAbiError::Layout( + LayoutError::SizeOverflow(_) + | LayoutError::Cycle(_) + | LayoutError::InvalidSimd { .. }, + ) => { self.tcx.dcx().emit_fatal(Spanned { span, node: err }); } _ => match fn_abi_request { diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs index a4b60d420f3fb..caa36c5dd4992 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs @@ -1,5 +1,3 @@ -use rustc_middle::mir::coverage::{CounterId, CovTerm, ExpressionId}; - /// Must match the layout of `LLVMRustCounterKind`. #[derive(Copy, Clone, Debug)] #[repr(C)] @@ -26,30 +24,12 @@ pub(crate) enum CounterKind { pub(crate) struct Counter { // Important: The layout (order and types of fields) must match its C++ counterpart. pub(crate) kind: CounterKind, - id: u32, + pub(crate) id: u32, } impl Counter { /// A `Counter` of kind `Zero`. For this counter kind, the `id` is not used. pub(crate) const ZERO: Self = Self { kind: CounterKind::Zero, id: 0 }; - - /// Constructs a new `Counter` of kind `CounterValueReference`. - pub(crate) fn counter_value_reference(counter_id: CounterId) -> Self { - Self { kind: CounterKind::CounterValueReference, id: counter_id.as_u32() } - } - - /// Constructs a new `Counter` of kind `Expression`. - pub(crate) fn expression(expression_id: ExpressionId) -> Self { - Self { kind: CounterKind::Expression, id: expression_id.as_u32() } - } - - pub(crate) fn from_term(term: CovTerm) -> Self { - match term { - CovTerm::Zero => Self::ZERO, - CovTerm::Counter(id) => Self::counter_value_reference(id), - CovTerm::Expression(id) => Self::expression(id), - } - } } /// Corresponds to enum `llvm::coverage::CounterExpression::ExprKind`. @@ -94,29 +74,6 @@ pub(crate) struct CoverageSpan { pub(crate) end_col: u32, } -/// Holds tables of the various region types in one struct. -/// -/// Don't pass this struct across FFI; pass the individual region tables as -/// pointer/length pairs instead. -/// -/// Each field name has a `_regions` suffix for improved readability after -/// exhaustive destructing, which ensures that all region types are handled. -#[derive(Clone, Debug, Default)] -pub(crate) struct Regions { - pub(crate) code_regions: Vec, - pub(crate) expansion_regions: Vec, - pub(crate) branch_regions: Vec, -} - -impl Regions { - /// Returns true if none of this structure's tables contain any regions. - pub(crate) fn has_no_regions(&self) -> bool { - let Self { code_regions, expansion_regions, branch_regions } = self; - - code_regions.is_empty() && expansion_regions.is_empty() && branch_regions.is_empty() - } -} - /// Must match the layout of `LLVMRustCoverageCodeRegion`. #[derive(Clone, Debug)] #[repr(C)] diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs index bc4f6bb6a82bc..a58202834cfa5 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/llvm_cov.rs @@ -2,26 +2,25 @@ use std::ffi::CString; -use crate::common::AsCCharPtr; use crate::coverageinfo::ffi; use crate::llvm; pub(crate) fn covmap_var_name() -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovmapVarNameToString(s); })) .expect("covmap variable name should not contain NUL") } pub(crate) fn covmap_section_name(llmod: &llvm::Module) -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovmapSectionNameToString(llmod, s); })) .expect("covmap section name should not contain NUL") } pub(crate) fn covfun_section_name(llmod: &llvm::Module) -> CString { - CString::new(llvm::build_byte_buffer(|s| unsafe { + CString::new(llvm::build_byte_buffer(|s| { llvm::LLVMRustCoverageWriteCovfunSectionNameToString(llmod, s); })) .expect("covfun section name should not contain NUL") @@ -34,7 +33,7 @@ pub(crate) fn create_pgo_func_name_var<'ll>( unsafe { llvm::LLVMRustCoverageCreatePGOFuncNameVar( llfn, - mangled_fn_name.as_c_char_ptr(), + mangled_fn_name.as_ptr(), mangled_fn_name.len(), ) } @@ -44,7 +43,7 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef]) -> Vec, Vec<_>>(); llvm::build_byte_buffer(|buffer| unsafe { @@ -58,12 +57,35 @@ pub(crate) fn write_filenames_to_buffer(filenames: &[impl AsRef]) -> Vec, + pub(crate) expansion_regions: Vec, + pub(crate) branch_regions: Vec, +} + +impl Regions { + /// Returns true if none of this structure's tables contain any regions. + pub(crate) fn has_no_regions(&self) -> bool { + let Self { code_regions, expansion_regions, branch_regions } = self; + + code_regions.is_empty() && expansion_regions.is_empty() && branch_regions.is_empty() + } +} + pub(crate) fn write_function_mappings_to_buffer( virtual_file_mapping: &[u32], expressions: &[ffi::CounterExpression], - regions: &ffi::Regions, + regions: &Regions, ) -> Vec { - let ffi::Regions { code_regions, expansion_regions, branch_regions } = regions; + let Regions { code_regions, expansion_regions, branch_regions } = regions; // SAFETY: // - All types are FFI-compatible and have matching representations in Rust/C++. @@ -89,12 +111,12 @@ pub(crate) fn write_function_mappings_to_buffer( /// Hashes some bytes into a 64-bit hash, via LLVM's `IndexedInstrProf::ComputeHash`, /// as required for parts of the LLVM coverage mapping format. pub(crate) fn hash_bytes(bytes: &[u8]) -> u64 { - unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_c_char_ptr(), bytes.len()) } + unsafe { llvm::LLVMRustCoverageHashBytes(bytes.as_ptr(), bytes.len()) } } /// Returns LLVM's `coverage::CovMapVersion::CurrentVersion` (CoverageMapping.h) /// as a raw numeric value. For historical reasons, the numeric value is 1 less /// than the number in the version's name, so `Version7` is actually `6u32`. pub(crate) fn mapping_version() -> u32 { - unsafe { llvm::LLVMRustCoverageMappingVersion() } + llvm::LLVMRustCoverageMappingVersion() } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index d1cb95507d91c..7e873347c82b0 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -6,7 +6,6 @@ use rustc_abi::Align; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods}; use rustc_data_structures::fx::FxIndexMap; use rustc_index::IndexVec; -use rustc_macros::TryFromU32; use rustc_middle::ty::TyCtxt; use rustc_session::RemapFileNameExt; use rustc_session::config::RemapPathScopeComponents; @@ -16,7 +15,7 @@ use tracing::debug; use crate::common::CodegenCx; use crate::coverageinfo::llvm_cov; use crate::coverageinfo::mapgen::covfun::prepare_covfun_record; -use crate::llvm; +use crate::{TryFromU32, llvm}; mod covfun; mod spans; diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs index e0da8d368762b..7835d18046860 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen/covfun.rs @@ -10,8 +10,8 @@ use std::sync::Arc; use rustc_abi::Align; use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods as _, ConstCodegenMethods}; use rustc_middle::mir::coverage::{ - BasicCoverageBlock, CovTerm, CoverageIdsInfo, Expression, FunctionCoverageInfo, Mapping, - MappingKind, Op, + BasicCoverageBlock, CounterId, CovTerm, CoverageIdsInfo, Expression, ExpressionId, + FunctionCoverageInfo, Mapping, MappingKind, Op, }; use rustc_middle::ty::{Instance, TyCtxt}; use rustc_span::{SourceFile, Span}; @@ -36,7 +36,7 @@ pub(crate) struct CovfunRecord<'tcx> { virtual_file_mapping: VirtualFileMapping, expressions: Vec, - regions: ffi::Regions, + regions: llvm_cov::Regions, } impl<'tcx> CovfunRecord<'tcx> { @@ -64,7 +64,7 @@ pub(crate) fn prepare_covfun_record<'tcx>( is_used, virtual_file_mapping: VirtualFileMapping::default(), expressions, - regions: ffi::Regions::default(), + regions: llvm_cov::Regions::default(), }; fill_region_tables(tcx, fn_cov_info, ids_info, &mut covfun); @@ -77,10 +77,21 @@ pub(crate) fn prepare_covfun_record<'tcx>( Some(covfun) } +pub(crate) fn counter_for_term(term: CovTerm) -> ffi::Counter { + use ffi::Counter; + match term { + CovTerm::Zero => Counter::ZERO, + CovTerm::Counter(id) => { + Counter { kind: ffi::CounterKind::CounterValueReference, id: CounterId::as_u32(id) } + } + CovTerm::Expression(id) => { + Counter { kind: ffi::CounterKind::Expression, id: ExpressionId::as_u32(id) } + } + } +} + /// Convert the function's coverage-counter expressions into a form suitable for FFI. fn prepare_expressions(ids_info: &CoverageIdsInfo) -> Vec { - let counter_for_term = ffi::Counter::from_term; - // We know that LLVM will optimize out any unused expressions before // producing the final coverage map, so there's no need to do the same // thing on the Rust side unless we're confident we can do much better. @@ -113,7 +124,7 @@ fn fill_region_tables<'tcx>( } else { CovTerm::Zero }; - ffi::Counter::from_term(term) + counter_for_term(term) }; // Currently a function's mappings must all be in the same file, so use the @@ -136,7 +147,7 @@ fn fill_region_tables<'tcx>( if discard_all { None } else { spans::make_coords(source_map, &source_file, span) } }; - let ffi::Regions { + let llvm_cov::Regions { code_regions, expansion_regions: _, // FIXME(Zalathar): Fill out support for expansion regions branch_regions, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs new file mode 100644 index 0000000000000..5d874631ca1ac --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/debuginfo/di_builder.rs @@ -0,0 +1,69 @@ +use libc::c_uint; +use rustc_abi::Align; + +use crate::llvm::debuginfo::DIBuilder; +use crate::llvm::{self, ToLlvmBool}; + +/// Extension trait for defining safe wrappers and helper methods on +/// `&DIBuilder<'ll>`, without requiring it to be defined in the same crate. +pub(crate) trait DIBuilderExt<'ll> { + fn as_di_builder(&self) -> &DIBuilder<'ll>; + + fn create_expression(&self, addr_ops: &[u64]) -> &'ll llvm::Metadata { + let this = self.as_di_builder(); + unsafe { llvm::LLVMDIBuilderCreateExpression(this, addr_ops.as_ptr(), addr_ops.len()) } + } + + fn create_static_variable( + &self, + scope: Option<&'ll llvm::Metadata>, + name: &str, + linkage_name: &str, + file: &'ll llvm::Metadata, + line_number: c_uint, + ty: &'ll llvm::Metadata, + is_local_to_unit: bool, + val: &'ll llvm::Value, + decl: Option<&'ll llvm::Metadata>, + align: Option, + ) -> &'ll llvm::Metadata { + let this = self.as_di_builder(); + let align_in_bits = align.map_or(0, |align| align.bits() as u32); + + // `LLVMDIBuilderCreateGlobalVariableExpression` would assert if we + // gave it a null `Expr` pointer, so give it an empty expression + // instead, which is what the C++ `createGlobalVariableExpression` + // method would do if given a null `DIExpression` pointer. + let expr = self.create_expression(&[]); + + let global_var_expr = unsafe { + llvm::LLVMDIBuilderCreateGlobalVariableExpression( + this, + scope, + name.as_ptr(), + name.len(), + linkage_name.as_ptr(), + linkage_name.len(), + file, + line_number, + ty, + is_local_to_unit.to_llvm_bool(), + expr, + decl, + align_in_bits, + ) + }; + + unsafe { llvm::LLVMGlobalSetMetadata(val, llvm::MD_dbg, global_var_expr) }; + + global_var_expr + } +} + +impl<'ll> DIBuilderExt<'ll> for &DIBuilder<'ll> { + fn as_di_builder(&self) -> &DIBuilder<'ll> { + self + } + + // All other methods have default bodies that rely on `as_di_builder`. +} diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs index 408429152223d..52d04625749b9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/dwarf_const.rs @@ -35,3 +35,6 @@ declare_constant!(DW_OP_plus_uconst: u64); /// Double-checked by a static assertion in `RustWrapper.cpp`. #[allow(non_upper_case_globals)] pub(crate) const DW_OP_LLVM_fragment: u64 = 0x1000; +// It describes the actual value of a source variable which might not exist in registers or in memory. +#[allow(non_upper_case_globals)] +pub(crate) const DW_OP_stack_value: u64 = 0x9f; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index 7a6dc008c7b9e..3a750b6b53eb1 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -2,15 +2,14 @@ use rustc_codegen_ssa::base::collect_debugger_visualizers_transitive; use rustc_codegen_ssa::traits::*; +use rustc_hir::attrs::DebuggerVisualizerType; use rustc_hir::def_id::LOCAL_CRATE; use rustc_middle::bug; -use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerType; use rustc_session::config::{CrateType, DebugInfo}; use crate::builder::Builder; use crate::common::CodegenCx; -use crate::llvm; -use crate::value::Value; +use crate::llvm::{self, Value}; /// Inserts a side-effect free instruction sequence that makes sure that the /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index dc3a84b6a151a..5535ebe65859e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -32,19 +32,16 @@ use self::type_map::{DINodeCreationResult, Stub, UniqueTypeId}; use super::CodegenUnitDebugContext; use super::namespace::mangled_name_of_instance; use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name}; -use super::utils::{ - DIB, create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, -}; +use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit}; use crate::common::{AsCCharPtr, CodegenCx}; -use crate::debuginfo::dwarf_const; use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind}; -use crate::llvm; +use crate::debuginfo::{DIBuilderExt, dwarf_const}; use crate::llvm::debuginfo::{ DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind, DebugNameTableKind, }; -use crate::value::Value; +use crate::llvm::{self, FromGeneric, Value}; impl PartialEq for llvm::Metadata { fn eq(&self, other: &Self) -> bool { @@ -119,17 +116,17 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>( .try_to_target_usize(cx.tcx) .expect("expected monomorphic const in codegen") as c_longlong; - let subrange = - unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) }; + let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound) }; + let subscripts = &[subrange]; - let subscripts = create_DIArray(DIB(cx), &[subrange]); let di_node = unsafe { - llvm::LLVMRustDIBuilderCreateArrayType( + llvm::LLVMDIBuilderCreateArrayType( DIB(cx), size.bits(), align.bits() as u32, element_type_di_node, - subscripts, + subscripts.as_ptr(), + subscripts.len() as c_uint, ) }; @@ -175,17 +172,13 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( "ptr_type={ptr_type}, pointee_type={pointee_type}", ); - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - pointee_type_di_node, - pointer_size.bits(), - pointer_align.abi.bits() as u32, - 0, // Ignore DWARF address space. - ptr_type_debuginfo_name.as_c_char_ptr(), - ptr_type_debuginfo_name.len(), - ) - }; + let di_node = create_pointer_type( + cx, + pointee_type_di_node, + pointer_size, + pointer_align.abi, + &ptr_type_debuginfo_name, + ); DINodeCreationResult { di_node, already_stored_in_typemap: false } } @@ -233,17 +226,13 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>( // The data pointer type is a regular, thin pointer, regardless of whether this // is a slice or a trait object. - let data_ptr_type_di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - pointee_type_di_node, - addr_field.size.bits(), - addr_field.align.abi.bits() as u32, - 0, // Ignore DWARF address space. - std::ptr::null(), - 0, - ) - }; + let data_ptr_type_di_node = create_pointer_type( + cx, + pointee_type_di_node, + addr_field.size, + addr_field.align.abi, + "", + ); smallvec![ build_field_di_node( @@ -318,7 +307,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id); - let fn_di_node = create_subroutine_type(cx, create_DIArray(DIB(cx), &signature_di_nodes[..])); + let fn_di_node = create_subroutine_type(cx, &signature_di_nodes[..]); // This is actually a function pointer, so wrap it in pointer DI. let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false); @@ -329,26 +318,44 @@ fn build_subroutine_type_di_node<'ll, 'tcx>( } _ => unreachable!(), }; - let di_node = unsafe { - llvm::LLVMRustDIBuilderCreatePointerType( - DIB(cx), - fn_di_node, - size.bits(), - align.bits() as u32, - 0, // Ignore DWARF address space. - name.as_c_char_ptr(), - name.len(), - ) - }; + let di_node = create_pointer_type(cx, fn_di_node, size, align, &name); DINodeCreationResult::new(di_node, false) } pub(super) fn create_subroutine_type<'ll>( cx: &CodegenCx<'ll, '_>, - signature: &'ll DICompositeType, + signature: &[Option<&'ll llvm::Metadata>], ) -> &'ll DICompositeType { - unsafe { llvm::LLVMRustDIBuilderCreateSubroutineType(DIB(cx), signature) } + unsafe { + llvm::LLVMDIBuilderCreateSubroutineType( + DIB(cx), + None, // ("File" is ignored and has no effect) + signature.as_ptr(), + signature.len() as c_uint, + DIFlags::FlagZero, // (default value) + ) + } +} + +fn create_pointer_type<'ll>( + cx: &CodegenCx<'ll, '_>, + pointee_ty: &'ll llvm::Metadata, + size: Size, + align: Align, + name: &str, +) -> &'ll llvm::Metadata { + unsafe { + llvm::LLVMDIBuilderCreatePointerType( + DIB(cx), + pointee_ty, + size.bits(), + align.bits() as u32, + 0, // Ignore DWARF address space. + name.as_ptr(), + name.len(), + ) + } } /// Create debuginfo for `dyn SomeTrait` types. Currently these are empty structs @@ -469,8 +476,8 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>( ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id), ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id), ty::Adt(def, ..) => match def.adt_kind() { - AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id), - AdtKind::Union => build_union_type_di_node(cx, unique_type_id), + AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id, span), + AdtKind::Union => build_union_type_di_node(cx, unique_type_id, span), AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span), }, ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id), @@ -813,14 +820,15 @@ fn build_basic_type_di_node<'ll, 'tcx>( }; let typedef_di_node = unsafe { - llvm::LLVMRustDIBuilderCreateTypedef( + llvm::LLVMDIBuilderCreateTypedef( DIB(cx), ty_di_node, - typedef_name.as_c_char_ptr(), + typedef_name.as_ptr(), typedef_name.len(), unknown_file_metadata(cx), - 0, - None, + 0, // (no line number) + None, // (no scope) + 0u32, // (no alignment specified) ) }; @@ -834,12 +842,13 @@ fn create_basic_type<'ll, 'tcx>( encoding: u32, ) -> &'ll DIBasicType { unsafe { - llvm::LLVMRustDIBuilderCreateBasicType( + llvm::LLVMDIBuilderCreateBasicType( DIB(cx), - name.as_c_char_ptr(), + name.as_ptr(), name.len(), size.bits(), encoding, + DIFlags::FlagZero, ) } } @@ -1025,15 +1034,15 @@ fn create_member_type<'ll, 'tcx>( type_di_node: &'ll DIType, ) -> &'ll DIType { unsafe { - llvm::LLVMRustDIBuilderCreateMemberType( + llvm::LLVMDIBuilderCreateMemberType( DIB(cx), owner, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), file_metadata, line_number, layout.size.bits(), - layout.align.abi.bits() as u32, + layout.align.bits() as u32, offset.bits(), flags, type_di_node, @@ -1066,6 +1075,7 @@ fn visibility_di_flags<'ll, 'tcx>( fn build_struct_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, unique_type_id: UniqueTypeId<'tcx>, + span: Span, ) -> DINodeCreationResult<'ll> { let struct_type = unique_type_id.expect_ty(); let ty::Adt(adt_def, _) = struct_type.kind() else { @@ -1073,7 +1083,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( }; assert!(adt_def.is_struct()); let containing_scope = get_namespace_for_item(cx, adt_def.did()); - let struct_type_and_layout = cx.layout_of(struct_type); + let struct_type_and_layout = cx.spanned_layout_of(struct_type, span); let variant_def = adt_def.non_enum_variant(); let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { Some(file_metadata_from_def_id(cx, Some(adt_def.did()))) @@ -1266,6 +1276,7 @@ fn build_closure_env_di_node<'ll, 'tcx>( fn build_union_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, unique_type_id: UniqueTypeId<'tcx>, + span: Span, ) -> DINodeCreationResult<'ll> { let union_type = unique_type_id.expect_ty(); let (union_def_id, variant_def) = match union_type.kind() { @@ -1273,7 +1284,7 @@ fn build_union_type_di_node<'ll, 'tcx>( _ => bug!("build_union_type_di_node on a non-ADT"), }; let containing_scope = get_namespace_for_item(cx, union_def_id); - let union_ty_and_layout = cx.layout_of(union_type); + let union_ty_and_layout = cx.spanned_layout_of(union_type, span); let type_name = compute_debuginfo_type_name(cx.tcx, union_type, false); let def_location = if cx.sess().opts.unstable_opts.debug_info_type_line_numbers { Some(file_metadata_from_def_id(cx, Some(union_def_id))) @@ -1399,23 +1410,18 @@ pub(crate) fn build_global_var_di_node<'ll>( let global_align = cx.align_of(variable_type); - unsafe { - llvm::LLVMRustDIBuilderCreateStaticVariable( - DIB(cx), - Some(var_scope), - var_name.as_c_char_ptr(), - var_name.len(), - linkage_name.as_c_char_ptr(), - linkage_name.len(), - file_metadata, - line_number, - type_di_node, - is_local_to_unit, - global, - None, - global_align.bits() as u32, - ); - } + DIB(cx).create_static_variable( + Some(var_scope), + var_name, + linkage_name, + file_metadata, + line_number, + type_di_node, + is_local_to_unit, + global, // (value) + None, // (decl) + Some(global_align), + ); } /// Generates LLVM debuginfo for a vtable. @@ -1595,21 +1601,11 @@ pub(crate) fn apply_vcall_visibility_metadata<'ll, 'tcx>( let trait_ref_typeid = typeid_for_trait_ref(cx.tcx, trait_ref); let typeid = cx.create_metadata(trait_ref_typeid.as_bytes()); - unsafe { - let v = [llvm::LLVMValueAsMetadata(cx.const_usize(0)), typeid]; - llvm::LLVMRustGlobalAddMetadata( - vtable, - llvm::MD_type as c_uint, - llvm::LLVMMDNodeInContext2(cx.llcx, v.as_ptr(), v.len()), - ); - let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64)); - let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1); - llvm::LLVMGlobalSetMetadata( - vtable, - llvm::MetadataType::MD_vcall_visibility as c_uint, - vcall_visibility_metadata, - ); - } + let type_ = [llvm::LLVMValueAsMetadata(cx.const_usize(0)), typeid]; + cx.global_add_metadata_node(vtable, llvm::MD_type, &type_); + + let vcall_visibility = [llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64))]; + cx.global_set_metadata_node(vtable, llvm::MD_vcall_visibility, &vcall_visibility); } /// Creates debug information for the given vtable, which is for the @@ -1642,25 +1638,19 @@ pub(crate) fn create_vtable_di_node<'ll, 'tcx>( let vtable_name = compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::GlobalVariable); let vtable_type_di_node = build_vtable_type_di_node(cx, ty, poly_trait_ref); - let linkage_name = ""; - unsafe { - llvm::LLVMRustDIBuilderCreateStaticVariable( - DIB(cx), - NO_SCOPE_METADATA, - vtable_name.as_c_char_ptr(), - vtable_name.len(), - linkage_name.as_c_char_ptr(), - linkage_name.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, - vtable_type_di_node, - true, - vtable, - None, - 0, - ); - } + DIB(cx).create_static_variable( + NO_SCOPE_METADATA, + &vtable_name, + "", // (linkage_name) + unknown_file_metadata(cx), + UNKNOWN_LINE_NUMBER, + vtable_type_di_node, + true, // (is_local_to_unit) + vtable, // (value) + None, // (decl) + None::, + ); } /// Creates an "extension" of an existing `DIScope` into another file. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index a5c808957410e..4ecc3086e1bdf 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty}; use smallvec::smallvec; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::dwarf_const::DW_TAG_const_type; use crate::debuginfo::metadata::enums::DiscrResult; use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId}; @@ -378,20 +378,17 @@ fn build_single_variant_union_fields<'ll, 'tcx>( variant_struct_type_wrapper_di_node, None, ), - unsafe { - llvm::LLVMRustDIBuilderCreateStaticMemberType( - DIB(cx), - enum_type_di_node, - TAG_FIELD_NAME.as_c_char_ptr(), - TAG_FIELD_NAME.len(), - unknown_file_metadata(cx), - UNKNOWN_LINE_NUMBER, - variant_names_type_di_node, - visibility_flags, - Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)), - tag_base_type_align.bits() as u32, - ) - } + create_static_member_type( + cx, + enum_type_di_node, + TAG_FIELD_NAME, + unknown_file_metadata(cx), + UNKNOWN_LINE_NUMBER, + variant_names_type_di_node, + visibility_flags, + Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)), + tag_base_type_align, + ), ] } @@ -570,27 +567,28 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( let build_assoc_const = |name: &str, type_di_node_: &'ll DIType, value: u64, - align: Align| unsafe { + align: Align| + -> &'ll llvm::Metadata { // FIXME: Currently we force all DISCR_* values to be u64's as LLDB seems to have // problems inspecting other value types. Since DISCR_* is typically only going to be // directly inspected via the debugger visualizer - which compares it to the `tag` value // (whose type is not modified at all) it shouldn't cause any real problems. let (t_di, align) = if name == ASSOC_CONST_DISCR_NAME { - (type_di_node_, align.bits() as u32) + (type_di_node_, align) } else { let ty_u64 = Ty::new_uint(cx.tcx, ty::UintTy::U64); - (type_di_node(cx, ty_u64), Align::EIGHT.bits() as u32) + (type_di_node(cx, ty_u64), Align::EIGHT) }; // must wrap type in a `const` modifier for LLDB to be able to inspect the value of the member - let field_type = - llvm::LLVMRustDIBuilderCreateQualifiedType(DIB(cx), DW_TAG_const_type, t_di); + let field_type = unsafe { + llvm::LLVMDIBuilderCreateQualifiedType(DIB(cx), DW_TAG_const_type, t_di) + }; - llvm::LLVMRustDIBuilderCreateStaticMemberType( - DIB(cx), + create_static_member_type( + cx, wrapper_struct_type_di_node, - name.as_c_char_ptr(), - name.len(), + name, unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER, field_type, @@ -975,3 +973,30 @@ fn variant_struct_wrapper_type_name(variant_index: VariantIdx) -> Cow<'static, s .map(|&s| Cow::from(s)) .unwrap_or_else(|| format!("Variant{}", variant_index.as_usize()).into()) } + +fn create_static_member_type<'ll>( + cx: &CodegenCx<'ll, '_>, + scope: &'ll llvm::Metadata, + name: &str, + file: &'ll llvm::Metadata, + line_number: c_uint, + ty: &'ll llvm::Metadata, + flags: DIFlags, + value: Option<&'ll llvm::Value>, + align: Align, +) -> &'ll llvm::Metadata { + unsafe { + llvm::LLVMDIBuilderCreateStaticMemberType( + DIB(cx), + scope, + name.as_ptr(), + name.len(), + file, + line_number, + ty, + flags, + value, + align.bits() as c_uint, + ) + } +} diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index 62d38d463aba7..1ae6e6e5eecab 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -289,7 +289,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( file_metadata, line_number, enum_type_and_layout.size.bits(), - enum_type_and_layout.align.abi.bits() as u32, + enum_type_and_layout.align.bits() as u32, DIFlags::FlagZero, tag_member_di_node, create_DIArray(DIB(cx), &[]), @@ -449,7 +449,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( file_di_node, line_number, enum_type_and_layout.size.bits(), - enum_type_and_layout.align.abi.bits() as u32, + enum_type_and_layout.align.bits() as u32, Size::ZERO.bits(), discr, DIFlags::FlagZero, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs index 18a783a348a45..37200fdc41afa 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/type_map.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; +use libc::c_uint; use rustc_abi::{Align, Size, VariantIdx}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; @@ -9,7 +10,7 @@ use rustc_middle::bug; use rustc_middle::ty::{self, ExistentialTraitRef, Ty, TyCtxt}; use super::{DefinitionLocation, SmallVec, UNKNOWN_LINE_NUMBER, unknown_file_metadata}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::utils::{DIB, create_DIArray, debug_context}; use crate::llvm::debuginfo::{DIFlags, DIScope, DIType}; use crate::llvm::{self}; @@ -191,7 +192,7 @@ pub(super) fn stub<'ll, 'tcx>( containing_scope: Option<&'ll DIScope>, flags: DIFlags, ) -> StubInfo<'ll, 'tcx> { - let empty_array = create_DIArray(DIB(cx), &[]); + let no_elements: &[Option<&llvm::Metadata>] = &[]; let unique_type_id_str = unique_type_id.generate_unique_id_string(cx.tcx); let (file_metadata, line_number) = if let Some(def_location) = def_location { @@ -207,10 +208,10 @@ pub(super) fn stub<'ll, 'tcx>( _ => None, }; unsafe { - llvm::LLVMRustDIBuilderCreateStructType( + llvm::LLVMDIBuilderCreateStructType( DIB(cx), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), file_metadata, line_number, @@ -218,28 +219,30 @@ pub(super) fn stub<'ll, 'tcx>( align.bits() as u32, flags, None, - empty_array, - 0, + no_elements.as_ptr(), + no_elements.len() as c_uint, + 0u32, // (Objective-C runtime version; default is 0) vtable_holder, - unique_type_id_str.as_c_char_ptr(), + unique_type_id_str.as_ptr(), unique_type_id_str.len(), ) } } Stub::Union => unsafe { - llvm::LLVMRustDIBuilderCreateUnionType( + llvm::LLVMDIBuilderCreateUnionType( DIB(cx), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), file_metadata, line_number, size.bits(), align.bits() as u32, flags, - Some(empty_array), - 0, - unique_type_id_str.as_c_char_ptr(), + no_elements.as_ptr(), + no_elements.len() as c_uint, + 0u32, // (Objective-C runtime version; default is 0) + unique_type_id_str.as_ptr(), unique_type_id_str.len(), ) }, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 79334f7f9fe84..b95ad03b70e03 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -28,6 +28,9 @@ use rustc_target::spec::DebuginfoKind; use smallvec::SmallVec; use tracing::debug; +use self::create_scope_map::compute_mir_scopes; +pub(crate) use self::di_builder::DIBuilderExt; +pub(crate) use self::metadata::build_global_var_di_node; use self::metadata::{ UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, spanned_type_di_node, type_di_node, }; @@ -35,32 +38,20 @@ use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use crate::builder::Builder; use crate::common::{AsCCharPtr, CodegenCx}; -use crate::llvm; use crate::llvm::debuginfo::{ DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DITemplateTypeParameter, DIType, DIVariable, }; -use crate::value::Value; +use crate::llvm::{self, Value}; mod create_scope_map; +mod di_builder; mod dwarf_const; mod gdb; pub(crate) mod metadata; mod namespace; mod utils; -use self::create_scope_map::compute_mir_scopes; -pub(crate) use self::metadata::build_global_var_di_node; - -// FIXME(Zalathar): These `DW_TAG_*` constants are fake values that were -// removed from LLVM in 2015, and are only used by our own `RustWrapper.cpp` -// to decide which C++ API to call. Instead, we should just have two separate -// FFI functions and choose the correct one on the Rust side. -#[allow(non_upper_case_globals)] -const DW_TAG_auto_variable: c_uint = 0x100; -#[allow(non_upper_case_globals)] -const DW_TAG_arg_variable: c_uint = 0x101; - /// A context object for maintaining all state needed by the debuginfo module. pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { llmod: &'ll llvm::Module, @@ -165,16 +156,64 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { variable_alloca: Self::Value, direct_offset: Size, indirect_offsets: &[Size], - fragment: Option>, + fragment: &Option>, ) { use dwarf_const::{DW_OP_LLVM_fragment, DW_OP_deref, DW_OP_plus_uconst}; // Convert the direct and indirect offsets and fragment byte range to address ops. let mut addr_ops = SmallVec::<[u64; 8]>::new(); + if direct_offset.bytes() > 0 { + addr_ops.push(DW_OP_plus_uconst); + addr_ops.push(direct_offset.bytes()); + } + for &offset in indirect_offsets { + addr_ops.push(DW_OP_deref); + if offset.bytes() > 0 { + addr_ops.push(DW_OP_plus_uconst); + addr_ops.push(offset.bytes()); + } + } + if let Some(fragment) = fragment { + // `DW_OP_LLVM_fragment` takes as arguments the fragment's + // offset and size, both of them in bits. + addr_ops.push(DW_OP_LLVM_fragment); + addr_ops.push(fragment.start.bits()); + addr_ops.push((fragment.end - fragment.start).bits()); + } + + let di_builder = DIB(self.cx()); + let addr_expr = di_builder.create_expression(&addr_ops); + unsafe { + llvm::LLVMDIBuilderInsertDeclareRecordAtEnd( + di_builder, + variable_alloca, + dbg_var, + addr_expr, + dbg_loc, + self.llbb(), + ) + }; + } + + fn dbg_var_value( + &mut self, + dbg_var: &'ll DIVariable, + dbg_loc: &'ll DILocation, + value: Self::Value, + direct_offset: Size, + indirect_offsets: &[Size], + fragment: &Option>, + ) { + use dwarf_const::{DW_OP_LLVM_fragment, DW_OP_deref, DW_OP_plus_uconst, DW_OP_stack_value}; + + // Convert the direct and indirect offsets and fragment byte range to address ops. + let mut addr_ops = SmallVec::<[u64; 8]>::new(); + if direct_offset.bytes() > 0 { addr_ops.push(DW_OP_plus_uconst); addr_ops.push(direct_offset.bytes() as u64); + addr_ops.push(DW_OP_stack_value); } for &offset in indirect_offsets { addr_ops.push(DW_OP_deref); @@ -191,14 +230,16 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> { addr_ops.push((fragment.end - fragment.start).bits() as u64); } + let di_builder = DIB(self.cx()); + let addr_expr = unsafe { + llvm::LLVMDIBuilderCreateExpression(di_builder, addr_ops.as_ptr(), addr_ops.len()) + }; unsafe { - // FIXME(eddyb) replace `llvm.dbg.declare` with `llvm.dbg.addr`. - llvm::LLVMRustDIBuilderInsertDeclareAtEnd( - DIB(self.cx()), - variable_alloca, + llvm::LLVMDIBuilderInsertDbgValueRecordAtEnd( + di_builder, + value, dbg_var, - addr_ops.as_ptr(), - addr_ops.len() as c_uint, + addr_expr, dbg_loc, self.llbb(), ); @@ -349,7 +390,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let file_metadata = file_metadata(self, &loc.file); let function_type_metadata = - create_subroutine_type(self, get_function_signature(self, fn_abi)); + create_subroutine_type(self, &get_function_signature(self, fn_abi)); let mut name = String::with_capacity(64); type_names::push_item_name(tcx, def_id, false, &mut name); @@ -441,9 +482,9 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn get_function_signature<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, - ) -> &'ll DIArray { + ) -> Vec> { if cx.sess().opts.debuginfo != DebugInfo::Full { - return create_DIArray(DIB(cx), &[]); + return vec![]; } let mut signature = Vec::with_capacity(fn_abi.args.len() + 1); @@ -484,7 +525,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { .extend(fn_abi.args.iter().map(|arg| Some(type_di_node(cx, arg.layout.ty)))); } - create_DIArray(DIB(cx), &signature[..]) + signature } fn get_template_parameters<'ll, 'tcx>( @@ -630,28 +671,39 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { let type_metadata = spanned_type_di_node(self, variable_type, span); - let (argument_index, dwarf_tag) = match variable_kind { - ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable => (0, DW_TAG_auto_variable), - }; let align = self.align_of(variable_type); let name = variable_name.as_str(); - unsafe { - llvm::LLVMRustDIBuilderCreateVariable( - DIB(self), - dwarf_tag, - scope_metadata, - name.as_c_char_ptr(), - name.len(), - file_metadata, - loc.line, - type_metadata, - true, - DIFlags::FlagZero, - argument_index, - align.bits() as u32, - ) + + match variable_kind { + ArgumentVariable(arg_index) => unsafe { + llvm::LLVMDIBuilderCreateParameterVariable( + DIB(self), + scope_metadata, + name.as_ptr(), + name.len(), + arg_index as c_uint, + file_metadata, + loc.line, + type_metadata, + llvm::Bool::TRUE, // (preserve descriptor during optimizations) + DIFlags::FlagZero, + ) + }, + LocalVariable => unsafe { + llvm::LLVMDIBuilderCreateAutoVariable( + DIB(self), + scope_metadata, + name.as_ptr(), + name.len(), + file_metadata, + loc.line, + type_metadata, + llvm::Bool::TRUE, // (preserve descriptor during optimizations) + DIFlags::FlagZero, + align.bits() as u32, + ) + }, } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index cc1d504b43017..7e1e49310f61c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -28,7 +28,7 @@ pub(crate) fn create_DIArray<'ll>( builder: &DIBuilder<'ll>, arr: &[Option<&'ll DIDescriptor>], ) -> &'ll DIArray { - unsafe { llvm::LLVMRustDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) } + unsafe { llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len()) } } #[inline] diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 960a895a2031c..8f69f176138cf 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -23,13 +23,11 @@ use smallvec::SmallVec; use tracing::debug; use crate::abi::FnAbiLlvmExt; +use crate::attributes; use crate::common::AsCCharPtr; use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx}; use crate::llvm::AttributePlace::Function; -use crate::llvm::Visibility; -use crate::type_::Type; -use crate::value::Value; -use crate::{attributes, llvm}; +use crate::llvm::{self, FromGeneric, Type, Value, Visibility}; /// Declare a function with a SimpleCx. /// @@ -76,7 +74,7 @@ pub(crate) fn declare_raw_fn<'ll, 'tcx>( attrs.push(llvm::AttributeKind::NoRedZone.create_attr(cx.llcx)); } - attrs.extend(attributes::non_lazy_bind_attr(cx)); + attrs.extend(attributes::non_lazy_bind_attr(cx, cx.tcx.sess)); attributes::apply_to_llfn(llfn, Function, &attrs); @@ -232,13 +230,6 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { } } - /// Declare a private global - /// - /// Use this function when you intend to define a global without a name. - pub(crate) fn define_private_global(&self, ty: &'ll Type) -> &'ll Value { - unsafe { llvm::LLVMRustInsertPrivateGlobal(self.llmod(), ty) } - } - /// Gets declared value by name. pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { debug!("get_declared_value(name={:?})", name); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 85f71f331a491..14b3f3626efe9 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -18,7 +18,6 @@ use rustc_middle::{bug, span_bug}; use rustc_span::{Span, Symbol, sym}; use rustc_symbol_mangling::{mangle_internal_symbol, symbol_name_for_instance_in_crate}; use rustc_target::callconv::PassMode; -use rustc_target::spec::PanicStrategy; use tracing::debug; use crate::abi::FnAbiLlvmExt; @@ -26,11 +25,9 @@ use crate::builder::Builder; use crate::builder::autodiff::{adjust_activity_to_abi, generate_enzyme_call}; use crate::context::CodegenCx; use crate::errors::AutoDiffWithoutEnable; -use crate::llvm::{self, Metadata}; -use crate::type_::Type; +use crate::llvm::{self, Metadata, Type, Value}; use crate::type_of::LayoutLlvmExt; use crate::va_arg::emit_va_arg; -use crate::value::Value; fn call_simple_intrinsic<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, @@ -298,7 +295,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let align = if name == sym::unaligned_volatile_load { 1 } else { - result.layout.align.abi.bytes() as u32 + result.layout.align.bytes() as u32 }; unsafe { llvm::LLVMSetAlignment(load, align); @@ -674,7 +671,7 @@ fn catch_unwind_intrinsic<'ll, 'tcx>( catch_func: &'ll Value, dest: PlaceRef<'tcx, &'ll Value>, ) { - if bx.sess().panic_strategy() == PanicStrategy::Abort { + if !bx.sess().panic_strategy().unwinds() { let try_func_ty = bx.type_func(&[bx.type_ptr()], bx.type_void()); bx.call(try_func_ty, None, None, try_func, &[data], None, None); // Return 0 unconditionally from the intrinsic call; @@ -1048,7 +1045,7 @@ fn codegen_emcc_try<'ll, 'tcx>( // create an alloca and pass a pointer to that. let ptr_size = bx.tcx().data_layout.pointer_size(); let ptr_align = bx.tcx().data_layout.pointer_align().abi; - let i8_align = bx.tcx().data_layout.i8_align.abi; + let i8_align = bx.tcx().data_layout.i8_align; // Required in order for there to be no padding between the fields. assert!(i8_align <= ptr_align); let catch_data = bx.alloca(2 * ptr_size, ptr_align); @@ -1208,10 +1205,14 @@ fn codegen_autodiff<'ll, 'tcx>( adjust_activity_to_abi( tcx, - fn_source.ty(tcx, TypingEnv::fully_monomorphized()), + fn_source, + TypingEnv::fully_monomorphized(), &mut diff_attrs.input_activity, ); + let fnc_tree = + rustc_middle::ty::fnc_typetrees(tcx, fn_source.ty(tcx, TypingEnv::fully_monomorphized())); + // Build body generate_enzyme_call( bx, @@ -1222,6 +1223,7 @@ fn codegen_autodiff<'ll, 'tcx>( &val_arr, diff_attrs.clone(), result, + fnc_tree, ); } @@ -1323,6 +1325,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }; } + let llvm_version = crate::llvm_util::get_version(); + /// Converts a vector mask, where each element has a bit width equal to the data elements it is used with, /// down to an i1 based mask that can be used by llvm intrinsics. /// @@ -1806,7 +1810,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); + let alignment = bx.align_of(in_elem).bytes(); // Truncate the mask vector to a vector of i1s: let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); @@ -1817,11 +1821,23 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len); - return Ok(bx.call_intrinsic( - "llvm.masked.gather", - &[llvm_elem_vec_ty, llvm_pointer_vec_ty], - &[args[1].immediate(), alignment, mask, args[0].immediate()], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[1].immediate(), alignment, mask, args[0].immediate()] + } else { + &[args[1].immediate(), mask, args[0].immediate()] + }; + + let call = + bx.call_intrinsic("llvm.masked.gather", &[llvm_elem_vec_ty, llvm_pointer_vec_ty], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(0), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_masked_load { @@ -1889,18 +1905,30 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); + let alignment = bx.align_of(values_elem).bytes(); let llvm_pointer = bx.type_ptr(); // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len); - return Ok(bx.call_intrinsic( - "llvm.masked.load", - &[llvm_elem_vec_ty, llvm_pointer], - &[args[1].immediate(), alignment, mask, args[2].immediate()], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + + &[args[1].immediate(), alignment, mask, args[2].immediate()] + } else { + &[args[1].immediate(), mask, args[2].immediate()] + }; + + let call = bx.call_intrinsic("llvm.masked.load", &[llvm_elem_vec_ty, llvm_pointer], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(0), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_masked_store { @@ -1962,18 +1990,29 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let mask = vector_mask_to_bitmask(bx, args[0].immediate(), m_elem_bitwidth, mask_len); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(values_elem).bytes() as i32); + let alignment = bx.align_of(values_elem).bytes(); let llvm_pointer = bx.type_ptr(); // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, values_elem, values_len); - return Ok(bx.call_intrinsic( - "llvm.masked.store", - &[llvm_elem_vec_ty, llvm_pointer], - &[args[2].immediate(), args[1].immediate(), alignment, mask], - )); + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[2].immediate(), args[1].immediate(), alignment, mask] + } else { + &[args[2].immediate(), args[1].immediate(), mask] + }; + + let call = bx.call_intrinsic("llvm.masked.store", &[llvm_elem_vec_ty, llvm_pointer], args); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(1), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } if name == sym::simd_scatter { @@ -2038,7 +2077,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( ); // Alignment of T, must be a constant integer value: - let alignment = bx.const_i32(bx.align_of(in_elem).bytes() as i32); + let alignment = bx.align_of(in_elem).bytes(); // Truncate the mask vector to a vector of i1s: let mask = vector_mask_to_bitmask(bx, args[2].immediate(), mask_elem_bitwidth, in_len); @@ -2048,12 +2087,25 @@ fn generic_simd_intrinsic<'ll, 'tcx>( // Type of the vector of elements: let llvm_elem_vec_ty = llvm_vector_ty(bx, element_ty0, in_len); - - return Ok(bx.call_intrinsic( + let args: &[&'ll Value] = if llvm_version < (22, 0, 0) { + let alignment = bx.const_i32(alignment as i32); + &[args[0].immediate(), args[1].immediate(), alignment, mask] + } else { + &[args[0].immediate(), args[1].immediate(), mask] + }; + let call = bx.call_intrinsic( "llvm.masked.scatter", &[llvm_elem_vec_ty, llvm_pointer_vec_ty], - &[args[0].immediate(), args[1].immediate(), alignment, mask], - )); + args, + ); + if llvm_version >= (22, 0, 0) { + crate::attributes::apply_to_callsite( + call, + crate::llvm::AttributePlace::Argument(1), + &[crate::llvm::CreateAlignmentAttr(bx.llcx, alignment)], + ) + } + return Ok(call); } macro_rules! arith_red { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 6fb23d0984335..982d5cd3ac418 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -14,6 +14,7 @@ #![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] +#![feature(macro_derive)] #![feature(rustdoc_internals)] #![feature(slice_as_array)] #![feature(try_blocks)] @@ -29,7 +30,7 @@ use back::write::{create_informational_target_machine, create_target_machine}; use context::SimpleCx; use errors::ParseTargetMachineConfig; use llvm_util::target_config; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::AllocatorMethod; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, @@ -45,6 +46,9 @@ use rustc_middle::util::Providers; use rustc_session::Session; use rustc_session::config::{OptLevel, OutputFilenames, PrintKind, PrintRequest}; use rustc_span::Symbol; +use rustc_target::spec::{RelocModel, TlsModel}; + +use crate::llvm::ToLlvmBool; mod abi; mod allocator; @@ -64,14 +68,18 @@ mod errors; mod intrinsic; mod llvm; mod llvm_util; +mod macros; mod mono_item; mod type_; mod type_of; +mod typetree; mod va_arg; mod value; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } +pub(crate) use macros::TryFromU32; + #[derive(Clone)] pub struct LlvmCodegenBackend(()); @@ -101,14 +109,13 @@ impl ExtraBackendMethods for LlvmCodegenBackend { &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) -> ModuleLlvm { let module_llvm = ModuleLlvm::new_metadata(tcx, module_name); let cx = SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size()); unsafe { - allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, cx, module_name, methods); } module_llvm } @@ -230,6 +237,10 @@ impl CodegenBackend for LlvmCodegenBackend { crate::DEFAULT_LOCALE_RESOURCE } + fn name(&self) -> &'static str { + "llvm" + } + fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited } @@ -244,16 +255,7 @@ impl CodegenBackend for LlvmCodegenBackend { match req.kind { PrintKind::RelocationModels => { writeln!(out, "Available relocation models:").unwrap(); - for name in &[ - "static", - "pic", - "pie", - "dynamic-no-pic", - "ropi", - "rwpi", - "ropi-rwpi", - "default", - ] { + for name in RelocModel::ALL.iter().map(RelocModel::desc).chain(["default"]) { writeln!(out, " {name}").unwrap(); } writeln!(out).unwrap(); @@ -267,9 +269,7 @@ impl CodegenBackend for LlvmCodegenBackend { } PrintKind::TlsModels => { writeln!(out, "Available TLS models:").unwrap(); - for name in - &["global-dynamic", "local-dynamic", "initial-exec", "local-exec", "emulated"] - { + for name in TlsModel::ALL.iter().map(TlsModel::desc) { writeln!(out, " {name}").unwrap(); } writeln!(out).unwrap(); @@ -359,7 +359,14 @@ impl CodegenBackend for LlvmCodegenBackend { // Run the linker on any artifacts that resulted from the LLVM run. // This should produce either a finished executable or library. - link_binary(sess, &LlvmArchiveBuilderBuilder, codegen_results, metadata, outputs); + link_binary( + sess, + &LlvmArchiveBuilderBuilder, + codegen_results, + metadata, + outputs, + self.name(), + ); } } @@ -378,7 +385,8 @@ unsafe impl Sync for ModuleLlvm {} impl ModuleLlvm { fn new(tcx: TyCtxt<'_>, mod_name: &str) -> Self { unsafe { - let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); + let llcx = llvm::LLVMContextCreate(); + llvm::LLVMContextSetDiscardValueNames(llcx, tcx.sess.fewer_names().to_llvm_bool()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; ModuleLlvm { llmod_raw, @@ -390,7 +398,8 @@ impl ModuleLlvm { fn new_metadata(tcx: TyCtxt<'_>, mod_name: &str) -> Self { unsafe { - let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names()); + let llcx = llvm::LLVMContextCreate(); + llvm::LLVMContextSetDiscardValueNames(llcx, tcx.sess.fewer_names().to_llvm_bool()); let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _; ModuleLlvm { llmod_raw, @@ -421,7 +430,8 @@ impl ModuleLlvm { dcx: DiagCtxtHandle<'_>, ) -> Self { unsafe { - let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names); + let llcx = llvm::LLVMContextCreate(); + llvm::LLVMContextSetDiscardValueNames(llcx, cgcx.fewer_names.to_llvm_bool()); let llmod_raw = back::lto::parse_module(llcx, name, buffer, dcx); let tm = ModuleLlvm::tm_from_cgcx(cgcx, name.to_str().unwrap(), dcx); diff --git a/compiler/rustc_codegen_llvm/src/llvm/conversions.rs b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs new file mode 100644 index 0000000000000..9e9f9339ade85 --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/llvm/conversions.rs @@ -0,0 +1,115 @@ +//! Conversions from backend-independent data types to/from LLVM FFI types. + +use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate}; +use rustc_middle::ty::AtomicOrdering; +use rustc_session::config::DebugInfo; +use rustc_target::spec::SymbolVisibility; + +use crate::llvm; + +/// Helper trait for converting backend-independent types to LLVM-specific +/// types, for FFI purposes. +pub(crate) trait FromGeneric { + fn from_generic(other: T) -> Self; +} + +impl FromGeneric for llvm::Visibility { + fn from_generic(visibility: SymbolVisibility) -> Self { + match visibility { + SymbolVisibility::Hidden => Self::Hidden, + SymbolVisibility::Protected => Self::Protected, + SymbolVisibility::Interposable => Self::Default, + } + } +} + +impl FromGeneric for llvm::IntPredicate { + fn from_generic(int_pred: IntPredicate) -> Self { + match int_pred { + IntPredicate::IntEQ => Self::IntEQ, + IntPredicate::IntNE => Self::IntNE, + IntPredicate::IntUGT => Self::IntUGT, + IntPredicate::IntUGE => Self::IntUGE, + IntPredicate::IntULT => Self::IntULT, + IntPredicate::IntULE => Self::IntULE, + IntPredicate::IntSGT => Self::IntSGT, + IntPredicate::IntSGE => Self::IntSGE, + IntPredicate::IntSLT => Self::IntSLT, + IntPredicate::IntSLE => Self::IntSLE, + } + } +} + +impl FromGeneric for llvm::RealPredicate { + fn from_generic(real_pred: RealPredicate) -> Self { + match real_pred { + RealPredicate::RealPredicateFalse => Self::RealPredicateFalse, + RealPredicate::RealOEQ => Self::RealOEQ, + RealPredicate::RealOGT => Self::RealOGT, + RealPredicate::RealOGE => Self::RealOGE, + RealPredicate::RealOLT => Self::RealOLT, + RealPredicate::RealOLE => Self::RealOLE, + RealPredicate::RealONE => Self::RealONE, + RealPredicate::RealORD => Self::RealORD, + RealPredicate::RealUNO => Self::RealUNO, + RealPredicate::RealUEQ => Self::RealUEQ, + RealPredicate::RealUGT => Self::RealUGT, + RealPredicate::RealUGE => Self::RealUGE, + RealPredicate::RealULT => Self::RealULT, + RealPredicate::RealULE => Self::RealULE, + RealPredicate::RealUNE => Self::RealUNE, + RealPredicate::RealPredicateTrue => Self::RealPredicateTrue, + } + } +} + +impl FromGeneric for llvm::AtomicRmwBinOp { + fn from_generic(op: AtomicRmwBinOp) -> Self { + match op { + AtomicRmwBinOp::AtomicXchg => Self::AtomicXchg, + AtomicRmwBinOp::AtomicAdd => Self::AtomicAdd, + AtomicRmwBinOp::AtomicSub => Self::AtomicSub, + AtomicRmwBinOp::AtomicAnd => Self::AtomicAnd, + AtomicRmwBinOp::AtomicNand => Self::AtomicNand, + AtomicRmwBinOp::AtomicOr => Self::AtomicOr, + AtomicRmwBinOp::AtomicXor => Self::AtomicXor, + AtomicRmwBinOp::AtomicMax => Self::AtomicMax, + AtomicRmwBinOp::AtomicMin => Self::AtomicMin, + AtomicRmwBinOp::AtomicUMax => Self::AtomicUMax, + AtomicRmwBinOp::AtomicUMin => Self::AtomicUMin, + } + } +} + +impl FromGeneric for llvm::AtomicOrdering { + fn from_generic(ordering: AtomicOrdering) -> Self { + match ordering { + AtomicOrdering::Relaxed => Self::Monotonic, + AtomicOrdering::Acquire => Self::Acquire, + AtomicOrdering::Release => Self::Release, + AtomicOrdering::AcqRel => Self::AcquireRelease, + AtomicOrdering::SeqCst => Self::SequentiallyConsistent, + } + } +} + +impl FromGeneric for llvm::debuginfo::DebugEmissionKind { + fn from_generic(kind: DebugInfo) -> Self { + // We should be setting LLVM's emission kind to `LineTablesOnly` if + // we are compiling with "limited" debuginfo. However, some of the + // existing tools relied on slightly more debuginfo being generated than + // would be the case with `LineTablesOnly`, and we did not want to break + // these tools in a "drive-by fix", without a good idea or plan about + // what limited debuginfo should exactly look like. So for now we are + // instead adding a new debuginfo option "line-tables-only" so as to + // not break anything and to allow users to have 'limited' debug info. + // + // See https://github.com/rust-lang/rust/issues/60020 for details. + match kind { + DebugInfo::None => Self::NoDebug, + DebugInfo::LineDirectivesOnly => Self::DebugDirectivesOnly, + DebugInfo::LineTablesOnly => Self::LineTablesOnly, + DebugInfo::Limited | DebugInfo::Full => Self::FullDebug, + } + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs index 0e0f2b0eab016..59b2cd329ae76 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs @@ -6,7 +6,7 @@ use rustc_span::InnerSpan; pub(crate) use self::Diagnostic::*; use self::OptimizationDiagnosticKind::*; use super::{DiagnosticInfo, SMDiagnostic}; -use crate::value::Value; +use crate::llvm::Value; #[derive(Copy, Clone, Debug)] pub(crate) enum OptimizationDiagnosticKind { diff --git a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs index 56d756e52cce1..e63043b21227f 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs @@ -3,9 +3,36 @@ use libc::{c_char, c_uint}; use super::MetadataKindId; -use super::ffi::{AttributeKind, BasicBlock, Metadata, Module, Type, Value}; +use super::ffi::{AttributeKind, BasicBlock, Context, Metadata, Module, Type, Value}; use crate::llvm::{Bool, Builder}; +// TypeTree types +pub(crate) type CTypeTreeRef = *mut EnzymeTypeTree; + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub(crate) struct EnzymeTypeTree { + _unused: [u8; 0], +} + +#[repr(u32)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[allow(non_camel_case_types)] +pub(crate) enum CConcreteType { + DT_Anything = 0, + DT_Integer = 1, + DT_Pointer = 2, + DT_Half = 3, + DT_Float = 4, + DT_Double = 5, + DT_Unknown = 6, + DT_FP128 = 9, +} + +pub(crate) struct TypeTree { + pub(crate) inner: CTypeTreeRef, +} + #[link(name = "llvm-wrapper", kind = "static")] unsafe extern "C" { // Enzyme @@ -59,19 +86,49 @@ pub(crate) enum LLVMRustVerifierFailureAction { LLVMReturnStatusAction = 2, } -#[cfg(llvm_enzyme)] +#[cfg(feature = "llvm_enzyme")] pub(crate) use self::Enzyme_AD::*; -#[cfg(llvm_enzyme)] +#[cfg(feature = "llvm_enzyme")] pub(crate) mod Enzyme_AD { use std::ffi::{CString, c_char}; use libc::c_void; + use super::{CConcreteType, CTypeTreeRef, Context}; + unsafe extern "C" { pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8); pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char); } + + // TypeTree functions + unsafe extern "C" { + pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef; + pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef; + pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef; + pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef); + pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool; + pub(crate) fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64); + pub(crate) fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef); + pub(crate) fn EnzymeTypeTreeShiftIndiciesEq( + arg1: CTypeTreeRef, + data_layout: *const c_char, + offset: i64, + max_size: i64, + add_offset: u64, + ); + pub(crate) fn EnzymeTypeTreeInsertEq( + CTT: CTypeTreeRef, + indices: *const i64, + len: usize, + ct: CConcreteType, + ctx: &Context, + ); + pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char; + pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char); + } + unsafe extern "C" { static mut EnzymePrintPerf: c_void; static mut EnzymePrintActivity: c_void; @@ -134,13 +191,74 @@ pub(crate) mod Enzyme_AD { } } -#[cfg(not(llvm_enzyme))] +#[cfg(not(feature = "llvm_enzyme"))] pub(crate) use self::Fallback_AD::*; -#[cfg(not(llvm_enzyme))] +#[cfg(not(feature = "llvm_enzyme"))] pub(crate) mod Fallback_AD { #![allow(unused_variables)] + use libc::c_char; + + use super::{CConcreteType, CTypeTreeRef, Context}; + + // TypeTree function fallbacks + pub(crate) unsafe fn EnzymeNewTypeTree() -> CTypeTreeRef { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeFreeTypeTree(CTT: CTypeTreeRef) { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64) { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef) { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeShiftIndiciesEq( + arg1: CTypeTreeRef, + data_layout: *const c_char, + offset: i64, + max_size: i64, + add_offset: u64, + ) { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeInsertEq( + CTT: CTypeTreeRef, + indices: *const i64, + len: usize, + ct: CConcreteType, + ctx: &Context, + ) { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char { + unimplemented!() + } + + pub(crate) unsafe fn EnzymeTypeTreeToStringFree(arg1: *const c_char) { + unimplemented!() + } + pub(crate) fn set_inline(val: bool) { unimplemented!() } @@ -169,3 +287,89 @@ pub(crate) mod Fallback_AD { unimplemented!() } } + +impl TypeTree { + pub(crate) fn new() -> TypeTree { + let inner = unsafe { EnzymeNewTypeTree() }; + TypeTree { inner } + } + + pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree { + let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) }; + TypeTree { inner } + } + + pub(crate) fn merge(self, other: Self) -> Self { + unsafe { + EnzymeMergeTypeTree(self.inner, other.inner); + } + drop(other); + self + } + + #[must_use] + pub(crate) fn shift( + self, + layout: &str, + offset: isize, + max_size: isize, + add_offset: usize, + ) -> Self { + let layout = std::ffi::CString::new(layout).unwrap(); + + unsafe { + EnzymeTypeTreeShiftIndiciesEq( + self.inner, + layout.as_ptr(), + offset as i64, + max_size as i64, + add_offset as u64, + ); + } + + self + } + + pub(crate) fn insert(&mut self, indices: &[i64], ct: CConcreteType, ctx: &Context) { + unsafe { + EnzymeTypeTreeInsertEq(self.inner, indices.as_ptr(), indices.len(), ct, ctx); + } + } +} + +impl Clone for TypeTree { + fn clone(&self) -> Self { + let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) }; + TypeTree { inner } + } +} + +impl std::fmt::Display for TypeTree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let ptr = unsafe { EnzymeTypeTreeToString(self.inner) }; + let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) }; + match cstr.to_str() { + Ok(x) => write!(f, "{}", x)?, + Err(err) => write!(f, "could not parse: {}", err)?, + } + + // delete C string pointer + unsafe { + EnzymeTypeTreeToStringFree(ptr); + } + + Ok(()) + } +} + +impl std::fmt::Debug for TypeTree { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + ::fmt(self, f) + } +} + +impl Drop for TypeTree { + fn drop(&mut self) { + unsafe { EnzymeFreeTypeTree(self.inner) } + } +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 0679f55ab7f08..2456ed2e46d67 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -19,16 +19,15 @@ use std::ptr; use bitflags::bitflags; use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t}; -use rustc_macros::TryFromU32; -use rustc_target::spec::SymbolVisibility; use super::RustString; use super::debuginfo::{ - DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator, - DIFile, DIFlags, DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram, - DISubrange, DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, DebugNameTableKind, + DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags, DILocation, + DISPFlags, DIScope, DISubprogram, DITemplateTypeParameter, DIType, DebugEmissionKind, + DebugNameTableKind, }; -use crate::llvm; +use crate::llvm::MetadataKindId; +use crate::{TryFromU32, llvm}; /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`, /// which has a different ABI from Rust or C++ `bool`. @@ -219,16 +218,6 @@ pub(crate) enum Visibility { Protected = 2, } -impl Visibility { - pub(crate) fn from_generic(visibility: SymbolVisibility) -> Self { - match visibility { - SymbolVisibility::Hidden => Visibility::Hidden, - SymbolVisibility::Protected => Visibility::Protected, - SymbolVisibility::Interposable => Visibility::Default, - } - } -} - /// LLVMUnnamedAddr #[repr(C)] pub(crate) enum UnnamedAddr { @@ -318,24 +307,6 @@ pub(crate) enum IntPredicate { IntSLE = 41, } -impl IntPredicate { - pub(crate) fn from_generic(intpre: rustc_codegen_ssa::common::IntPredicate) -> Self { - use rustc_codegen_ssa::common::IntPredicate as Common; - match intpre { - Common::IntEQ => Self::IntEQ, - Common::IntNE => Self::IntNE, - Common::IntUGT => Self::IntUGT, - Common::IntUGE => Self::IntUGE, - Common::IntULT => Self::IntULT, - Common::IntULE => Self::IntULE, - Common::IntSGT => Self::IntSGT, - Common::IntSGE => Self::IntSGE, - Common::IntSLT => Self::IntSLT, - Common::IntSLE => Self::IntSLE, - } - } -} - /// LLVMRealPredicate #[derive(Copy, Clone)] #[repr(C)] @@ -358,30 +329,6 @@ pub(crate) enum RealPredicate { RealPredicateTrue = 15, } -impl RealPredicate { - pub(crate) fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self { - use rustc_codegen_ssa::common::RealPredicate as Common; - match realp { - Common::RealPredicateFalse => Self::RealPredicateFalse, - Common::RealOEQ => Self::RealOEQ, - Common::RealOGT => Self::RealOGT, - Common::RealOGE => Self::RealOGE, - Common::RealOLT => Self::RealOLT, - Common::RealOLE => Self::RealOLE, - Common::RealONE => Self::RealONE, - Common::RealORD => Self::RealORD, - Common::RealUNO => Self::RealUNO, - Common::RealUEQ => Self::RealUEQ, - Common::RealUGT => Self::RealUGT, - Common::RealUGE => Self::RealUGE, - Common::RealULT => Self::RealULT, - Common::RealULE => Self::RealULE, - Common::RealUNE => Self::RealUNE, - Common::RealPredicateTrue => Self::RealPredicateTrue, - } - } -} - /// Must match the layout of `LLVMTypeKind`. /// /// Use [`RawEnum`] for values of `LLVMTypeKind` returned from LLVM, @@ -457,25 +404,6 @@ pub(crate) enum AtomicRmwBinOp { AtomicUMin = 10, } -impl AtomicRmwBinOp { - pub(crate) fn from_generic(op: rustc_codegen_ssa::common::AtomicRmwBinOp) -> Self { - use rustc_codegen_ssa::common::AtomicRmwBinOp as Common; - match op { - Common::AtomicXchg => Self::AtomicXchg, - Common::AtomicAdd => Self::AtomicAdd, - Common::AtomicSub => Self::AtomicSub, - Common::AtomicAnd => Self::AtomicAnd, - Common::AtomicNand => Self::AtomicNand, - Common::AtomicOr => Self::AtomicOr, - Common::AtomicXor => Self::AtomicXor, - Common::AtomicMax => Self::AtomicMax, - Common::AtomicMin => Self::AtomicMin, - Common::AtomicUMax => Self::AtomicUMax, - Common::AtomicUMin => Self::AtomicUMin, - } - } -} - /// LLVMAtomicOrdering #[derive(Copy, Clone)] #[repr(C)] @@ -492,19 +420,6 @@ pub(crate) enum AtomicOrdering { SequentiallyConsistent = 7, } -impl AtomicOrdering { - pub(crate) fn from_generic(ao: rustc_middle::ty::AtomicOrdering) -> Self { - use rustc_middle::ty::AtomicOrdering as Common; - match ao { - Common::Relaxed => Self::Monotonic, - Common::Acquire => Self::Acquire, - Common::Release => Self::Release, - Common::AcqRel => Self::AcquireRelease, - Common::SeqCst => Self::SequentiallyConsistent, - } - } -} - /// LLVMRustFileType #[derive(Copy, Clone)] #[repr(C)] @@ -513,31 +428,6 @@ pub(crate) enum FileType { ObjectFile, } -/// LLVMMetadataType -#[derive(Copy, Clone)] -#[repr(C)] -#[expect(dead_code, reason = "Some variants are unused, but are kept to match LLVM-C")] -pub(crate) enum MetadataType { - MD_dbg = 0, - MD_tbaa = 1, - MD_prof = 2, - MD_fpmath = 3, - MD_range = 4, - MD_tbaa_struct = 5, - MD_invariant_load = 6, - MD_alias_scope = 7, - MD_noalias = 8, - MD_nontemporal = 9, - MD_mem_parallel_loop_access = 10, - MD_nonnull = 11, - MD_unpredictable = 15, - MD_align = 17, - MD_type = 19, - MD_vcall_visibility = 28, - MD_noundef = 29, - MD_kcfi_type = 36, -} - /// Must match the layout of `LLVMInlineAsmDialect`. #[derive(Copy, Clone, PartialEq)] #[repr(C)] @@ -710,6 +600,7 @@ pub(crate) enum MemoryEffects { None, ReadOnly, InaccessibleMemOnly, + ReadOnlyNotPure, } /// LLVMOpcode @@ -806,6 +697,8 @@ unsafe extern "C" { pub(crate) type Metadata; pub(crate) type BasicBlock; pub(crate) type Comdat; + /// `&'ll DbgRecord` represents `LLVMDbgRecordRef`. + pub(crate) type DbgRecord; } #[repr(C)] pub(crate) struct Builder<'a>(InvariantOpaque<'a>); @@ -888,9 +781,7 @@ pub(crate) mod debuginfo { pub(crate) type DIDerivedType = DIType; pub(crate) type DICompositeType = DIDerivedType; pub(crate) type DIVariable = DIDescriptor; - pub(crate) type DIGlobalVariableExpression = DIDescriptor; pub(crate) type DIArray = DIDescriptor; - pub(crate) type DISubrange = DIDescriptor; pub(crate) type DIEnumerator = DIDescriptor; pub(crate) type DITemplateTypeParameter = DIDescriptor; @@ -962,28 +853,6 @@ pub(crate) mod debuginfo { DebugDirectivesOnly, } - impl DebugEmissionKind { - pub(crate) fn from_generic(kind: rustc_session::config::DebugInfo) -> Self { - // We should be setting LLVM's emission kind to `LineTablesOnly` if - // we are compiling with "limited" debuginfo. However, some of the - // existing tools relied on slightly more debuginfo being generated than - // would be the case with `LineTablesOnly`, and we did not want to break - // these tools in a "drive-by fix", without a good idea or plan about - // what limited debuginfo should exactly look like. So for now we are - // instead adding a new debuginfo option "line-tables-only" so as to - // not break anything and to allow users to have 'limited' debug info. - // - // See https://github.com/rust-lang/rust/issues/60020 for details. - use rustc_session::config::DebugInfo; - match kind { - DebugInfo::None => DebugEmissionKind::NoDebug, - DebugInfo::LineDirectivesOnly => DebugEmissionKind::DebugDirectivesOnly, - DebugInfo::LineTablesOnly => DebugEmissionKind::LineTablesOnly, - DebugInfo::Limited | DebugInfo::Full => DebugEmissionKind::FullDebug, - } - } - } - /// LLVMRustDebugNameTableKind #[derive(Clone, Copy)] #[repr(C)] @@ -1033,25 +902,19 @@ pub(crate) type GetSymbolsCallback = unsafe extern "C" fn(*mut c_void, *const c_char) -> *mut c_void; pub(crate) type GetSymbolsErrorCallback = unsafe extern "C" fn(*const c_char) -> *mut c_void; -#[derive(Copy, Clone)] -#[repr(transparent)] -pub(crate) struct MetadataKindId(c_uint); - -impl From for MetadataKindId { - fn from(value: MetadataType) -> Self { - Self(value as c_uint) - } -} - unsafe extern "C" { // Create and destroy contexts. + pub(crate) fn LLVMContextCreate() -> &'static mut Context; pub(crate) fn LLVMContextDispose(C: &'static mut Context); + pub(crate) fn LLVMContextSetDiscardValueNames(C: &Context, Discard: Bool); pub(crate) fn LLVMGetMDKindIDInContext( C: &Context, Name: *const c_char, SLen: c_uint, ) -> MetadataKindId; + pub(crate) fn LLVMDisposeTargetMachine(T: ptr::NonNull); + // Create modules. pub(crate) fn LLVMModuleCreateWithNameInContext( ModuleID: *const c_char, @@ -1091,7 +954,7 @@ unsafe extern "C" { pub(crate) fn LLVMInt16TypeInContext(C: &Context) -> &Type; pub(crate) fn LLVMInt32TypeInContext(C: &Context) -> &Type; pub(crate) fn LLVMInt64TypeInContext(C: &Context) -> &Type; - pub(crate) fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type; + pub(crate) safe fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type; pub(crate) fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint; @@ -1120,7 +983,7 @@ unsafe extern "C" { ) -> &'a Type; // Operations on array, pointer, and vector types (sequence types) - pub(crate) fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type; + pub(crate) safe fn LLVMPointerTypeInContext(C: &Context, AddressSpace: c_uint) -> &Type; pub(crate) fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type; pub(crate) fn LLVMGetElementType(Ty: &Type) -> &Type; @@ -1135,7 +998,11 @@ unsafe extern "C" { pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t); pub(crate) fn LLVMReplaceAllUsesWith<'a>(OldVal: &'a Value, NewVal: &'a Value); pub(crate) safe fn LLVMSetMetadata<'a>(Val: &'a Value, KindID: MetadataKindId, Node: &'a Value); - pub(crate) fn LLVMGlobalSetMetadata<'a>(Val: &'a Value, KindID: c_uint, Metadata: &'a Metadata); + pub(crate) fn LLVMGlobalSetMetadata<'a>( + Val: &'a Value, + KindID: MetadataKindId, + Metadata: &'a Metadata, + ); pub(crate) safe fn LLVMValueAsMetadata(Node: &Value) -> &Metadata; // Operations on constants of any type @@ -1237,6 +1104,7 @@ unsafe extern "C" { pub(crate) safe fn LLVMSetGlobalConstant(GlobalVar: &Value, IsConstant: Bool); pub(crate) safe fn LLVMSetTailCall(CallInst: &Value, IsTailCall: Bool); pub(crate) safe fn LLVMSetTailCallKind(CallInst: &Value, kind: TailCallKind); + pub(crate) safe fn LLVMSetExternallyInitialized(GlobalVar: &Value, IsExtInit: Bool); // Operations on attributes pub(crate) fn LLVMCreateStringAttribute( @@ -1249,6 +1117,7 @@ unsafe extern "C" { // Operations on functions pub(crate) fn LLVMSetFunctionCallConv(Fn: &Value, CC: c_uint); + pub(crate) fn LLVMDeleteFunction(Fn: &Value); // Operations about llvm intrinsics pub(crate) fn LLVMLookupIntrinsicID(Name: *const c_char, NameLen: size_t) -> c_uint; @@ -1278,12 +1147,15 @@ unsafe extern "C" { pub(crate) fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>; pub(crate) fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock; pub(crate) fn LLVMGetOperand(Val: &Value, Index: c_uint) -> Option<&Value>; + pub(crate) fn LLVMGetNextInstruction(Val: &Value) -> Option<&Value>; + pub(crate) fn LLVMInstructionEraseFromParent(Val: &Value); // Operations on call sites pub(crate) fn LLVMSetInstructionCallConv(Instr: &Value, CC: c_uint); // Operations on load/store instructions (only) pub(crate) fn LLVMSetVolatile(MemoryAccessInst: &Value, volatile: Bool); + pub(crate) fn LLVMSetOrdering(MemoryAccessInst: &Value, Ordering: AtomicOrdering); // Operations on phi nodes pub(crate) fn LLVMAddIncoming<'a>( @@ -1870,6 +1742,202 @@ unsafe extern "C" { Scope: &'ll Metadata, InlinedAt: Option<&'ll Metadata>, ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateSubroutineType<'ll>( + Builder: &DIBuilder<'ll>, + File: Option<&'ll Metadata>, // (ignored and has no effect) + ParameterTypes: *const Option<&'ll Metadata>, + NumParameterTypes: c_uint, + Flags: DIFlags, // (default is `DIFlags::DIFlagZero`) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateUnionType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: Option<&'ll Metadata>, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + Elements: *const Option<&'ll Metadata>, + NumElements: c_uint, + RunTimeLang: c_uint, // (optional Objective-C runtime version; default is 0) + UniqueId: *const c_uchar, // See "PTR_LEN_STR". + UniqueIdLen: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateArrayType<'ll>( + Builder: &DIBuilder<'ll>, + Size: u64, + Align: u32, + Ty: &'ll Metadata, + Subscripts: *const &'ll Metadata, + NumSubscripts: c_uint, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateBasicType<'ll>( + Builder: &DIBuilder<'ll>, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + SizeInBits: u64, + Encoding: c_uint, // (`LLVMDWARFTypeEncoding`) + Flags: DIFlags, // (default is `DIFlags::DIFlagZero`) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreatePointerType<'ll>( + Builder: &DIBuilder<'ll>, + PointeeTy: &'ll Metadata, + SizeInBits: u64, + AlignInBits: u32, + AddressSpace: c_uint, // (optional DWARF address space; default is 0) + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateStructType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: Option<&'ll Metadata>, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNumber: c_uint, + SizeInBits: u64, + AlignInBits: u32, + Flags: DIFlags, + DerivedFrom: Option<&'ll Metadata>, + Elements: *const Option<&'ll Metadata>, + NumElements: c_uint, + RunTimeLang: c_uint, // (optional Objective-C runtime version; default is 0) + VTableHolder: Option<&'ll Metadata>, + UniqueId: *const c_uchar, // See "PTR_LEN_STR". + UniqueIdLen: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateMemberType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + SizeInBits: u64, + AlignInBits: u32, + OffsetInBits: u64, + Flags: DIFlags, + Ty: &'ll Metadata, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateStaticMemberType<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNumber: c_uint, + Type: &'ll Metadata, + Flags: DIFlags, + ConstantVal: Option<&'ll Value>, + AlignInBits: u32, + ) -> &'ll Metadata; + + /// Creates a "qualified type" in the C/C++ sense, by adding modifiers + /// like `const` or `volatile`. + pub(crate) fn LLVMDIBuilderCreateQualifiedType<'ll>( + Builder: &DIBuilder<'ll>, + Tag: c_uint, // (DWARF tag, e.g. `DW_TAG_const_type`) + Type: &'ll Metadata, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateTypedef<'ll>( + Builder: &DIBuilder<'ll>, + Type: &'ll Metadata, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + Scope: Option<&'ll Metadata>, + AlignInBits: u32, // (optional; default is 0) + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderGetOrCreateSubrange<'ll>( + Builder: &DIBuilder<'ll>, + LowerBound: i64, + Count: i64, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderGetOrCreateArray<'ll>( + Builder: &DIBuilder<'ll>, + Data: *const Option<&'ll Metadata>, + NumElements: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateExpression<'ll>( + Builder: &DIBuilder<'ll>, + Addr: *const u64, + Length: size_t, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateGlobalVariableExpression<'ll>( + Builder: &DIBuilder<'ll>, + Scope: Option<&'ll Metadata>, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + Linkage: *const c_uchar, // See "PTR_LEN_STR". + LinkLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + Ty: &'ll Metadata, + LocalToUnit: llvm::Bool, + Expr: &'ll Metadata, + Decl: Option<&'ll Metadata>, + AlignInBits: u32, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderInsertDeclareRecordAtEnd<'ll>( + Builder: &DIBuilder<'ll>, + Storage: &'ll Value, + VarInfo: &'ll Metadata, + Expr: &'ll Metadata, + DebugLoc: &'ll Metadata, + Block: &'ll BasicBlock, + ) -> &'ll DbgRecord; + + pub(crate) fn LLVMDIBuilderInsertDbgValueRecordAtEnd<'ll>( + Builder: &DIBuilder<'ll>, + Val: &'ll Value, + VarInfo: &'ll Metadata, + Expr: &'ll Metadata, + DebugLoc: &'ll Metadata, + Block: &'ll BasicBlock, + ) -> &'ll DbgRecord; + + pub(crate) fn LLVMDIBuilderCreateAutoVariable<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + File: &'ll Metadata, + LineNo: c_uint, + Ty: &'ll Metadata, + AlwaysPreserve: llvm::Bool, // "If true, this descriptor will survive optimizations." + Flags: DIFlags, + AlignInBits: u32, + ) -> &'ll Metadata; + + pub(crate) fn LLVMDIBuilderCreateParameterVariable<'ll>( + Builder: &DIBuilder<'ll>, + Scope: &'ll Metadata, + Name: *const c_uchar, // See "PTR_LEN_STR". + NameLen: size_t, + ArgNo: c_uint, + File: &'ll Metadata, + LineNo: c_uint, + Ty: &'ll Metadata, + AlwaysPreserve: llvm::Bool, // "If true, this descriptor will survive optimizations." + Flags: DIFlags, + ) -> &'ll Metadata; } #[link(name = "llvm-wrapper", kind = "static")] @@ -1877,13 +1945,10 @@ unsafe extern "C" { pub(crate) fn LLVMRustInstallErrorHandlers(); pub(crate) fn LLVMRustDisableSystemDialogsOnCrash(); - // Create and destroy contexts. - pub(crate) fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context; - // Operations on all values pub(crate) fn LLVMRustGlobalAddMetadata<'a>( Val: &'a Value, - KindID: c_uint, + KindID: MetadataKindId, Metadata: &'a Metadata, ); pub(crate) fn LLVMRustIsNonGVFunctionPointerTy(Val: &Value) -> bool; @@ -1907,7 +1972,6 @@ unsafe extern "C" { NameLen: size_t, T: &'a Type, ) -> &'a Value; - pub(crate) fn LLVMRustInsertPrivateGlobal<'a>(M: &'a Module, T: &'a Type) -> &'a Value; pub(crate) fn LLVMRustGetNamedValue( M: &Module, Name: *const c_char, @@ -1996,69 +2060,6 @@ unsafe extern "C" { IsVolatile: bool, ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceFAdd<'a>( - B: &Builder<'a>, - Acc: &'a Value, - Src: &'a Value, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceFMul<'a>( - B: &Builder<'a>, - Acc: &'a Value, - Src: &'a Value, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceAdd<'a>(B: &Builder<'a>, Src: &'a Value) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceMul<'a>(B: &Builder<'a>, Src: &'a Value) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceAnd<'a>(B: &Builder<'a>, Src: &'a Value) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceOr<'a>(B: &Builder<'a>, Src: &'a Value) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceXor<'a>(B: &Builder<'a>, Src: &'a Value) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceMin<'a>( - B: &Builder<'a>, - Src: &'a Value, - IsSigned: bool, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceMax<'a>( - B: &Builder<'a>, - Src: &'a Value, - IsSigned: bool, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceFMin<'a>( - B: &Builder<'a>, - Src: &'a Value, - IsNaN: bool, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildVectorReduceFMax<'a>( - B: &Builder<'a>, - Src: &'a Value, - IsNaN: bool, - ) -> &'a Value; - - pub(crate) fn LLVMRustBuildMinNum<'a>( - B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - ) -> &'a Value; - pub(crate) fn LLVMRustBuildMaxNum<'a>( - B: &Builder<'a>, - LHS: &'a Value, - RHS: &'a Value, - ) -> &'a Value; - - // Atomic Operations - pub(crate) fn LLVMRustBuildAtomicLoad<'a>( - B: &Builder<'a>, - ElementType: &'a Type, - PointerVal: &'a Value, - Name: *const c_char, - Order: AtomicOrdering, - ) -> &'a Value; - - pub(crate) fn LLVMRustBuildAtomicStore<'a>( - B: &Builder<'a>, - Val: &'a Value, - Ptr: &'a Value, - Order: AtomicOrdering, - ) -> &'a Value; - pub(crate) fn LLVMRustTimeTraceProfilerInitialize(); pub(crate) fn LLVMRustTimeTraceProfilerFinishThread(); @@ -2080,8 +2081,11 @@ unsafe extern "C" { ConstraintsLen: size_t, ) -> bool; + /// A list of pointer-length strings is passed as two pointer-length slices, + /// one slice containing pointers and one slice containing their corresponding + /// lengths. The implementation will check that both slices have the same length. pub(crate) fn LLVMRustCoverageWriteFilenamesToBuffer( - Filenames: *const *const c_char, + Filenames: *const *const c_uchar, // See "PTR_LEN_STR". FilenamesLen: size_t, Lengths: *const size_t, LengthsLen: size_t, @@ -2104,18 +2108,25 @@ unsafe extern "C" { pub(crate) fn LLVMRustCoverageCreatePGOFuncNameVar( F: &Value, - FuncName: *const c_char, + FuncName: *const c_uchar, // See "PTR_LEN_STR". FuncNameLen: size_t, ) -> &Value; - pub(crate) fn LLVMRustCoverageHashBytes(Bytes: *const c_char, NumBytes: size_t) -> u64; - - pub(crate) fn LLVMRustCoverageWriteCovmapSectionNameToString(M: &Module, OutStr: &RustString); + pub(crate) fn LLVMRustCoverageHashBytes( + Bytes: *const c_uchar, // See "PTR_LEN_STR". + NumBytes: size_t, + ) -> u64; - pub(crate) fn LLVMRustCoverageWriteCovfunSectionNameToString(M: &Module, OutStr: &RustString); - - pub(crate) fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString); + pub(crate) safe fn LLVMRustCoverageWriteCovmapSectionNameToString( + M: &Module, + OutStr: &RustString, + ); + pub(crate) safe fn LLVMRustCoverageWriteCovfunSectionNameToString( + M: &Module, + OutStr: &RustString, + ); + pub(crate) safe fn LLVMRustCoverageWriteCovmapVarNameToString(OutStr: &RustString); - pub(crate) fn LLVMRustCoverageMappingVersion() -> u32; + pub(crate) safe fn LLVMRustCoverageMappingVersion() -> u32; pub(crate) fn LLVMRustDebugMetadataVersion() -> u32; pub(crate) fn LLVMRustVersionMajor() -> u32; pub(crate) fn LLVMRustVersionMinor() -> u32; @@ -2172,11 +2183,6 @@ unsafe extern "C" { SourceLen: size_t, ) -> &'a DIFile; - pub(crate) fn LLVMRustDIBuilderCreateSubroutineType<'a>( - Builder: &DIBuilder<'a>, - ParameterTypes: &'a DIArray, - ) -> &'a DICompositeType; - pub(crate) fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, @@ -2210,66 +2216,6 @@ unsafe extern "C" { TParam: &'a DIArray, ) -> &'a DISubprogram; - pub(crate) fn LLVMRustDIBuilderCreateBasicType<'a>( - Builder: &DIBuilder<'a>, - Name: *const c_char, - NameLen: size_t, - SizeInBits: u64, - Encoding: c_uint, - ) -> &'a DIBasicType; - - pub(crate) fn LLVMRustDIBuilderCreateTypedef<'a>( - Builder: &DIBuilder<'a>, - Type: &'a DIBasicType, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Scope: Option<&'a DIScope>, - ) -> &'a DIDerivedType; - - pub(crate) fn LLVMRustDIBuilderCreatePointerType<'a>( - Builder: &DIBuilder<'a>, - PointeeTy: &'a DIType, - SizeInBits: u64, - AlignInBits: u32, - AddressSpace: c_uint, - Name: *const c_char, - NameLen: size_t, - ) -> &'a DIDerivedType; - - pub(crate) fn LLVMRustDIBuilderCreateStructType<'a>( - Builder: &DIBuilder<'a>, - Scope: Option<&'a DIDescriptor>, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - DerivedFrom: Option<&'a DIType>, - Elements: &'a DIArray, - RunTimeLang: c_uint, - VTableHolder: Option<&'a DIType>, - UniqueId: *const c_char, - UniqueIdLen: size_t, - ) -> &'a DICompositeType; - - pub(crate) fn LLVMRustDIBuilderCreateMemberType<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - SizeInBits: u64, - AlignInBits: u32, - OffsetInBits: u64, - Flags: DIFlags, - Ty: &'a DIType, - ) -> &'a DIDerivedType; - pub(crate) fn LLVMRustDIBuilderCreateVariantMemberType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2285,86 +2231,6 @@ unsafe extern "C" { Ty: &'a DIType, ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateStaticMemberType<'a>( - Builder: &DIBuilder<'a>, - Scope: &'a DIDescriptor, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - Flags: DIFlags, - val: Option<&'a Value>, - AlignInBits: u32, - ) -> &'a DIDerivedType; - - pub(crate) fn LLVMRustDIBuilderCreateQualifiedType<'a>( - Builder: &DIBuilder<'a>, - Tag: c_uint, - Type: &'a DIType, - ) -> &'a DIDerivedType; - - pub(crate) fn LLVMRustDIBuilderCreateStaticVariable<'a>( - Builder: &DIBuilder<'a>, - Context: Option<&'a DIScope>, - Name: *const c_char, - NameLen: size_t, - LinkageName: *const c_char, - LinkageNameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - isLocalToUnit: bool, - Val: &'a Value, - Decl: Option<&'a DIDescriptor>, - AlignInBits: u32, - ) -> &'a DIGlobalVariableExpression; - - pub(crate) fn LLVMRustDIBuilderCreateVariable<'a>( - Builder: &DIBuilder<'a>, - Tag: c_uint, - Scope: &'a DIDescriptor, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNo: c_uint, - Ty: &'a DIType, - AlwaysPreserve: bool, - Flags: DIFlags, - ArgNo: c_uint, - AlignInBits: u32, - ) -> &'a DIVariable; - - pub(crate) fn LLVMRustDIBuilderCreateArrayType<'a>( - Builder: &DIBuilder<'a>, - Size: u64, - AlignInBits: u32, - Ty: &'a DIType, - Subscripts: &'a DIArray, - ) -> &'a DIType; - - pub(crate) fn LLVMRustDIBuilderGetOrCreateSubrange<'a>( - Builder: &DIBuilder<'a>, - Lo: i64, - Count: i64, - ) -> &'a DISubrange; - - pub(crate) fn LLVMRustDIBuilderGetOrCreateArray<'a>( - Builder: &DIBuilder<'a>, - Ptr: *const Option<&'a DIDescriptor>, - Count: c_uint, - ) -> &'a DIArray; - - pub(crate) fn LLVMRustDIBuilderInsertDeclareAtEnd<'a>( - Builder: &DIBuilder<'a>, - Val: &'a Value, - VarInfo: &'a DIVariable, - AddrOps: *const u64, - AddrOpsCount: c_uint, - DL: &'a DILocation, - InsertAtEnd: &'a BasicBlock, - ); - pub(crate) fn LLVMRustDIBuilderCreateEnumerator<'a>( Builder: &DIBuilder<'a>, Name: *const c_char, @@ -2388,22 +2254,6 @@ unsafe extern "C" { IsScoped: bool, ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateUnionType<'a>( - Builder: &DIBuilder<'a>, - Scope: Option<&'a DIScope>, - Name: *const c_char, - NameLen: size_t, - File: &'a DIFile, - LineNumber: c_uint, - SizeInBits: u64, - AlignInBits: u32, - Flags: DIFlags, - Elements: Option<&'a DIArray>, - RunTimeLang: c_uint, - UniqueId: *const c_char, - UniqueIdLen: size_t, - ) -> &'a DIType; - pub(crate) fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, @@ -2480,12 +2330,9 @@ unsafe extern "C" { OutputObjFile: *const c_char, DebugInfoCompression: *const c_char, UseEmulatedTls: bool, - ArgsCstrBuff: *const c_uchar, // See "PTR_LEN_STR". - ArgsCstrBuffLen: usize, UseWasmEH: bool, ) -> *mut TargetMachine; - pub(crate) fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine); pub(crate) fn LLVMRustAddLibraryInfo<'a>( PM: &PassManager<'a>, M: &'a Module, diff --git a/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs new file mode 100644 index 0000000000000..a8a671b5c85f1 --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/llvm/metadata_kind.rs @@ -0,0 +1,71 @@ +use libc::c_uint; + +pub(crate) use self::fixed_kinds::*; + +#[derive(Copy, Clone)] +#[repr(transparent)] +pub(crate) struct MetadataKindId(c_uint); + +macro_rules! declare_fixed_metadata_kinds { + ( + $( + FIXED_MD_KIND($variant:ident, $value:literal) + )* + ) => { + // Use a submodule to group all declarations into one `#[expect(..)]`. + #[expect(dead_code)] + mod fixed_kinds { + use super::MetadataKindId; + $( + #[expect(non_upper_case_globals)] + pub(crate) const $variant: MetadataKindId = MetadataKindId($value); + )* + } + }; +} + +// Must be kept in sync with the corresponding static assertions in `RustWrapper.cpp`. +declare_fixed_metadata_kinds! { + FIXED_MD_KIND(MD_dbg, 0) + FIXED_MD_KIND(MD_tbaa, 1) + FIXED_MD_KIND(MD_prof, 2) + FIXED_MD_KIND(MD_fpmath, 3) + FIXED_MD_KIND(MD_range, 4) + FIXED_MD_KIND(MD_tbaa_struct, 5) + FIXED_MD_KIND(MD_invariant_load, 6) + FIXED_MD_KIND(MD_alias_scope, 7) + FIXED_MD_KIND(MD_noalias, 8) + FIXED_MD_KIND(MD_nontemporal, 9) + FIXED_MD_KIND(MD_mem_parallel_loop_access, 10) + FIXED_MD_KIND(MD_nonnull, 11) + FIXED_MD_KIND(MD_dereferenceable, 12) + FIXED_MD_KIND(MD_dereferenceable_or_null, 13) + FIXED_MD_KIND(MD_make_implicit, 14) + FIXED_MD_KIND(MD_unpredictable, 15) + FIXED_MD_KIND(MD_invariant_group, 16) + FIXED_MD_KIND(MD_align, 17) + FIXED_MD_KIND(MD_loop, 18) + FIXED_MD_KIND(MD_type, 19) + FIXED_MD_KIND(MD_section_prefix, 20) + FIXED_MD_KIND(MD_absolute_symbol, 21) + FIXED_MD_KIND(MD_associated, 22) + FIXED_MD_KIND(MD_callees, 23) + FIXED_MD_KIND(MD_irr_loop, 24) + FIXED_MD_KIND(MD_access_group, 25) + FIXED_MD_KIND(MD_callback, 26) + FIXED_MD_KIND(MD_preserve_access_index, 27) + FIXED_MD_KIND(MD_vcall_visibility, 28) + FIXED_MD_KIND(MD_noundef, 29) + FIXED_MD_KIND(MD_annotation, 30) + FIXED_MD_KIND(MD_nosanitize, 31) + FIXED_MD_KIND(MD_func_sanitize, 32) + FIXED_MD_KIND(MD_exclude, 33) + FIXED_MD_KIND(MD_memprof, 34) + FIXED_MD_KIND(MD_callsite, 35) + FIXED_MD_KIND(MD_kcfi_type, 36) + FIXED_MD_KIND(MD_pcsections, 37) + FIXED_MD_KIND(MD_DIAssignID, 38) + FIXED_MD_KIND(MD_coro_outside_frame, 39) + FIXED_MD_KIND(MD_mmra, 40) + FIXED_MD_KIND(MD_noalias_addrspace, 41) +} diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index d6974e22c85c5..4c58a92106d5c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -11,13 +11,16 @@ use rustc_llvm::RustString; pub(crate) use self::CallConv::*; pub(crate) use self::CodeGenOptSize::*; -pub(crate) use self::MetadataType::*; +pub(crate) use self::conversions::*; pub(crate) use self::ffi::*; +pub(crate) use self::metadata_kind::*; use crate::common::AsCCharPtr; +mod conversions; pub(crate) mod diagnostic; pub(crate) mod enzyme_ffi; mod ffi; +mod metadata_kind; pub(crate) use self::enzyme_ffi::*; @@ -258,6 +261,10 @@ pub(crate) fn set_alignment(llglobal: &Value, align: Align) { } } +pub(crate) fn set_externally_initialized(llglobal: &Value, is_ext_init: bool) { + LLVMSetExternallyInitialized(llglobal, is_ext_init.to_llvm_bool()); +} + /// Get the `name`d comdat from `llmod` and assign it to `llglobal`. /// /// Inserts the comdat into `llmod` if it does not exist. diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index d927ffd78c298..3b920168e06dc 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -106,7 +106,7 @@ unsafe fn configure_llvm(sess: &Session) { if sess.target.os == "emscripten" && !sess.opts.unstable_opts.emscripten_wasm_eh - && sess.panic_strategy() == PanicStrategy::Unwind + && sess.panic_strategy().unwinds() { add("-enable-emscripten-cxx-exceptions", false); } @@ -217,27 +217,16 @@ impl<'a> IntoIterator for LLVMFeature<'a> { /// Rust can also be build with an external precompiled version of LLVM which might lead to failures /// if the oldest tested / supported LLVM version doesn't yet support the relevant intrinsics. pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option> { - let arch = if sess.target.arch == "x86_64" { - "x86" - } else if sess.target.arch == "arm64ec" { - "aarch64" - } else if sess.target.arch == "sparc64" { - "sparc" - } else if sess.target.arch == "powerpc64" { - "powerpc" - } else { - &*sess.target.arch + let raw_arch = &*sess.target.arch; + let arch = match raw_arch { + "x86_64" => "x86", + "arm64ec" => "aarch64", + "sparc64" => "sparc", + "powerpc64" => "powerpc", + _ => raw_arch, }; + let (major, _, _) = get_version(); match (arch, s) { - ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies( - "sse4.2", - smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")], - )), - ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")), - ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")), - ("x86", "bmi1") => Some(LLVMFeature::new("bmi")), - ("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")), - ("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")), ("aarch64", "rcpc2") => Some(LLVMFeature::new("rcpc-immo")), ("aarch64", "dpb") => Some(LLVMFeature::new("ccpp")), ("aarch64", "dpb2") => Some(LLVMFeature::new("ccdp")), @@ -246,9 +235,6 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option Some(LLVMFeature::new("perfmon")), ("aarch64", "paca") => Some(LLVMFeature::new("pauth")), ("aarch64", "pacg") => Some(LLVMFeature::new("pauth")), - // Before LLVM 20 those two features were packaged together as b16b16 - ("aarch64", "sve-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")), - ("aarch64", "sme-b16b16") if get_version().0 < 20 => Some(LLVMFeature::new("b16b16")), ("aarch64", "flagm2") => Some(LLVMFeature::new("altnzcv")), // Rust ties fp and neon together. ("aarch64", "neon") => Some(LLVMFeature::with_dependencies( @@ -262,57 +248,26 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option None, // only existed in 18 ("arm", "fp16") => Some(LLVMFeature::new("fullfp16")), - // NVPTX targets added in LLVM 20 - ("nvptx64", "sm_100") if get_version().0 < 20 => None, - ("nvptx64", "sm_100a") if get_version().0 < 20 => None, - ("nvptx64", "sm_101") if get_version().0 < 20 => None, - ("nvptx64", "sm_101a") if get_version().0 < 20 => None, - ("nvptx64", "sm_120") if get_version().0 < 20 => None, - ("nvptx64", "sm_120a") if get_version().0 < 20 => None, - ("nvptx64", "ptx86") if get_version().0 < 20 => None, - ("nvptx64", "ptx87") if get_version().0 < 20 => None, // Filter out features that are not supported by the current LLVM version - ("loongarch64", "div32" | "lam-bh" | "lamcas" | "ld-seq-sa" | "scq") - if get_version().0 < 20 => - { - None - } - ("loongarch32" | "loongarch64", "32s") if get_version().0 < 21 => None, - // Filter out features that are not supported by the current LLVM version - ("riscv32" | "riscv64", "zacas" | "rva23u64" | "supm") if get_version().0 < 20 => None, - ( - "s390x", - "message-security-assist-extension12" - | "concurrent-functions" - | "miscellaneous-extensions-4" - | "vector-enhancements-3" - | "vector-packed-decimal-enhancement-3", - ) if get_version().0 < 20 => None, + ("loongarch32" | "loongarch64", "32s") if major < 21 => None, + ("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")), + ("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")), + ("x86", "sse4.2") => Some(LLVMFeature::with_dependencies( + "sse4.2", + smallvec![TargetFeatureFoldStrength::EnableOnly("crc32")], + )), + ("x86", "pclmulqdq") => Some(LLVMFeature::new("pclmul")), + ("x86", "rdrand") => Some(LLVMFeature::new("rdrnd")), + ("x86", "bmi1") => Some(LLVMFeature::new("bmi")), + ("x86", "cmpxchg16b") => Some(LLVMFeature::new("cx16")), + ("x86", "lahfsahf") => Some(LLVMFeature::new("sahf")), // Enable the evex512 target feature if an avx512 target feature is enabled. ("x86", s) if s.starts_with("avx512") => Some(LLVMFeature::with_dependencies( s, smallvec![TargetFeatureFoldStrength::EnableOnly("evex512")], )), - // Support for `wide-arithmetic` will first land in LLVM 20 as part of - // llvm/llvm-project#111598 - ("wasm32" | "wasm64", "wide-arithmetic") if get_version() < (20, 0, 0) => None, - ("sparc", "leoncasa") => Some(LLVMFeature::new("hasleoncasa")), - // In LLVM 19, there is no `v8plus` feature and `v9` means "SPARC-V9 instruction available and SPARC-V8+ ABI used". - // https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L27-L28 - // Before LLVM 19, there was no `v8plus` feature and `v9` means "SPARC-V9 instruction available". - // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.0/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp#L26 - ("sparc", "v8plus") if get_version().0 == 19 => Some(LLVMFeature::new("v9")), - ("powerpc", "power8-crypto") => Some(LLVMFeature::new("crypto")), - // These new `amx` variants and `movrs` were introduced in LLVM20 - ("x86", "amx-avx512" | "amx-fp8" | "amx-movrs" | "amx-tf32" | "amx-transpose") - if get_version().0 < 20 => - { - None - } - ("x86", "movrs") if get_version().0 < 20 => None, ("x86", "avx10.1") => Some(LLVMFeature::new("avx10.1-512")), - ("x86", "avx10.2") if get_version().0 < 20 => None, - ("x86", "avx10.2") if get_version().0 >= 20 => Some(LLVMFeature::new("avx10.2-512")), + ("x86", "avx10.2") => Some(LLVMFeature::new("avx10.2-512")), ("x86", "apxf") => Some(LLVMFeature::with_dependencies( "egpr", smallvec![ @@ -716,17 +671,7 @@ pub(crate) fn global_llvm_features( }; // Features implied by an implicit or explicit `--target`. - features.extend( - sess.target - .features - .split(',') - .filter(|v| !v.is_empty()) - // Drop +v8plus feature introduced in LLVM 20. - // (Hard-coded target features do not go through `to_llvm_feature` since they already - // are LLVM feature names, hence we need a special case here.) - .filter(|v| *v != "+v8plus" || get_version() >= (20, 0, 0)) - .map(String::from), - ); + features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from)); if wants_wasm_eh(sess) && sess.panic_strategy() == PanicStrategy::Unwind { features.push("+exception-handling".into()); diff --git a/compiler/rustc_codegen_llvm/src/macros.rs b/compiler/rustc_codegen_llvm/src/macros.rs new file mode 100644 index 0000000000000..fddc428ca273b --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/macros.rs @@ -0,0 +1,22 @@ +macro_rules! TryFromU32 { + derive() ( + $(#[$meta:meta])* + $vis:vis enum $Type:ident { + $( + $(#[$varmeta:meta])* + $Variant:ident $(= $discr:expr)? + ),* $(,)? + } + ) => { + impl ::core::convert::TryFrom for $Type { + type Error = u32; + #[allow(deprecated)] // Don't warn about deprecated variants. + fn try_from(value: u32) -> ::core::result::Result<$Type, Self::Error> { + $( if value == const { $Type::$Variant as u32 } { return Ok($Type::$Variant) } )* + Err(value) + } + } + } +} + +pub(crate) use TryFromU32; diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs index 9ecaf5f24fe15..81bb70c958790 100644 --- a/compiler/rustc_codegen_llvm/src/type_.rs +++ b/compiler/rustc_codegen_llvm/src/type_.rs @@ -13,12 +13,10 @@ use rustc_middle::ty::{self, Ty}; use rustc_target::callconv::{CastTarget, FnAbi}; use crate::abi::{FnAbiLlvmExt, LlvmType}; +use crate::common; use crate::context::{CodegenCx, GenericCx, SCx}; -pub(crate) use crate::llvm::Type; -use crate::llvm::{FALSE, Metadata, TRUE, ToLlvmBool}; +use crate::llvm::{self, FALSE, Metadata, TRUE, ToLlvmBool, Type, Value}; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; -use crate::{common, llvm}; impl PartialEq for Type { fn eq(&self, other: &Self) -> bool { @@ -63,7 +61,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { ///x Creates an integer type with the given number of bits, e.g., i24 pub(crate) fn type_ix(&self, num_bits: u64) -> &'ll Type { - unsafe { llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint) } + llvm::LLVMIntTypeInContext(self.llcx(), num_bits as c_uint) } pub(crate) fn type_vector(&self, ty: &'ll Type, len: u64) -> &'ll Type { @@ -178,7 +176,7 @@ impl<'ll, CX: Borrow>> BaseTypeCodegenMethods for GenericCx<'ll, CX> { } fn type_i128(&self) -> &'ll Type { - unsafe { llvm::LLVMIntTypeInContext(self.llcx(), 128) } + self.type_ix(128) } fn type_isize(&self) -> &'ll Type { @@ -210,11 +208,11 @@ impl<'ll, CX: Borrow>> BaseTypeCodegenMethods for GenericCx<'ll, CX> { } fn type_ptr(&self) -> &'ll Type { - self.type_ptr_ext(AddressSpace::ZERO) + llvm_type_ptr(self.llcx()) } fn type_ptr_ext(&self, address_space: AddressSpace) -> &'ll Type { - unsafe { llvm::LLVMPointerTypeInContext(self.llcx(), address_space.0) } + llvm_type_ptr_in_address_space(self.llcx(), address_space) } fn element_type(&self, ty: &'ll Type) -> &'ll Type { @@ -253,15 +251,15 @@ impl<'ll, CX: Borrow>> BaseTypeCodegenMethods for GenericCx<'ll, CX> { } } -impl Type { - /// Creates an integer type with the given number of bits, e.g., i24 - pub(crate) fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type { - unsafe { llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint) } - } +pub(crate) fn llvm_type_ptr(llcx: &llvm::Context) -> &Type { + llvm_type_ptr_in_address_space(llcx, AddressSpace::ZERO) +} - pub(crate) fn ptr_llcx(llcx: &llvm::Context) -> &Type { - unsafe { llvm::LLVMPointerTypeInContext(llcx, AddressSpace::ZERO.0) } - } +pub(crate) fn llvm_type_ptr_in_address_space<'ll>( + llcx: &'ll llvm::Context, + addr_space: AddressSpace, +) -> &'ll Type { + llvm::LLVMPointerTypeInContext(llcx, addr_space.0) } impl<'ll, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { @@ -302,26 +300,14 @@ impl<'ll, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { fn add_type_metadata(&self, function: &'ll Value, typeid: &[u8]) { let typeid_metadata = self.create_metadata(typeid); - unsafe { - let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata]; - llvm::LLVMRustGlobalAddMetadata( - function, - llvm::MD_type as c_uint, - llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()), - ) - } + let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata]; + self.global_add_metadata_node(function, llvm::MD_type, &v); } fn set_type_metadata(&self, function: &'ll Value, typeid: &[u8]) { let typeid_metadata = self.create_metadata(typeid); - unsafe { - let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata]; - llvm::LLVMGlobalSetMetadata( - function, - llvm::MD_type as c_uint, - llvm::LLVMMDNodeInContext2(self.llcx, v.as_ptr(), v.len()), - ) - } + let v = [llvm::LLVMValueAsMetadata(self.const_usize(0)), typeid_metadata]; + self.global_set_metadata_node(function, llvm::MD_type, &v); } fn typeid_metadata(&self, typeid: &[u8]) -> Option<&'ll Metadata> { @@ -329,32 +315,12 @@ impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn add_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) { - let kcfi_type_metadata = self.const_u32(kcfi_typeid); - unsafe { - llvm::LLVMRustGlobalAddMetadata( - function, - llvm::MD_kcfi_type as c_uint, - llvm::LLVMMDNodeInContext2( - self.llcx, - &llvm::LLVMValueAsMetadata(kcfi_type_metadata), - 1, - ), - ) - } + let kcfi_type_metadata = [llvm::LLVMValueAsMetadata(self.const_u32(kcfi_typeid))]; + self.global_add_metadata_node(function, llvm::MD_kcfi_type, &kcfi_type_metadata); } fn set_kcfi_type_metadata(&self, function: &'ll Value, kcfi_typeid: u32) { - let kcfi_type_metadata = self.const_u32(kcfi_typeid); - unsafe { - llvm::LLVMGlobalSetMetadata( - function, - llvm::MD_kcfi_type as c_uint, - llvm::LLVMMDNodeInContext2( - self.llcx, - &llvm::LLVMValueAsMetadata(kcfi_type_metadata), - 1, - ), - ) - } + let kcfi_type_metadata = [llvm::LLVMValueAsMetadata(self.const_u32(kcfi_typeid))]; + self.global_set_metadata_node(function, llvm::MD_kcfi_type, &kcfi_type_metadata); } } diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 84998b5499bdf..2b2ac1c6eb29f 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -11,7 +11,7 @@ use rustc_span::{DUMMY_SP, Span}; use tracing::debug; use crate::common::*; -use crate::type_::Type; +use crate::llvm::Type; fn uncached_llvm_type<'a, 'tcx>( cx: &CodegenCx<'a, 'tcx>, diff --git a/compiler/rustc_codegen_llvm/src/typetree.rs b/compiler/rustc_codegen_llvm/src/typetree.rs new file mode 100644 index 0000000000000..7e2635037008e --- /dev/null +++ b/compiler/rustc_codegen_llvm/src/typetree.rs @@ -0,0 +1,122 @@ +use rustc_ast::expand::typetree::FncTree; +#[cfg(feature = "llvm_enzyme")] +use { + crate::attributes, + rustc_ast::expand::typetree::TypeTree as RustTypeTree, + std::ffi::{CString, c_char, c_uint}, +}; + +use crate::llvm::{self, Value}; + +#[cfg(feature = "llvm_enzyme")] +fn to_enzyme_typetree( + rust_typetree: RustTypeTree, + _data_layout: &str, + llcx: &llvm::Context, +) -> llvm::TypeTree { + let mut enzyme_tt = llvm::TypeTree::new(); + process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx); + enzyme_tt +} +#[cfg(feature = "llvm_enzyme")] +fn process_typetree_recursive( + enzyme_tt: &mut llvm::TypeTree, + rust_typetree: &RustTypeTree, + parent_indices: &[i64], + llcx: &llvm::Context, +) { + for rust_type in &rust_typetree.0 { + let concrete_type = match rust_type.kind { + rustc_ast::expand::typetree::Kind::Anything => llvm::CConcreteType::DT_Anything, + rustc_ast::expand::typetree::Kind::Integer => llvm::CConcreteType::DT_Integer, + rustc_ast::expand::typetree::Kind::Pointer => llvm::CConcreteType::DT_Pointer, + rustc_ast::expand::typetree::Kind::Half => llvm::CConcreteType::DT_Half, + rustc_ast::expand::typetree::Kind::Float => llvm::CConcreteType::DT_Float, + rustc_ast::expand::typetree::Kind::Double => llvm::CConcreteType::DT_Double, + rustc_ast::expand::typetree::Kind::F128 => llvm::CConcreteType::DT_FP128, + rustc_ast::expand::typetree::Kind::Unknown => llvm::CConcreteType::DT_Unknown, + }; + + let mut indices = parent_indices.to_vec(); + if !parent_indices.is_empty() { + indices.push(rust_type.offset as i64); + } else if rust_type.offset == -1 { + indices.push(-1); + } else { + indices.push(rust_type.offset as i64); + } + + enzyme_tt.insert(&indices, concrete_type, llcx); + + if rust_type.kind == rustc_ast::expand::typetree::Kind::Pointer + && !rust_type.child.0.is_empty() + { + process_typetree_recursive(enzyme_tt, &rust_type.child, &indices, llcx); + } + } +} + +#[cfg(feature = "llvm_enzyme")] +pub(crate) fn add_tt<'ll>( + llmod: &'ll llvm::Module, + llcx: &'ll llvm::Context, + fn_def: &'ll Value, + tt: FncTree, +) { + let inputs = tt.args; + let ret_tt: RustTypeTree = tt.ret; + + let llvm_data_layout: *const c_char = unsafe { llvm::LLVMGetDataLayoutStr(&*llmod) }; + let llvm_data_layout = + std::str::from_utf8(unsafe { std::ffi::CStr::from_ptr(llvm_data_layout) }.to_bytes()) + .expect("got a non-UTF8 data-layout from LLVM"); + + let attr_name = "enzyme_type"; + let c_attr_name = CString::new(attr_name).unwrap(); + + for (i, input) in inputs.iter().enumerate() { + unsafe { + let enzyme_tt = to_enzyme_typetree(input.clone(), llvm_data_layout, llcx); + let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let c_str = std::ffi::CStr::from_ptr(c_str); + + let attr = llvm::LLVMCreateStringAttribute( + llcx, + c_attr_name.as_ptr(), + c_attr_name.as_bytes().len() as c_uint, + c_str.as_ptr(), + c_str.to_bytes().len() as c_uint, + ); + + attributes::apply_to_llfn(fn_def, llvm::AttributePlace::Argument(i as u32), &[attr]); + llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + } + } + + unsafe { + let enzyme_tt = to_enzyme_typetree(ret_tt, llvm_data_layout, llcx); + let c_str = llvm::EnzymeTypeTreeToString(enzyme_tt.inner); + let c_str = std::ffi::CStr::from_ptr(c_str); + + let ret_attr = llvm::LLVMCreateStringAttribute( + llcx, + c_attr_name.as_ptr(), + c_attr_name.as_bytes().len() as c_uint, + c_str.as_ptr(), + c_str.to_bytes().len() as c_uint, + ); + + attributes::apply_to_llfn(fn_def, llvm::AttributePlace::ReturnValue, &[ret_attr]); + llvm::EnzymeTypeTreeToStringFree(c_str.as_ptr()); + } +} + +#[cfg(not(feature = "llvm_enzyme"))] +pub(crate) fn add_tt<'ll>( + _llmod: &'ll llvm::Module, + _llcx: &'ll llvm::Context, + _fn_def: &'ll Value, + _tt: FncTree, +) { + unimplemented!() +} diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index ab08125217ff5..2d9abb412d4f1 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -9,9 +9,8 @@ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use crate::builder::Builder; -use crate::type_::Type; +use crate::llvm::{Type, Value}; use crate::type_of::LayoutLlvmExt; -use crate::value::Value; fn round_up_to_alignment<'ll>( bx: &mut Builder<'_, 'll, '_>, @@ -193,7 +192,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>( // the offset again. bx.switch_to_block(maybe_reg); - if gr_type && layout.align.abi.bytes() > 8 { + if gr_type && layout.align.bytes() > 8 { reg_off_v = bx.add(reg_off_v, bx.const_i32(15)); reg_off_v = bx.and(reg_off_v, bx.const_i32(-16)); } @@ -291,7 +290,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( bx.inbounds_ptradd(va_list_addr, bx.const_usize(1)) // fpr }; - let mut num_regs = bx.load(bx.type_i8(), num_regs_addr, dl.i8_align.abi); + let mut num_regs = bx.load(bx.type_i8(), num_regs_addr, dl.i8_align); // "Align" the register count when the type is passed as `i64`. if is_i64 || (is_f64 && is_soft_float_abi) { @@ -329,7 +328,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( // Increase the used-register count. let reg_incr = if is_i64 || (is_f64 && is_soft_float_abi) { 2 } else { 1 }; let new_num_regs = bx.add(num_regs, bx.cx.const_u8(reg_incr)); - bx.store(new_num_regs, num_regs_addr, dl.i8_align.abi); + bx.store(new_num_regs, num_regs_addr, dl.i8_align); bx.br(end); @@ -339,7 +338,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( let mem_addr = { bx.switch_to_block(in_mem); - bx.store(bx.const_u8(max_regs), num_regs_addr, dl.i8_align.abi); + bx.store(bx.const_u8(max_regs), num_regs_addr, dl.i8_align); // Everything in the overflow area is rounded up to a size of at least 4. let overflow_area_align = Align::from_bytes(4).unwrap(); @@ -738,6 +737,7 @@ fn copy_to_temporary_if_more_aligned<'ll, 'tcx>( src_align, bx.const_u32(layout.layout.size().bytes() as u32), MemFlags::empty(), + None, ); tmp } else { @@ -760,7 +760,7 @@ fn x86_64_sysv64_va_arg_from_memory<'ll, 'tcx>( // byte boundary if alignment needed by type exceeds 8 byte boundary. // It isn't stated explicitly in the standard, but in practice we use // alignment greater than 16 where necessary. - if layout.layout.align.abi.bytes() > 8 { + if layout.layout.align.bytes() > 8 { unreachable!("all instances of VaArgSafe have an alignment <= 8"); } @@ -813,7 +813,7 @@ fn emit_xtensa_va_arg<'ll, 'tcx>( let va_ndx_offset = va_reg_offset + 4; let offset_ptr = bx.inbounds_ptradd(va_list_addr, bx.cx.const_usize(va_ndx_offset)); - let offset = bx.load(bx.type_i32(), offset_ptr, bx.tcx().data_layout.i32_align.abi); + let offset = bx.load(bx.type_i32(), offset_ptr, bx.tcx().data_layout.i32_align); let offset = round_up_to_alignment(bx, offset, layout.align.abi); let slot_size = layout.size.align_to(Align::from_bytes(4).unwrap()).bytes() as i32; diff --git a/compiler/rustc_codegen_llvm/src/value.rs b/compiler/rustc_codegen_llvm/src/value.rs index 2eabac3be8c56..37f05f10c50cd 100644 --- a/compiler/rustc_codegen_llvm/src/value.rs +++ b/compiler/rustc_codegen_llvm/src/value.rs @@ -1,8 +1,7 @@ use std::hash::{Hash, Hasher}; use std::{fmt, ptr}; -use crate::llvm; -pub(crate) use crate::llvm::Value; +use crate::llvm::{self, Value}; impl PartialEq for Value { fn eq(&self, other: &Self) -> bool { diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 5462163f4ffd3..9c5a3d839ceba 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -8,9 +8,7 @@ edition = "2024" ar_archive_writer = "0.5" bitflags = "2.4.1" bstr = "1.11.3" -# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version -# per crate", so if you change this, you need to also change it in `rustc_llvm` and `rustc_windows_rc`. -cc = "=1.2.16" +find-msvc-tools = "0.1.2" itertools = "0.12" pathdiff = "0.2.0" regex = "1.4" diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 1dd65d38a2be7..e321b0773ec39 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -8,8 +8,6 @@ codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error} -codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto - codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty @@ -99,10 +97,10 @@ codegen_ssa_invalid_literal_value = invalid literal value codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` -codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` - codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}` +codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` + codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` codegen_ssa_invalid_monomorphization_cast_wide_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}` @@ -225,8 +223,6 @@ codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple time codegen_ssa_no_field = no field `{$name}` -codegen_ssa_no_mangle_nameless = `#[no_mangle]` cannot be used on {$definition} as it has no name - codegen_ssa_no_module_named = no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names} diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 48b01ea2df197..ea538d3d46981 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -9,7 +9,7 @@ use std::path::{Path, PathBuf}; use std::process::{Output, Stdio}; use std::{env, fmt, fs, io, mem, str}; -use cc::windows_registry; +use find_msvc_tools; use itertools::Itertools; use regex::Regex; use rustc_arena::TypedArena; @@ -47,8 +47,8 @@ use rustc_span::Symbol; use rustc_target::spec::crt_objects::CrtObjects; use rustc_target::spec::{ BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, - LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, - SanitizerSet, SplitDebuginfo, + LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, RelocModel, RelroLevel, SanitizerSet, + SplitDebuginfo, }; use tracing::{debug, info, warn}; @@ -79,6 +79,7 @@ pub fn link_binary( codegen_results: CodegenResults, metadata: EncodedMetadata, outputs: &OutputFilenames, + codegen_backend: &'static str, ) { let _timer = sess.timer("link_binary"); let output_metadata = sess.opts.output_types.contains_key(&OutputType::Metadata); @@ -154,6 +155,7 @@ pub fn link_binary( &codegen_results, &metadata, path.as_ref(), + codegen_backend, ); } } @@ -680,6 +682,7 @@ fn link_natively( codegen_results: &CodegenResults, metadata: &EncodedMetadata, tmpdir: &Path, + codegen_backend: &'static str, ) { info!("preparing {:?} to {:?}", crate_type, out_filename); let (linker_path, flavor) = linker_and_flavor(sess); @@ -705,6 +708,7 @@ fn link_natively( codegen_results, metadata, self_contained_components, + codegen_backend, ); linker::disable_localization(&mut cmd); @@ -877,9 +881,9 @@ fn link_natively( // All Microsoft `link.exe` linking ror codes are // four digit numbers in the range 1000 to 9999 inclusive if is_msvc_link_exe && (code < 1000 || code > 9999) { - let is_vs_installed = windows_registry::find_vs_version().is_ok(); + let is_vs_installed = find_msvc_tools::find_vs_version().is_ok(); let has_linker = - windows_registry::find_tool(&sess.target.arch, "link.exe").is_some(); + find_msvc_tools::find_tool(&sess.target.arch, "link.exe").is_some(); sess.dcx().emit_note(errors::LinkExeUnexpectedError); @@ -1486,7 +1490,7 @@ fn print_native_static_libs( NativeLibKind::Static { bundle: None | Some(true), .. } | NativeLibKind::LinkArg | NativeLibKind::WasmImportModule - | NativeLibKind::RawDylib => None, + | NativeLibKind::RawDylib { .. } => None, } }) // deduplication of consecutive repeated libraries, see rust-lang/rust#113209 @@ -2208,6 +2212,7 @@ fn linker_with_args( codegen_results: &CodegenResults, metadata: &EncodedMetadata, self_contained_components: LinkSelfContainedComponents, + codegen_backend: &'static str, ) -> Command { let self_contained_crt_objects = self_contained_components.is_crt_objects_enabled(); let cmd = &mut *super::linker::get_linker( @@ -2216,6 +2221,7 @@ fn linker_with_args( flavor, self_contained_components.are_any_components_enabled(), &codegen_results.crate_info.target_cpu, + codegen_backend, ); let link_output_kind = link_output_kind(sess, crate_type); @@ -2358,13 +2364,13 @@ fn linker_with_args( cmd.add_object(&output_path); } } else { - for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects( + for (link_path, as_needed) in raw_dylib::create_raw_dylib_elf_stub_shared_objects( sess, codegen_results.crate_info.used_libraries.iter(), &raw_dylib_dir, ) { // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. - cmd.link_dylib_by_name(&link_path, true, false); + cmd.link_dylib_by_name(&link_path, true, as_needed); } } // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case @@ -2405,13 +2411,13 @@ fn linker_with_args( cmd.add_object(&output_path); } } else { - for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects( + for (link_path, as_needed) in raw_dylib::create_raw_dylib_elf_stub_shared_objects( sess, native_libraries_from_nonstatics, &raw_dylib_dir, ) { // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects. - cmd.link_dylib_by_name(&link_path, true, false); + cmd.link_dylib_by_name(&link_path, true, as_needed); } } @@ -2512,10 +2518,10 @@ fn add_order_independent_options( if sess.target.os == "emscripten" { cmd.cc_arg(if sess.opts.unstable_opts.emscripten_wasm_eh { "-fwasm-exceptions" - } else if sess.panic_strategy() == PanicStrategy::Abort { - "-sDISABLE_EXCEPTION_CATCHING=1" - } else { + } else if sess.panic_strategy().unwinds() { "-sDISABLE_EXCEPTION_CATCHING=0" + } else { + "-sDISABLE_EXCEPTION_CATCHING=1" }); } @@ -2720,7 +2726,7 @@ fn add_native_libs_from_crate( cmd.link_framework_by_name(name, verbatim, as_needed.unwrap_or(true)) } } - NativeLibKind::RawDylib => { + NativeLibKind::RawDylib { as_needed: _ } => { // Handled separately in `linker_with_args`. } NativeLibKind::WasmImportModule => {} diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs index 9f42991d4c06a..7321bc1da391a 100644 --- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs +++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs @@ -31,7 +31,7 @@ fn collate_raw_dylibs_windows<'a>( let mut dylib_table = FxIndexMap::>::default(); for lib in used_libraries { - if lib.kind == NativeLibKind::RawDylib { + if let NativeLibKind::RawDylib { .. } = lib.kind { let ext = if lib.verbatim { "" } else { ".dll" }; let name = format!("{}{}", lib.name, ext); let imports = dylib_table.entry(name.clone()).or_default(); @@ -128,12 +128,12 @@ pub(super) fn create_raw_dylib_dll_import_libs<'a>( fn collate_raw_dylibs_elf<'a>( sess: &Session, used_libraries: impl IntoIterator, -) -> Vec<(String, Vec)> { +) -> Vec<(String, Vec, bool)> { // Use index maps to preserve original order of imports and libraries. - let mut dylib_table = FxIndexMap::>::default(); + let mut dylib_table = FxIndexMap::, bool)>::default(); for lib in used_libraries { - if lib.kind == NativeLibKind::RawDylib { + if let NativeLibKind::RawDylib { as_needed } = lib.kind { let filename = if lib.verbatim { lib.name.as_str().to_owned() } else { @@ -142,17 +142,19 @@ fn collate_raw_dylibs_elf<'a>( format!("{prefix}{}{ext}", lib.name) }; - let imports = dylib_table.entry(filename.clone()).or_default(); + let (stub_imports, stub_as_needed) = + dylib_table.entry(filename.clone()).or_insert((Default::default(), true)); for import in &lib.dll_imports { - imports.insert(import.name, import); + stub_imports.insert(import.name, import); } + *stub_as_needed = *stub_as_needed && as_needed.unwrap_or(true); } } sess.dcx().abort_if_errors(); dylib_table .into_iter() - .map(|(name, imports)| { - (name, imports.into_iter().map(|(_, import)| import.clone()).collect()) + .map(|(name, (imports, as_needed))| { + (name, imports.into_iter().map(|(_, import)| import.clone()).collect(), as_needed) }) .collect() } @@ -161,10 +163,10 @@ pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>( sess: &Session, used_libraries: impl IntoIterator, raw_dylib_so_dir: &Path, -) -> Vec { +) -> Vec<(String, bool)> { collate_raw_dylibs_elf(sess, used_libraries) .into_iter() - .map(|(load_filename, raw_dylib_imports)| { + .map(|(load_filename, raw_dylib_imports, as_needed)| { use std::hash::Hash; // `load_filename` is the *target/loader* filename that will end up in NEEDED. @@ -205,7 +207,7 @@ pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>( }); }; - temporary_lib_name + (temporary_lib_name, as_needed) }) .collect() } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index a2efd420a327a..ac12314373828 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -4,7 +4,7 @@ use std::io::prelude::*; use std::path::{Path, PathBuf}; use std::{env, io, iter, mem, str}; -use cc::windows_registry; +use find_msvc_tools; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::{ find_native_static_library, try_find_native_dynamic_library, try_find_native_static_library, @@ -17,7 +17,6 @@ use rustc_middle::middle::exported_symbols::{ use rustc_middle::ty::TyCtxt; use rustc_session::Session; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; -use rustc_span::sym; use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld}; use tracing::{debug, warn}; @@ -52,8 +51,9 @@ pub(crate) fn get_linker<'a>( flavor: LinkerFlavor, self_contained: bool, target_cpu: &'a str, + codegen_backend: &'static str, ) -> Box { - let msvc_tool = windows_registry::find_tool(&sess.target.arch, "link.exe"); + let msvc_tool = find_msvc_tools::find_tool(&sess.target.arch, "link.exe"); // If our linker looks like a batch script on Windows then to execute this // we'll need to spawn `cmd` explicitly. This is primarily done to handle @@ -117,7 +117,6 @@ pub(crate) fn get_linker<'a>( if sess.target.is_like_msvc && let Some(ref tool) = msvc_tool { - cmd.args(tool.args()); for (k, v) in tool.env() { if k == "PATH" { new_path.extend(env::split_paths(v)); @@ -155,6 +154,7 @@ pub(crate) fn get_linker<'a>( is_ld: cc == Cc::No, is_gnu: flavor.is_gnu(), uses_lld: flavor.uses_lld(), + codegen_backend, }) as Box, LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box, LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box, @@ -368,6 +368,7 @@ struct GccLinker<'a> { is_ld: bool, is_gnu: bool, uses_lld: bool, + codegen_backend: &'static str, } impl<'a> GccLinker<'a> { @@ -424,9 +425,15 @@ impl<'a> GccLinker<'a> { if let Some(path) = &self.sess.opts.unstable_opts.profile_sample_use { self.link_arg(&format!("-plugin-opt=sample-profile={}", path.display())); }; + let prefix = if self.codegen_backend == "gcc" { + // The GCC linker plugin requires a leading dash. + "-" + } else { + "" + }; self.link_args(&[ - &format!("-plugin-opt={opt_level}"), - &format!("-plugin-opt=mcpu={}", self.target_cpu), + &format!("-plugin-opt={prefix}{opt_level}"), + &format!("-plugin-opt={prefix}mcpu={}", self.target_cpu), ]); } @@ -845,6 +852,11 @@ impl<'a> Linker for GccLinker<'a> { self.sess.dcx().emit_fatal(errors::VersionScriptWriteFailure { error }); } self.link_arg("--dynamic-list").link_arg(path); + } else if self.sess.target.is_like_wasm { + self.link_arg("--no-export-dynamic"); + for (sym, _) in symbols { + self.link_arg("--export").link_arg(sym); + } } else { // Write an LD version script let res: io::Result<()> = try { @@ -1311,37 +1323,7 @@ struct WasmLd<'a> { impl<'a> WasmLd<'a> { fn new(cmd: Command, sess: &'a Session) -> WasmLd<'a> { - // If the atomics feature is enabled for wasm then we need a whole bunch - // of flags: - // - // * `--shared-memory` - the link won't even succeed without this, flags - // the one linear memory as `shared` - // - // * `--max-memory=1G` - when specifying a shared memory this must also - // be specified. We conservatively choose 1GB but users should be able - // to override this with `-C link-arg`. - // - // * `--import-memory` - it doesn't make much sense for memory to be - // exported in a threaded module because typically you're - // sharing memory and instantiating the module multiple times. As a - // result if it were exported then we'd just have no sharing. - // - // On wasm32-unknown-unknown, we also export symbols for glue code to use: - // * `--export=*tls*` - when `#[thread_local]` symbols are used these - // symbols are how the TLS segments are initialized and configured. - let mut wasm_ld = WasmLd { cmd, sess }; - if sess.target_features.contains(&sym::atomics) { - wasm_ld.link_args(&["--shared-memory", "--max-memory=1073741824", "--import-memory"]); - if sess.target.os == "unknown" || sess.target.os == "none" { - wasm_ld.link_args(&[ - "--export=__wasm_init_tls", - "--export=__tls_size", - "--export=__tls_align", - "--export=__tls_base", - ]); - } - } - wasm_ld + WasmLd { cmd, sess } } } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index b49e67217fb01..5bc18e2d7f8bb 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,7 +1,9 @@ use std::collections::hash_map::Entry::*; use rustc_abi::{CanonAbi, X86Call}; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name}; +use rustc_ast::expand::allocator::{ + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, global_fn_name, +}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -498,7 +500,7 @@ pub(crate) fn allocator_shim_symbols( .iter() .map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str())) .chain([ - mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), + mangle_internal_symbol(tcx, global_fn_name(ALLOC_ERROR_HANDLER).as_str()), mangle_internal_symbol(tcx, OomStrategy::SYMBOL), mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), ]) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index cbaf67d734547..7518bbaf16a14 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -15,8 +15,8 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard}; use rustc_errors::emitter::Emitter; use rustc_errors::translation::Translator; use rustc_errors::{ - Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalErrorMarker, Level, MultiSpan, Style, - Suggestions, + Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FatalErrorMarker, Level, + MultiSpan, Style, Suggestions, }; use rustc_fs_util::link_or_copy; use rustc_incremental::{ @@ -346,12 +346,6 @@ pub struct CodegenContext { pub split_dwarf_kind: rustc_session::config::SplitDwarfKind, pub pointer_size: Size, - /// All commandline args used to invoke the compiler, with @file args fully expanded. - /// This will only be used within debug info, e.g. in the pdb file on windows - /// This is mainly useful for other tools that reads that debuginfo to figure out - /// how to call the compiler with the same arguments. - pub expanded_args: Vec, - /// Emitter to use for diagnostics produced during codegen. pub diag_emitter: SharedEmitter, /// LLVM optimizations for which we want to print remarks. @@ -380,7 +374,7 @@ fn generate_thin_lto_work( each_linked_rlib_for_lto: &[PathBuf], needs_thin_lto: Vec<(String, B::ThinBuffer)>, import_only_modules: Vec<(SerializedModule, WorkProduct)>, -) -> Vec<(WorkItem, u64)> { +) -> Vec<(ThinLtoWorkItem, u64)> { let _prof_timer = cgcx.prof.generic_activity("codegen_thin_generate_lto_work"); let (lto_modules, copy_jobs) = B::run_thin_lto( @@ -394,11 +388,11 @@ fn generate_thin_lto_work( .into_iter() .map(|module| { let cost = module.cost(); - (WorkItem::ThinLto(module), cost) + (ThinLtoWorkItem::ThinLto(module), cost) }) .chain(copy_jobs.into_iter().map(|wp| { ( - WorkItem::CopyPostLtoArtifacts(CachedModuleCodegen { + ThinLtoWorkItem::CopyPostLtoArtifacts(CachedModuleCodegen { name: wp.cgu_name.clone(), source: wp, }), @@ -703,64 +697,73 @@ pub(crate) enum WorkItem { /// Copy the post-LTO artifacts from the incremental cache to the output /// directory. CopyPostLtoArtifacts(CachedModuleCodegen), - /// Performs fat LTO on the given module. - FatLto { - exported_symbols_for_lto: Arc>, - each_linked_rlib_for_lto: Vec, - needs_fat_lto: Vec>, - import_only_modules: Vec<(SerializedModule, WorkProduct)>, - }, +} + +enum ThinLtoWorkItem { + /// Copy the post-LTO artifacts from the incremental cache to the output + /// directory. + CopyPostLtoArtifacts(CachedModuleCodegen), /// Performs thin-LTO on the given module. ThinLto(lto::ThinModule), } +// `pthread_setname()` on *nix ignores anything beyond the first 15 +// bytes. Use short descriptions to maximize the space available for +// the module name. +#[cfg(not(windows))] +fn desc(short: &str, _long: &str, name: &str) -> String { + // The short label is three bytes, and is followed by a space. That + // leaves 11 bytes for the CGU name. How we obtain those 11 bytes + // depends on the CGU name form. + // + // - Non-incremental, e.g. `regex.f10ba03eb5ec7975-cgu.0`: the part + // before the `-cgu.0` is the same for every CGU, so use the + // `cgu.0` part. The number suffix will be different for each + // CGU. + // + // - Incremental (normal), e.g. `2i52vvl2hco29us0`: use the whole + // name because each CGU will have a unique ASCII hash, and the + // first 11 bytes will be enough to identify it. + // + // - Incremental (with `-Zhuman-readable-cgu-names`), e.g. + // `regex.f10ba03eb5ec7975-re_builder.volatile`: use the whole + // name. The first 11 bytes won't be enough to uniquely identify + // it, but no obvious substring will, and this is a rarely used + // option so it doesn't matter much. + // + assert_eq!(short.len(), 3); + let name = if let Some(index) = name.find("-cgu.") { + &name[index + 1..] // +1 skips the leading '-'. + } else { + name + }; + format!("{short} {name}") +} + +// Windows has no thread name length limit, so use more descriptive names. +#[cfg(windows)] +fn desc(_short: &str, long: &str, name: &str) -> String { + format!("{long} {name}") +} + impl WorkItem { /// Generate a short description of this work item suitable for use as a thread name. fn short_description(&self) -> String { - // `pthread_setname()` on *nix ignores anything beyond the first 15 - // bytes. Use short descriptions to maximize the space available for - // the module name. - #[cfg(not(windows))] - fn desc(short: &str, _long: &str, name: &str) -> String { - // The short label is three bytes, and is followed by a space. That - // leaves 11 bytes for the CGU name. How we obtain those 11 bytes - // depends on the CGU name form. - // - // - Non-incremental, e.g. `regex.f10ba03eb5ec7975-cgu.0`: the part - // before the `-cgu.0` is the same for every CGU, so use the - // `cgu.0` part. The number suffix will be different for each - // CGU. - // - // - Incremental (normal), e.g. `2i52vvl2hco29us0`: use the whole - // name because each CGU will have a unique ASCII hash, and the - // first 11 bytes will be enough to identify it. - // - // - Incremental (with `-Zhuman-readable-cgu-names`), e.g. - // `regex.f10ba03eb5ec7975-re_builder.volatile`: use the whole - // name. The first 11 bytes won't be enough to uniquely identify - // it, but no obvious substring will, and this is a rarely used - // option so it doesn't matter much. - // - assert_eq!(short.len(), 3); - let name = if let Some(index) = name.find("-cgu.") { - &name[index + 1..] // +1 skips the leading '-'. - } else { - name - }; - format!("{short} {name}") - } - - // Windows has no thread name length limit, so use more descriptive names. - #[cfg(windows)] - fn desc(_short: &str, long: &str, name: &str) -> String { - format!("{long} {name}") - } - match self { WorkItem::Optimize(m) => desc("opt", "optimize module", &m.name), WorkItem::CopyPostLtoArtifacts(m) => desc("cpy", "copy LTO artifacts for", &m.name), - WorkItem::FatLto { .. } => desc("lto", "fat LTO module", "everything"), - WorkItem::ThinLto(m) => desc("lto", "thin-LTO module", m.name()), + } + } +} + +impl ThinLtoWorkItem { + /// Generate a short description of this work item suitable for use as a thread name. + fn short_description(&self) -> String { + match self { + ThinLtoWorkItem::CopyPostLtoArtifacts(m) => { + desc("cpy", "copy LTO artifacts for", &m.name) + } + ThinLtoWorkItem::ThinLto(m) => desc("lto", "thin-LTO module", m.name()), } } } @@ -891,7 +894,7 @@ fn execute_optimize_work_item( fn execute_copy_from_cache_work_item( cgcx: &CodegenContext, module: CachedModuleCodegen, -) -> WorkItemResult { +) -> CompiledModule { let _timer = cgcx .prof .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*module.name); @@ -964,7 +967,7 @@ fn execute_copy_from_cache_work_item( cgcx.create_dcx().handle().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) } - WorkItemResult::Finished(CompiledModule { + CompiledModule { links_from_incr_cache, kind: ModuleKind::Regular, name: module.name, @@ -973,17 +976,19 @@ fn execute_copy_from_cache_work_item( bytecode, assembly, llvm_ir, - }) + } } -fn execute_fat_lto_work_item( +fn do_fat_lto( cgcx: &CodegenContext, exported_symbols_for_lto: &[String], each_linked_rlib_for_lto: &[PathBuf], mut needs_fat_lto: Vec>, import_only_modules: Vec<(SerializedModule, WorkProduct)>, -) -> WorkItemResult { - let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", "everything"); +) -> CompiledModule { + let _timer = cgcx.prof.verbose_generic_activity("LLVM_fatlto"); + + check_lto_allowed(&cgcx); for (module, wp) in import_only_modules { needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module }) @@ -995,19 +1000,155 @@ fn execute_fat_lto_work_item( each_linked_rlib_for_lto, needs_fat_lto, ); - let module = B::codegen(cgcx, module, &cgcx.module_config); - WorkItemResult::Finished(module) + B::codegen(cgcx, module, &cgcx.module_config) +} + +fn do_thin_lto<'a, B: ExtraBackendMethods>( + cgcx: &'a CodegenContext, + exported_symbols_for_lto: Arc>, + each_linked_rlib_for_lto: Vec, + needs_thin_lto: Vec<(String, ::ThinBuffer)>, + lto_import_only_modules: Vec<( + SerializedModule<::ModuleBuffer>, + WorkProduct, + )>, +) -> Vec { + let _timer = cgcx.prof.verbose_generic_activity("LLVM_thinlto"); + + check_lto_allowed(&cgcx); + + let (coordinator_send, coordinator_receive) = channel(); + + // First up, convert our jobserver into a helper thread so we can use normal + // mpsc channels to manage our messages and such. + // After we've requested tokens then we'll, when we can, + // get tokens on `coordinator_receive` which will + // get managed in the main loop below. + let coordinator_send2 = coordinator_send.clone(); + let helper = jobserver::client() + .into_helper_thread(move |token| { + drop(coordinator_send2.send(ThinLtoMessage::Token(token))); + }) + .expect("failed to spawn helper thread"); + + let mut work_items = vec![]; + + // We have LTO work to do. Perform the serial work here of + // figuring out what we're going to LTO and then push a + // bunch of work items onto our queue to do LTO. This all + // happens on the coordinator thread but it's very quick so + // we don't worry about tokens. + for (work, cost) in generate_thin_lto_work( + cgcx, + &exported_symbols_for_lto, + &each_linked_rlib_for_lto, + needs_thin_lto, + lto_import_only_modules, + ) { + let insertion_index = + work_items.binary_search_by_key(&cost, |&(_, cost)| cost).unwrap_or_else(|e| e); + work_items.insert(insertion_index, (work, cost)); + if cgcx.parallel { + helper.request_token(); + } + } + + let mut codegen_aborted = None; + + // These are the Jobserver Tokens we currently hold. Does not include + // the implicit Token the compiler process owns no matter what. + let mut tokens = vec![]; + + // Amount of tokens that are used (including the implicit token). + let mut used_token_count = 0; + + let mut compiled_modules = vec![]; + + // Run the message loop while there's still anything that needs message + // processing. Note that as soon as codegen is aborted we simply want to + // wait for all existing work to finish, so many of the conditions here + // only apply if codegen hasn't been aborted as they represent pending + // work to be done. + loop { + if codegen_aborted.is_none() { + if used_token_count == 0 && work_items.is_empty() { + // All codegen work is done. + break; + } + + // Spin up what work we can, only doing this while we've got available + // parallelism slots and work left to spawn. + while used_token_count < tokens.len() + 1 + && let Some((item, _)) = work_items.pop() + { + spawn_thin_lto_work(&cgcx, coordinator_send.clone(), item); + used_token_count += 1; + } + } else { + // Don't queue up any more work if codegen was aborted, we're + // just waiting for our existing children to finish. + if used_token_count == 0 { + break; + } + } + + // Relinquish accidentally acquired extra tokens. Subtract 1 for the implicit token. + tokens.truncate(used_token_count.saturating_sub(1)); + + match coordinator_receive.recv().unwrap() { + // Save the token locally and the next turn of the loop will use + // this to spawn a new unit of work, or it may get dropped + // immediately if we have no more work to spawn. + ThinLtoMessage::Token(token) => match token { + Ok(token) => { + tokens.push(token); + } + Err(e) => { + let msg = &format!("failed to acquire jobserver token: {e}"); + cgcx.diag_emitter.fatal(msg); + codegen_aborted = Some(FatalError); + } + }, + + ThinLtoMessage::WorkItem { result } => { + // If a thread exits successfully then we drop a token associated + // with that worker and update our `used_token_count` count. + // We may later re-acquire a token to continue running more work. + // We may also not actually drop a token here if the worker was + // running with an "ephemeral token". + used_token_count -= 1; + + match result { + Ok(compiled_module) => compiled_modules.push(compiled_module), + Err(Some(WorkerFatalError)) => { + // Like `CodegenAborted`, wait for remaining work to finish. + codegen_aborted = Some(FatalError); + } + Err(None) => { + // If the thread failed that means it panicked, so + // we abort immediately. + bug!("worker thread panicked"); + } + } + } + } + } + + if let Some(codegen_aborted) = codegen_aborted { + codegen_aborted.raise(); + } + + compiled_modules } fn execute_thin_lto_work_item( cgcx: &CodegenContext, module: lto::ThinModule, -) -> WorkItemResult { +) -> CompiledModule { let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", module.name()); let module = B::optimize_thin(cgcx, module); - let module = B::codegen(cgcx, module, &cgcx.module_config); - WorkItemResult::Finished(module) + B::codegen(cgcx, module, &cgcx.module_config) } /// Messages sent to the coordinator. @@ -1041,6 +1182,17 @@ pub(crate) enum Message { CodegenAborted, } +/// Messages sent to the coordinator. +pub(crate) enum ThinLtoMessage { + /// A jobserver token has become available. Sent from the jobserver helper + /// thread. + Token(io::Result), + + /// The backend has finished processing a work item for a codegen unit. + /// Sent from a backend worker thread. + WorkItem { result: Result> }, +} + /// A message sent from the coordinator thread to the main thread telling it to /// process another codegen unit. pub struct CguMessage; @@ -1092,9 +1244,8 @@ fn start_executing_work( regular_config: Arc, allocator_config: Arc, allocator_module: Option>, - tx_to_llvm_workers: Sender>, + coordinator_send: Sender>, ) -> thread::JoinHandle> { - let coordinator_send = tx_to_llvm_workers; let sess = tcx.sess; let mut each_linked_rlib_for_lto = Vec::new(); @@ -1153,7 +1304,6 @@ fn start_executing_work( remark: sess.opts.cg.remark.clone(), remark_dir, incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), - expanded_args: tcx.sess.expanded_args.clone(), diag_emitter: shared_emitter.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), module_config: regular_config, @@ -1314,7 +1464,6 @@ fn start_executing_work( let mut needs_fat_lto = Vec::new(); let mut needs_thin_lto = Vec::new(); let mut lto_import_only_modules = Vec::new(); - let mut started_lto = false; /// Possible state transitions: /// - Ongoing -> Completed @@ -1404,63 +1553,8 @@ fn start_executing_work( if running_with_any_token(main_thread_state, running_with_own_token) == 0 && work_items.is_empty() { - // All codegen work is done. Do we have LTO work to do? - if needs_fat_lto.is_empty() - && needs_thin_lto.is_empty() - && lto_import_only_modules.is_empty() - { - // Nothing more to do! - break; - } - - // We have LTO work to do. Perform the serial work here of - // figuring out what we're going to LTO and then push a - // bunch of work items onto our queue to do LTO. This all - // happens on the coordinator thread but it's very quick so - // we don't worry about tokens. - assert!(!started_lto); - started_lto = true; - - let needs_fat_lto = mem::take(&mut needs_fat_lto); - let needs_thin_lto = mem::take(&mut needs_thin_lto); - let import_only_modules = mem::take(&mut lto_import_only_modules); - let each_linked_rlib_file_for_lto = - mem::take(&mut each_linked_rlib_file_for_lto); - - check_lto_allowed(&cgcx); - - if !needs_fat_lto.is_empty() { - assert!(needs_thin_lto.is_empty()); - - work_items.push(( - WorkItem::FatLto { - exported_symbols_for_lto: Arc::clone(&exported_symbols_for_lto), - each_linked_rlib_for_lto: each_linked_rlib_file_for_lto, - needs_fat_lto, - import_only_modules, - }, - 0, - )); - if cgcx.parallel { - helper.request_token(); - } - } else { - for (work, cost) in generate_thin_lto_work( - &cgcx, - &exported_symbols_for_lto, - &each_linked_rlib_file_for_lto, - needs_thin_lto, - import_only_modules, - ) { - let insertion_index = work_items - .binary_search_by_key(&cost, |&(_, cost)| cost) - .unwrap_or_else(|e| e); - work_items.insert(insertion_index, (work, cost)); - if cgcx.parallel { - helper.request_token(); - } - } - } + // All codegen work is done. + break; } // In this branch, we know that everything has been codegened, @@ -1598,12 +1692,10 @@ fn start_executing_work( compiled_modules.push(compiled_module); } Ok(WorkItemResult::NeedsFatLto(fat_lto_input)) => { - assert!(!started_lto); assert!(needs_thin_lto.is_empty()); needs_fat_lto.push(fat_lto_input); } Ok(WorkItemResult::NeedsThinLto(name, thin_buffer)) => { - assert!(!started_lto); assert!(needs_fat_lto.is_empty()); needs_thin_lto.push((name, thin_buffer)); } @@ -1620,7 +1712,6 @@ fn start_executing_work( } Message::AddImportOnlyModule { module_data, work_product } => { - assert!(!started_lto); assert_eq!(codegen_state, Ongoing); assert_eq!(main_thread_state, MainThreadState::Codegenning); lto_import_only_modules.push((module_data, work_product)); @@ -1629,12 +1720,43 @@ fn start_executing_work( } } + // Drop to print timings + drop(llvm_start_time); + if codegen_state == Aborted { return Err(()); } - // Drop to print timings - drop(llvm_start_time); + drop(codegen_state); + drop(tokens); + drop(helper); + assert!(work_items.is_empty()); + + if !needs_fat_lto.is_empty() { + assert!(compiled_modules.is_empty()); + assert!(needs_thin_lto.is_empty()); + + // This uses the implicit token + let module = do_fat_lto( + &cgcx, + &exported_symbols_for_lto, + &each_linked_rlib_file_for_lto, + needs_fat_lto, + lto_import_only_modules, + ); + compiled_modules.push(module); + } else if !needs_thin_lto.is_empty() || !lto_import_only_modules.is_empty() { + assert!(compiled_modules.is_empty()); + assert!(needs_fat_lto.is_empty()); + + compiled_modules.extend(do_thin_lto( + &cgcx, + exported_symbols_for_lto, + each_linked_rlib_file_for_lto, + needs_thin_lto, + lto_import_only_modules, + )); + } // Regardless of what order these modules completed in, report them to // the backend in the same order every time to ensure that we're handing @@ -1725,20 +1847,9 @@ fn spawn_work<'a, B: ExtraBackendMethods>( B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, m), - WorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m), - WorkItem::FatLto { - exported_symbols_for_lto, - each_linked_rlib_for_lto, - needs_fat_lto, - import_only_modules, - } => execute_fat_lto_work_item( - &cgcx, - &exported_symbols_for_lto, - &each_linked_rlib_for_lto, - needs_fat_lto, - import_only_modules, - ), - WorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m), + WorkItem::CopyPostLtoArtifacts(m) => { + WorkItemResult::Finished(execute_copy_from_cache_work_item(&cgcx, m)) + } })); let msg = match result { @@ -1758,6 +1869,36 @@ fn spawn_work<'a, B: ExtraBackendMethods>( .expect("failed to spawn work thread"); } +fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>( + cgcx: &'a CodegenContext, + coordinator_send: Sender, + work: ThinLtoWorkItem, +) { + let cgcx = cgcx.clone(); + + B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || { + let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work { + ThinLtoWorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m), + ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m), + })); + + let msg = match result { + Ok(result) => ThinLtoMessage::WorkItem { result: Ok(result) }, + + // We ignore any `FatalError` coming out of `execute_work_item`, as a + // diagnostic was already sent off to the main thread - just surface + // that there was an error in this worker. + Err(err) if err.is::() => { + ThinLtoMessage::WorkItem { result: Err(Some(WorkerFatalError)) } + } + + Err(_) => ThinLtoMessage::WorkItem { result: Err(None) }, + }; + drop(coordinator_send.send(msg)); + }) + .expect("failed to spawn work thread"); +} + enum SharedEmitterMessage { Diagnostic(Diagnostic), InlineAsmError(SpanData, String, Level, Option<(String, Vec)>), diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 45b028aa8eff2..c35b05f798eac 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -6,17 +6,19 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; use rustc_ast as ast; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::{ + ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorMethod, AllocatorTy, +}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::{IntoDynSyncSend, par_map}; use rustc_data_structures::unord::UnordMap; -use rustc_hir::attrs::OptimizeAttr; +use rustc_hir::attrs::{DebuggerVisualizerType, OptimizeAttr}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::{ItemId, Target}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; -use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType}; +use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::{self, SymbolExportKind}; use rustc_middle::middle::lang_items; @@ -139,7 +141,7 @@ pub fn validate_trivial_unsize<'tcx>( ) else { return false; }; - if !ocx.select_all_or_error().is_empty() { + if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() { return false; } infcx.leak_check(universe, None).is_ok() @@ -168,9 +170,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize( len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"), ), - (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind)) - if src_dyn_kind == target_dyn_kind => - { + (&ty::Dynamic(data_a, _), &ty::Dynamic(data_b, _)) => { let old_info = old_info.expect("unsized_info: missing old info for trait upcasting coercion"); let b_principal_def_id = data_b.principal_def_id(); @@ -208,7 +208,7 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( old_info } } - (_, ty::Dynamic(data, _, _)) => meth::get_vtable( + (_, ty::Dynamic(data, _)) => meth::get_vtable( cx, source, data.principal() @@ -228,6 +228,7 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( ) -> (Bx::Value, Bx::Value) { debug!("unsize_ptr: {:?} => {:?}", src_ty, dst_ty); match (src_ty.kind(), dst_ty.kind()) { + (&ty::Pat(a, _), &ty::Pat(b, _)) => unsize_ptr(bx, src, a, b, old_info), (&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _)) | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => { assert_eq!(bx.cx().type_is_sized(a), old_info.is_none()); @@ -657,6 +658,27 @@ pub(crate) fn needs_allocator_shim_for_linking( !any_dynamic_crate } +pub fn allocator_shim_contents(tcx: TyCtxt<'_>, kind: AllocatorKind) -> Vec { + let mut methods = Vec::new(); + + if kind == AllocatorKind::Default { + methods.extend(ALLOCATOR_METHODS.into_iter().copied()); + } + + // If the return value of allocator_kind_for_codegen is Some then + // alloc_error_handler_kind must also be Some. + if tcx.alloc_error_handler_kind(()).unwrap() == AllocatorKind::Default { + methods.push(AllocatorMethod { + name: ALLOC_ERROR_HANDLER, + special: None, + inputs: &[], + output: AllocatorTy::Never, + }); + } + + methods +} + pub fn codegen_crate( backend: B, tcx: TyCtxt<'_>, @@ -701,14 +723,8 @@ pub fn codegen_crate( cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); tcx.sess.time("write_allocator_module", || { - let module = backend.codegen_allocator( - tcx, - &llmod_id, - kind, - // If allocator_kind is Some then alloc_error_handler_kind must - // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), - ); + let module = + backend.codegen_allocator(tcx, &llmod_id, &allocator_shim_contents(tcx, kind)); Some(ModuleCodegen::new_allocator(llmod_id, module)) }) } else { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index dc500c363f4a7..44de48a3ada51 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -19,7 +19,6 @@ use rustc_span::{Ident, Span, sym}; use rustc_target::spec::SanitizerSet; use crate::errors; -use crate::errors::NoMangleNameless; use crate::target_features::{ check_target_feature_trait_unsafe, check_tied_features, from_target_feature_attr, }; @@ -182,14 +181,10 @@ fn process_builtin_attrs( if tcx.opt_item_name(did.to_def_id()).is_some() { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; } else { - tcx.dcx().emit_err(NoMangleNameless { - span: *attr_span, - definition: format!( - "{} {}", - tcx.def_descr_article(did.to_def_id()), - tcx.def_descr(did.to_def_id()) - ), - }); + tcx.dcx().span_delayed_bug( + *attr_span, + "no_mangle should be on a named function", + ); } } AttributeKind::Optimize(optimize, _) => codegen_fn_attrs.optimize = *optimize, @@ -263,6 +258,19 @@ fn process_builtin_attrs( AttributeKind::Used { used_by, .. } => match used_by { UsedBy::Compiler => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_COMPILER, UsedBy::Linker => codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER, + UsedBy::Default => { + let used_form = if tcx.sess.target.os == "illumos" { + // illumos' `ld` doesn't support a section header that would represent + // `#[used(linker)]`, see + // https://github.com/rust-lang/rust/issues/146169. For that target, + // downgrade as if `#[used(compiler)]` was requested and hope for the + // best. + CodegenFnAttrFlags::USED_COMPILER + } else { + CodegenFnAttrFlags::USED_LINKER + }; + codegen_fn_attrs.flags |= used_form; + } }, AttributeKind::FfiConst(_) => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST @@ -271,7 +279,7 @@ fn process_builtin_attrs( AttributeKind::StdInternalSymbol(_) => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL } - AttributeKind::Linkage(linkage, _) => { + AttributeKind::Linkage(linkage, span) => { let linkage = Some(*linkage); if tcx.is_foreign_item(did) { @@ -279,7 +287,7 @@ fn process_builtin_attrs( if tcx.is_mutable_static(did.into()) { let mut diag = tcx.dcx().struct_span_err( - attr.span(), + *span, "extern mutable statics are not allowed with `#[linkage]`", ); diag.note( @@ -296,6 +304,12 @@ fn process_builtin_attrs( AttributeKind::Sanitize { span, .. } => { interesting_spans.sanitize = Some(*span); } + AttributeKind::ObjcClass { classname, .. } => { + codegen_fn_attrs.objc_class = Some(*classname); + } + AttributeKind::ObjcSelector { methname, .. } => { + codegen_fn_attrs.objc_selector = Some(*methname); + } _ => {} } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index fb5a82051405d..2dd7c6fa7c080 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -37,10 +37,6 @@ pub(crate) struct CguNotRecorded<'a> { pub cgu_name: &'a str, } -#[derive(Diagnostic)] -#[diag(codegen_ssa_autodiff_without_lto)] -pub struct AutodiffWithoutLto; - #[derive(Diagnostic)] #[diag(codegen_ssa_unknown_reuse_kind)] pub(crate) struct UnknownReuseKind { @@ -1288,14 +1284,6 @@ impl Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_ } } -#[derive(Diagnostic)] -#[diag(codegen_ssa_no_mangle_nameless)] -pub(crate) struct NoMangleNameless { - #[primary_span] - pub span: Span, - pub definition: String, -} - #[derive(Diagnostic)] #[diag(codegen_ssa_feature_not_valid)] pub(crate) struct FeatureNotValid<'a> { diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 34ad35a729b98..2fa466b500179 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -78,7 +78,7 @@ fn dyn_trait_in_self<'tcx>( ) -> Option> { for arg in ty.peel_refs().walk() { if let GenericArgKind::Type(ty) = arg.kind() - && let ty::Dynamic(data, _, _) = ty.kind() + && let ty::Dynamic(data, _) = ty.kind() { // FIXME(arbitrary_self_types): This is likely broken for receivers which // have a "non-self" trait objects as a generic argument. diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index c2c023af090a5..de755d5617801 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -150,10 +150,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> { layout.for_variant(self.fx.cx, vidx) } - mir::PlaceElem::Subtype(subtype_ty) => { - let subtype_ty = self.fx.monomorphize(subtype_ty); - self.fx.cx.layout_of(subtype_ty) - } _ => { self.locals[place_ref.local] = LocalKind::Memory; return; @@ -233,7 +229,6 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer PlaceContext::MutatingUse( MutatingUseContext::Store - | MutatingUseContext::Deinit | MutatingUseContext::SetDiscriminant | MutatingUseContext::AsmOutput | MutatingUseContext::Borrow @@ -264,6 +259,10 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer PlaceContext::MutatingUse(MutatingUseContext::Yield) => bug!(), } } + + fn visit_statement_debuginfo(&mut self, _: &mir::StmtDebugInfo<'tcx>, _: Location) { + // Debuginfo does not generate actual code. + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 6492ef73956b0..e2241a77d186c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -200,10 +200,11 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { let fn_ty = bx.fn_decl_backend_type(fn_abi); let fn_attrs = if bx.tcx().def_kind(fx.instance.def_id()).has_codegen_attrs() { - Some(bx.tcx().codegen_fn_attrs(fx.instance.def_id())) + Some(bx.tcx().codegen_instance_attrs(fx.instance.def)) } else { None }; + let fn_attrs = fn_attrs.as_deref(); if !fn_abi.can_unwind { unwind = mir::UnwindAction::Unreachable; @@ -614,7 +615,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (maybe_null, drop_fn, fn_abi, drop_instance) = match ty.kind() { // FIXME(eddyb) perhaps move some of this logic into // `Instance::resolve_drop_in_place`? - ty::Dynamic(_, _, ty::Dyn) => { + ty::Dynamic(_, _) => { // IN THIS ARM, WE HAVE: // ty = *mut (dyn Trait) // which is: exists ( *mut T, Vtable ) @@ -1320,6 +1321,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { for statement in &data.statements { self.codegen_statement(bx, statement); } + self.codegen_stmt_debuginfos(bx, &data.after_last_stmt_debuginfos); let merging_succ = self.codegen_terminator(bx, bb, data.terminator()); if let MergingSucc::False = merging_succ { @@ -1626,6 +1628,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { align, bx.const_usize(copy_bytes), MemFlags::empty(), + None, ); // ...and then load it with the ABI type. llval = load_cast(bx, cast, llscratch, scratch_align); diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index b8f635ab78161..0c9acf087f9f3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -253,6 +253,53 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { spill_slot } + // Indicates that local is set to a new value. The `layout` and `projection` are used to + // calculate the offset. + pub(crate) fn debug_new_val_to_local( + &self, + bx: &mut Bx, + local: mir::Local, + base: PlaceRef<'tcx, Bx::Value>, + projection: &[mir::PlaceElem<'tcx>], + ) { + let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full; + if !full_debug_info { + return; + } + + let vars = match &self.per_local_var_debug_info { + Some(per_local) => &per_local[local], + None => return, + }; + + let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } = + calculate_debuginfo_offset(bx, projection, base.layout); + for var in vars.iter() { + let Some(dbg_var) = var.dbg_var else { + continue; + }; + let Some(dbg_loc) = self.dbg_loc(var.source_info) else { + continue; + }; + bx.dbg_var_value( + dbg_var, + dbg_loc, + base.val.llval, + direct_offset, + &indirect_offsets, + &var.fragment, + ); + } + } + + pub(crate) fn debug_poison_to_local(&self, bx: &mut Bx, local: mir::Local) { + let ty = self.monomorphize(self.mir.local_decls[local].ty); + let layout = bx.cx().layout_of(ty); + let to_backend_ty = bx.cx().immediate_backend_type(layout); + let place_ref = PlaceRef::new_sized(bx.cx().const_poison(to_backend_ty), layout); + self.debug_new_val_to_local(bx, local, place_ref, &[]); + } + /// Apply debuginfo and/or name, after creating the `alloca` for a local, /// or initializing the local with an operand (whichever applies). pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) { @@ -424,7 +471,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { alloca.val.llval, Size::ZERO, &[Size::ZERO], - var.fragment, + &var.fragment, ); } else { bx.dbg_var_addr( @@ -433,7 +480,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { base.val.llval, direct_offset, &indirect_offsets, - var.fragment, + &var.fragment, ); } } @@ -455,7 +502,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx); bx.clear_dbg_loc(); - bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment); + bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], &fragment); } } } diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 3c667b8e88203..befa00c6861ed 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -30,7 +30,7 @@ fn copy_intrinsic<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if allow_overlap { bx.memmove(dst, align, src, align, size, flags); } else { - bx.memcpy(dst, align, src, align, size, flags); + bx.memcpy(dst, align, src, align, size, flags, None); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/locals.rs b/compiler/rustc_codegen_ssa/src/mir/locals.rs index 93f0ab36f2a2f..5d586d97641d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/locals.rs +++ b/compiler/rustc_codegen_ssa/src/mir/locals.rs @@ -40,12 +40,12 @@ impl<'tcx, V> Locals<'tcx, V> { impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub(super) fn initialize_locals(&mut self, values: Vec>) { assert!(self.locals.values.is_empty()); + self.locals.values = IndexVec::from_raw(values); // FIXME(#115215): After #115025 get's merged this might not be necessary - for (local, value) in values.into_iter().enumerate() { + for (local, value) in self.locals.values.iter_enumerated() { match value { LocalRef::Place(_) | LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => (), LocalRef::Operand(op) => { - let local = mir::Local::from_usize(local); let expected_ty = self.monomorphize(self.mir.local_decls[local].ty); if expected_ty != op.layout.ty { warn!( @@ -56,7 +56,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - self.locals.values.push(value); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 6b109e8b8e2f4..1670e2da71fb3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -180,6 +180,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let llfn = cx.get_fn(instance); let mut mir = tcx.instance_mir(instance.def); + // Note that the ABI logic has deduced facts about the functions' parameters based on the MIR we + // got here (`deduce_param_attrs`). That means we can *not* apply arbitrary further MIR + // transforms as that may invalidate those deduced facts! let fn_abi = cx.fn_abi_of_instance(instance, ty::List::empty()); debug!("fn_abi: {:?}", fn_abi); @@ -317,6 +320,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } +/// Replace `clone` calls that come from `use` statements with direct copies if possible. // FIXME: Move this function to mir::transform when post-mono MIR passes land. fn optimize_use_clone<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, diff --git a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs index 31784cabf4af3..e7239ebfecf63 100644 --- a/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs +++ b/compiler/rustc_codegen_ssa/src/mir/naked_asm.rs @@ -228,6 +228,9 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + // emit a label starting with `func_end` for `cargo asm` and other tooling that might + // pattern match on assembly generated by LLVM. + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".size {asm_name}, . - {asm_name}").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { @@ -246,6 +249,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -263,6 +267,7 @@ fn prefix_and_suffix<'tcx>( writeln!(begin, "{asm_name}:").unwrap(); writeln!(end).unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); writeln!(end, ".popsection").unwrap(); if !arch_suffix.is_empty() { writeln!(end, "{}", arch_suffix).unwrap(); @@ -287,6 +292,7 @@ fn prefix_and_suffix<'tcx>( writeln!(end).unwrap(); // .size is ignored for function symbols, so we can skip it writeln!(end, "end_function").unwrap(); + writeln!(end, ".Lfunc_end_{asm_name}:").unwrap(); } BinaryFormat::Xcoff => { // the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index d851c3329802c..88a8e2a844cbc 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -71,16 +71,23 @@ pub enum OperandValue { } impl OperandValue { + /// Return the data pointer and optional metadata as backend values + /// if this value can be treat as a pointer. + pub(crate) fn try_pointer_parts(self) -> Option<(V, Option)> { + match self { + OperandValue::Immediate(llptr) => Some((llptr, None)), + OperandValue::Pair(llptr, llextra) => Some((llptr, Some(llextra))), + OperandValue::Ref(_) | OperandValue::ZeroSized => None, + } + } + /// Treat this value as a pointer and return the data pointer and /// optional metadata as backend values. /// /// If you're making a place, use [`Self::deref`] instead. pub(crate) fn pointer_parts(self) -> (V, Option) { - match self { - OperandValue::Immediate(llptr) => (llptr, None), - OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), - _ => bug!("OperandValue cannot be a pointer: {self:?}"), - } + self.try_pointer_parts() + .unwrap_or_else(|| bug!("OperandValue cannot be a pointer: {self:?}")) } /// Treat this value as a pointer and return the place to which it points. @@ -956,11 +963,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = o.layout.for_variant(bx.cx(), vidx); o = OperandRef { val: o.val, layout } } - mir::PlaceElem::Subtype(subtype_ty) => { - let subtype_ty = self.monomorphize(subtype_ty); - let layout = self.cx.layout_of(subtype_ty); - o = OperandRef { val: o.val, layout } - } _ => return None, } } diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 0090be9fdef06..50f56f913a51e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -347,7 +347,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::ProjectionElem::OpaqueCast(ty) => { bug!("encountered OpaqueCast({ty}) in codegen") } - mir::ProjectionElem::Subtype(ty) => cg_base.project_type(bx, self.monomorphize(ty)), mir::ProjectionElem::UnwrapUnsafeBinder(ty) => { cg_base.project_type(bx, self.monomorphize(ty)) } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index f6f2e3f2a3a3c..0c626a9cd7817 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -1,5 +1,5 @@ use itertools::Itertools as _; -use rustc_abi::{self as abi, FIRST_VARIANT}; +use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT}; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; @@ -7,9 +7,9 @@ use rustc_middle::{bug, mir, span_bug}; use rustc_session::config::OptLevel; use tracing::{debug, instrument}; +use super::FunctionCx; use super::operand::{OperandRef, OperandRefBuilder, OperandValue}; use super::place::{PlaceRef, PlaceValue, codegen_tag_value}; -use super::{FunctionCx, LocalRef}; use crate::common::{IntPredicate, TypeKind}; use crate::traits::*; use crate::{MemFlags, base}; @@ -25,6 +25,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match *rvalue { mir::Rvalue::Use(ref operand) => { let cg_operand = self.codegen_operand(bx, operand); + // Crucially, we do *not* use `OperandValue::Ref` for types with + // `BackendRepr::Scalar | BackendRepr::ScalarPair`. This ensures we match the MIR + // semantics regarding when assignment operators allow overlap of LHS and RHS. + if matches!( + cg_operand.layout.backend_repr, + BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..), + ) { + debug_assert!(!matches!(cg_operand.val, OperandValue::Ref(..))); + } // FIXME: consider not copying constants through stack. (Fixable by codegen'ing // constants into `OperandValue::Ref`; why don’t we do that yet if we don’t?) cg_operand.val.store(bx, dest); @@ -77,7 +86,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, _ty) => { + mir::Rvalue::Cast( + mir::CastKind::Transmute | mir::CastKind::Subtype, + ref operand, + _ty, + ) => { let src = self.codegen_operand(bx, operand); self.codegen_transmute(bx, src, dest); } @@ -477,7 +490,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("Unsupported cast of {operand:?} to {cast:?}"); }) } - mir::CastKind::Transmute => { + mir::CastKind::Transmute | mir::CastKind::Subtype => { self.codegen_transmute_operand(bx, operand, cast) } }; @@ -491,9 +504,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ref) } - mir::Rvalue::CopyForDeref(place) => { - self.codegen_operand(bx, &mir::Operand::Copy(place)) - } mir::Rvalue::RawPtr(kind, place) => { let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { Ty::new_ptr(tcx, ty, kind.to_mutbl_lossy()) @@ -501,14 +511,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ptr) } - mir::Rvalue::Len(place) => { - let size = self.evaluate_array_len(bx, place); - OperandRef { - val: OperandValue::Immediate(size), - layout: bx.cx().layout_of(bx.tcx().types.usize), - } - } - mir::Rvalue::BinaryOp(op_with_overflow, box (ref lhs, ref rhs)) if let Some(op) = op_with_overflow.overflowing_to_wrapping() => { @@ -616,7 +618,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::NullOp::AlignOf => { assert!(bx.cx().type_is_sized(ty)); - let val = layout.align.abi.bytes(); + let val = layout.align.bytes(); bx.cx().const_usize(val) } mir::NullOp::OffsetOf(fields) => { @@ -722,39 +724,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - mir::Rvalue::ShallowInitBox(ref operand, content_ty) => { - let operand = self.codegen_operand(bx, operand); - let val = operand.immediate(); - - let content_ty = self.monomorphize(content_ty); - let box_layout = bx.cx().layout_of(Ty::new_box(bx.tcx(), content_ty)); - - OperandRef { val: OperandValue::Immediate(val), layout: box_layout } - } mir::Rvalue::WrapUnsafeBinder(ref operand, binder_ty) => { let operand = self.codegen_operand(bx, operand); let binder_ty = self.monomorphize(binder_ty); let layout = bx.cx().layout_of(binder_ty); OperandRef { val: operand.val, layout } } + mir::Rvalue::CopyForDeref(_) => bug!("`CopyForDeref` in codegen"), + mir::Rvalue::ShallowInitBox(..) => bug!("`ShallowInitBox` in codegen"), } } - fn evaluate_array_len(&mut self, bx: &mut Bx, place: mir::Place<'tcx>) -> Bx::Value { - // ZST are passed as operands and require special handling - // because codegen_place() panics if Local is operand. - if let Some(index) = place.as_local() - && let LocalRef::Operand(op) = self.locals[index] - && let ty::Array(_, n) = op.layout.ty.kind() - { - let n = n.try_to_target_usize(bx.tcx()).expect("expected monomorphic const in codegen"); - return bx.cx().const_usize(n); - } - // use common size calculation for non zero-sized types - let cg_value = self.codegen_place(bx, place.as_ref()); - cg_value.len(bx.cx()) - } - /// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref` fn codegen_place_to_pointer( &mut self, @@ -892,36 +872,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::BinOp::Cmp => { - use std::cmp::Ordering; assert!(!is_float); - if let Some(value) = bx.three_way_compare(lhs_ty, lhs, rhs) { - return value; - } - let pred = |op| base::bin_op_to_icmp_predicate(op, is_signed); - if bx.cx().tcx().sess.opts.optimize == OptLevel::No { - // FIXME: This actually generates tighter assembly, and is a classic trick - // - // However, as of 2023-11 it optimizes worse in things like derived - // `PartialOrd`, so only use it in debug for now. Once LLVM can handle it - // better (see ), it'll - // be worth trying it in optimized builds as well. - let is_gt = bx.icmp(pred(mir::BinOp::Gt), lhs, rhs); - let gtext = bx.zext(is_gt, bx.type_i8()); - let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs); - let ltext = bx.zext(is_lt, bx.type_i8()); - bx.unchecked_ssub(gtext, ltext) - } else { - // These operations are those expected by `tests/codegen-llvm/integer-cmp.rs`, - // from . - let is_lt = bx.icmp(pred(mir::BinOp::Lt), lhs, rhs); - let is_ne = bx.icmp(pred(mir::BinOp::Ne), lhs, rhs); - let ge = bx.select( - is_ne, - bx.cx().const_i8(Ordering::Greater as i8), - bx.cx().const_i8(Ordering::Equal as i8), - ); - bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge) - } + bx.three_way_compare(lhs_ty, lhs, rhs) } mir::BinOp::AddWithOverflow | mir::BinOp::SubWithOverflow @@ -1048,14 +1000,14 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( imm = match (from_scalar.primitive(), to_scalar.primitive()) { (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), - (Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm), + (Int(..), Pointer(..)) => bx.inttoptr(imm, to_backend_ty), (Pointer(..), Int(..)) => { // FIXME: this exposes the provenance, which shouldn't be necessary. bx.ptrtoint(imm, to_backend_ty) } (Float(_), Pointer(..)) => { let int_imm = bx.bitcast(imm, bx.cx().type_isize()); - bx.ptradd(bx.const_null(bx.type_ptr()), int_imm) + bx.inttoptr(int_imm, to_backend_ty) } (Pointer(..), Float(_)) => { // FIXME: this exposes the provenance, which shouldn't be necessary. diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index f164e0f912373..d0121f7643800 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -1,4 +1,4 @@ -use rustc_middle::mir::{self, NonDivergingIntrinsic}; +use rustc_middle::mir::{self, NonDivergingIntrinsic, StmtDebugInfo}; use rustc_middle::span_bug; use tracing::instrument; @@ -8,6 +8,7 @@ use crate::traits::*; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "debug", skip(self, bx))] pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) { + self.codegen_stmt_debuginfos(bx, &statement.debuginfos); self.set_debug_loc(bx, statement.source_info); match statement.kind { mir::StatementKind::Assign(box (ref place, ref rvalue)) => { @@ -49,11 +50,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::StatementKind::SetDiscriminant { box ref place, variant_index } => { self.codegen_place(bx, place.as_ref()).codegen_set_discr(bx, variant_index); } - mir::StatementKind::Deinit(..) => { - // For now, don't codegen this to anything. In the future it may be worth - // experimenting with what kind of information we can emit to LLVM without hurting - // perf here - } mir::StatementKind::StorageLive(local) => { if let LocalRef::Place(cg_place) = self.locals[local] { cg_place.storage_live(bx); @@ -90,7 +86,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let align = pointee_layout.align; let dst = dst_val.immediate(); let src = src_val.immediate(); - bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty()); + bx.memcpy(dst, align, src, align, bytes, crate::MemFlags::empty(), None); } mir::StatementKind::FakeRead(..) | mir::StatementKind::Retag { .. } @@ -101,4 +97,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { | mir::StatementKind::Nop => {} } } + + pub(crate) fn codegen_stmt_debuginfo(&mut self, bx: &mut Bx, debuginfo: &StmtDebugInfo<'tcx>) { + match debuginfo { + StmtDebugInfo::AssignRef(dest, place) => { + let local_ref = match self.locals[place.local] { + // For an rvalue like `&(_1.1)`, when `BackendRepr` is `BackendRepr::Memory`, we allocate a block of memory to this place. + // The place is an indirect pointer, we can refer to it directly. + LocalRef::Place(place_ref) => Some((place_ref, place.projection.as_slice())), + // For an rvalue like `&((*_1).1)`, we are calculating the address of `_1.1`. + // The deref projection is no-op here. + LocalRef::Operand(operand_ref) if place.is_indirect_first_projection() => { + Some((operand_ref.deref(bx.cx()), &place.projection[1..])) + } + // For an rvalue like `&1`, when `BackendRepr` is `BackendRepr::Scalar`, + // we cannot get the address. + // N.B. `non_ssa_locals` returns that this is an SSA local. + LocalRef::Operand(_) => None, + LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => None, + } + .filter(|(_, projection)| { + // Drop unsupported projections. + projection.iter().all(|p| p.can_use_in_debuginfo()) + }); + if let Some((base, projection)) = local_ref { + self.debug_new_val_to_local(bx, *dest, base, projection); + } else { + // If the address cannot be calculated, use poison to indicate that the value has been optimized out. + self.debug_poison_to_local(bx, *dest); + } + } + StmtDebugInfo::InvalidAssign(local) => { + self.debug_poison_to_local(bx, *local); + } + } + } + + pub(crate) fn codegen_stmt_debuginfos( + &mut self, + bx: &mut Bx, + debuginfos: &[StmtDebugInfo<'tcx>], + ) { + for debuginfo in debuginfos { + self.codegen_stmt_debuginfo(bx, debuginfo); + } + } } diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs index 577012151e49f..e1bd8014d7a2f 100644 --- a/compiler/rustc_codegen_ssa/src/size_of_val.rs +++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs @@ -21,7 +21,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( trace!("size_and_align_of_dst(ty={}, info={:?}): layout: {:?}", t, info, layout); if layout.is_sized() { let size = bx.const_usize(layout.size.bytes()); - let align = bx.const_usize(layout.align.abi.bytes()); + let align = bx.const_usize(layout.align.bytes()); return (size, align); } match t.kind() { @@ -49,7 +49,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // All slice sizes must fit into `isize`, so this multiplication cannot // wrap -- neither signed nor unsigned. bx.unchecked_sumul(info.unwrap(), bx.const_usize(unit.size.bytes())), - bx.const_usize(unit.align.abi.bytes()), + bx.const_usize(unit.align.bytes()), ) } ty::Foreign(_) => { @@ -82,7 +82,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // This function does not return so we can now return whatever we want. let size = bx.const_usize(layout.size.bytes()); - let align = bx.const_usize(layout.align.abi.bytes()); + let align = bx.const_usize(layout.align.bytes()); (size, align) } ty::Adt(..) | ty::Tuple(..) => { @@ -94,7 +94,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let i = layout.fields.count() - 1; let unsized_offset_unadjusted = layout.fields.offset(i).bytes(); - let sized_align = layout.align.abi.bytes(); + let sized_align = layout.align.bytes(); debug!( "DST {} offset of dyn field: {}, statically sized align: {}", t, unsized_offset_unadjusted, sized_align diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 29ec7eb1da3b3..ec53d9f53eb83 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,7 +1,7 @@ use std::any::Any; use std::hash::Hash; -use rustc_ast::expand::allocator::AllocatorKind; +use rustc_ast::expand::allocator::AllocatorMethod; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; @@ -41,6 +41,8 @@ pub trait CodegenBackend { /// Called before `init` so that all other functions are able to emit translatable diagnostics. fn locale_resource(&self) -> &'static str; + fn name(&self) -> &'static str; + fn init(&self, _sess: &Session) {} fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {} @@ -96,7 +98,14 @@ pub trait CodegenBackend { metadata: EncodedMetadata, outputs: &OutputFilenames, ) { - link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, metadata, outputs); + link_binary( + sess, + &ArArchiveBuilderBuilder, + codegen_results, + metadata, + outputs, + self.name(), + ); } } @@ -107,8 +116,7 @@ pub trait ExtraBackendMethods: &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, + methods: &[AllocatorMethod], ) -> Self::Module; /// This generates the codegen unit and returns it along with diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f417d1a7bf724..60296e36e0c1a 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use rustc_abi::{Align, Scalar, Size, WrappingRange}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; +use rustc_middle::mir; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::{AtomicOrdering, Instance, Ty}; use rustc_session::config::OptLevel; @@ -405,15 +406,41 @@ pub trait BuilderMethods<'a, 'tcx>: fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; /// Returns `-1` if `lhs < rhs`, `0` if `lhs == rhs`, and `1` if `lhs > rhs`. - // FIXME: Move the default implementation from `codegen_scalar_binop` into this method and - // remove the `Option` return once LLVM 20 is the minimum version. fn three_way_compare( &mut self, - _ty: Ty<'tcx>, - _lhs: Self::Value, - _rhs: Self::Value, - ) -> Option { - None + ty: Ty<'tcx>, + lhs: Self::Value, + rhs: Self::Value, + ) -> Self::Value { + // FIXME: This implementation was designed around LLVM's ability to optimize, but `cg_llvm` + // overrides this to just use `@llvm.scmp`/`ucmp` since LLVM 20. This default impl should be + // reevaluated with respect to the remaining backends like cg_gcc, whether they might use + // specialized implementations as well, or continue to use a generic implementation here. + use std::cmp::Ordering; + let pred = |op| crate::base::bin_op_to_icmp_predicate(op, ty.is_signed()); + if self.cx().sess().opts.optimize == OptLevel::No { + // This actually generates tighter assembly, and is a classic trick: + // . + // However, as of 2023-11 it optimized worse in LLVM in things like derived + // `PartialOrd`, so we were only using it in debug. Since LLVM now uses its own + // intrinsics, it may be be worth trying it in optimized builds for other backends. + let is_gt = self.icmp(pred(mir::BinOp::Gt), lhs, rhs); + let gtext = self.zext(is_gt, self.type_i8()); + let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs); + let ltext = self.zext(is_lt, self.type_i8()); + self.unchecked_ssub(gtext, ltext) + } else { + // These operations were better optimized by LLVM, before `@llvm.scmp`/`ucmp` in 20. + // See . + let is_lt = self.icmp(pred(mir::BinOp::Lt), lhs, rhs); + let is_ne = self.icmp(pred(mir::BinOp::Ne), lhs, rhs); + let ge = self.select( + is_ne, + self.cx().const_i8(Ordering::Greater as i8), + self.cx().const_i8(Ordering::Equal as i8), + ); + self.select(is_lt, self.cx().const_i8(Ordering::Less as i8), ge) + } } fn memcpy( @@ -424,6 +451,7 @@ pub trait BuilderMethods<'a, 'tcx>: src_align: Align, size: Self::Value, flags: MemFlags, + tt: Option, ); fn memmove( &mut self, @@ -480,7 +508,7 @@ pub trait BuilderMethods<'a, 'tcx>: temp.val.store_with_flags(self, dst.with_type(layout), flags); } else if !layout.is_zst() { let bytes = self.const_usize(layout.size.bytes()); - self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags); + self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, None); } } diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs index b9d4950e0ad36..a4da6c915deec 100644 --- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs @@ -77,7 +77,19 @@ pub trait DebugInfoBuilderMethods: BackendTypes { indirect_offsets: &[Size], // Byte range in the `dbg_var` covered by this fragment, // if this is a fragment of a composite `DIVariable`. - fragment: Option>, + fragment: &Option>, + ); + fn dbg_var_value( + &mut self, + dbg_var: Self::DIVariable, + dbg_loc: Self::DILocation, + value: Self::Value, + direct_offset: Size, + // NB: each offset implies a deref (i.e. they're steps in a pointer chain). + indirect_offsets: &[Size], + // Byte range in the `dbg_var` covered by this fragment, + // if this is a fragment of a composite `DIVariable`. + fragment: &Option>, ); fn set_dbg_loc(&mut self, dbg_loc: Self::DILocation); fn clear_dbg_loc(&mut self); diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 700d7c26752b6..3a2b3f8843191 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -231,9 +231,6 @@ const_eval_mutable_borrow_escaping = const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind} -const_eval_partial_pointer_in_final = encountered partial pointer in final value of {const_eval_intern_kind} - .note = while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value - const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead const_eval_non_const_await = @@ -302,6 +299,9 @@ const_eval_panic = evaluation panicked: {$msg} const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str` +const_eval_partial_pointer_in_final = encountered partial pointer in final value of {const_eval_intern_kind} + .note = while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value + const_eval_partial_pointer_read = unable to read parts of a pointer from memory at {$ptr} const_eval_pointer_arithmetic_overflow = @@ -476,14 +476,23 @@ const_eval_validation_invalid_vtable_trait = {$front_matter}: wrong trait in wid const_eval_validation_mutable_ref_in_const = {$front_matter}: encountered mutable reference in `const` value const_eval_validation_mutable_ref_to_immutable = {$front_matter}: encountered mutable reference or box pointing to read-only memory const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!` -const_eval_validation_null_box = {$front_matter}: encountered a null box -const_eval_validation_null_fn_ptr = {$front_matter}: encountered a null function pointer -const_eval_validation_null_ref = {$front_matter}: encountered a null reference -const_eval_validation_nullable_ptr_out_of_range = {$front_matter}: encountered a potentially null pointer, but expected something that cannot possibly fail to be {$in_range} +const_eval_validation_nonnull_ptr_out_of_range = {$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero +const_eval_validation_null_box = {$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } box +const_eval_validation_null_fn_ptr = {$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } function pointer +const_eval_validation_null_ref = {$front_matter}: encountered a {$maybe -> + [true] maybe-null + *[false] null + } reference const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but expected something {$in_range} const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected} -const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range} +const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range} const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty} const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes}) const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes}) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index ca707b50d50d9..2c6dd5bd01f9c 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -415,7 +415,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { ) })); - let errors = ocx.select_all_or_error(); + let errors = ocx.evaluate_obligations_error_on_ambiguity(); if errors.is_empty() { Some(ConstConditionsHold::Yes) } else { @@ -573,8 +573,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Use(_) | Rvalue::CopyForDeref(..) | Rvalue::Repeat(..) - | Rvalue::Discriminant(..) - | Rvalue::Len(_) => {} + | Rvalue::Discriminant(..) => {} Rvalue::Aggregate(kind, ..) => { if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref() @@ -733,7 +732,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { match statement.kind { StatementKind::Assign(..) | StatementKind::SetDiscriminant { .. } - | StatementKind::Deinit(..) | StatementKind::FakeRead(..) | StatementKind::StorageLive(_) | StatementKind::StorageDead(_) diff --git a/compiler/rustc_const_eval/src/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/check_consts/qualifs.rs index faf41f1658b70..5b65f1726f6c2 100644 --- a/compiler/rustc_const_eval/src/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/check_consts/qualifs.rs @@ -119,7 +119,7 @@ impl Qualif for HasMutInterior { ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]), ); ocx.register_obligation(obligation); - let errors = ocx.select_all_or_error(); + let errors = ocx.evaluate_obligations_error_on_ambiguity(); !errors.is_empty() } @@ -197,7 +197,7 @@ impl Qualif for NeedsNonConstDrop { }, ), )); - !ocx.select_all_or_error().is_empty() + !ocx.evaluate_obligations_error_on_ambiguity().is_empty() } fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool { @@ -232,9 +232,7 @@ where Q::in_any_value_of_ty(cx, rvalue.ty(cx.body, cx.tcx)) } - Rvalue::Discriminant(place) | Rvalue::Len(place) => { - in_place::(cx, in_local, place.as_ref()) - } + Rvalue::Discriminant(place) => in_place::(cx, in_local, place.as_ref()), Rvalue::CopyForDeref(place) => in_place::(cx, in_local, place.as_ref()), @@ -295,7 +293,6 @@ where ProjectionElem::Index(index) if in_local(index) => return true, ProjectionElem::Deref - | ProjectionElem::Subtype(_) | ProjectionElem::Field(_, _) | ProjectionElem::OpaqueCast(_) | ProjectionElem::ConstantIndex { .. } diff --git a/compiler/rustc_const_eval/src/check_consts/resolver.rs b/compiler/rustc_const_eval/src/check_consts/resolver.rs index d98e5027e4d6b..664dda8701a63 100644 --- a/compiler/rustc_const_eval/src/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/check_consts/resolver.rs @@ -197,7 +197,6 @@ where | mir::Rvalue::CopyForDeref(..) | mir::Rvalue::ThreadLocalRef(..) | mir::Rvalue::Repeat(..) - | mir::Rvalue::Len(..) | mir::Rvalue::BinaryOp(..) | mir::Rvalue::NullaryOp(..) | mir::Rvalue::UnaryOp(..) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index e00fb2c1eaf98..69a8f163ca93c 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -110,7 +110,7 @@ pub fn get_span_and_frames<'tcx>( if frame.times < 3 { let times = frame.times; frame.times = 0; - frames.extend(std::iter::repeat(frame).take(times as usize)); + frames.extend(std::iter::repeat_n(frame, times as usize)); } else { frames.push(frame); } diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 35c3e3ed3150e..530d8d4b1fa62 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt; fn parent_impl_or_trait_constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { let parent_id = tcx.local_parent(def_id); match tcx.def_kind(parent_id) { - DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).unwrap().constness, + DefKind::Impl { of_trait: true } => tcx.impl_trait_header(parent_id).constness, DefKind::Trait => { if tcx.is_const_trait(parent_id.into()) { hir::Constness::Const diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 37c6c4a61d8d6..7c41258ebfe5f 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,6 +1,7 @@ use rustc_abi::{BackendRepr, FieldIdx, VariantIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId, ValTreeCreationError}; +use rustc_middle::traits::ObligationCause; use rustc_middle::ty::layout::{LayoutCx, TyAndLayout}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, mir}; @@ -196,6 +197,7 @@ fn reconstruct_place_meta<'tcx>( // Traverse the type, and update `last_valtree` as we go. let tail = tcx.struct_tail_raw( layout.ty, + &ObligationCause::dummy(), |ty| ty, || { let branches = last_valtree.unwrap_branch(); diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 2d412ee5ec26e..a0958a2b9ef3a 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -666,9 +666,9 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { PartialPointer => const_eval_validation_partial_pointer, MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable, MutableRefInConst => const_eval_validation_mutable_ref_in_const, - NullFnPtr => const_eval_validation_null_fn_ptr, + NullFnPtr { .. } => const_eval_validation_null_fn_ptr, NeverVal => const_eval_validation_never_val, - NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range, + NonnullPtrMaybeNull { .. } => const_eval_validation_nonnull_ptr_out_of_range, PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range, OutOfRange { .. } => const_eval_validation_out_of_range, UnsafeCellInImmutable => const_eval_validation_unsafe_cell, @@ -696,8 +696,8 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { } UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box, - NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box, - NullPtr { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_null_ref, + NullPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_null_box, + NullPtr { ptr_kind: PointerKind::Ref(_), .. } => const_eval_validation_null_ref, DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => { const_eval_validation_dangling_box_no_provenance } @@ -804,9 +804,7 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { | InvalidFnPtr { value } => { err.arg("value", value); } - NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => { - add_range_arg(range, max_value, err) - } + PtrOutOfRange { range, max_value } => add_range_arg(range, max_value, err), OutOfRange { range, max_value, value } => { err.arg("value", value); add_range_arg(range, max_value, err); @@ -822,10 +820,12 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> { err.arg("vtable_dyn_type", vtable_dyn_type.to_string()); err.arg("expected_dyn_type", expected_dyn_type.to_string()); } - NullPtr { .. } - | MutableRefToImmutable + NullPtr { maybe, .. } | NullFnPtr { maybe } => { + err.arg("maybe", maybe); + } + MutableRefToImmutable | MutableRefInConst - | NullFnPtr + | NonnullPtrMaybeNull | NeverVal | UnsafeCellInImmutable | InvalidMetaSliceTooLarge { .. } diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index 4cb88d44e1b11..312ebe7ddd09d 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -127,7 +127,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } else if all_fields_1zst(def.variant(var1))? { def.variant(var0) } else { - // No varant is all-1-ZST, so no NPO. + // No variant is all-1-ZST, so no NPO. return interp_ok(layout); }; // The "relevant" variant must have exactly one field, and its type is the "inner" type. @@ -658,7 +658,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let val = self.read_immediate(&receiver)?; break self.ref_to_mplace(&val)?; } - ty::Dynamic(.., ty::Dyn) => break receiver.assert_mem_place(), // no immediate unsized values + ty::Dynamic(..) => break receiver.assert_mem_place(), // no immediate unsized values _ => { // Not there yet, search for the only non-ZST field. // (The rules for `DispatchFromDyn` ensure there's exactly one such field.) @@ -675,7 +675,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // (For that reason we also cannot use `unpack_dyn_trait`.) let receiver_tail = self.tcx.struct_tail_for_codegen(receiver_place.layout.ty, self.typing_env); - let ty::Dynamic(receiver_trait, _, ty::Dyn) = receiver_tail.kind() else { + let ty::Dynamic(receiver_trait, _) = receiver_tail.kind() else { span_bug!(self.cur_span(), "dynamic call on non-`dyn` type {}", receiver_tail) }; assert!(receiver_place.layout.is_unsized()); @@ -822,7 +822,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // instead we do the virtual call stuff ourselves. It's easier here than in `eval_fn_call` // since we can just get a place of the underlying type and use `mplace_to_ref`. let place = match place.layout.ty.kind() { - ty::Dynamic(data, _, ty::Dyn) => { + ty::Dynamic(data, _) => { // Dropping a trait object. Need to find actual drop fn. self.unpack_dyn_trait(&place, data)? } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index e3afeda5b7c97..cf5ee03bedae8 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -133,7 +133,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } - CastKind::Transmute => { + CastKind::Transmute | CastKind::Subtype => { assert!(src.layout.is_sized()); assert!(dest.layout.is_sized()); assert_eq!(cast_ty, dest.layout.ty); // we otherwise ignore `cast_ty` enirely... @@ -386,7 +386,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ); self.write_immediate(val, dest) } - (ty::Dynamic(data_a, _, ty::Dyn), ty::Dynamic(data_b, _, ty::Dyn)) => { + (ty::Dynamic(data_a, _), ty::Dynamic(data_b, _)) => { let val = self.read_immediate(src)?; // MIR building generates odd NOP casts, prevent them from causing unexpected trouble. // See . @@ -436,7 +436,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let new_vptr = self.get_vtable_ptr(ty, data_b)?; self.write_immediate(Immediate::new_dyn_trait(old_data, new_vptr, self), dest) } - (_, &ty::Dynamic(data, _, ty::Dyn)) => { + (_, &ty::Dynamic(data, _)) => { // Initial cast from sized to dyn trait let vtable = self.get_vtable_ptr(src_pointee_ty, data)?; let ptr = self.read_pointer(src)?; @@ -466,6 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> InterpResult<'tcx> { trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty); match (src.layout.ty.kind(), cast_ty.ty.kind()) { + (&ty::Pat(_, s_pat), &ty::Pat(cast_ty, c_pat)) if s_pat == c_pat => { + let src = self.project_field(src, FieldIdx::ZERO)?; + let dest = self.project_field(dest, FieldIdx::ZERO)?; + let cast_ty = self.layout_of(cast_ty)?; + self.unsize_into(&src, cast_ty, &dest) + } (&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _)) | (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c), (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 91ed71ac3e54c..0e4a98f0941ac 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -469,7 +469,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } interp_ok(Some((full_size, full_align))) } - ty::Dynamic(expected_trait, _, ty::Dyn) => { + ty::Dynamic(expected_trait, _) => { let vtable = metadata.unwrap_meta().to_pointer(self)?; // Read size and align from vtable (already checks size). interp_ok(Some(self.get_vtable_size_and_align(vtable, Some(expected_trait))?)) diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 5e3d0a15d8bc1..fc7f1166af99a 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -2,6 +2,8 @@ //! looking at their MIR. Intrinsics/functions supported here are shared by CTFE //! and miri. +mod simd; + use std::assert_matches::assert_matches; use rustc_abi::{FieldIdx, HasDataLayout, Size}; @@ -9,8 +11,8 @@ use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_middle::mir::interpret::{CTFE_ALLOC_SALT, read_target_uint, write_target_uint}; use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{Ty, TyCtxt}; -use rustc_middle::{bug, ty}; +use rustc_middle::ty::{FloatTy, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug, ty}; use rustc_span::{Symbol, sym}; use tracing::trace; @@ -121,6 +123,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ) -> InterpResult<'tcx, bool> { let instance_args = instance.args; let intrinsic_name = self.tcx.item_name(instance.def_id()); + + if intrinsic_name.as_str().starts_with("simd_") { + return self.eval_simd_intrinsic(intrinsic_name, instance_args, args, dest, ret); + } + let tcx = self.tcx.tcx; match intrinsic_name { @@ -181,7 +188,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::Ref(_, _, _) | ty::FnDef(_, _) | ty::FnPtr(..) - | ty::Dynamic(_, _, _) + | ty::Dynamic(_, _) | ty::Closure(_, _) | ty::CoroutineClosure(_, _) | ty::Coroutine(_, _) @@ -454,37 +461,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.exact_div(&val, &size, dest)?; } - sym::simd_insert => { - let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); - let elem = &args[2]; - let (input, input_len) = self.project_to_simd(&args[0])?; - let (dest, dest_len) = self.project_to_simd(dest)?; - assert_eq!(input_len, dest_len, "Return vector length must match input length"); - // Bounds are not checked by typeck so we have to do it ourselves. - if index >= input_len { - throw_ub_format!( - "`simd_insert` index {index} is out-of-bounds of vector with length {input_len}" - ); - } - - for i in 0..dest_len { - let place = self.project_index(&dest, i)?; - let value = - if i == index { elem.clone() } else { self.project_index(&input, i)? }; - self.copy_op(&value, &place)?; - } - } - sym::simd_extract => { - let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); - let (input, input_len) = self.project_to_simd(&args[0])?; - // Bounds are not checked by typeck so we have to do it ourselves. - if index >= input_len { - throw_ub_format!( - "`simd_extract` index {index} is out-of-bounds of vector with length {input_len}" - ); - } - self.copy_op(&self.project_index(&input, index)?, dest)?; - } sym::black_box => { // These just return their argument self.copy_op(&args[0], dest)?; @@ -636,6 +612,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { dest, rustc_apfloat::Round::NearestTiesToEven, )?, + sym::fmaf16 => self.fma_intrinsic::(args, dest)?, + sym::fmaf32 => self.fma_intrinsic::(args, dest)?, + sym::fmaf64 => self.fma_intrinsic::(args, dest)?, + sym::fmaf128 => self.fma_intrinsic::(args, dest)?, + sym::fmuladdf16 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf32 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf64 => self.float_muladd_intrinsic::(args, dest)?, + sym::fmuladdf128 => self.float_muladd_intrinsic::(args, dest)?, // Unsupported intrinsic: skip the return_to_block below. _ => return interp_ok(false), @@ -870,7 +854,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { .compute_size_in_bytes(layout.size, count) .ok_or_else(|| err_ub_custom!(fluent::const_eval_size_overflow, name = name))?; - let bytes = std::iter::repeat(byte).take(len.bytes_usize()); + let bytes = std::iter::repeat_n(byte, len.bytes_usize()); self.write_bytes_ptr(dst, bytes) } @@ -1035,4 +1019,104 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_scalar(res, dest)?; interp_ok(()) } + + fn fma_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let c: F = self.read_scalar(&args[2])?.to_float()?; + + let res = a.mul_add(b, c).value; + let res = self.adjust_nan(res, &[a, b, c]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + fn float_muladd_intrinsic( + &mut self, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + ) -> InterpResult<'tcx, ()> + where + F: rustc_apfloat::Float + rustc_apfloat::FloatConvert + Into>, + { + let a: F = self.read_scalar(&args[0])?.to_float()?; + let b: F = self.read_scalar(&args[1])?.to_float()?; + let c: F = self.read_scalar(&args[2])?.to_float()?; + + let fuse = M::float_fuse_mul_add(self); + + let res = if fuse { a.mul_add(b, c).value } else { ((a * b).value + c).value }; + let res = self.adjust_nan(res, &[a, b, c]); + self.write_scalar(res, dest)?; + interp_ok(()) + } + + /// Converts `src` from floating point to integer type `dest_ty` + /// after rounding with mode `round`. + /// Returns `None` if `f` is NaN or out of range. + pub fn float_to_int_checked( + &self, + src: &ImmTy<'tcx, M::Provenance>, + cast_to: TyAndLayout<'tcx>, + round: rustc_apfloat::Round, + ) -> InterpResult<'tcx, Option>> { + fn float_to_int_inner<'tcx, F: rustc_apfloat::Float, M: Machine<'tcx>>( + ecx: &InterpCx<'tcx, M>, + src: F, + cast_to: TyAndLayout<'tcx>, + round: rustc_apfloat::Round, + ) -> (Scalar, rustc_apfloat::Status) { + let int_size = cast_to.layout.size; + match cast_to.ty.kind() { + // Unsigned + ty::Uint(_) => { + let res = src.to_u128_r(int_size.bits_usize(), round, &mut false); + (Scalar::from_uint(res.value, int_size), res.status) + } + // Signed + ty::Int(_) => { + let res = src.to_i128_r(int_size.bits_usize(), round, &mut false); + (Scalar::from_int(res.value, int_size), res.status) + } + // Nothing else + _ => span_bug!( + ecx.cur_span(), + "attempted float-to-int conversion with non-int output type {}", + cast_to.ty, + ), + } + } + + let ty::Float(fty) = src.layout.ty.kind() else { + bug!("float_to_int_checked: non-float input type {}", src.layout.ty) + }; + + let (val, status) = match fty { + FloatTy::F16 => float_to_int_inner(self, src.to_scalar().to_f16()?, cast_to, round), + FloatTy::F32 => float_to_int_inner(self, src.to_scalar().to_f32()?, cast_to, round), + FloatTy::F64 => float_to_int_inner(self, src.to_scalar().to_f64()?, cast_to, round), + FloatTy::F128 => float_to_int_inner(self, src.to_scalar().to_f128()?, cast_to, round), + }; + + if status.intersects( + rustc_apfloat::Status::INVALID_OP + | rustc_apfloat::Status::OVERFLOW + | rustc_apfloat::Status::UNDERFLOW, + ) { + // Floating point value is NaN (flagged with INVALID_OP) or outside the range + // of values of the integer type (flagged with OVERFLOW or UNDERFLOW). + interp_ok(None) + } else { + // Floating point value can be represented by the integer type after rounding. + // The INEXACT flag is ignored on purpose to allow rounding. + interp_ok(Some(ImmTy::from_scalar(val, cast_to))) + } + } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs new file mode 100644 index 0000000000000..0dba66ae93721 --- /dev/null +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/simd.rs @@ -0,0 +1,782 @@ +use either::Either; +use rustc_abi::Endian; +use rustc_apfloat::{Float, Round}; +use rustc_middle::mir::interpret::{InterpErrorKind, UndefinedBehaviorInfo}; +use rustc_middle::ty::FloatTy; +use rustc_middle::{bug, err_ub_format, mir, span_bug, throw_unsup_format, ty}; +use rustc_span::{Symbol, sym}; +use tracing::trace; + +use super::{ + ImmTy, InterpCx, InterpResult, Machine, OpTy, PlaceTy, Provenance, Scalar, Size, interp_ok, + throw_ub_format, +}; +use crate::interpret::Writeable; + +#[derive(Copy, Clone)] +pub(crate) enum MinMax { + Min, + Max, +} + +impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { + /// Returns `true` if emulation happened. + /// Here we implement the intrinsics that are common to all CTFE instances; individual machines can add their own + /// intrinsic handling. + pub fn eval_simd_intrinsic( + &mut self, + intrinsic_name: Symbol, + generic_args: ty::GenericArgsRef<'tcx>, + args: &[OpTy<'tcx, M::Provenance>], + dest: &PlaceTy<'tcx, M::Provenance>, + ret: Option, + ) -> InterpResult<'tcx, bool> { + let dest = dest.force_mplace(self)?; + + match intrinsic_name { + sym::simd_insert => { + let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); + let elem = &args[2]; + let (input, input_len) = self.project_to_simd(&args[0])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + assert_eq!(input_len, dest_len, "Return vector length must match input length"); + // Bounds are not checked by typeck so we have to do it ourselves. + if index >= input_len { + throw_ub_format!( + "`simd_insert` index {index} is out-of-bounds of vector with length {input_len}" + ); + } + + for i in 0..dest_len { + let place = self.project_index(&dest, i)?; + let value = + if i == index { elem.clone() } else { self.project_index(&input, i)? }; + self.copy_op(&value, &place)?; + } + } + sym::simd_extract => { + let index = u64::from(self.read_scalar(&args[1])?.to_u32()?); + let (input, input_len) = self.project_to_simd(&args[0])?; + // Bounds are not checked by typeck so we have to do it ourselves. + if index >= input_len { + throw_ub_format!( + "`simd_extract` index {index} is out-of-bounds of vector with length {input_len}" + ); + } + self.copy_op(&self.project_index(&input, index)?, &dest)?; + } + sym::simd_neg + | sym::simd_fabs + | sym::simd_ceil + | sym::simd_floor + | sym::simd_round + | sym::simd_round_ties_even + | sym::simd_trunc + | sym::simd_ctlz + | sym::simd_ctpop + | sym::simd_cttz + | sym::simd_bswap + | sym::simd_bitreverse => { + let (op, op_len) = self.project_to_simd(&args[0])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, op_len); + + #[derive(Copy, Clone)] + enum Op { + MirOp(mir::UnOp), + Abs, + Round(rustc_apfloat::Round), + Numeric(Symbol), + } + let which = match intrinsic_name { + sym::simd_neg => Op::MirOp(mir::UnOp::Neg), + sym::simd_fabs => Op::Abs, + sym::simd_ceil => Op::Round(rustc_apfloat::Round::TowardPositive), + sym::simd_floor => Op::Round(rustc_apfloat::Round::TowardNegative), + sym::simd_round => Op::Round(rustc_apfloat::Round::NearestTiesToAway), + sym::simd_round_ties_even => Op::Round(rustc_apfloat::Round::NearestTiesToEven), + sym::simd_trunc => Op::Round(rustc_apfloat::Round::TowardZero), + sym::simd_ctlz => Op::Numeric(sym::ctlz), + sym::simd_ctpop => Op::Numeric(sym::ctpop), + sym::simd_cttz => Op::Numeric(sym::cttz), + sym::simd_bswap => Op::Numeric(sym::bswap), + sym::simd_bitreverse => Op::Numeric(sym::bitreverse), + _ => unreachable!(), + }; + + for i in 0..dest_len { + let op = self.read_immediate(&self.project_index(&op, i)?)?; + let dest = self.project_index(&dest, i)?; + let val = match which { + Op::MirOp(mir_op) => { + // this already does NaN adjustments + self.unary_op(mir_op, &op)?.to_scalar() + } + Op::Abs => { + // Works for f32 and f64. + let ty::Float(float_ty) = op.layout.ty.kind() else { + span_bug!( + self.cur_span(), + "{} operand is not a float", + intrinsic_name + ) + }; + let op = op.to_scalar(); + // "Bitwise" operation, no NaN adjustments + match float_ty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => Scalar::from_f32(op.to_f32()?.abs()), + FloatTy::F64 => Scalar::from_f64(op.to_f64()?.abs()), + FloatTy::F128 => unimplemented!("f16_f128"), + } + } + Op::Round(rounding) => { + let ty::Float(float_ty) = op.layout.ty.kind() else { + span_bug!( + self.cur_span(), + "{} operand is not a float", + intrinsic_name + ) + }; + match float_ty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => { + let f = op.to_scalar().to_f32()?; + let res = f.round_to_integral(rounding).value; + let res = self.adjust_nan(res, &[f]); + Scalar::from_f32(res) + } + FloatTy::F64 => { + let f = op.to_scalar().to_f64()?; + let res = f.round_to_integral(rounding).value; + let res = self.adjust_nan(res, &[f]); + Scalar::from_f64(res) + } + FloatTy::F128 => unimplemented!("f16_f128"), + } + } + Op::Numeric(name) => { + self.numeric_intrinsic(name, op.to_scalar(), op.layout, op.layout)? + } + }; + self.write_scalar(val, &dest)?; + } + } + sym::simd_add + | sym::simd_sub + | sym::simd_mul + | sym::simd_div + | sym::simd_rem + | sym::simd_shl + | sym::simd_shr + | sym::simd_and + | sym::simd_or + | sym::simd_xor + | sym::simd_eq + | sym::simd_ne + | sym::simd_lt + | sym::simd_le + | sym::simd_gt + | sym::simd_ge + | sym::simd_fmax + | sym::simd_fmin + | sym::simd_saturating_add + | sym::simd_saturating_sub + | sym::simd_arith_offset => { + use mir::BinOp; + + let (left, left_len) = self.project_to_simd(&args[0])?; + let (right, right_len) = self.project_to_simd(&args[1])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, left_len); + assert_eq!(dest_len, right_len); + + enum Op { + MirOp(BinOp), + SaturatingOp(BinOp), + FMinMax(MinMax), + WrappingOffset, + } + let which = match intrinsic_name { + sym::simd_add => Op::MirOp(BinOp::Add), + sym::simd_sub => Op::MirOp(BinOp::Sub), + sym::simd_mul => Op::MirOp(BinOp::Mul), + sym::simd_div => Op::MirOp(BinOp::Div), + sym::simd_rem => Op::MirOp(BinOp::Rem), + sym::simd_shl => Op::MirOp(BinOp::ShlUnchecked), + sym::simd_shr => Op::MirOp(BinOp::ShrUnchecked), + sym::simd_and => Op::MirOp(BinOp::BitAnd), + sym::simd_or => Op::MirOp(BinOp::BitOr), + sym::simd_xor => Op::MirOp(BinOp::BitXor), + sym::simd_eq => Op::MirOp(BinOp::Eq), + sym::simd_ne => Op::MirOp(BinOp::Ne), + sym::simd_lt => Op::MirOp(BinOp::Lt), + sym::simd_le => Op::MirOp(BinOp::Le), + sym::simd_gt => Op::MirOp(BinOp::Gt), + sym::simd_ge => Op::MirOp(BinOp::Ge), + sym::simd_fmax => Op::FMinMax(MinMax::Max), + sym::simd_fmin => Op::FMinMax(MinMax::Min), + sym::simd_saturating_add => Op::SaturatingOp(BinOp::Add), + sym::simd_saturating_sub => Op::SaturatingOp(BinOp::Sub), + sym::simd_arith_offset => Op::WrappingOffset, + _ => unreachable!(), + }; + + for i in 0..dest_len { + let left = self.read_immediate(&self.project_index(&left, i)?)?; + let right = self.read_immediate(&self.project_index(&right, i)?)?; + let dest = self.project_index(&dest, i)?; + let val = match which { + Op::MirOp(mir_op) => { + // this does NaN adjustments. + let val = self.binary_op(mir_op, &left, &right).map_err_kind(|kind| { + match kind { + InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ShiftOverflow { shift_amount, .. }) => { + // this resets the interpreter backtrace, but it's not worth avoiding that. + let shift_amount = match shift_amount { + Either::Left(v) => v.to_string(), + Either::Right(v) => v.to_string(), + }; + err_ub_format!("overflowing shift by {shift_amount} in `{intrinsic_name}` in lane {i}") + } + kind => kind + } + })?; + if matches!( + mir_op, + BinOp::Eq + | BinOp::Ne + | BinOp::Lt + | BinOp::Le + | BinOp::Gt + | BinOp::Ge + ) { + // Special handling for boolean-returning operations + assert_eq!(val.layout.ty, self.tcx.types.bool); + let val = val.to_scalar().to_bool().unwrap(); + bool_to_simd_element(val, dest.layout.size) + } else { + assert_ne!(val.layout.ty, self.tcx.types.bool); + assert_eq!(val.layout.ty, dest.layout.ty); + val.to_scalar() + } + } + Op::SaturatingOp(mir_op) => self.saturating_arith(mir_op, &left, &right)?, + Op::WrappingOffset => { + let ptr = left.to_scalar().to_pointer(self)?; + let offset_count = right.to_scalar().to_target_isize(self)?; + let pointee_ty = left.layout.ty.builtin_deref(true).unwrap(); + + let pointee_size = + i64::try_from(self.layout_of(pointee_ty)?.size.bytes()).unwrap(); + let offset_bytes = offset_count.wrapping_mul(pointee_size); + let offset_ptr = ptr.wrapping_signed_offset(offset_bytes, self); + Scalar::from_maybe_pointer(offset_ptr, self) + } + Op::FMinMax(op) => self.fminmax_op(op, &left, &right)?, + }; + self.write_scalar(val, &dest)?; + } + } + sym::simd_reduce_and + | sym::simd_reduce_or + | sym::simd_reduce_xor + | sym::simd_reduce_any + | sym::simd_reduce_all + | sym::simd_reduce_max + | sym::simd_reduce_min => { + use mir::BinOp; + + let (op, op_len) = self.project_to_simd(&args[0])?; + + let imm_from_bool = |b| { + ImmTy::from_scalar( + Scalar::from_bool(b), + self.layout_of(self.tcx.types.bool).unwrap(), + ) + }; + + enum Op { + MirOp(BinOp), + MirOpBool(BinOp), + MinMax(MinMax), + } + let which = match intrinsic_name { + sym::simd_reduce_and => Op::MirOp(BinOp::BitAnd), + sym::simd_reduce_or => Op::MirOp(BinOp::BitOr), + sym::simd_reduce_xor => Op::MirOp(BinOp::BitXor), + sym::simd_reduce_any => Op::MirOpBool(BinOp::BitOr), + sym::simd_reduce_all => Op::MirOpBool(BinOp::BitAnd), + sym::simd_reduce_max => Op::MinMax(MinMax::Max), + sym::simd_reduce_min => Op::MinMax(MinMax::Min), + _ => unreachable!(), + }; + + // Initialize with first lane, then proceed with the rest. + let mut res = self.read_immediate(&self.project_index(&op, 0)?)?; + if matches!(which, Op::MirOpBool(_)) { + // Convert to `bool` scalar. + res = imm_from_bool(simd_element_to_bool(res)?); + } + for i in 1..op_len { + let op = self.read_immediate(&self.project_index(&op, i)?)?; + res = match which { + Op::MirOp(mir_op) => self.binary_op(mir_op, &res, &op)?, + Op::MirOpBool(mir_op) => { + let op = imm_from_bool(simd_element_to_bool(op)?); + self.binary_op(mir_op, &res, &op)? + } + Op::MinMax(mmop) => { + if matches!(res.layout.ty.kind(), ty::Float(_)) { + ImmTy::from_scalar(self.fminmax_op(mmop, &res, &op)?, res.layout) + } else { + // Just boring integers, so NaNs to worry about + let mirop = match mmop { + MinMax::Min => BinOp::Le, + MinMax::Max => BinOp::Ge, + }; + if self.binary_op(mirop, &res, &op)?.to_scalar().to_bool()? { + res + } else { + op + } + } + } + }; + } + self.write_immediate(*res, &dest)?; + } + sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => { + use mir::BinOp; + + let (op, op_len) = self.project_to_simd(&args[0])?; + let init = self.read_immediate(&args[1])?; + + let mir_op = match intrinsic_name { + sym::simd_reduce_add_ordered => BinOp::Add, + sym::simd_reduce_mul_ordered => BinOp::Mul, + _ => unreachable!(), + }; + + let mut res = init; + for i in 0..op_len { + let op = self.read_immediate(&self.project_index(&op, i)?)?; + res = self.binary_op(mir_op, &res, &op)?; + } + self.write_immediate(*res, &dest)?; + } + sym::simd_select => { + let (mask, mask_len) = self.project_to_simd(&args[0])?; + let (yes, yes_len) = self.project_to_simd(&args[1])?; + let (no, no_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, mask_len); + assert_eq!(dest_len, yes_len); + assert_eq!(dest_len, no_len); + + for i in 0..dest_len { + let mask = self.read_immediate(&self.project_index(&mask, i)?)?; + let yes = self.read_immediate(&self.project_index(&yes, i)?)?; + let no = self.read_immediate(&self.project_index(&no, i)?)?; + let dest = self.project_index(&dest, i)?; + + let val = if simd_element_to_bool(mask)? { yes } else { no }; + self.write_immediate(*val, &dest)?; + } + } + // Variant of `select` that takes a bitmask rather than a "vector of bool". + sym::simd_select_bitmask => { + let mask = &args[0]; + let (yes, yes_len) = self.project_to_simd(&args[1])?; + let (no, no_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + let bitmask_len = dest_len.next_multiple_of(8); + if bitmask_len > 64 { + throw_unsup_format!( + "simd_select_bitmask: vectors larger than 64 elements are currently not supported" + ); + } + + assert_eq!(dest_len, yes_len); + assert_eq!(dest_len, no_len); + + // Read the mask, either as an integer or as an array. + let mask: u64 = match mask.layout.ty.kind() { + ty::Uint(_) => { + // Any larger integer type is fine. + assert!(mask.layout.size.bits() >= bitmask_len); + self.read_scalar(mask)?.to_bits(mask.layout.size)?.try_into().unwrap() + } + ty::Array(elem, _len) if elem == &self.tcx.types.u8 => { + // The array must have exactly the right size. + assert_eq!(mask.layout.size.bits(), bitmask_len); + // Read the raw bytes. + let mask = mask.assert_mem_place(); // arrays cannot be immediate + let mask_bytes = + self.read_bytes_ptr_strip_provenance(mask.ptr(), mask.layout.size)?; + // Turn them into a `u64` in the right way. + let mask_size = mask.layout.size.bytes_usize(); + let mut mask_arr = [0u8; 8]; + match self.tcx.data_layout.endian { + Endian::Little => { + // Fill the first N bytes. + mask_arr[..mask_size].copy_from_slice(mask_bytes); + u64::from_le_bytes(mask_arr) + } + Endian::Big => { + // Fill the last N bytes. + let i = mask_arr.len().strict_sub(mask_size); + mask_arr[i..].copy_from_slice(mask_bytes); + u64::from_be_bytes(mask_arr) + } + } + } + _ => bug!("simd_select_bitmask: invalid mask type {}", mask.layout.ty), + }; + + let dest_len = u32::try_from(dest_len).unwrap(); + for i in 0..dest_len { + let bit_i = simd_bitmask_index(i, dest_len, self.tcx.data_layout.endian); + let mask = mask & 1u64.strict_shl(bit_i); + let yes = self.read_immediate(&self.project_index(&yes, i.into())?)?; + let no = self.read_immediate(&self.project_index(&no, i.into())?)?; + let dest = self.project_index(&dest, i.into())?; + + let val = if mask != 0 { yes } else { no }; + self.write_immediate(*val, &dest)?; + } + // The remaining bits of the mask are ignored. + } + // Converts a "vector of bool" into a bitmask. + sym::simd_bitmask => { + let (op, op_len) = self.project_to_simd(&args[0])?; + let bitmask_len = op_len.next_multiple_of(8); + if bitmask_len > 64 { + throw_unsup_format!( + "simd_bitmask: vectors larger than 64 elements are currently not supported" + ); + } + + let op_len = u32::try_from(op_len).unwrap(); + let mut res = 0u64; + for i in 0..op_len { + let op = self.read_immediate(&self.project_index(&op, i.into())?)?; + if simd_element_to_bool(op)? { + let bit_i = simd_bitmask_index(i, op_len, self.tcx.data_layout.endian); + res |= 1u64.strict_shl(bit_i); + } + } + // Write the result, depending on the `dest` type. + // Returns either an unsigned integer or array of `u8`. + match dest.layout.ty.kind() { + ty::Uint(_) => { + // Any larger integer type is fine, it will be zero-extended. + assert!(dest.layout.size.bits() >= bitmask_len); + self.write_scalar(Scalar::from_uint(res, dest.layout.size), &dest)?; + } + ty::Array(elem, _len) if elem == &self.tcx.types.u8 => { + // The array must have exactly the right size. + assert_eq!(dest.layout.size.bits(), bitmask_len); + // We have to write the result byte-for-byte. + let res_size = dest.layout.size.bytes_usize(); + let res_bytes; + let res_bytes_slice = match self.tcx.data_layout.endian { + Endian::Little => { + res_bytes = res.to_le_bytes(); + &res_bytes[..res_size] // take the first N bytes + } + Endian::Big => { + res_bytes = res.to_be_bytes(); + &res_bytes[res_bytes.len().strict_sub(res_size)..] // take the last N bytes + } + }; + self.write_bytes_ptr(dest.ptr(), res_bytes_slice.iter().cloned())?; + } + _ => bug!("simd_bitmask: invalid return type {}", dest.layout.ty), + } + } + sym::simd_cast + | sym::simd_as + | sym::simd_cast_ptr + | sym::simd_with_exposed_provenance => { + let (op, op_len) = self.project_to_simd(&args[0])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, op_len); + + let unsafe_cast = intrinsic_name == sym::simd_cast; + let safe_cast = intrinsic_name == sym::simd_as; + let ptr_cast = intrinsic_name == sym::simd_cast_ptr; + let from_exposed_cast = intrinsic_name == sym::simd_with_exposed_provenance; + + for i in 0..dest_len { + let op = self.read_immediate(&self.project_index(&op, i)?)?; + let dest = self.project_index(&dest, i)?; + + let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) { + // Int-to-(int|float): always safe + (ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) + if safe_cast || unsafe_cast => + self.int_to_int_or_float(&op, dest.layout)?, + // Float-to-float: always safe + (ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast => + self.float_to_float_or_int(&op, dest.layout)?, + // Float-to-int in safe mode + (ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast => + self.float_to_float_or_int(&op, dest.layout)?, + // Float-to-int in unchecked mode + (ty::Float(_), ty::Int(_) | ty::Uint(_)) if unsafe_cast => { + self.float_to_int_checked(&op, dest.layout, Round::TowardZero)? + .ok_or_else(|| { + err_ub_format!( + "`simd_cast` intrinsic called on {op} which cannot be represented in target type `{:?}`", + dest.layout.ty + ) + })? + } + // Ptr-to-ptr cast + (ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => + self.ptr_to_ptr(&op, dest.layout)?, + // Int->Ptr casts + (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => + self.pointer_with_exposed_provenance_cast(&op, dest.layout)?, + // Error otherwise + _ => + throw_unsup_format!( + "Unsupported SIMD cast from element type {from_ty} to {to_ty}", + from_ty = op.layout.ty, + to_ty = dest.layout.ty, + ), + }; + self.write_immediate(*val, &dest)?; + } + } + sym::simd_shuffle_const_generic => { + let (left, left_len) = self.project_to_simd(&args[0])?; + let (right, right_len) = self.project_to_simd(&args[1])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + let index = generic_args[2].expect_const().to_value().valtree.unwrap_branch(); + let index_len = index.len(); + + assert_eq!(left_len, right_len); + assert_eq!(u64::try_from(index_len).unwrap(), dest_len); + + for i in 0..dest_len { + let src_index: u64 = + index[usize::try_from(i).unwrap()].unwrap_leaf().to_u32().into(); + let dest = self.project_index(&dest, i)?; + + let val = if src_index < left_len { + self.read_immediate(&self.project_index(&left, src_index)?)? + } else if src_index < left_len.strict_add(right_len) { + let right_idx = src_index.strict_sub(left_len); + self.read_immediate(&self.project_index(&right, right_idx)?)? + } else { + throw_ub_format!( + "`simd_shuffle_const_generic` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}" + ); + }; + self.write_immediate(*val, &dest)?; + } + } + sym::simd_shuffle => { + let (left, left_len) = self.project_to_simd(&args[0])?; + let (right, right_len) = self.project_to_simd(&args[1])?; + let (index, index_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(left_len, right_len); + assert_eq!(index_len, dest_len); + + for i in 0..dest_len { + let src_index: u64 = self + .read_immediate(&self.project_index(&index, i)?)? + .to_scalar() + .to_u32()? + .into(); + let dest = self.project_index(&dest, i)?; + + let val = if src_index < left_len { + self.read_immediate(&self.project_index(&left, src_index)?)? + } else if src_index < left_len.strict_add(right_len) { + let right_idx = src_index.strict_sub(left_len); + self.read_immediate(&self.project_index(&right, right_idx)?)? + } else { + throw_ub_format!( + "`simd_shuffle` index {src_index} is out-of-bounds for 2 vectors with length {dest_len}" + ); + }; + self.write_immediate(*val, &dest)?; + } + } + sym::simd_gather => { + let (passthru, passthru_len) = self.project_to_simd(&args[0])?; + let (ptrs, ptrs_len) = self.project_to_simd(&args[1])?; + let (mask, mask_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, passthru_len); + assert_eq!(dest_len, ptrs_len); + assert_eq!(dest_len, mask_len); + + for i in 0..dest_len { + let passthru = self.read_immediate(&self.project_index(&passthru, i)?)?; + let ptr = self.read_immediate(&self.project_index(&ptrs, i)?)?; + let mask = self.read_immediate(&self.project_index(&mask, i)?)?; + let dest = self.project_index(&dest, i)?; + + let val = if simd_element_to_bool(mask)? { + let place = self.deref_pointer(&ptr)?; + self.read_immediate(&place)? + } else { + passthru + }; + self.write_immediate(*val, &dest)?; + } + } + sym::simd_scatter => { + let (value, value_len) = self.project_to_simd(&args[0])?; + let (ptrs, ptrs_len) = self.project_to_simd(&args[1])?; + let (mask, mask_len) = self.project_to_simd(&args[2])?; + + assert_eq!(ptrs_len, value_len); + assert_eq!(ptrs_len, mask_len); + + for i in 0..ptrs_len { + let value = self.read_immediate(&self.project_index(&value, i)?)?; + let ptr = self.read_immediate(&self.project_index(&ptrs, i)?)?; + let mask = self.read_immediate(&self.project_index(&mask, i)?)?; + + if simd_element_to_bool(mask)? { + let place = self.deref_pointer(&ptr)?; + self.write_immediate(*value, &place)?; + } + } + } + sym::simd_masked_load => { + let (mask, mask_len) = self.project_to_simd(&args[0])?; + let ptr = self.read_pointer(&args[1])?; + let (default, default_len) = self.project_to_simd(&args[2])?; + let (dest, dest_len) = self.project_to_simd(&dest)?; + + assert_eq!(dest_len, mask_len); + assert_eq!(dest_len, default_len); + + for i in 0..dest_len { + let mask = self.read_immediate(&self.project_index(&mask, i)?)?; + let default = self.read_immediate(&self.project_index(&default, i)?)?; + let dest = self.project_index(&dest, i)?; + + let val = if simd_element_to_bool(mask)? { + // Size * u64 is implemented as always checked + let ptr = ptr.wrapping_offset(dest.layout.size * i, self); + let place = self.ptr_to_mplace(ptr, dest.layout); + self.read_immediate(&place)? + } else { + default + }; + self.write_immediate(*val, &dest)?; + } + } + sym::simd_masked_store => { + let (mask, mask_len) = self.project_to_simd(&args[0])?; + let ptr = self.read_pointer(&args[1])?; + let (vals, vals_len) = self.project_to_simd(&args[2])?; + + assert_eq!(mask_len, vals_len); + + for i in 0..vals_len { + let mask = self.read_immediate(&self.project_index(&mask, i)?)?; + let val = self.read_immediate(&self.project_index(&vals, i)?)?; + + if simd_element_to_bool(mask)? { + // Size * u64 is implemented as always checked + let ptr = ptr.wrapping_offset(val.layout.size * i, self); + let place = self.ptr_to_mplace(ptr, val.layout); + self.write_immediate(*val, &place)? + }; + } + } + + // Unsupported intrinsic: skip the return_to_block below. + _ => return interp_ok(false), + } + + trace!("{:?}", self.dump_place(&dest.clone().into())); + self.return_to_block(ret)?; + interp_ok(true) + } + + fn fminmax_op( + &self, + op: MinMax, + left: &ImmTy<'tcx, Prov>, + right: &ImmTy<'tcx, Prov>, + ) -> InterpResult<'tcx, Scalar> { + assert_eq!(left.layout.ty, right.layout.ty); + let ty::Float(float_ty) = left.layout.ty.kind() else { + bug!("fmax operand is not a float") + }; + let left = left.to_scalar(); + let right = right.to_scalar(); + interp_ok(match float_ty { + FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F32 => { + let left = left.to_f32()?; + let right = right.to_f32()?; + let res = match op { + MinMax::Min => left.min(right), + MinMax::Max => left.max(right), + }; + let res = self.adjust_nan(res, &[left, right]); + Scalar::from_f32(res) + } + FloatTy::F64 => { + let left = left.to_f64()?; + let right = right.to_f64()?; + let res = match op { + MinMax::Min => left.min(right), + MinMax::Max => left.max(right), + }; + let res = self.adjust_nan(res, &[left, right]); + Scalar::from_f64(res) + } + FloatTy::F128 => unimplemented!("f16_f128"), + }) + } +} + +fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 { + assert!(idx < vec_len); + match endianness { + Endian::Little => idx, + #[expect(clippy::arithmetic_side_effects)] // idx < vec_len + Endian::Big => vec_len - 1 - idx, // reverse order of bits + } +} + +fn bool_to_simd_element(b: bool, size: Size) -> Scalar { + // SIMD uses all-1 as pattern for "true". In two's complement, + // -1 has all its bits set to one and `from_int` will truncate or + // sign-extend it to `size` as required. + let val = if b { -1 } else { 0 }; + Scalar::from_int(val, size) +} + +fn simd_element_to_bool(elem: ImmTy<'_, Prov>) -> InterpResult<'_, bool> { + assert!( + matches!(elem.layout.ty.kind(), ty::Int(_) | ty::Uint(_)), + "SIMD mask element type must be an integer, but this is `{}`", + elem.layout.ty + ); + let val = elem.to_scalar().to_int(elem.layout.size)?; + interp_ok(match val { + 0 => false, + -1 => true, + _ => throw_ub_format!("each element of a SIMD mask must be all-0-bits or all-1-bits"), + }) +} diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index e22629993fba7..1725635e0b479 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -289,6 +289,9 @@ pub trait Machine<'tcx>: Sized { a } + /// Determines whether the `fmuladd` intrinsics fuse the multiply-add or use separate operations. + fn float_fuse_mul_add(_ecx: &mut InterpCx<'tcx, Self>) -> bool; + /// Called before a basic block terminator is executed. #[inline] fn before_terminator(_ecx: &mut InterpCx<'tcx, Self>) -> InterpResult<'tcx> { @@ -672,6 +675,11 @@ pub macro compile_time_machine(<$tcx: lifetime>) { match fn_val {} } + #[inline(always)] + fn float_fuse_mul_add(_ecx: &mut InterpCx<$tcx, Self>) -> bool { + true + } + #[inline(always)] fn ub_checks(_ecx: &InterpCx<$tcx, Self>) -> InterpResult<$tcx, bool> { // We can't look at `tcx.sess` here as that can differ across crates, which can lead to diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index ebcdb9461d024..323e1cefd5869 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1504,7 +1504,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // This will also error if copying partial provenance is not supported. let provenance = src_alloc .provenance() - .prepare_copy(src_range, dest_offset, num_copies, self) + .prepare_copy(src_range, self) .map_err(|e| e.to_interp_error(src_alloc_id))?; // Prepare a copy of the initialization mask. let init = src_alloc.init_mask().prepare_copy(src_range); @@ -1590,7 +1590,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { num_copies, ); // copy the provenance to the destination - dest_alloc.provenance_apply_copy(provenance); + dest_alloc.provenance_apply_copy(provenance, alloc_range(dest_offset, size), num_copies); interp_ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 74f8a0a7b093c..f0819423aa0fa 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -528,7 +528,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if !layout.is_sized() { span_bug!(self.cur_span(), "unsized type for `NullaryOp::AlignOf`"); } - let val = layout.align.abi.bytes(); + let val = layout.align.bytes(); ImmTy::from_uint(val, usize_layout()) } OffsetOf(fields) => { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a86fdf80f601a..cd34892f029cf 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -858,7 +858,7 @@ where /// Also, if you use this you are responsible for validating that things get copied at the /// right type. #[instrument(skip(self), level = "trace")] - fn copy_op_no_validate( + pub(super) fn copy_op_no_validate( &mut self, src: &impl Projectable<'tcx, M::Provenance>, dest: &impl Writeable<'tcx, M::Provenance>, diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index d05871bfc773c..027e634ef7f7b 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -2,7 +2,7 @@ //! //! OpTy and PlaceTy generally work by "let's see if we are actually an MPlaceTy, and do something custom if not". //! For PlaceTy, the custom thing is basically always to call `force_allocation` and then use the MPlaceTy logic anyway. -//! For OpTy, the custom thing on field pojections has to be pretty clever (since `Operand::Immediate` can have fields), +//! For OpTy, the custom thing on field projections has to be pretty clever (since `Operand::Immediate` can have fields), //! but for array/slice operations it only has to worry about `Operand::Uninit`. That makes the value part trivial, //! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually //! implement the logic on OpTy, and MPlaceTy calls that. @@ -395,8 +395,6 @@ where span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck") } UnwrapUnsafeBinder(target) => base.transmute(self.layout_of(target)?, self)?, - // We don't want anything happening here, this is here as a dummy. - Subtype(_) => base.transmute(base.layout(), self)?, Field(field, _) => self.project_field(base, field)?, Downcast(_, variant) => self.project_downcast(base, variant)?, Deref => self.deref_pointer(&base.to_op(self)?)?.into(), diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 7cabfd961212f..1c1c59da9d886 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -509,7 +509,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { | ty::Never | ty::Error(_) => true, - ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false, + ty::Str | ty::Slice(_) | ty::Dynamic(_, _) | ty::Foreign(..) => false, ty::Tuple(tys) => tys.last().is_none_or(|ty| is_very_trivially_sized(*ty)), diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 23d362de308f3..1766bbe92480a 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -17,7 +17,7 @@ use tracing::{info, instrument, trace}; use super::{ FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy, - Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format, + Projectable, interp_ok, throw_ub, throw_unsup_format, }; use crate::interpret::EnteredTraceSpan; use crate::{enter_trace_span, util}; @@ -98,11 +98,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_discriminant(*variant_index, &dest)?; } - Deinit(place) => { - let dest = self.eval_place(**place)?; - self.write_uninit(&dest)?; - } - // Mark locals as alive StorageLive(local) => { self.storage_live(*local)?; @@ -188,10 +183,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.copy_op(&op, &dest)?; } - CopyForDeref(place) => { - let op = self.eval_place_to_op(place, Some(dest.layout))?; - self.copy_op(&op, &dest)?; - } + CopyForDeref(_) => bug!("`CopyForDeref` in runtime MIR"), BinaryOp(bin_op, box (ref left, ref right)) => { let layout = util::binop_left_homogeneous(bin_op).then_some(dest.layout); @@ -225,12 +217,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { self.write_repeat(operand, &dest)?; } - Len(place) => { - let src = self.eval_place(place)?; - let len = src.len(self)?; - self.write_scalar(Scalar::from_target_usize(len, self), &dest)?; - } - Ref(_, borrow_kind, place) => { let src = self.eval_place(place)?; let place = self.force_allocation(&src)?; @@ -310,7 +296,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { operands: &IndexSlice>, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { - self.write_uninit(dest)?; // make sure all the padding ends up as uninit let (variant_index, variant_dest, active_field_index) = match *kind { mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => { let variant_dest = self.project_downcast(dest, variant_index)?; @@ -346,9 +331,20 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let field_index = active_field_index.unwrap_or(field_index); let field_dest = self.project_field(&variant_dest, field_index)?; let op = self.eval_operand(operand, Some(field_dest.layout))?; - self.copy_op(&op, &field_dest)?; + // We validate manually below so we don't have to do it here. + self.copy_op_no_validate(&op, &field_dest, /*allow_transmute*/ false)?; } - self.write_discriminant(variant_index, dest) + self.write_discriminant(variant_index, dest)?; + // Validate that the entire thing is valid, and reset padding that might be in between the + // fields. + if M::enforce_validity(self, dest.layout()) { + self.validate_operand( + dest, + M::enforce_validity_recursively(self, dest.layout()), + /*reset_provenance_and_padding*/ true, + )?; + } + interp_ok(()) } /// Repeats `operand` into the destination. `dest` must have array type, and that type diff --git a/compiler/rustc_const_eval/src/interpret/traits.rs b/compiler/rustc_const_eval/src/interpret/traits.rs index 870f9a396ae2b..d982ed9616742 100644 --- a/compiler/rustc_const_eval/src/interpret/traits.rs +++ b/compiler/rustc_const_eval/src/interpret/traits.rs @@ -109,7 +109,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { expected_trait: &'tcx ty::List>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> { assert!( - matches!(mplace.layout.ty.kind(), ty::Dynamic(_, _, ty::Dyn)), + matches!(mplace.layout.ty.kind(), ty::Dynamic(_, _)), "`unpack_dyn_trait` only makes sense on `dyn*` types" ); let vtable = mplace.meta().unwrap_meta().to_pointer(self)?; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index f667823723c0a..b5cf6c4c3723c 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -74,7 +74,7 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan { } } -/// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span!]. +/// Shorthand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span!]. /// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the /// default implementation (i.e. when it does not actually enter the span but instead returns `()`). /// This macro takes a type implementing the [crate::interpret::Machine] trait as its first argument diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 02e3d90f4af70..89a3303eb3902 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -449,7 +449,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ) -> InterpResult<'tcx> { let tail = self.ecx.tcx.struct_tail_for_codegen(pointee.ty, self.ecx.typing_env); match tail.kind() { - ty::Dynamic(data, _, ty::Dyn) => { + ty::Dynamic(data, _) => { let vtable = meta.unwrap_meta().to_pointer(self.ecx)?; // Make sure it is a genuine vtable pointer for the right trait. try_validation!( @@ -511,7 +511,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message ), self.path, - Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind }, + Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind, maybe: false }, Ub(DanglingIntPointer { addr: i, .. }) => DanglingPtrNoProvenance { ptr_kind, // FIXME this says "null pointer" when null but we need translate @@ -538,8 +538,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ); // Make sure this is non-null. We checked dereferenceability above, but if `size` is zero // that does not imply non-null. - if self.ecx.scalar_may_be_null(Scalar::from_maybe_pointer(place.ptr(), self.ecx))? { - throw_validation_failure!(self.path, NullPtr { ptr_kind }) + let scalar = Scalar::from_maybe_pointer(place.ptr(), self.ecx); + if self.ecx.scalar_may_be_null(scalar)? { + let maybe = !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..)); + throw_validation_failure!(self.path, NullPtr { ptr_kind, maybe }) } // Do not allow references to uninhabited types. if place.layout.is_uninhabited() { @@ -755,9 +757,12 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { ); // FIXME: Check if the signature matches } else { - // Otherwise (for standalone Miri), we have to still check it to be non-null. + // Otherwise (for standalone Miri and for `-Zextra-const-ub-checks`), + // we have to still check it to be non-null. if self.ecx.scalar_may_be_null(scalar)? { - throw_validation_failure!(self.path, NullFnPtr); + let maybe = + !M::Provenance::OFFSET_IS_ADDR && matches!(scalar, Scalar::Ptr(..)); + throw_validation_failure!(self.path, NullFnPtr { maybe }); } } if self.reset_provenance_and_padding { @@ -819,10 +824,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { if start == 1 && end == max_value { // Only null is the niche. So make sure the ptr is NOT null. if self.ecx.scalar_may_be_null(scalar)? { - throw_validation_failure!( - self.path, - NullablePtrOutOfRange { range: valid_range, max_value } - ) + throw_validation_failure!(self.path, NonnullPtrMaybeNull) } else { return interp_ok(()); } @@ -1259,9 +1261,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, // When you extend this match, make sure to also add tests to // tests/ui/type/pattern_types/validity.rs(( match **pat { - // Range patterns are precisely reflected into `valid_range` and thus + // Range and non-null patterns are precisely reflected into `valid_range` and thus // handled fully by `visit_scalar` (called below). ty::PatternKind::Range { .. } => {}, + ty::PatternKind::NotNull => {}, // FIXME(pattern_types): check that the value is covered by one of the variants. // For now, we rely on layout computation setting the scalar's `valid_range` to diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 82c50fac6c0ee..b5de10c7dcd11 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -90,7 +90,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // Special treatment for special types, where the (static) layout is not sufficient. match *ty.kind() { // If it is a trait object, switch to the real type that was used to create it. - ty::Dynamic(data, _, ty::Dyn) => { + ty::Dynamic(data, _) => { // Dyn types. This is unsized, and the actual dynamic type of the data is given by the // vtable stored in the place metadata. // unsized values are never immediate, so we can assert_mem_place diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 8ace560d85d16..9c0ec4e51a0c3 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -1,7 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] #![allow(rustc::diagnostic_outside_of_impl)] -#![cfg_attr(bootstrap, feature(strict_overflow_ops))] #![doc(rust_logo)] #![feature(array_try_map)] #![feature(assert_matches)] diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs index 9507b24f603eb..9aafc7efd8a6a 100644 --- a/compiler/rustc_const_eval/src/util/alignment.rs +++ b/compiler/rustc_const_eval/src/util/alignment.rs @@ -37,7 +37,7 @@ where debug!( "is_disaligned({:?}) - align = {}, packed = {}; not disaligned", place, - layout.align.abi.bytes(), + layout.align.bytes(), pack.bytes() ); false diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index 5249b32eca469..4e7c8310007b8 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -61,7 +61,7 @@ pub(crate) fn const_caller_location_provider( trace!("const_caller_location: {}:{}:{}", file, line, col); let mut ecx = mk_eval_cx_to_read_const_val( tcx, - rustc_span::DUMMY_SP, // FIXME: use a proper span here? + rustc_span::DUMMY_SP, // This interpreter cannot fail, so the span is irrelevant. ty::TypingEnv::fully_monomorphized(), CanAccessMutGlobal::No, ); diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index b1f2959875051..34bd8423e8e15 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -59,7 +59,7 @@ fn check_validity_requirement_strict<'tcx>( if kind == ValidityRequirement::Zero { cx.write_bytes_ptr( allocated.ptr(), - std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()), + std::iter::repeat_n(0_u8, ty.layout.size().bytes_usize()), ) .expect("failed to write bytes for zero valid check"); } @@ -129,7 +129,7 @@ fn check_validity_requirement_lax<'tcx>( if let Some(pointee) = this.ty.builtin_deref(false) { let pointee = cx.layout_of(pointee)?; // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied. - if pointee.align.abi.bytes() > 1 { + if pointee.align.bytes() > 1 { // 0x01-filling is not aligned. return Ok(false); } diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 9eed1a20f1523..8db056ed8737d 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -43,5 +43,5 @@ pub fn relate_types<'tcx>( Ok(()) => {} Err(_) => return false, }; - ocx.select_all_or_error().is_empty() + ocx.evaluate_obligations_error_on_ambiguity().is_empty() } diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 5bcf96abd8cb5..db651811551f3 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -41,7 +41,7 @@ impl<'tcx> Printer<'tcx> for TypeNamePrinter<'tcx> { | ty::FnPtr(..) | ty::Never | ty::Tuple(_) - | ty::Dynamic(_, _, _) + | ty::Dynamic(_, _) | ty::UnsafeBinder(_) => self.pretty_print_type(ty), // Placeholders (all printed as `_` to uniformize them). diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 518817ea0f53a..1882e6e835a4e 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -289,7 +289,7 @@ enum NodeState { #[derive(Copy, Clone, Debug)] enum WalkReturn { /// The walk found a cycle, but the entire component is not known to have - /// been fully walked yet. We only know the minimum depth of this + /// been fully walked yet. We only know the minimum depth of this /// component in a minimum spanning tree of the graph. This component /// is tentatively represented by the state of the first node of this /// cycle we met, which is at `min_depth`. diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 17da3ea83c819..132f04b05100f 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -34,6 +34,7 @@ #![feature(sized_hierarchy)] #![feature(test)] #![feature(thread_id_value)] +#![feature(trusted_len)] #![feature(type_alias_impl_trait)] #![feature(unwrap_infallible)] // tidy-alphabetical-end @@ -43,6 +44,8 @@ use std::fmt; pub use atomic_ref::AtomicRef; pub use ena::{snapshot_vec, undo_log, unify}; pub use rustc_index::static_assert_size; +// Re-export some data-structure crates which are part of our public API. +pub use {either, indexmap, smallvec, thin_vec}; pub mod aligned; pub mod base_n; diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index c002d47815b17..15e3e6ea4c329 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -1,6 +1,7 @@ use std::borrow::Borrow; use std::cmp::Ordering; use std::fmt::Debug; +use std::iter::TrustedLen; use std::mem; use std::ops::{Bound, Index, IndexMut, RangeBounds}; @@ -215,36 +216,40 @@ impl SortedMap { /// It is up to the caller to make sure that the elements are sorted by key /// and that there are no duplicates. #[inline] - pub fn insert_presorted(&mut self, elements: Vec<(K, V)>) { - if elements.is_empty() { + pub fn insert_presorted( + &mut self, + // We require `TrustedLen` to ensure that the `splice` below is actually efficient. + mut elements: impl Iterator + DoubleEndedIterator + TrustedLen, + ) { + let Some(first) = elements.next() else { return; - } - - debug_assert!(elements.array_windows().all(|[fst, snd]| fst.0 < snd.0)); + }; - let start_index = self.lookup_index_for(&elements[0].0); + let start_index = self.lookup_index_for(&first.0); let elements = match start_index { Ok(index) => { - let mut elements = elements.into_iter(); - self.data[index] = elements.next().unwrap(); - elements + self.data[index] = first; // overwrite first element + elements.chain(None) // insert the rest below } Err(index) => { - if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 { + let last = elements.next_back(); + if index == self.data.len() + || last.as_ref().is_none_or(|l| l.0 < self.data[index].0) + { // We can copy the whole range without having to mix with // existing elements. - self.data.splice(index..index, elements); + self.data + .splice(index..index, std::iter::once(first).chain(elements).chain(last)); return; } - let mut elements = elements.into_iter(); - self.data.insert(index, elements.next().unwrap()); - elements + self.data.insert(index, first); + elements.chain(last) // insert the rest below } }; - // Insert the rest + // Insert the rest. This is super inefficicent since each insertion copies the entire tail. for (k, v) in elements { self.insert(k, v); } diff --git a/compiler/rustc_data_structures/src/sorted_map/tests.rs b/compiler/rustc_data_structures/src/sorted_map/tests.rs index ea4d2f1feacc0..17d0d3cb1701d 100644 --- a/compiler/rustc_data_structures/src/sorted_map/tests.rs +++ b/compiler/rustc_data_structures/src/sorted_map/tests.rs @@ -171,7 +171,7 @@ fn test_insert_presorted_non_overlapping() { map.insert(2, 0); map.insert(8, 0); - map.insert_presorted(vec![(3, 0), (7, 0)]); + map.insert_presorted(vec![(3, 0), (7, 0)].into_iter()); let expected = vec![2, 3, 7, 8]; assert_eq!(keys(map), expected); @@ -183,7 +183,7 @@ fn test_insert_presorted_first_elem_equal() { map.insert(2, 2); map.insert(8, 8); - map.insert_presorted(vec![(2, 0), (7, 7)]); + map.insert_presorted(vec![(2, 0), (7, 7)].into_iter()); let expected = vec![(2, 0), (7, 7), (8, 8)]; assert_eq!(elements(map), expected); @@ -195,7 +195,7 @@ fn test_insert_presorted_last_elem_equal() { map.insert(2, 2); map.insert(8, 8); - map.insert_presorted(vec![(3, 3), (8, 0)]); + map.insert_presorted(vec![(3, 3), (8, 0)].into_iter()); let expected = vec![(2, 2), (3, 3), (8, 0)]; assert_eq!(elements(map), expected); @@ -207,7 +207,7 @@ fn test_insert_presorted_shuffle() { map.insert(2, 2); map.insert(7, 7); - map.insert_presorted(vec![(1, 1), (3, 3), (8, 8)]); + map.insert_presorted(vec![(1, 1), (3, 3), (8, 8)].into_iter()); let expected = vec![(1, 1), (2, 2), (3, 3), (7, 7), (8, 8)]; assert_eq!(elements(map), expected); @@ -219,7 +219,7 @@ fn test_insert_presorted_at_end() { map.insert(1, 1); map.insert(2, 2); - map.insert_presorted(vec![(3, 3), (8, 8)]); + map.insert_presorted(vec![(3, 3), (8, 8)].into_iter()); let expected = vec![(1, 1), (2, 2), (3, 3), (8, 8)]; assert_eq!(elements(map), expected); diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index ae1dbd2cf5148..46efa50cff364 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -74,6 +74,7 @@ ctrlc = "3.4.4" # tidy-alphabetical-start check_only = ['rustc_interface/check_only'] llvm = ['rustc_interface/llvm'] +llvm_enzyme = ['rustc_interface/llvm_enzyme'] max_level_info = ['rustc_log/max_level_info'] rustc_randomized_layouts = [ 'rustc_index/rustc_randomized_layouts', diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 4f875cf99ec21..9529ef2b99ad3 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -206,7 +206,7 @@ impl Callbacks for TimePassesCallbacks { // time because it will mess up the --print output. See #64339. // self.time_passes = (config.opts.prints.is_empty() && config.opts.unstable_opts.time_passes) - .then(|| config.opts.unstable_opts.time_passes_format); + .then_some(config.opts.unstable_opts.time_passes_format); config.opts.trimmed_def_paths = true; } } @@ -269,7 +269,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) make_codegen_backend: None, registry: diagnostics_registry(), using_internal_features: &USING_INTERNAL_FEATURES, - expanded_args: args, }; callbacks.config(&mut config); @@ -439,8 +438,9 @@ fn make_input(early_dcx: &EarlyDiagCtxt, free_matches: &[String]) -> Option() + .expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be a number"); FileName::doc_test_source_code(PathBuf::from(path), line) } Err(_) => FileName::anon_source_code(&input), @@ -474,8 +474,7 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col let mut text = String::new(); // Slice off the leading newline and print. for line in description.lines() { - let indent_level = - line.find(|c: char| !c.is_whitespace()).unwrap_or_else(|| line.len()); + let indent_level = line.find(|c: char| !c.is_whitespace()).unwrap_or(line.len()); let dedented_line = &line[indent_level..]; if dedented_line.starts_with("```") { is_in_code_block = !is_in_code_block; @@ -521,11 +520,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { }; // Try to prettify the raw markdown text. The result can be used by the pager or on stdout. - let pretty_data = { + let mut pretty_data = { let mdstream = markdown::MdStream::parse_str(content); let bufwtr = markdown::create_stdout_bufwtr(); - let mut mdbuf = bufwtr.buffer(); - if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None } + let mut mdbuf = Vec::new(); + if mdstream.write_anstream_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None } }; // Try to print via the pager, pretty output if possible. @@ -546,8 +545,8 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) { } // The pager failed. Try to print pretty output to stdout. - if let Some((bufwtr, mdbuf)) = &pretty_data - && bufwtr.print(&mdbuf).is_ok() + if let Some((bufwtr, mdbuf)) = &mut pretty_data + && bufwtr.write_all(&mdbuf).is_ok() { return; } @@ -598,8 +597,7 @@ fn process_rlink(sess: &Session, compiler: &interface::Compiler) { fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) { match sess.io.input { - Input::File(ref ifile) => { - let path = &(*ifile); + Input::File(ref path) => { let mut v = Vec::new(); locator::list_file_metadata( &sess.target, @@ -833,7 +831,7 @@ fn print_crate_info( SupportedCrateTypes => { let supported_crate_types = CRATE_TYPES .iter() - .filter(|(_, crate_type)| !invalid_output_for_target(&sess, *crate_type)) + .filter(|(_, crate_type)| !invalid_output_for_target(sess, *crate_type)) .filter(|(_, crate_type)| *crate_type != CrateType::Sdylib) .map(|(crate_type_sym, _)| *crate_type_sym) .collect::>(); @@ -1434,7 +1432,7 @@ pub fn install_ice_hook(bug_report_url: &'static str, extra_info: fn(&DiagCtxt)) eprintln!(); if let Some(ice_path) = ice_path() - && let Ok(mut out) = File::options().create(true).append(true).open(&ice_path) + && let Ok(mut out) = File::options().create(true).append(true).open(ice_path) { // The current implementation always returns `Some`. let location = info.location().unwrap(); @@ -1510,7 +1508,7 @@ fn report_ice( let file = if let Some(path) = ice_path() { // Create the ICE dump target file. - match crate::fs::File::options().create(true).append(true).open(&path) { + match crate::fs::File::options().create(true).append(true).open(path) { Ok(mut file) => { dcx.emit_note(session_diagnostics::IcePath { path: path.clone() }); if FIRST_PANIC.swap(false, Ordering::SeqCst) { diff --git a/compiler/rustc_driver_impl/src/print.rs b/compiler/rustc_driver_impl/src/print.rs index 70de55320f7ae..3f107eb7a61aa 100644 --- a/compiler/rustc_driver_impl/src/print.rs +++ b/compiler/rustc_driver_impl/src/print.rs @@ -14,7 +14,7 @@ macro_rules! safe_println { } pub(crate) fn print(args: fmt::Arguments<'_>) { - if let Err(_) = io::stdout().write_fmt(args) { + if io::stdout().write_fmt(args).is_err() { rustc_errors::FatalError.raise(); } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0608.md b/compiler/rustc_error_codes/src/error_codes/E0608.md index d0ebc3a26f082..3c29484f575ce 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0608.md +++ b/compiler/rustc_error_codes/src/error_codes/E0608.md @@ -1,5 +1,5 @@ -An attempt to use index on a type which doesn't implement the `std::ops::Index` -trait was performed. +Attempted to index a value whose type doesn't implement the +`std::ops::Index` trait. Erroneous code example: @@ -7,8 +7,8 @@ Erroneous code example: 0u8[2]; // error: cannot index into a value of type `u8` ``` -To be able to index into a type it needs to implement the `std::ops::Index` -trait. Example: +Only values with types that implement the `std::ops::Index` trait +can be indexed with square brackets. Example: ``` let v: Vec = vec![0, 1, 2, 3]; @@ -16,3 +16,10 @@ let v: Vec = vec![0, 1, 2, 3]; // The `Vec` type implements the `Index` trait so you can do: println!("{}", v[2]); ``` + +Tuples and structs are indexed with dot (`.`), not with brackets (`[]`), +and tuple element names are their positions: +```ignore(pseudo code) +// this (pseudo code) expression is true for any tuple: +tuple == (tuple.0, tuple.1, ...) +``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0719.md b/compiler/rustc_error_codes/src/error_codes/E0719.md index cd981db1058a6..6aec38b42a3b1 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0719.md +++ b/compiler/rustc_error_codes/src/error_codes/E0719.md @@ -1,4 +1,4 @@ -An associated type value was specified more than once. +An associated item was specified more than once in a trait object. Erroneous code example: @@ -7,21 +7,15 @@ trait FooTrait {} trait BarTrait {} // error: associated type `Item` in trait `Iterator` is specified twice -struct Foo> { f: T } +type Foo = dyn Iterator; ``` -`Item` in trait `Iterator` cannot be specified multiple times for struct `Foo`. -To fix this, create a new trait that is a combination of the desired traits and -specify the associated type with the new trait. +To fix this, remove the duplicate specifier: Corrected example: ``` -trait FooTrait {} -trait BarTrait {} -trait FooBarTrait: FooTrait + BarTrait {} - -struct Foo> { f: T } // ok! +type Foo = dyn Iterator; // ok! ``` For more information about associated types, see [the book][bk-at]. For more diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 7912b8e6098b3..b7b5cbd35741f 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -6,6 +6,8 @@ edition = "2024" [dependencies] # tidy-alphabetical-start annotate-snippets = "0.11" +anstream = "0.6.20" +anstyle = "1.0.13" derive_setters = "0.1.6" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } @@ -22,7 +24,6 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } serde = { version = "1.0.125", features = ["derive"] } serde_json = "1.0.59" -termcolor = "1.2.0" termize = "0.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ae23ef1e25536..96a4ed3218fbf 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -945,6 +945,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { None, "Span must not be empty and have no suggestion", ); + debug_assert_eq!( + parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), + None, + "suggestion must not have overlapping parts", + ); self.push_suggestion(CodeSuggestion { substitutions: vec![Substitution { parts }], diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 93b1e6b761520..8d84e380ab793 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -16,6 +16,8 @@ use std::iter; use std::path::Path; use std::sync::Arc; +use anstream::{AutoStream, ColorChoice}; +use anstyle::{AnsiColor, Effects}; use derive_setters::Setters; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::{DynSend, IntoDynSyncSend}; @@ -25,7 +27,6 @@ use rustc_lint_defs::pluralize; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width}; -use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use tracing::{debug, instrument, trace, warn}; use crate::registry::Registry; @@ -525,10 +526,6 @@ impl Emitter for HumanEmitter { !self.short_message } - fn supports_color(&self) -> bool { - self.dst.supports_color() - } - fn translator(&self) -> &Translator { &self.translator } @@ -1701,7 +1698,6 @@ impl HumanEmitter { } else { col_sep_before_no_show_source = true; } - // print out the span location and spacer before we print the annotated source // to do this, we need to know if this span will be primary let is_primary = primary_lo.file.name == annotated_file.file.name; @@ -2021,7 +2017,7 @@ impl HumanEmitter { if let Some(width) = self.diagnostic_width { width.saturating_sub(code_offset) } else if self.ui_testing || cfg!(miri) { - DEFAULT_COLUMN_WIDTH + DEFAULT_COLUMN_WIDTH.saturating_sub(code_offset) } else { termize::dimensions() .map(|(w, _)| w.saturating_sub(code_offset)) @@ -2154,11 +2150,11 @@ impl HumanEmitter { assert!(!file_lines.lines.is_empty() || parts[0].span.is_dummy()); - let line_start = sm.lookup_char_pos(parts[0].span.lo()).line; + let line_start = sm.lookup_char_pos(parts[0].original_span.lo()).line; let mut lines = complete.lines(); if lines.clone().next().is_none() { // Account for a suggestion to completely remove a line(s) with whitespace (#94192). - let line_end = sm.lookup_char_pos(parts[0].span.hi()).line; + let line_end = sm.lookup_char_pos(parts[0].original_span.hi()).line; for line in line_start..=line_end { self.draw_line_num( &mut buffer, @@ -2354,6 +2350,7 @@ impl HumanEmitter { .sum(); let underline_start = (span_start_pos + start) as isize + offset; let underline_end = (span_start_pos + start + sub_len) as isize + offset; + assert!(underline_start >= 0 && underline_end >= 0); let padding: usize = max_line_num_len + 3; for p in underline_start..underline_end { if let DisplaySuggestion::Underline = show_code_change @@ -2412,7 +2409,7 @@ impl HumanEmitter { // too bad to begin with, so we side-step that issue here. for (i, line) in snippet.lines().enumerate() { let line = normalize_whitespace(line); - let row = row_num - 2 - (newlines - i - 1); + let row = (row_num - 2 - (newlines - i - 1)).max(2); // On the first line, we highlight between the start of the part // span, and the end of that line. // On the last line, we highlight between the start of the line, and @@ -2702,8 +2699,7 @@ impl HumanEmitter { [SubstitutionHighlight { start: 0, end }] if *end == line_to_add.len() => { buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); } - [] => { - // FIXME: needed? Doesn't get exercised in any test. + [] | [SubstitutionHighlight { start: 0, end: 0 }] => { self.draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1); } _ => { @@ -3127,7 +3123,6 @@ impl FileWithAnnotatedLines { multiline_depth: 0, }); } - let mut output = vec![]; let mut multiline_annotations = vec![]; @@ -3361,7 +3356,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[ ('\u{2069}', "�"), ]; -fn normalize_whitespace(s: &str) -> String { +pub(crate) fn normalize_whitespace(s: &str) -> String { const { let mut i = 1; while i < OUTPUT_REPLACEMENTS.len() { @@ -3406,7 +3401,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { ) } -fn emit_to_destination( +pub(crate) fn emit_to_destination( rendered_buffer: &[Vec], lvl: &Level, dst: &mut Destination, @@ -3429,10 +3424,8 @@ fn emit_to_destination( let _buffer_lock = lock::acquire_global_lock("rustc_errors"); for (pos, line) in rendered_buffer.iter().enumerate() { for part in line { - let style = part.style.color_spec(*lvl); - dst.set_color(&style)?; - write!(dst, "{}", part.text)?; - dst.reset()?; + let style = part.style.anstyle(*lvl); + write!(dst, "{style}{}{style:#}", part.text)?; } if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) { writeln!(dst)?; @@ -3442,11 +3435,11 @@ fn emit_to_destination( Ok(()) } -pub type Destination = Box; +pub type Destination = AutoStream>; struct Buffy { - buffer_writer: BufferWriter, - buffer: Buffer, + buffer_writer: std::io::Stderr, + buffer: Vec, } impl Write for Buffy { @@ -3455,7 +3448,7 @@ impl Write for Buffy { } fn flush(&mut self) -> io::Result<()> { - self.buffer_writer.print(&self.buffer)?; + self.buffer_writer.write_all(&self.buffer)?; self.buffer.clear(); Ok(()) } @@ -3470,22 +3463,11 @@ impl Drop for Buffy { } } -impl WriteColor for Buffy { - fn supports_color(&self) -> bool { - self.buffer.supports_color() - } - - fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> { - self.buffer.set_color(spec) - } - - fn reset(&mut self) -> io::Result<()> { - self.buffer.reset() - } -} - pub fn stderr_destination(color: ColorConfig) -> Destination { - let choice = color.to_color_choice(); + let buffer_writer = std::io::stderr(); + // We need to resolve `ColorChoice::Auto` before `Box`ing since + // `ColorChoice::Auto` on `dyn Write` will always resolve to `Never` + let choice = get_stderr_color_choice(color, &buffer_writer); // On Windows we'll be performing global synchronization on the entire // system for emitting rustc errors, so there's no need to buffer // anything. @@ -3493,60 +3475,47 @@ pub fn stderr_destination(color: ColorConfig) -> Destination { // On non-Windows we rely on the atomicity of `write` to ensure errors // don't get all jumbled up. if cfg!(windows) { - Box::new(StandardStream::stderr(choice)) + AutoStream::new(Box::new(buffer_writer), choice) } else { - let buffer_writer = BufferWriter::stderr(choice); - let buffer = buffer_writer.buffer(); - Box::new(Buffy { buffer_writer, buffer }) + let buffer = Vec::new(); + AutoStream::new(Box::new(Buffy { buffer_writer, buffer }), choice) } } +pub fn get_stderr_color_choice(color: ColorConfig, stderr: &std::io::Stderr) -> ColorChoice { + let choice = color.to_color_choice(); + if matches!(choice, ColorChoice::Auto) { AutoStream::choice(stderr) } else { choice } +} + /// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead. /// /// See #36178. -const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue }; +const BRIGHT_BLUE: anstyle::Style = if cfg!(windows) { + AnsiColor::BrightCyan.on_default() +} else { + AnsiColor::BrightBlue.on_default() +}; impl Style { - fn color_spec(&self, lvl: Level) -> ColorSpec { - let mut spec = ColorSpec::new(); + pub(crate) fn anstyle(&self, lvl: Level) -> anstyle::Style { match self { - Style::Addition => { - spec.set_fg(Some(Color::Green)).set_intense(true); - } - Style::Removal => { - spec.set_fg(Some(Color::Red)).set_intense(true); - } - Style::LineAndColumn => {} - Style::LineNumber => { - spec.set_bold(true); - spec.set_intense(true); - spec.set_fg(Some(BRIGHT_BLUE)); - } - Style::Quotation => {} - Style::MainHeaderMsg => { - spec.set_bold(true); - if cfg!(windows) { - spec.set_intense(true).set_fg(Some(Color::White)); - } - } - Style::UnderlinePrimary | Style::LabelPrimary => { - spec = lvl.color(); - spec.set_bold(true); - } - Style::UnderlineSecondary | Style::LabelSecondary => { - spec.set_bold(true).set_intense(true); - spec.set_fg(Some(BRIGHT_BLUE)); - } - Style::HeaderMsg | Style::NoStyle => {} - Style::Level(lvl) => { - spec = lvl.color(); - spec.set_bold(true); - } - Style::Highlight => { - spec.set_bold(true).set_fg(Some(Color::Magenta)); + Style::Addition => AnsiColor::BrightGreen.on_default(), + Style::Removal => AnsiColor::BrightRed.on_default(), + Style::LineAndColumn => anstyle::Style::new(), + Style::LineNumber => BRIGHT_BLUE.effects(Effects::BOLD), + Style::Quotation => anstyle::Style::new(), + Style::MainHeaderMsg => if cfg!(windows) { + AnsiColor::BrightWhite.on_default() + } else { + anstyle::Style::new() } + .effects(Effects::BOLD), + Style::UnderlinePrimary | Style::LabelPrimary => lvl.color().effects(Effects::BOLD), + Style::UnderlineSecondary | Style::LabelSecondary => BRIGHT_BLUE.effects(Effects::BOLD), + Style::HeaderMsg | Style::NoStyle => anstyle::Style::new(), + Style::Level(lvl) => lvl.color().effects(Effects::BOLD), + Style::Highlight => AnsiColor::Magenta.on_default().effects(Effects::BOLD), } - spec } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 719d4ca625ae7..03ce1d82ef3c4 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -15,6 +15,7 @@ use std::path::Path; use std::sync::{Arc, Mutex}; use std::vec; +use anstream::{AutoStream, ColorChoice}; use derive_setters::Setters; use rustc_data_structures::sync::IntoDynSyncSend; use rustc_error_messages::FluentArgs; @@ -23,7 +24,6 @@ use rustc_span::Span; use rustc_span::hygiene::ExpnData; use rustc_span::source_map::{FilePathMapping, SourceMap}; use serde::Serialize; -use termcolor::{ColorSpec, WriteColor}; use crate::diagnostic::IsLint; use crate::emitter::{ @@ -333,7 +333,7 @@ impl Diagnostic { // generate regular command line output and store it in the json // A threadsafe buffer for writing. - #[derive(Default, Clone)] + #[derive(Clone)] struct BufWriter(Arc>>); impl Write for BufWriter { @@ -344,19 +344,6 @@ impl Diagnostic { self.0.lock().unwrap().flush() } } - impl WriteColor for BufWriter { - fn supports_color(&self) -> bool { - false - } - - fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> { - Ok(()) - } - - fn reset(&mut self) -> io::Result<()> { - Ok(()) - } - } let translated_message = je.translator.translate_messages(&diag.messages, &args); @@ -382,13 +369,15 @@ impl Diagnostic { children .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je)); } - let buf = BufWriter::default(); - let mut dst: Destination = Box::new(buf.clone()); + let buf = BufWriter(Arc::new(Mutex::new(Vec::new()))); let short = je.json_rendered.short(); - match je.color_config { - ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)), - ColorConfig::Never => {} - } + let dst: Destination = AutoStream::new( + Box::new(buf.clone()), + match je.color_config.to_color_choice() { + ColorChoice::Auto => ColorChoice::Always, + choice => choice, + }, + ); HumanEmitter::new(dst, je.translator.clone()) .short_message(short) .sm(je.sm.clone()) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8869799ce90d9..17cd466f96b87 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -39,6 +39,12 @@ use std::path::{Path, PathBuf}; use std::{fmt, panic}; use Level::*; +// Used by external projects such as `rust-gpu`. +// See https://github.com/rust-lang/rust/pull/115393. +pub use anstream::{AutoStream, ColorChoice}; +pub use anstyle::{ + Ansi256Color, AnsiColor, Color, EffectIter, Effects, Reset, RgbColor, Style as Anstyle, +}; pub use codes::*; pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer}; pub use diagnostic::{ @@ -69,9 +75,6 @@ pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, DUMMY_SP, Loc, Span}; pub use snippet::Style; -// Used by external projects such as `rust-gpu`. -// See https://github.com/rust-lang/rust/pull/115393. -pub use termcolor::{Color, ColorSpec, WriteColor}; use tracing::debug; use crate::emitter::TimingEvent; @@ -224,6 +227,13 @@ pub struct SubstitutionPart { pub snippet: String, } +#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] +pub struct TrimmedSubstitutionPart { + pub original_span: Span, + pub span: Span, + pub snippet: String, +} + /// Used to translate between `Span`s and byte positions within a single output line in highlighted /// code of structured suggestions. #[derive(Debug, Clone, Copy)] @@ -233,6 +243,35 @@ pub(crate) struct SubstitutionHighlight { } impl SubstitutionPart { + /// Try to turn a replacement into an addition when the span that is being + /// overwritten matches either the prefix or suffix of the replacement. + fn trim_trivial_replacements(self, sm: &SourceMap) -> TrimmedSubstitutionPart { + let mut trimmed_part = TrimmedSubstitutionPart { + original_span: self.span, + span: self.span, + snippet: self.snippet, + }; + if trimmed_part.snippet.is_empty() { + return trimmed_part; + } + let Ok(snippet) = sm.span_to_snippet(trimmed_part.span) else { + return trimmed_part; + }; + + if let Some((prefix, substr, suffix)) = as_substr(&snippet, &trimmed_part.snippet) { + trimmed_part.span = Span::new( + trimmed_part.span.lo() + BytePos(prefix as u32), + trimmed_part.span.hi() - BytePos(suffix as u32), + trimmed_part.span.ctxt(), + trimmed_part.span.parent(), + ); + trimmed_part.snippet = substr.to_string(); + } + trimmed_part + } +} + +impl TrimmedSubstitutionPart { pub fn is_addition(&self, sm: &SourceMap) -> bool { !self.snippet.is_empty() && !self.replaces_meaningful_content(sm) } @@ -260,27 +299,6 @@ impl SubstitutionPart { sm.span_to_snippet(self.span) .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) } - - /// Try to turn a replacement into an addition when the span that is being - /// overwritten matches either the prefix or suffix of the replacement. - fn trim_trivial_replacements(&mut self, sm: &SourceMap) { - if self.snippet.is_empty() { - return; - } - let Ok(snippet) = sm.span_to_snippet(self.span) else { - return; - }; - - if let Some((prefix, substr, suffix)) = as_substr(&snippet, &self.snippet) { - self.span = Span::new( - self.span.lo() + BytePos(prefix as u32), - self.span.hi() - BytePos(suffix as u32), - self.span.ctxt(), - self.span.parent(), - ); - self.snippet = substr.to_string(); - } - } } /// Given an original string like `AACC`, and a suggestion like `AABBCC`, try to detect @@ -310,7 +328,8 @@ impl CodeSuggestion { pub(crate) fn splice_lines( &self, sm: &SourceMap, - ) -> Vec<(String, Vec, Vec>, ConfusionType)> { + ) -> Vec<(String, Vec, Vec>, ConfusionType)> + { // For the `Vec>` value, the first level of the vector // corresponds to the output snippet's lines, while the second level corresponds to the // substrings within that line that should be highlighted. @@ -381,17 +400,6 @@ impl CodeSuggestion { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. substitution.parts.sort_by_key(|part| part.span.lo()); - // Verify the assumption that all spans are disjoint - assert_eq!( - substitution.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), - None, - "all spans must be disjoint", - ); - - // Account for cases where we are suggesting the same code that's already - // there. This shouldn't happen often, but in some cases for multipart - // suggestions it's much easier to handle it here than in the origin. - substitution.parts.retain(|p| is_different(sm, &p.snippet, p.span)); // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min()?; @@ -428,12 +436,17 @@ impl CodeSuggestion { // or deleted code in order to point at the correct column *after* substitution. let mut acc = 0; let mut confusion_type = ConfusionType::None; - for part in &mut substitution.parts { + + let trimmed_parts = substitution + .parts + .into_iter() // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the // suggestion and snippet to look as if we just suggested to add // `"b"`, which is typically much easier for the user to understand. - part.trim_trivial_replacements(sm); + .map(|part| part.trim_trivial_replacements(sm)) + .collect::>(); + for part in &trimmed_parts { let part_confusion = detect_confusion_type(sm, &part.snippet, part.span); confusion_type = confusion_type.combine(part_confusion); let cur_lo = sm.lookup_char_pos(part.span.lo()); @@ -481,12 +494,16 @@ impl CodeSuggestion { _ => 1, }) .sum(); - - line_highlight.push(SubstitutionHighlight { - start: (cur_lo.col.0 as isize + acc) as usize, - end: (cur_lo.col.0 as isize + acc + len) as usize, - }); - + if !is_different(sm, &part.snippet, part.span) { + // Account for cases where we are suggesting the same code that's already + // there. This shouldn't happen often, but in some cases for multipart + // suggestions it's much easier to handle it here than in the origin. + } else { + line_highlight.push(SubstitutionHighlight { + start: (cur_lo.col.0 as isize + acc) as usize, + end: (cur_lo.col.0 as isize + acc + len) as usize, + }); + } buf.push_str(&part.snippet); let cur_hi = sm.lookup_char_pos(part.span.hi()); // Account for the difference between the width of the current code and the @@ -521,7 +538,7 @@ impl CodeSuggestion { if highlights.iter().all(|parts| parts.is_empty()) { None } else { - Some((buf, substitution.parts, highlights, confusion_type)) + Some((buf, trimmed_parts, highlights, confusion_type)) } }) .collect() @@ -1961,25 +1978,21 @@ impl fmt::Display for Level { } impl Level { - fn color(self) -> ColorSpec { - let mut spec = ColorSpec::new(); + fn color(self) -> anstyle::Style { match self { - Bug | Fatal | Error | DelayedBug => { - spec.set_fg(Some(Color::Red)).set_intense(true); - } + Bug | Fatal | Error | DelayedBug => AnsiColor::BrightRed.on_default(), ForceWarning | Warning => { - spec.set_fg(Some(Color::Yellow)).set_intense(cfg!(windows)); - } - Note | OnceNote => { - spec.set_fg(Some(Color::Green)).set_intense(true); - } - Help | OnceHelp => { - spec.set_fg(Some(Color::Cyan)).set_intense(true); + if cfg!(windows) { + AnsiColor::BrightYellow.on_default() + } else { + AnsiColor::Yellow.on_default() + } } - FailureNote => {} + Note | OnceNote => AnsiColor::BrightGreen.on_default(), + Help | OnceHelp => AnsiColor::BrightCyan.on_default(), + FailureNote => anstyle::Style::new(), Allow | Expect => unreachable!(), } - spec } pub fn to_str(self) -> &'static str { diff --git a/compiler/rustc_errors/src/markdown/mod.rs b/compiler/rustc_errors/src/markdown/mod.rs index 64576cdc8caca..4f5e2328234d8 100644 --- a/compiler/rustc_errors/src/markdown/mod.rs +++ b/compiler/rustc_errors/src/markdown/mod.rs @@ -4,7 +4,6 @@ use std::io; -use termcolor::{Buffer, BufferWriter, ColorChoice}; mod parse; mod term; @@ -19,15 +18,15 @@ impl<'a> MdStream<'a> { parse::entrypoint(s) } - /// Write formatted output to a termcolor buffer - pub fn write_termcolor_buf(&self, buf: &mut Buffer) -> io::Result<()> { + /// Write formatted output to an anstream buffer + pub fn write_anstream_buf(&self, buf: &mut Vec) -> io::Result<()> { term::entrypoint(self, buf) } } -/// Create a termcolor buffer with the `Always` color choice -pub fn create_stdout_bufwtr() -> BufferWriter { - BufferWriter::stdout(ColorChoice::Always) +/// Create an anstream buffer with the `Always` color choice +pub fn create_stdout_bufwtr() -> anstream::Stdout { + anstream::Stdout::always(std::io::stdout()) } /// A single tokentree within a Markdown document diff --git a/compiler/rustc_errors/src/markdown/term.rs b/compiler/rustc_errors/src/markdown/term.rs index fe1d80bdbe8e0..b0ce01548f00f 100644 --- a/compiler/rustc_errors/src/markdown/term.rs +++ b/compiler/rustc_errors/src/markdown/term.rs @@ -1,7 +1,7 @@ use std::cell::Cell; use std::io::{self, Write}; -use termcolor::{Buffer, Color, ColorSpec, WriteColor}; +use anstyle::{AnsiColor, Effects, Style}; use crate::markdown::{MdStream, MdTree}; @@ -15,7 +15,7 @@ thread_local! { } /// Print to terminal output to a buffer -pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result<()> { +pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Vec) -> io::Result<()> { #[cfg(not(test))] if let Some((w, _)) = termize::dimensions() { WIDTH.set(std::cmp::min(w, DEFAULT_COLUMN_WIDTH)); @@ -23,57 +23,65 @@ pub(crate) fn entrypoint(stream: &MdStream<'_>, buf: &mut Buffer) -> io::Result< write_stream(stream, buf, None, 0)?; buf.write_all(b"\n") } - /// Write the buffer, reset to the default style after each fn write_stream( MdStream(stream): &MdStream<'_>, - buf: &mut Buffer, - default: Option<&ColorSpec>, + buf: &mut Vec, + default: Option +
// This is a regular comment
+/// This is a doc comment
+fn main() {
+    // Another comment
+    println!("Hello, world!");
+}
\ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index 00925bd81ed8e..d99b29cfb8fa6 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -127,9 +127,9 @@ let y = &mut x; let z = &y; - let Foo { x: z, y } = Foo { x: z, y }; + let Foo { x: z, y } = Foo { x: z, y }; - y; + y; let mut foo = Foo { x, y: x }; let foo2 = Foo { x, y: x }; @@ -142,7 +142,7 @@ copy.qux(); copy.baz(copy); - let a = |x| x; + let a = |x| x; let bar = Foo::baz; let baz = (-42,); @@ -172,13 +172,13 @@ } async fn learn_and_sing() { - let song = learn_song().await; - sing_song(song).await; + let song = learn_song().await; + sing_song(song).await; } async fn async_main() { let f1 = learn_and_sing(); - let f2 = dance(); + let f2 = dance(); futures::join!(f1, f2); } diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index f7d798208037e..47ee2ad1c0d70 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html @@ -78,8 +78,8 @@ } use foo::bar as baz; -trait Bar = Baz; -trait Foo = Bar; +trait Bar = Baz; +trait Foo = Bar; fn main() { let a = '\n'; diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index 828b8f762c58a..8339daf32462b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html @@ -96,7 +96,7 @@ u.field; &u.field; - &raw const u.field; + &raw const u.field; // this should be safe! let Union { field: _ }; // but not these diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs index dd359326c61d6..8198701d68432 100644 --- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs @@ -9,6 +9,7 @@ use crate::{FileRange, HighlightConfig, HlTag, TextRange, fixture}; const HL_CONFIG: HighlightConfig = HighlightConfig { strings: true, + comments: true, punctuation: true, specialize_punctuation: true, specialize_operator: true, @@ -1220,16 +1221,25 @@ fn foo(x: &fn(&dyn Trait)) {} /// Highlights the code given by the `ra_fixture` argument, renders the /// result as HTML, and compares it with the HTML file given as `snapshot`. /// Note that the `snapshot` file is overwritten by the rendered HTML. -fn check_highlighting( +fn check_highlighting_with_config( #[rust_analyzer::rust_fixture] ra_fixture: &str, + config: HighlightConfig, expect: ExpectFile, rainbow: bool, ) { let (analysis, file_id) = fixture::file(ra_fixture.trim()); - let actual_html = &analysis.highlight_as_html(file_id, rainbow).unwrap(); + let actual_html = &analysis.highlight_as_html_with_config(config, file_id, rainbow).unwrap(); expect.assert_eq(actual_html) } +fn check_highlighting( + #[rust_analyzer::rust_fixture] ra_fixture: &str, + expect: ExpectFile, + rainbow: bool, +) { + check_highlighting_with_config(ra_fixture, HL_CONFIG, expect, rainbow) +} + #[test] fn benchmark_syntax_highlighting_long_struct() { if skip_slow_tests() { @@ -1435,3 +1445,24 @@ fn main() { false, ); } + +#[test] +fn test_comment_highlighting_disabled() { + // Test that comments are not highlighted when disabled + check_highlighting_with_config( + r#" +// This is a regular comment +/// This is a doc comment +fn main() { + // Another comment + println!("Hello, world!"); +} +"#, + HighlightConfig { + comments: false, // Disable comment highlighting + ..HL_CONFIG + }, + expect_file!["./test_data/highlight_comments_disabled.html"], + false, + ); +} diff --git a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs index 06cbd50e946ac..bd60ffe559120 100644 --- a/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs +++ b/src/tools/rust-analyzer/crates/ide/src/test_explorer.rs @@ -94,7 +94,7 @@ fn discover_tests_in_module( if !f.is_test(db) { continue; } - let nav = f.try_to_nav(db).map(|r| r.call_site); + let nav = f.try_to_nav(&sema).map(|r| r.call_site); let fn_name = f.name(db).as_str().to_owned(); r.push(TestItem { id: format!("{prefix_id}::{fn_name}"), diff --git a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs index 63701a4d15e94..47ca616f3199b 100644 --- a/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs +++ b/src/tools/rust-analyzer/crates/ide/src/view_memory_layout.rs @@ -98,7 +98,7 @@ pub(crate) fn view_memory_layout( Definition::BuiltinType(it) => it.ty(db), Definition::SelfType(it) => it.self_ty(db), Definition::Local(it) => it.ty(db), - Definition::Field(it) => it.ty(db), + Definition::Field(it) => it.ty(db).to_type(db), Definition::Const(it) => it.ty(db), Definition::Static(it) => it.ty(db), _ => return None, @@ -141,7 +141,7 @@ pub(crate) fn view_memory_layout( if let Ok(child_layout) = child_ty.layout(db) { nodes.push(MemoryLayoutNode { item_name: field.name(db), - typename: child_ty.display(db, display_target).to_string(), + typename: { child_ty.display(db, display_target).to_string() }, size: child_layout.size(), alignment: child_layout.align(), offset: match *field { @@ -219,7 +219,7 @@ mod tests { ) -> Option { let (analysis, position, _) = fixture::annotations(ra_fixture); - view_memory_layout(&analysis.db, position) + hir::attach_db(&analysis.db, || view_memory_layout(&analysis.db, position)) } #[test] diff --git a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs index 4780743c4d92a..920bdd9568fcf 100644 --- a/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs +++ b/src/tools/rust-analyzer/crates/intern/src/symbol/symbols.rs @@ -178,6 +178,8 @@ define_symbols! { core, coroutine_state, coroutine, + coroutine_return, + coroutine_yield, count, crate_type, CStr, @@ -226,6 +228,8 @@ define_symbols! { async_fn_once_output, async_fn_mut, async_fn, + call_ref_future, + call_once_future, fn_ptr_addr, fn_ptr_trait, format_alignment, @@ -416,6 +420,7 @@ define_symbols! { rustc_allow_incoherent_impl, rustc_builtin_macro, rustc_coherence_is_core, + rustc_coinductive, rustc_const_panic_str, rustc_deallocator, rustc_deprecated_safe_2024, @@ -432,6 +437,7 @@ define_symbols! { rustc_safe_intrinsic, rustc_skip_array_during_method_dispatch, rustc_skip_during_method_dispatch, + rustc_force_inline, semitransparent, shl_assign, shl, @@ -510,4 +516,5 @@ define_symbols! { flags, precision, width, + never_type_fallback, } diff --git a/src/tools/rust-analyzer/crates/macros/Cargo.toml b/src/tools/rust-analyzer/crates/macros/Cargo.toml new file mode 100644 index 0000000000000..8184cc6d1c03d --- /dev/null +++ b/src/tools/rust-analyzer/crates/macros/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "macros" +version = "0.0.0" +repository.workspace = true +description = "Proc macros for rust-analyzer." + +authors.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1" +quote = "1" +syn = "2.0.9" +synstructure = "0.13.0" diff --git a/src/tools/rust-analyzer/crates/macros/src/lib.rs b/src/tools/rust-analyzer/crates/macros/src/lib.rs new file mode 100644 index 0000000000000..8bafcf498c510 --- /dev/null +++ b/src/tools/rust-analyzer/crates/macros/src/lib.rs @@ -0,0 +1,164 @@ +//! Proc macros for rust-analyzer. + +use quote::{ToTokens, quote}; +use syn::parse_quote; +use synstructure::decl_derive; + +decl_derive!( + [TypeFoldable, attributes(type_foldable)] => + /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported). + /// + /// The fold will produce a value of the same struct or enum variant as the input, with + /// each field respectively folded using the `TypeFoldable` implementation for its type. + /// However, if a field of a struct or an enum variant is annotated with + /// `#[type_foldable(identity)]` then that field will retain its incumbent value (and its + /// type is not required to implement `TypeFoldable`). + type_foldable_derive +); +decl_derive!( + [TypeVisitable, attributes(type_visitable)] => + /// Derives `TypeVisitable` for the annotated `struct` or `enum` (`union` is not supported). + /// + /// Each field of the struct or enum variant will be visited in definition order, using the + /// `TypeVisitable` implementation for its type. However, if a field of a struct or an enum + /// variant is annotated with `#[type_visitable(ignore)]` then that field will not be + /// visited (and its type is not required to implement `TypeVisitable`). + type_visitable_derive +); + +fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + // ignore fields with #[type_visitable(ignore)] + s.filter(|bi| { + let mut ignored = false; + + bi.ast().attrs.iter().for_each(|attr| { + if !attr.path().is_ident("type_visitable") { + return; + } + let _ = attr.parse_nested_meta(|nested| { + if nested.path.is_ident("ignore") { + ignored = true; + } + Ok(()) + }); + }); + + !ignored + }); + + if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "db") { + s.add_impl_generic(parse_quote! { 'db }); + } + + s.add_bounds(synstructure::AddBounds::Generics); + let body_visit = s.each(|bind| { + quote! { + match ::rustc_type_ir::VisitorResult::branch( + ::rustc_type_ir::TypeVisitable::visit_with(#bind, __visitor) + ) { + ::core::ops::ControlFlow::Continue(()) => {}, + ::core::ops::ControlFlow::Break(r) => { + return ::rustc_type_ir::VisitorResult::from_residual(r); + }, + } + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl( + quote!(::rustc_type_ir::TypeVisitable<::hir_ty::next_solver::DbInterner<'db>>), + quote! { + fn visit_with<__V: ::rustc_type_ir::TypeVisitor<::hir_ty::next_solver::DbInterner<'db>>>( + &self, + __visitor: &mut __V + ) -> __V::Result { + match *self { #body_visit } + <__V::Result as ::rustc_type_ir::VisitorResult>::output() + } + }, + ) +} + +fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "db") { + s.add_impl_generic(parse_quote! { 'db }); + } + + s.add_bounds(synstructure::AddBounds::Generics); + s.bind_with(|_| synstructure::BindStyle::Move); + let try_body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|_, index| { + let bind = &bindings[index]; + + // retain value of fields with #[type_foldable(identity)] + if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") { + bind.to_token_stream() + } else { + quote! { + ::rustc_type_ir::TypeFoldable::try_fold_with(#bind, __folder)? + } + } + }) + }); + + let body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|_, index| { + let bind = &bindings[index]; + + // retain value of fields with #[type_foldable(identity)] + if has_ignore_attr(&bind.ast().attrs, "type_foldable", "identity") { + bind.to_token_stream() + } else { + quote! { + ::rustc_type_ir::TypeFoldable::fold_with(#bind, __folder) + } + } + }) + }); + + s.bound_impl( + quote!(::rustc_type_ir::TypeFoldable<::hir_ty::next_solver::DbInterner<'db>>), + quote! { + fn try_fold_with<__F: ::rustc_type_ir::FallibleTypeFolder<::hir_ty::next_solver::DbInterner<'db>>>( + self, + __folder: &mut __F + ) -> Result { + Ok(match self { #try_body_fold }) + } + + fn fold_with<__F: ::rustc_type_ir::TypeFolder<::hir_ty::next_solver::DbInterner<'db>>>( + self, + __folder: &mut __F + ) -> Self { + match self { #body_fold } + } + }, + ) +} + +fn has_ignore_attr(attrs: &[syn::Attribute], name: &'static str, meta: &'static str) -> bool { + let mut ignored = false; + attrs.iter().for_each(|attr| { + if !attr.path().is_ident(name) { + return; + } + let _ = attr.parse_nested_meta(|nested| { + if nested.path.is_ident(meta) { + ignored = true; + } + Ok(()) + }); + }); + + ignored +} diff --git a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs index 2c046df10f5e5..3e4ab8bdc1d8d 100644 --- a/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs +++ b/src/tools/rust-analyzer/crates/mbe/src/expander/transcriber.rs @@ -401,7 +401,19 @@ fn expand_var( let sub = sub.strip_invisible(); let mut span = id; marker(&mut span); - let wrap_in_parens = !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) + + // Check if this is a simple negative literal (MINUS + LITERAL) + // that should not be wrapped in parentheses + let is_negative_literal = matches!( + sub.flat_tokens(), + [ + tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '-', .. })), + tt::TokenTree::Leaf(tt::Leaf::Literal(_)) + ] + ); + + let wrap_in_parens = !is_negative_literal + && !matches!(sub.flat_tokens(), [tt::TokenTree::Leaf(_)]) && sub.try_into_subtree().is_none_or(|it| { it.top_subtree().delimiter.kind == tt::DelimiterKind::Invisible }); diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs index cb1b59f649774..d419817e5cd70 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/generic_params.rs @@ -182,12 +182,6 @@ fn type_bound(p: &mut Parser<'_>) -> bool { ); m.complete(p, USE_BOUND_GENERIC_ARGS); } - T![?] if p.nth_at(1, T![for]) => { - // test question_for_type_trait_bound - // fn f() where T: ?for<> Sized {} - p.bump_any(); - types::for_type(p, false) - } _ => { if path_type_bound(p).is_err() { m.abandon(p); @@ -219,8 +213,13 @@ fn path_type_bound(p: &mut Parser<'_>) -> Result<(), ()> { // test async_trait_bound // fn async_foo(_: impl async Fn(&i32)) {} p.eat(T![async]); + // test question_for_type_trait_bound + // fn f() where T: for<> ?Sized {} p.eat(T![?]); + // test_err invalid_question_for_type_trait_bound + // fn f() where T: ?for<> Sized {} + if paths::is_use_path_start(p) { types::path_type_bounds(p, false); // test_err type_bounds_macro_call_recovery diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs index 8e255985a205d..e6a8aca5861a6 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items/consts.rs @@ -25,21 +25,28 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) { } // FIXME: Recover on statics with generic params/where clause. - if is_const { - // test generic_const - // const C: u32 = 0; - // impl Foo { - // const C<'a>: &'a () = &(); - // } - generic_params::opt_generic_param_list(p); + if !is_const && p.at(T![<]) { + // test_err generic_static + // static C: u32 = 0; + p.error("`static` may not have generic parameters"); } - // test_err generic_static - // static C: u32 = 0; + // test generic_const + // const C: u32 = 0; + // impl Foo { + // const C<'a>: &'a () = &(); + // } + generic_params::opt_generic_param_list(p); if p.at(T![:]) { types::ascription(p); + } else if is_const { + // test_err missing_const_type + // const C = 0; + p.error("missing type for `const`"); } else { - p.error("missing type for `const` or `static`"); + // test_err missing_static_type + // static C = 0; + p.error("missing type for `static`"); } if p.eat(T![=]) { expressions::expr(p); diff --git a/src/tools/rust-analyzer/crates/parser/src/grammar/items/traits.rs b/src/tools/rust-analyzer/crates/parser/src/grammar/items/traits.rs index 47f86ce8c6cc4..c1b1a3fc8a94a 100644 --- a/src/tools/rust-analyzer/crates/parser/src/grammar/items/traits.rs +++ b/src/tools/rust-analyzer/crates/parser/src/grammar/items/traits.rs @@ -20,7 +20,7 @@ pub(super) fn trait_(p: &mut Parser<'_>, m: Marker) { // trait Z = where Self: T; generic_params::opt_where_clause(p); p.expect(T![;]); - m.complete(p, TRAIT_ALIAS); + m.complete(p, TRAIT); return; } diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 8fff1c3db7485..edc3f406a67e8 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -149,6 +149,24 @@ impl<'a> Converter<'a> { } } + /// Check for likely unterminated string by analyzing STRING token content + fn has_likely_unterminated_string(&self) -> bool { + let Some(last_idx) = self.res.kind.len().checked_sub(1) else { return false }; + + for i in (0..=last_idx).rev().take(5) { + if self.res.kind[i] == STRING { + let start = self.res.start[i] as usize; + let end = self.res.start.get(i + 1).map(|&s| s as usize).unwrap_or(self.offset); + let content = &self.res.text[start..end]; + + if content.contains('(') && (content.contains("//") || content.contains(";\n")) { + return true; + } + } + } + false + } + fn finalize_with_eof(mut self) -> LexedStr<'a> { self.res.push(EOF, self.offset); self.res @@ -267,7 +285,16 @@ impl<'a> Converter<'a> { rustc_lexer::TokenKind::Unknown => ERROR, rustc_lexer::TokenKind::UnknownPrefix if token_text == "builtin" => IDENT, rustc_lexer::TokenKind::UnknownPrefix => { - errors.push("unknown literal prefix".into()); + let has_unterminated = self.has_likely_unterminated_string(); + + let error_msg = if has_unterminated { + format!( + "unknown literal prefix `{token_text}` (note: check for unterminated string literal)" + ) + } else { + "unknown literal prefix".to_owned() + }; + errors.push(error_msg); IDENT } rustc_lexer::TokenKind::Eof => EOF, diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index 3a8041d2df9ee..93e02a92abdad 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -284,7 +284,6 @@ pub enum SyntaxKind { STRUCT, TOKEN_TREE, TRAIT, - TRAIT_ALIAS, TRY_EXPR, TUPLE_EXPR, TUPLE_FIELD, @@ -457,7 +456,6 @@ impl SyntaxKind { | STRUCT | TOKEN_TREE | TRAIT - | TRAIT_ALIAS | TRY_EXPR | TUPLE_EXPR | TUPLE_FIELD diff --git a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs index c642e1a3354fc..cd6d433d0efa7 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/generated/runner.rs @@ -796,6 +796,12 @@ mod err { #[test] fn impl_type() { run_and_expect_errors("test_data/parser/inline/err/impl_type.rs"); } #[test] + fn invalid_question_for_type_trait_bound() { + run_and_expect_errors( + "test_data/parser/inline/err/invalid_question_for_type_trait_bound.rs", + ); + } + #[test] fn let_else_right_curly_brace() { run_and_expect_errors("test_data/parser/inline/err/let_else_right_curly_brace.rs"); } @@ -818,10 +824,18 @@ mod err { run_and_expect_errors("test_data/parser/inline/err/misplaced_label_err.rs"); } #[test] + fn missing_const_type() { + run_and_expect_errors("test_data/parser/inline/err/missing_const_type.rs"); + } + #[test] fn missing_fn_param_type() { run_and_expect_errors("test_data/parser/inline/err/missing_fn_param_type.rs"); } #[test] + fn missing_static_type() { + run_and_expect_errors("test_data/parser/inline/err/missing_static_type.rs"); + } + #[test] fn path_item_without_excl() { run_and_expect_errors("test_data/parser/inline/err/path_item_without_excl.rs"); } diff --git a/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rast b/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rast new file mode 100644 index 0000000000000..f7f24ca3f810a --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rast @@ -0,0 +1,15 @@ +FN_KW "fn" +WHITESPACE " " +IDENT "main" +L_PAREN "(" +R_PAREN ")" +WHITESPACE " " +L_CURLY "{" +WHITESPACE "\n " +IDENT "hello" +L_PAREN "(" +STRING "\"world);\n // a bunch of code was here\n env(\"FLAGS" +STRING "\", \"" +MINUS "-" +IDENT "help" error: unknown literal prefix `help` (note: check for unterminated string literal) +STRING "\")\n}" error: Missing trailing `"` symbol to terminate the string literal diff --git a/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rs b/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rs new file mode 100644 index 0000000000000..338b9582605bd --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/lexer/err/unterminated_string_unknown_prefix.rs @@ -0,0 +1,5 @@ +fn main() { + hello("world); + // a bunch of code was here + env("FLAGS", "-help") +} \ No newline at end of file diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast index d6e3219c39577..7a3ca66476e32 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/err/0044_item_modifiers.rast @@ -42,7 +42,7 @@ SOURCE_FILE WHITESPACE "\n" error 6: expected fn, trait or impl error 38: expected a name -error 40: missing type for `const` or `static` +error 40: missing type for `const` error 40: expected SEMICOLON error 44: expected an item error 44: expected an item diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast index 485ad11f233ac..08017cb0fcd91 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/generic_static.rast @@ -4,39 +4,24 @@ SOURCE_FILE WHITESPACE " " NAME IDENT "C" - ERROR - L_ANGLE "<" - ERROR - PATH - PATH_SEGMENT - NAME_REF + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME IDENT "i32" - ERROR - R_ANGLE ">" - ERROR + R_ANGLE ">" COLON ":" - WHITESPACE " " - ERROR - PATH - PATH_SEGMENT - NAME_REF - IDENT "u32" - WHITESPACE " " - ERROR + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "u32" + WHITESPACE " " EQ "=" - WHITESPACE " " - ERROR - INT_NUMBER "0" - ERROR + WHITESPACE " " + LITERAL + INT_NUMBER "0" SEMICOLON ";" WHITESPACE "\n" -error 8: missing type for `const` or `static` -error 8: expected SEMICOLON -error 8: expected an item -error 12: expected an item -error 12: expected an item -error 13: expected an item -error 18: expected an item -error 19: expected an item -error 21: expected an item -error 22: expected an item +error 8: `static` may not have generic parameters diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rast new file mode 100644 index 0000000000000..b060ee81d6178 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rast @@ -0,0 +1,49 @@ +SOURCE_FILE + FN + FN_KW "fn" + WHITESPACE " " + NAME + IDENT "f" + GENERIC_PARAM_LIST + L_ANGLE "<" + TYPE_PARAM + NAME + IDENT "T" + R_ANGLE ">" + PARAM_LIST + L_PAREN "(" + R_PAREN ")" + WHITESPACE " " + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + WHERE_PRED + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + COLON ":" + WHITESPACE " " + TYPE_BOUND_LIST + QUESTION "?" + WHERE_PRED + FOR_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + R_ANGLE ">" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Sized" + WHITESPACE " " + BLOCK_EXPR + STMT_LIST + L_CURLY "{" + R_CURLY "}" + WHITESPACE "\n" +error 20: expected comma +error 31: expected colon diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rs new file mode 100644 index 0000000000000..f80dd90d446c5 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/invalid_question_for_type_trait_bound.rs @@ -0,0 +1 @@ +fn f() where T: ?for<> Sized {} diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast new file mode 100644 index 0000000000000..11097232a6831 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rast @@ -0,0 +1,14 @@ +SOURCE_FILE + CONST + CONST_KW "const" + WHITESPACE " " + NAME + IDENT "C" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n" +error 7: missing type for `const` diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs new file mode 100644 index 0000000000000..e3ce44dadfbd2 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_const_type.rs @@ -0,0 +1 @@ +const C = 0; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast new file mode 100644 index 0000000000000..a9595401d6d62 --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rast @@ -0,0 +1,14 @@ +SOURCE_FILE + STATIC + STATIC_KW "static" + WHITESPACE " " + NAME + IDENT "C" + WHITESPACE " " + EQ "=" + WHITESPACE " " + LITERAL + INT_NUMBER "0" + SEMICOLON ";" + WHITESPACE "\n" +error 8: missing type for `static` diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs new file mode 100644 index 0000000000000..33ecedf80772b --- /dev/null +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err/missing_static_type.rs @@ -0,0 +1 @@ +static C = 0; diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast index cb296153c8f1a..69db1aee2c5a5 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rast @@ -27,19 +27,18 @@ SOURCE_FILE WHITESPACE " " TYPE_BOUND_LIST TYPE_BOUND + FOR_BINDER + FOR_KW "for" + GENERIC_PARAM_LIST + L_ANGLE "<" + R_ANGLE ">" + WHITESPACE " " QUESTION "?" - FOR_TYPE - FOR_BINDER - FOR_KW "for" - GENERIC_PARAM_LIST - L_ANGLE "<" - R_ANGLE ">" - WHITESPACE " " - PATH_TYPE - PATH - PATH_SEGMENT - NAME_REF - IDENT "Sized" + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "Sized" WHITESPACE " " BLOCK_EXPR STMT_LIST diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs index f80dd90d446c5..96353df3b9b33 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/question_for_type_trait_bound.rs @@ -1 +1 @@ -fn f() where T: ?for<> Sized {} +fn f() where T: for<> ?Sized {} diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast index c45f870898007..2ef66484ae48f 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias.rast @@ -1,5 +1,5 @@ SOURCE_FILE - TRAIT_ALIAS + TRAIT TRAIT_KW "trait" WHITESPACE " " NAME diff --git a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast index 8f678247731dc..4443d9d142630 100644 --- a/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast +++ b/src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/trait_alias_where_clause.rast @@ -1,5 +1,5 @@ SOURCE_FILE - TRAIT_ALIAS + TRAIT TRAIT_KW "trait" WHITESPACE " " NAME @@ -50,7 +50,7 @@ SOURCE_FILE IDENT "Copy" SEMICOLON ";" WHITESPACE "\n" - TRAIT_ALIAS + TRAIT TRAIT_KW "trait" WHITESPACE " " NAME diff --git a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs index 9f3e636ef816a..00c37c01d25e2 100644 --- a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs +++ b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs @@ -37,10 +37,10 @@ impl StopWatch { .build() .map_err(|err| eprintln!("Failed to create perf counter: {err}")) .ok(); - if let Some(counter) = &mut counter { - if let Err(err) = counter.enable() { - eprintln!("Failed to start perf counter: {err}") - } + if let Some(counter) = &mut counter + && let Err(err) = counter.enable() + { + eprintln!("Failed to start perf counter: {err}") } counter } else { diff --git a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs index 5bea74bed7ed2..5eda5af3ace0b 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/build_dependencies.rs @@ -9,7 +9,7 @@ use std::{cell::RefCell, io, mem, process::Command}; use base_db::Env; -use cargo_metadata::{Message, camino::Utf8Path}; +use cargo_metadata::{Message, PackageId, camino::Utf8Path}; use cfg::CfgAtom; use itertools::Itertools; use la_arena::ArenaMap; @@ -18,6 +18,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use serde::Deserialize as _; use stdx::never; use toolchain::Tool; +use triomphe::Arc; use crate::{ CargoConfig, CargoFeatures, CargoWorkspace, InvocationStrategy, ManifestPath, Package, Sysroot, @@ -284,7 +285,7 @@ impl WorkspaceBuildScripts { // NB: Cargo.toml could have been modified between `cargo metadata` and // `cargo check`. We shouldn't assume that package ids we see here are // exactly those from `config`. - let mut by_id: FxHashMap = FxHashMap::default(); + let mut by_id: FxHashMap, Package> = FxHashMap::default(); for package in workspace.packages() { outputs.insert(package, BuildScriptOutput::default()); by_id.insert(workspace[package].id.clone(), package); @@ -323,7 +324,7 @@ impl WorkspaceBuildScripts { // ideally this would be something like: // with_output_for: impl FnMut(&str, dyn FnOnce(&mut BuildScriptOutput)), // but owned trait objects aren't a thing - mut with_output_for: impl FnMut(&str, &mut dyn FnMut(&str, &mut BuildScriptOutput)), + mut with_output_for: impl FnMut(&PackageId, &mut dyn FnMut(&str, &mut BuildScriptOutput)), progress: &dyn Fn(String), ) -> io::Result> { let errors = RefCell::new(String::new()); @@ -346,10 +347,8 @@ impl WorkspaceBuildScripts { match message { Message::BuildScriptExecuted(mut message) => { - with_output_for(&message.package_id.repr, &mut |name, data| { - progress(format!( - "building compile-time-deps: build script {name} run" - )); + with_output_for(&message.package_id, &mut |name, data| { + progress(format!("build script {name} run")); let cfgs = { let mut acc = Vec::new(); for cfg in &message.cfgs { @@ -379,10 +378,8 @@ impl WorkspaceBuildScripts { }); } Message::CompilerArtifact(message) => { - with_output_for(&message.package_id.repr, &mut |name, data| { - progress(format!( - "building compile-time-deps: proc-macro {name} built" - )); + with_output_for(&message.package_id, &mut |name, data| { + progress(format!("proc-macro {name} built")); if data.proc_macro_dylib_path == ProcMacroDylibPath::NotBuilt { data.proc_macro_dylib_path = ProcMacroDylibPath::NotProcMacro; } diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs index e613fd590c70b..04fb2275893c7 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs @@ -5,7 +5,7 @@ use std::str::from_utf8; use anyhow::Context; use base_db::Env; -use cargo_metadata::{CargoOpt, MetadataCommand}; +use cargo_metadata::{CargoOpt, MetadataCommand, PackageId}; use la_arena::{Arena, Idx}; use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; @@ -13,11 +13,12 @@ use serde_derive::Deserialize; use serde_json::from_value; use span::Edition; use stdx::process::spawn_with_streaming_output; -use toolchain::Tool; +use toolchain::{NO_RUSTUP_AUTO_INSTALL_ENV, Tool}; +use triomphe::Arc; -use crate::cargo_config_file::make_lockfile_copy; -use crate::{CfgOverrides, InvocationStrategy}; -use crate::{ManifestPath, Sysroot}; +use crate::{ + CfgOverrides, InvocationStrategy, ManifestPath, Sysroot, cargo_config_file::make_lockfile_copy, +}; pub(crate) const MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH: semver::Version = semver::Version { @@ -155,8 +156,8 @@ pub struct PackageData { pub features: FxHashMap>, /// List of features enabled on this package pub active_features: Vec, - /// String representation of package id - pub id: String, + /// Package id + pub id: Arc, /// Authors as given in the `Cargo.toml` pub authors: Vec, /// Description as given in the `Cargo.toml` @@ -173,6 +174,10 @@ pub struct PackageData { pub rust_version: Option, /// The contents of [package.metadata.rust-analyzer] pub metadata: RustAnalyzerPackageMetaData, + /// If this package is a member of the workspace, store all direct and transitive + /// dependencies as long as they are workspace members, to track dependency relationships + /// between members. + pub all_member_deps: Option>, } #[derive(Deserialize, Default, Debug, Clone, Eq, PartialEq)] @@ -334,6 +339,8 @@ impl CargoWorkspace { let mut is_virtual_workspace = true; let mut requires_rustc_private = false; + let mut members = FxHashSet::default(); + meta.packages.sort_by(|a, b| a.id.cmp(&b.id)); for meta_pkg in meta.packages { let cargo_metadata::Package { @@ -356,6 +363,7 @@ impl CargoWorkspace { rust_version, .. } = meta_pkg; + let id = Arc::new(id); let meta = from_value::(metadata).unwrap_or_default(); let edition = match edition { cargo_metadata::Edition::E2015 => Edition::Edition2015, @@ -375,7 +383,7 @@ impl CargoWorkspace { let manifest = ManifestPath::try_from(AbsPathBuf::assert(manifest_path)).unwrap(); is_virtual_workspace &= manifest != ws_manifest_path; let pkg = packages.alloc(PackageData { - id: id.repr.clone(), + id: id.clone(), name: name.to_string(), version, manifest: manifest.clone(), @@ -395,7 +403,11 @@ impl CargoWorkspace { features: features.into_iter().collect(), active_features: Vec::new(), metadata: meta.rust_analyzer.unwrap_or_default(), + all_member_deps: None, }); + if is_member { + members.insert(pkg); + } let pkg_data = &mut packages[pkg]; requires_rustc_private |= pkg_data.metadata.rustc_private; pkg_by_id.insert(id, pkg); @@ -440,6 +452,43 @@ impl CargoWorkspace { .extend(node.features.into_iter().map(|it| it.to_string())); } + fn saturate_all_member_deps( + packages: &mut Arena, + to_visit: Package, + visited: &mut FxHashSet, + members: &FxHashSet, + ) { + let pkg_data = &mut packages[to_visit]; + + if !visited.insert(to_visit) { + return; + } + + let deps: Vec<_> = pkg_data + .dependencies + .iter() + .filter_map(|dep| { + let pkg = dep.pkg; + if members.contains(&pkg) { Some(pkg) } else { None } + }) + .collect(); + + let mut all_member_deps = FxHashSet::from_iter(deps.iter().copied()); + for dep in deps { + saturate_all_member_deps(packages, dep, visited, members); + if let Some(transitives) = &packages[dep].all_member_deps { + all_member_deps.extend(transitives); + } + } + + packages[to_visit].all_member_deps = Some(all_member_deps); + } + + let mut visited = FxHashSet::default(); + for member in members.iter() { + saturate_all_member_deps(&mut packages, *member, &mut visited, &members); + } + CargoWorkspace { packages, targets, @@ -583,6 +632,7 @@ impl FetchMetadata { ) -> Self { let cargo = sysroot.tool(Tool::Cargo, current_dir, &config.extra_env); let mut command = MetadataCommand::new(); + command.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1); command.cargo_path(cargo.get_program()); cargo.get_envs().for_each(|(var, val)| _ = command.env(var, val.unwrap_or_default())); command.manifest_path(cargo_toml.to_path_buf()); diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs index d39781b15066d..e36b904881513 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs @@ -18,7 +18,7 @@ pub mod project_json; pub mod toolchain_info { pub mod rustc_cfg; - pub mod target_data_layout; + pub mod target_data; pub mod target_tuple; pub mod version; diff --git a/src/tools/rust-analyzer/crates/project-model/src/tests.rs b/src/tools/rust-analyzer/crates/project-model/src/tests.rs index ed72520f40d4d..987d381fac638 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs @@ -9,7 +9,6 @@ use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf}; use rustc_hash::FxHashMap; use serde::de::DeserializeOwned; use span::FileId; -use triomphe::Arc; use crate::{ CargoWorkspace, CfgOverrides, ManifestPath, ProjectJson, ProjectJsonData, ProjectWorkspace, @@ -47,7 +46,7 @@ fn load_workspace_from_metadata(file: &str) -> ProjectWorkspace { sysroot: Sysroot::empty(), rustc_cfg: Vec::new(), toolchain: None, - target_layout: Err("target_data_layout not loaded".into()), + target: Err("target_data_layout not loaded".into()), extra_includes: Vec::new(), set_test: true, } @@ -62,7 +61,7 @@ fn load_rust_project(file: &str) -> (CrateGraphBuilder, ProcMacroPaths) { sysroot, rustc_cfg: Vec::new(), toolchain: None, - target_layout: Err(Arc::from("test has no data layout")), + target: Err("test has no target data".into()), cfg_overrides: Default::default(), extra_includes: Vec::new(), set_test: true, @@ -265,7 +264,7 @@ fn smoke_test_real_sysroot_cargo() { rustc_cfg: Vec::new(), cfg_overrides: Default::default(), toolchain: None, - target_layout: Err("target_data_layout not loaded".into()), + target: Err("target_data_layout not loaded".into()), extra_includes: Vec::new(), set_test: true, }; diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data.rs new file mode 100644 index 0000000000000..b815c0b79718e --- /dev/null +++ b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data.rs @@ -0,0 +1,107 @@ +//! Runs `rustc --print target-spec-json` to get the target_data_layout. + +use anyhow::Context; +use base_db::target; +use rustc_hash::FxHashMap; +use serde_derive::Deserialize; +use toolchain::Tool; + +use crate::{Sysroot, toolchain_info::QueryConfig, utf8_stdout}; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum Arch { + Wasm32, + Wasm64, + #[serde(other)] + Other, +} + +impl From for target::Arch { + fn from(value: Arch) -> Self { + match value { + Arch::Wasm32 => target::Arch::Wasm32, + Arch::Wasm64 => target::Arch::Wasm64, + Arch::Other => target::Arch::Other, + } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub struct TargetSpec { + pub data_layout: String, + pub arch: Arch, +} + +/// Uses `rustc --print target-spec-json`. +pub fn get( + config: QueryConfig<'_>, + target: Option<&str>, + extra_env: &FxHashMap>, +) -> anyhow::Result { + const RUSTC_ARGS: [&str; 2] = ["--print", "target-spec-json"]; + let process = |output: String| { + let target_spec = serde_json::from_str::(&output).map_err(|_| { + anyhow::format_err!("could not parse target-spec-json from command output") + })?; + Ok(target::TargetData { + arch: target_spec.arch.into(), + data_layout: target_spec.data_layout.into_boxed_str(), + }) + }; + let (sysroot, current_dir) = match config { + QueryConfig::Cargo(sysroot, cargo_toml, _) => { + let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent(), extra_env); + cmd.env("RUSTC_BOOTSTRAP", "1"); + cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS); + if let Some(target) = target { + cmd.args(["--target", target]); + } + cmd.args(["--", "-Z", "unstable-options"]); + match utf8_stdout(&mut cmd) { + Ok(output) => return process(output), + Err(e) => { + tracing::warn!(%e, "failed to run `{cmd:?}`, falling back to invoking rustc directly"); + (sysroot, cargo_toml.parent().as_ref()) + } + } + } + QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), + }; + + let mut cmd = Sysroot::tool(sysroot, Tool::Rustc, current_dir, extra_env); + cmd.env("RUSTC_BOOTSTRAP", "1").args(["-Z", "unstable-options"]).args(RUSTC_ARGS); + if let Some(target) = target { + cmd.args(["--target", target]); + } + utf8_stdout(&mut cmd) + .with_context(|| format!("unable to fetch target-data-layout via `{cmd:?}`")) + .and_then(process) +} + +#[cfg(test)] +mod tests { + use paths::{AbsPathBuf, Utf8PathBuf}; + + use crate::{ManifestPath, Sysroot}; + + use super::*; + + #[test] + fn cargo() { + let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"); + let sysroot = Sysroot::empty(); + let manifest_path = + ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); + let cfg = QueryConfig::Cargo(&sysroot, &manifest_path, &None); + assert!(get(cfg, None, &FxHashMap::default()).is_ok()); + } + + #[test] + fn rustc() { + let sysroot = Sysroot::empty(); + let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref()); + assert!(get(cfg, None, &FxHashMap::default()).is_ok()); + } +} diff --git a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs b/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs deleted file mode 100644 index a28f468e692d0..0000000000000 --- a/src/tools/rust-analyzer/crates/project-model/src/toolchain_info/target_data_layout.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Runs `rustc --print target-spec-json` to get the target_data_layout. - -use anyhow::Context; -use rustc_hash::FxHashMap; -use toolchain::Tool; - -use crate::{Sysroot, toolchain_info::QueryConfig, utf8_stdout}; - -/// Uses `rustc --print target-spec-json`. -pub fn get( - config: QueryConfig<'_>, - target: Option<&str>, - extra_env: &FxHashMap>, -) -> anyhow::Result { - const RUSTC_ARGS: [&str; 2] = ["--print", "target-spec-json"]; - let process = |output: String| { - (|| Some(output.split_once(r#""data-layout": ""#)?.1.split_once('"')?.0.to_owned()))() - .ok_or_else(|| { - anyhow::format_err!("could not parse target-spec-json from command output") - }) - }; - let (sysroot, current_dir) = match config { - QueryConfig::Cargo(sysroot, cargo_toml, _) => { - let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent(), extra_env); - cmd.env("RUSTC_BOOTSTRAP", "1"); - cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS).args([ - "--", - "-Z", - "unstable-options", - ]); - if let Some(target) = target { - cmd.args(["--target", target]); - } - match utf8_stdout(&mut cmd) { - Ok(output) => return process(output), - Err(e) => { - tracing::warn!(%e, "failed to run `{cmd:?}`, falling back to invoking rustc directly"); - (sysroot, cargo_toml.parent().as_ref()) - } - } - } - QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir), - }; - - let mut cmd = Sysroot::tool(sysroot, Tool::Rustc, current_dir, extra_env); - cmd.env("RUSTC_BOOTSTRAP", "1").args(["-Z", "unstable-options"]).args(RUSTC_ARGS); - if let Some(target) = target { - cmd.args(["--target", target]); - } - utf8_stdout(&mut cmd) - .with_context(|| format!("unable to fetch target-data-layout via `{cmd:?}`")) - .and_then(process) -} - -#[cfg(test)] -mod tests { - use paths::{AbsPathBuf, Utf8PathBuf}; - - use crate::{ManifestPath, Sysroot}; - - use super::*; - - #[test] - fn cargo() { - let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml"); - let sysroot = Sysroot::empty(); - let manifest_path = - ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); - let cfg = QueryConfig::Cargo(&sysroot, &manifest_path, &None); - assert!(get(cfg, None, &FxHashMap::default()).is_ok()); - } - - #[test] - fn rustc() { - let sysroot = Sysroot::empty(); - let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref()); - assert!(get(cfg, None, &FxHashMap::default()).is_ok()); - } -} diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs index 5b36e10fd6925..0649ce9eeb9df 100644 --- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs +++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs @@ -8,7 +8,7 @@ use anyhow::Context; use base_db::{ CrateBuilderId, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData, DependencyBuilder, Env, LangCrateOrigin, ProcMacroLoadingError, - ProcMacroPaths, TargetLayoutLoadResult, + ProcMacroPaths, target::TargetLoadResult, }; use cfg::{CfgAtom, CfgDiff, CfgOptions}; use intern::{Symbol, sym}; @@ -16,8 +16,9 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf}; use rustc_hash::{FxHashMap, FxHashSet}; use semver::Version; use span::{Edition, FileId}; -use toolchain::Tool; +use toolchain::{NO_RUSTUP_AUTO_INSTALL_ENV, Tool}; use tracing::instrument; +use tracing::{debug, error, info}; use triomphe::Arc; use crate::{ @@ -30,10 +31,9 @@ use crate::{ env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env}, project_json::{Crate, CrateArrayIdx}, sysroot::RustLibSrcWorkspace, - toolchain_info::{QueryConfig, rustc_cfg, target_data_layout, target_tuple, version}, + toolchain_info::{QueryConfig, rustc_cfg, target_data, target_tuple, version}, utf8_stdout, }; -use tracing::{debug, error, info}; pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option; @@ -63,7 +63,7 @@ pub struct ProjectWorkspace { /// The toolchain version used by this workspace. pub toolchain: Option, /// The target data layout queried for workspace. - pub target_layout: TargetLayoutLoadResult, + pub target: TargetLoadResult, /// A set of cfg overrides for this workspace. pub cfg_overrides: CfgOverrides, /// Additional includes to add for the VFS. @@ -115,7 +115,7 @@ impl fmt::Debug for ProjectWorkspace { sysroot, rustc_cfg, toolchain, - target_layout, + target: target_layout, cfg_overrides, extra_includes, set_test, @@ -157,7 +157,6 @@ impl fmt::Debug for ProjectWorkspace { .field("file", &file) .field("cargo_script", &cargo_script.is_some()) .field("n_sysroot_crates", &sysroot.num_packages()) - .field("cargo_script", &cargo_script.is_some()) .field("n_rustc_cfg", &rustc_cfg.len()) .field("toolchain", &toolchain) .field("data_layout", &target_layout) @@ -310,8 +309,8 @@ impl ProjectWorkspace { let rustc_cfg = s.spawn(|| { rustc_cfg::get(toolchain_config, targets.first().map(Deref::deref), extra_env) }); - let data_layout = s.spawn(|| { - target_data_layout::get( + let target_data = s.spawn(|| { + target_data::get( toolchain_config, targets.first().map(Deref::deref), extra_env, @@ -393,7 +392,7 @@ impl ProjectWorkspace { s.spawn(move || cargo_config_env(cargo_toml, &config_file)); thread::Result::Ok(( rustc_cfg.join()?, - data_layout.join()?, + target_data.join()?, rustc_dir.join()?, loaded_sysroot.join()?, cargo_metadata.join()?, @@ -443,7 +442,7 @@ impl ProjectWorkspace { rustc_cfg, cfg_overrides: cfg_overrides.clone(), toolchain, - target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), + target: data_layout.map_err(|it| it.to_string().into()), extra_includes: extra_includes.clone(), set_test: *set_test, }) @@ -481,11 +480,7 @@ impl ProjectWorkspace { rustc_cfg::get(query_config, targets.first().map(Deref::deref), &config.extra_env) }); let data_layout = s.spawn(|| { - target_data_layout::get( - query_config, - targets.first().map(Deref::deref), - &config.extra_env, - ) + target_data::get(query_config, targets.first().map(Deref::deref), &config.extra_env) }); let loaded_sysroot = s.spawn(|| { if let Some(sysroot_project) = sysroot_project { @@ -514,7 +509,7 @@ impl ProjectWorkspace { thread::Result::Ok((rustc_cfg.join()?, data_layout.join()?, loaded_sysroot.join()?)) }); - let (rustc_cfg, target_layout, loaded_sysroot) = match join { + let (rustc_cfg, target_data, loaded_sysroot) = match join { Ok(it) => it, Err(e) => std::panic::resume_unwind(e), }; @@ -528,7 +523,7 @@ impl ProjectWorkspace { sysroot, rustc_cfg, toolchain, - target_layout: target_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), + target: target_data.map_err(|it| it.to_string().into()), cfg_overrides: config.cfg_overrides.clone(), extra_includes: config.extra_includes.clone(), set_test: config.set_test, @@ -552,7 +547,7 @@ impl ProjectWorkspace { let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env) .unwrap_or_default(); let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env); - let data_layout = target_data_layout::get(query_config, None, &config.extra_env); + let target_data = target_data::get(query_config, None, &config.extra_env); let target_dir = config .target_dir .clone() @@ -611,7 +606,7 @@ impl ProjectWorkspace { sysroot, rustc_cfg, toolchain, - target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), + target: target_data.map_err(|it| it.to_string().into()), cfg_overrides: config.cfg_overrides.clone(), extra_includes: config.extra_includes.clone(), set_test: config.set_test, @@ -943,7 +938,7 @@ impl ProjectWorkspace { let Self { kind, sysroot, cfg_overrides, rustc_cfg, .. } = self; let crate_ws_data = Arc::new(CrateWorkspaceData { toolchain: self.toolchain.clone(), - data_layout: self.target_layout.clone(), + target: self.target.clone(), }); let (crate_graph, proc_macros) = match kind { ProjectWorkspaceKind::Json(project) => project_json_to_crate_graph( @@ -1001,13 +996,15 @@ impl ProjectWorkspace { } pub fn eq_ignore_build_data(&self, other: &Self) -> bool { - let Self { kind, sysroot, rustc_cfg, toolchain, target_layout, cfg_overrides, .. } = self; + let Self { + kind, sysroot, rustc_cfg, toolchain, target: target_layout, cfg_overrides, .. + } = self; let Self { kind: o_kind, sysroot: o_sysroot, rustc_cfg: o_rustc_cfg, toolchain: o_toolchain, - target_layout: o_target_layout, + target: o_target_layout, cfg_overrides: o_cfg_overrides, .. } = other; @@ -1910,6 +1907,7 @@ fn cargo_target_dir( ) -> Option { let cargo = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env); let mut meta = cargo_metadata::MetadataCommand::new(); + meta.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1); meta.cargo_path(cargo.get_program()); meta.manifest_path(manifest); // `--no-deps` doesn't (over)write lockfiles as it doesn't do any package resolve. diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt index 3722e2c721686..4f6ce4dc95374 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model.txt @@ -70,7 +70,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -155,7 +155,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -240,7 +240,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -325,7 +325,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -406,7 +406,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt index 3722e2c721686..4f6ce4dc95374 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_selective_overrides.txt @@ -70,7 +70,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -155,7 +155,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -240,7 +240,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -325,7 +325,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -406,7 +406,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt index 7b156ea63a58f..6862918e09ae6 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/cargo_hello_world_project_model_with_wildcard_overrides.txt @@ -69,7 +69,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -153,7 +153,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -237,7 +237,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -321,7 +321,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, @@ -402,7 +402,7 @@ }, }, ws_data: CrateWorkspaceData { - data_layout: Err( + target: Err( "target_data_layout not loaded", ), toolchain: None, diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt index 98fe598eb3a32..28ad3236ae813 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt @@ -43,8 +43,8 @@ entries: {}, }, ws_data: CrateWorkspaceData { - data_layout: Err( - "test has no data layout", + target: Err( + "test has no target data", ), toolchain: None, }, @@ -93,8 +93,8 @@ entries: {}, }, ws_data: CrateWorkspaceData { - data_layout: Err( - "test has no data layout", + target: Err( + "test has no target data", ), toolchain: None, }, diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt index 0dc373b5b47ed..dabb3aa674414 100644 --- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt +++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt @@ -40,8 +40,8 @@ entries: {}, }, ws_data: CrateWorkspaceData { - data_layout: Err( - "test has no data layout", + target: Err( + "test has no target data", ), toolchain: None, }, diff --git a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs index c151cca07272a..7698ce5fff13e 100644 --- a/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs +++ b/src/tools/rust-analyzer/crates/query-group-macro/src/queries.rs @@ -48,7 +48,8 @@ impl ToTokens for TrackedQuery { quote!(#(#options),*) }) .into_iter() - .chain(self.lru.map(|lru| quote!(lru = #lru))); + .chain(self.lru.map(|lru| quote!(lru = #lru))) + .chain(Some(quote!(unsafe(non_update_return_type)))); let annotation = quote!(#[salsa_macros::tracked( #(#options),* )]); let pat_and_tys = &self.pat_and_tys; @@ -326,7 +327,8 @@ impl ToTokens for Lookup { let wrapper_struct = self.interned_struct_path.to_token_stream(); let method = quote! { #sig { - #wrapper_struct::ingredient(self).data(self.as_dyn_database(), id.as_id()).0.clone() + let zalsa = self.zalsa(); + #wrapper_struct::ingredient(zalsa).data(zalsa, id.as_id()).0.clone() } }; diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml index b301a7189b3c9..c746f848b6a06 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml @@ -75,6 +75,8 @@ vfs-notify.workspace = true vfs.workspace = true paths.workspace = true +ra-ap-rustc_type_ir.workspace = true + [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.60", features = [ "Win32_System_Diagnostics_Debug", diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs index ab045e0bf9ff1..cc8db1b841ea4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/main.rs @@ -160,9 +160,9 @@ fn setup_logging(log_file_flag: Option) -> anyhow::Result<()> { rust_analyzer::tracing::Config { writer, - // Deliberately enable all `error` logs if the user has not set RA_LOG, as there is usually + // Deliberately enable all `warn` logs if the user has not set RA_LOG, as there is usually // useful information in there for debugging. - filter: env::var("RA_LOG").ok().unwrap_or_else(|| "error".to_owned()), + filter: env::var("RA_LOG").ok().unwrap_or_else(|| "warn".to_owned()), chalk_filter: env::var("CHALK_DEBUG").ok(), profile_filter: env::var("RA_PROFILE").ok(), json_profile_filter: std::env::var("RA_PROFILE_JSON").ok(), @@ -208,13 +208,24 @@ fn run_server() -> anyhow::Result<()> { tracing::info!("InitializeParams: {}", initialize_params); let lsp_types::InitializeParams { root_uri, - capabilities, + mut capabilities, workspace_folders, initialization_options, client_info, .. } = from_json::("InitializeParams", &initialize_params)?; + // lsp-types has a typo in the `/capabilities/workspace/diagnostics` field, its typoed as `diagnostic` + if let Some(val) = initialize_params.pointer("/capabilities/workspace/diagnostics") + && let Ok(diag_caps) = from_json::( + "DiagnosticWorkspaceClientCapabilities", + val, + ) + { + tracing::info!("Patching lsp-types workspace diagnostics capabilities: {diag_caps:#?}"); + capabilities.workspace.get_or_insert_default().diagnostic.get_or_insert(diag_caps); + } + let root_path = match root_uri .and_then(|it| it.to_file_path().ok()) .map(patch_path_prefix) diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs index 97886844a9f9e..2a9ef981291ec 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -10,15 +10,16 @@ use std::{ use cfg::{CfgAtom, CfgDiff}; use hir::{ - Adt, AssocItem, Crate, DefWithBody, HasSource, HirDisplay, ImportPathConfig, ModuleDef, Name, + Adt, AssocItem, Crate, DefWithBody, FindPathConfig, HasCrate, HasSource, HirDisplay, ModuleDef, + Name, db::{DefDatabase, ExpandDatabase, HirDatabase}, + next_solver::{DbInterner, GenericArgs}, }; use hir_def::{ SyntheticSyntax, expr_store::BodySourceMap, hir::{ExprId, PatId}, }; -use hir_ty::{Interner, Substitution, TyExt, TypeFlags}; use ide::{ Analysis, AnalysisHost, AnnotationConfig, DiagnosticsConfig, Edition, InlayFieldsToResolve, InlayHintsConfig, LineCol, RootDatabase, @@ -34,6 +35,7 @@ use profile::StopWatch; use project_model::{CargoConfig, CfgOverrides, ProjectManifest, ProjectWorkspace, RustLibSource}; use rayon::prelude::*; use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_type_ir::inherent::Ty as _; use syntax::AstNode; use vfs::{AbsPathBuf, Vfs, VfsPath}; @@ -310,32 +312,37 @@ impl flags::AnalysisStats { shuffle(&mut rng, &mut bodies); } - if !self.skip_lowering { - self.run_body_lowering(db, &vfs, &bodies, verbosity); - } + hir::attach_db(db, || { + if !self.skip_lowering { + self.run_body_lowering(db, &vfs, &bodies, verbosity); + } - if !self.skip_inference { - self.run_inference(db, &vfs, &bodies, verbosity); - } + if !self.skip_inference { + self.run_inference(db, &vfs, &bodies, verbosity); + } - if !self.skip_mir_stats { - self.run_mir_lowering(db, &bodies, verbosity); - } + if !self.skip_mir_stats { + self.run_mir_lowering(db, &bodies, verbosity); + } - if !self.skip_data_layout { - self.run_data_layout(db, &adts, verbosity); - } + if !self.skip_data_layout { + self.run_data_layout(db, &adts, verbosity); + } - if !self.skip_const_eval { - self.run_const_eval(db, &bodies, verbosity); - } + if !self.skip_const_eval { + self.run_const_eval(db, &bodies, verbosity); + } + }); + + file_ids.sort(); + file_ids.dedup(); if self.run_all_ide_things { - self.run_ide_things(host.analysis(), file_ids.clone()); + self.run_ide_things(host.analysis(), &file_ids, db, &vfs, verbosity); } if self.run_term_search { - self.run_term_search(&workspace, db, &vfs, file_ids, verbosity); + self.run_term_search(&workspace, db, &vfs, &file_ids, verbosity); } let db = host.raw_database_mut(); @@ -361,6 +368,7 @@ impl flags::AnalysisStats { let mut all = 0; let mut fail = 0; for &a in adts { + let interner = DbInterner::new_with(db, Some(a.krate(db).base()), None); let generic_params = db.generic_params(a.into()); if generic_params.iter_type_or_consts().next().is_some() || generic_params.iter_lt().next().is_some() @@ -371,7 +379,7 @@ impl flags::AnalysisStats { all += 1; let Err(e) = db.layout_of_adt( hir_def::AdtId::from(a), - Substitution::empty(Interner), + GenericArgs::new_from_iter(interner, []), db.trait_environment(a.into()), ) else { continue; @@ -390,15 +398,27 @@ impl flags::AnalysisStats { } fn run_const_eval(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) { + let len = bodies + .iter() + .filter(|body| matches!(body, DefWithBody::Const(_) | DefWithBody::Static(_))) + .count(); + let mut bar = match verbosity { + Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), + _ if self.parallel || self.output.is_some() => ProgressReport::hidden(), + _ => ProgressReport::new(len), + }; + let mut sw = self.stop_watch(); let mut all = 0; let mut fail = 0; for &b in bodies { + bar.set_message(move || format!("const eval: {}", full_name(db, b, b.module(db)))); let res = match b { DefWithBody::Const(c) => c.eval(db), DefWithBody::Static(s) => s.eval(db), _ => continue, }; + bar.inc(1); all += 1; let Err(error) = res else { continue; @@ -406,10 +426,11 @@ impl flags::AnalysisStats { if verbosity.is_spammy() { let full_name = full_name_of_item(db, b.module(db), b.name(db).unwrap_or(Name::missing())); - println!("Const eval for {full_name} failed due {error:?}"); + bar.println(format!("Const eval for {full_name} failed due {error:?}")); } fail += 1; } + bar.finish_and_clear(); let const_eval_time = sw.elapsed(); eprintln!("{:<20} {}", "Const evaluation:", const_eval_time); eprintln!("Failed const evals: {fail} ({}%)", percentage(fail, all)); @@ -417,12 +438,13 @@ impl flags::AnalysisStats { report_metric("const eval time", const_eval_time.time.as_millis() as u64, "ms"); } + /// Invariant: `file_ids` must be sorted and deduped before passing into here fn run_term_search( &self, ws: &ProjectWorkspace, db: &RootDatabase, vfs: &Vfs, - mut file_ids: Vec, + file_ids: &[EditionedFileId], verbosity: Verbosity, ) { let cargo_config = CargoConfig { @@ -440,9 +462,6 @@ impl flags::AnalysisStats { _ => ProgressReport::new(file_ids.len()), }; - file_ids.sort(); - file_ids.dedup(); - #[derive(Debug, Default)] struct Acc { tail_expr_syntax_hits: u64, @@ -456,7 +475,7 @@ impl flags::AnalysisStats { bar.tick(); let mut sw = self.stop_watch(); - for &file_id in &file_ids { + for &file_id in file_ids { let file_id = file_id.editioned_file_id(db); let sema = hir::Semantics::new(db); let display_target = match sema.first_crate(file_id.file_id()) { @@ -535,7 +554,7 @@ impl flags::AnalysisStats { .gen_source_code( &scope, &mut formatter, - ImportPathConfig { + FindPathConfig { prefer_no_std: false, prefer_prelude: true, prefer_absolute: false, @@ -659,6 +678,10 @@ impl flags::AnalysisStats { let mut all = 0; let mut fail = 0; for &body_id in bodies { + bar.set_message(move || { + format!("mir lowering: {}", full_name(db, body_id, body_id.module(db))) + }); + bar.inc(1); if matches!(body_id, DefWithBody::Variant(_)) { continue; } @@ -794,7 +817,7 @@ impl flags::AnalysisStats { for (expr_id, _) in body.exprs() { let ty = &inference_result[expr_id]; num_exprs += 1; - let unknown_or_partial = if ty.is_unknown() { + let unknown_or_partial = if ty.is_ty_error() { num_exprs_unknown += 1; if verbosity.is_spammy() { if let Some((path, start, end)) = expr_syntax_range(db, vfs, &sm(), expr_id) @@ -816,8 +839,7 @@ impl flags::AnalysisStats { } true } else { - let is_partially_unknown = - ty.data(Interner).flags.contains(TypeFlags::HAS_ERROR); + let is_partially_unknown = ty.references_non_lt_error(); if is_partially_unknown { num_exprs_partially_unknown += 1; } @@ -899,7 +921,7 @@ impl flags::AnalysisStats { for (pat_id, _) in body.pats() { let ty = &inference_result[pat_id]; num_pats += 1; - let unknown_or_partial = if ty.is_unknown() { + let unknown_or_partial = if ty.is_ty_error() { num_pats_unknown += 1; if verbosity.is_spammy() { if let Some((path, start, end)) = pat_syntax_range(db, vfs, &sm(), pat_id) { @@ -920,8 +942,7 @@ impl flags::AnalysisStats { } true } else { - let is_partially_unknown = - ty.data(Interner).flags.contains(TypeFlags::HAS_ERROR); + let is_partially_unknown = ty.references_non_lt_error(); if is_partially_unknown { num_pats_partially_unknown += 1; } @@ -1086,12 +1107,28 @@ impl flags::AnalysisStats { report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms"); } - fn run_ide_things(&self, analysis: Analysis, mut file_ids: Vec) { - file_ids.sort(); - file_ids.dedup(); + /// Invariant: `file_ids` must be sorted and deduped before passing into here + fn run_ide_things( + &self, + analysis: Analysis, + file_ids: &[EditionedFileId], + db: &RootDatabase, + vfs: &Vfs, + verbosity: Verbosity, + ) { + let len = file_ids.len(); + let create_bar = || match verbosity { + Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(), + _ if self.parallel || self.output.is_some() => ProgressReport::hidden(), + _ => ProgressReport::new(len), + }; + let mut sw = self.stop_watch(); - for &file_id in &file_ids { + let mut bar = create_bar(); + for &file_id in file_ids { + let msg = format!("diagnostics: {}", vfs.file_path(file_id.file_id(db))); + bar.set_message(move || msg.clone()); _ = analysis.full_diagnostics( &DiagnosticsConfig { enabled: true, @@ -1118,8 +1155,14 @@ impl flags::AnalysisStats { ide::AssistResolveStrategy::All, analysis.editioned_file_id_to_vfs(file_id), ); + bar.inc(1); } - for &file_id in &file_ids { + bar.finish_and_clear(); + + let mut bar = create_bar(); + for &file_id in file_ids { + let msg = format!("inlay hints: {}", vfs.file_path(file_id.file_id(db))); + bar.set_message(move || msg.clone()); _ = analysis.inlay_hints( &InlayHintsConfig { render_colons: false, @@ -1134,6 +1177,7 @@ impl flags::AnalysisStats { }, chaining_hints: true, adjustment_hints: ide::AdjustmentHints::Always, + adjustment_hints_disable_reborrows: true, adjustment_hints_mode: ide::AdjustmentHintsMode::Postfix, adjustment_hints_hide_outside_unsafe: false, closure_return_type_hints: ide::ClosureReturnTypeHints::Always, @@ -1154,8 +1198,14 @@ impl flags::AnalysisStats { analysis.editioned_file_id_to_vfs(file_id), None, ); + bar.inc(1); } - for &file_id in &file_ids { + bar.finish_and_clear(); + + let mut bar = create_bar(); + for &file_id in file_ids { + let msg = format!("annotations: {}", vfs.file_path(file_id.file_id(db))); + bar.set_message(move || msg.clone()); analysis .annotations( &AnnotationConfig { @@ -1174,7 +1224,10 @@ impl flags::AnalysisStats { .for_each(|annotation| { _ = analysis.resolve_annotation(annotation); }); + bar.inc(1); } + bar.finish_and_clear(); + let ide_time = sw.elapsed(); eprintln!("{:<20} {} ({} files)", "IDE:", ide_time, file_ids.len()); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs index 7b12cb14009ff..82590c8e707fa 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/diagnostics.rs @@ -9,7 +9,7 @@ use ide::{AnalysisHost, AssistResolveStrategy, Diagnostic, DiagnosticsConfig, Se use ide_db::{LineIndexDatabase, base_db::SourceDatabase}; use load_cargo::{LoadCargoConfig, ProcMacroServerChoice, load_workspace_at}; -use crate::cli::flags; +use crate::cli::{flags, progress_report::ProgressReport}; impl flags::Diagnostics { pub fn run(self) -> anyhow::Result<()> { @@ -50,23 +50,26 @@ impl flags::Diagnostics { let mut found_error = false; let mut visited_files = FxHashSet::default(); - - let work = all_modules(db).into_iter().filter(|module| { - let file_id = module.definition_source_file_id(db).original_file(db); - let source_root = db.file_source_root(file_id.file_id(db)).source_root_id(db); - let source_root = db.source_root(source_root).source_root(db); - !source_root.is_library - }); - + let min_severity = self.severity.unwrap_or(flags::Severity::Weak); + + let work = all_modules(db) + .into_iter() + .filter(|module| { + let file_id = module.definition_source_file_id(db).original_file(db); + let source_root = db.file_source_root(file_id.file_id(db)).source_root_id(db); + let source_root = db.source_root(source_root).source_root(db); + !source_root.is_library + }) + .collect::>(); + + let mut bar = ProgressReport::new(work.len()); for module in work { let file_id = module.definition_source_file_id(db).original_file(db); if !visited_files.contains(&file_id) { + let message = format!("processing {}", _vfs.file_path(file_id.file_id(db))); + bar.set_message(move || message.clone()); let crate_name = module.krate().display_name(db).as_deref().unwrap_or(&sym::unknown).to_owned(); - println!( - "processing crate: {crate_name}, module: {}", - _vfs.file_path(file_id.file_id(db)) - ); for diagnostic in analysis .full_diagnostics( &DiagnosticsConfig::test_sample(), @@ -75,6 +78,16 @@ impl flags::Diagnostics { ) .unwrap() { + let severity = match diagnostic.severity { + Severity::Error => flags::Severity::Error, + Severity::Warning => flags::Severity::Warning, + Severity::WeakWarning => flags::Severity::Weak, + Severity::Allow => continue, + }; + if severity < min_severity { + continue; + } + if matches!(diagnostic.severity, Severity::Error) { found_error = true; } @@ -83,12 +96,17 @@ impl flags::Diagnostics { let line_index = db.line_index(range.file_id); let start = line_index.line_col(range.range.start()); let end = line_index.line_col(range.range.end()); - println!("{severity:?} {code:?} from {start:?} to {end:?}: {message}"); + bar.println(format!( + "at crate {crate_name}, file {}: {severity:?} {code:?} from {start:?} to {end:?}: {message}", + _vfs.file_path(file_id.file_id(db)) + )); } visited_files.insert(file_id); } + bar.inc(1); } + bar.finish_and_clear(); println!(); println!("diagnostic scan complete"); diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs index 16f351272b691..75030bedfca3f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/flags.rs @@ -124,6 +124,9 @@ xflags::xflags! { optional --disable-proc-macros /// Run the proc-macro-srv binary at the specified path. optional --proc-macro-srv path: PathBuf + + /// The minimum severity. + optional --severity severity: Severity } /// Report unresolved references @@ -281,6 +284,7 @@ pub struct Diagnostics { pub disable_build_scripts: bool, pub disable_proc_macros: bool, pub proc_macro_srv: Option, + pub severity: Option, } #[derive(Debug)] @@ -376,3 +380,23 @@ impl FromStr for OutputFormat { } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Severity { + Weak, + Warning, + Error, +} + +impl FromStr for Severity { + type Err = String; + + fn from_str(s: &str) -> Result { + match &*s.to_ascii_lowercase() { + "weak" => Ok(Self::Weak), + "warning" => Ok(Self::Warning), + "error" => Ok(Self::Error), + _ => Err(format!("unknown severity `{s}`")), + } + } +} diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs index 36ae98b321b84..609ebf2b514f0 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/rustc_tests.rs @@ -11,7 +11,7 @@ use ide_db::base_db; use itertools::Either; use paths::Utf8PathBuf; use profile::StopWatch; -use project_model::toolchain_info::{QueryConfig, target_data_layout}; +use project_model::toolchain_info::{QueryConfig, target_data}; use project_model::{ CargoConfig, ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, RustLibSource, RustSourceWorkspaceConfig, Sysroot, @@ -19,7 +19,6 @@ use project_model::{ use load_cargo::{LoadCargoConfig, ProcMacroServerChoice, load_workspace}; use rustc_hash::FxHashMap; -use triomphe::Arc; use vfs::{AbsPathBuf, FileId}; use walkdir::WalkDir; @@ -87,7 +86,7 @@ impl Tester { sysroot.set_workspace(loaded_sysroot); } - let data_layout = target_data_layout::get( + let target_data = target_data::get( QueryConfig::Rustc(&sysroot, tmp_file.parent().unwrap().as_ref()), None, &cargo_config.extra_env, @@ -101,7 +100,7 @@ impl Tester { sysroot, rustc_cfg: vec![], toolchain: None, - target_layout: data_layout.map(Arc::from).map_err(|it| Arc::from(it.to_string())), + target: target_data.map_err(|it| it.to_string().into()), cfg_overrides: Default::default(), extra_includes: vec![], set_test: true, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/symbols.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/symbols.rs index 9fad6723afcd9..d7af56d3e15be 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/symbols.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/cli/symbols.rs @@ -1,5 +1,5 @@ //! Read Rust code on stdin, print syntax tree on stdout. -use ide::Analysis; +use ide::{Analysis, FileStructureConfig}; use crate::cli::{flags, read_stdin}; @@ -7,7 +7,12 @@ impl flags::Symbols { pub fn run(self) -> anyhow::Result<()> { let text = read_stdin()?; let (analysis, file_id) = Analysis::from_single_file(text); - let structure = analysis.file_structure(file_id).unwrap(); + let structure = analysis + // The default setting in config.rs (document_symbol_search_excludeLocals) is to exclude + // locals because it is unlikely that users want document search to return the names of + // local variables, but here we include them deliberately. + .file_structure(&FileStructureConfig { exclude_locals: false }, file_id) + .unwrap(); for s in structure { println!("{s:?}"); } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs index d6c80c399ba2e..674e8623b2d07 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs @@ -3,13 +3,15 @@ use std::{ ffi::OsString, - fmt, io, + fmt, + io::{self, BufWriter, Write}, marker::PhantomData, path::PathBuf, process::{ChildStderr, ChildStdout, Command, Stdio}, }; use crossbeam_channel::Sender; +use paths::Utf8PathBuf; use process_wrap::std::{StdChildWrapper, StdCommandWrap}; use stdx::process::streaming_output; @@ -40,7 +42,7 @@ impl CargoActor { } impl CargoActor { - fn run(self) -> io::Result<(bool, String)> { + fn run(self, outfile: Option) -> io::Result<(bool, String)> { // We manually read a line at a time, instead of using serde's // stream deserializers, because the deserializer cannot recover // from an error, resulting in it getting stuck, because we try to @@ -50,6 +52,15 @@ impl CargoActor { // simply skip a line if it doesn't parse, which just ignores any // erroneous output. + let mut stdout = outfile.as_ref().and_then(|path| { + _ = std::fs::create_dir_all(path); + Some(BufWriter::new(std::fs::File::create(path.join("stdout")).ok()?)) + }); + let mut stderr = outfile.as_ref().and_then(|path| { + _ = std::fs::create_dir_all(path); + Some(BufWriter::new(std::fs::File::create(path.join("stderr")).ok()?)) + }); + let mut stdout_errors = String::new(); let mut stderr_errors = String::new(); let mut read_at_least_one_stdout_message = false; @@ -67,11 +78,19 @@ impl CargoActor { self.stdout, self.stderr, &mut |line| { + if let Some(stdout) = &mut stdout { + _ = stdout.write_all(line.as_bytes()); + _ = stdout.write_all(b"\n"); + } if process_line(line, &mut stdout_errors) { read_at_least_one_stdout_message = true; } }, &mut |line| { + if let Some(stderr) = &mut stderr { + _ = stderr.write_all(line.as_bytes()); + _ = stderr.write_all(b"\n"); + } if process_line(line, &mut stderr_errors) { read_at_least_one_stderr_message = true; } @@ -130,6 +149,7 @@ impl CommandHandle { mut command: Command, parser: impl CargoParser, sender: Sender, + out_file: Option, ) -> std::io::Result { command.stdout(Stdio::piped()).stderr(Stdio::piped()).stdin(Stdio::null()); @@ -150,7 +170,7 @@ impl CommandHandle { let actor = CargoActor::::new(parser, sender, stdout, stderr); let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, "CommandHandle") - .spawn(move || actor.run()) + .spawn(move || actor.run(out_file)) .expect("failed to spawn thread"); Ok(CommandHandle { program, arguments, current_dir, child, thread, _phantom: PhantomData }) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs index 1a00295b9ac18..96b65838ae426 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs @@ -226,6 +226,14 @@ config_data! { inlayHints_discriminantHints_enable: DiscriminantHintsDef = DiscriminantHintsDef::Never, + /// Disable reborrows in expression adjustments inlay hints. + /// + /// Reborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer. + /// + /// Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed. + inlayHints_expressionAdjustmentHints_disableReborrows: bool = + true, + /// Show inlay hints for type adjustments. inlayHints_expressionAdjustmentHints_enable: AdjustmentHintsDef = AdjustmentHintsDef::Never, @@ -259,6 +267,8 @@ config_data! { inlayHints_lifetimeElisionHints_useParameterNames: bool = false, /// Maximum length for inlay hints. Set to null to have an unlimited length. + /// + /// **Note:** This is mostly a hint, and we don't guarantee to strictly follow the limit. inlayHints_maxLength: Option = Some(25), /// Show function parameter name inlay hints at the call site. @@ -374,6 +384,13 @@ config_data! { /// Exclude tests from find-all-references and call-hierarchy. references_excludeTests: bool = false, + /// Use semantic tokens for comments. + /// + /// In some editors (e.g. vscode) semantic tokens override other highlighting grammars. + /// By disabling semantic tokens for comments, other grammars can be used to highlight + /// their contents. + semanticHighlighting_comments_enable: bool = true, + /// Inject additional highlighting into doc comments. /// /// When enabled, rust-analyzer will highlight rust source in doc comments as well as intra @@ -858,6 +875,9 @@ config_data! { /// check will be performed. check_workspace: bool = true, + /// Exclude all locals from document symbol search. + document_symbol_search_excludeLocals: bool = true, + /// These proc-macros will be ignored when trying to expand them. /// /// This config takes a map of crate names with the exported proc-macro names to ignore as values. @@ -875,7 +895,7 @@ config_data! { /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field), /// they will end up being interpreted as options to /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments). - runnables_extraTestBinaryArgs: Vec = vec!["--show-output".to_owned()], + runnables_extraTestBinaryArgs: Vec = vec!["--nocapture".to_owned()], /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private /// projects, or "discover" to try to automatically find it if the `rustc-dev` component @@ -1481,6 +1501,13 @@ pub enum FilesWatcher { Server, } +/// Configuration for document symbol search requests. +#[derive(Debug, Clone)] +pub struct DocumentSymbolConfig { + /// Should locals be excluded. + pub search_exclude_locals: bool, +} + #[derive(Debug, Clone)] pub struct NotificationsConfig { pub cargo_toml_not_found: bool, @@ -1878,12 +1905,14 @@ impl Config { AdjustmentHintsDef::Always => ide::AdjustmentHints::Always, AdjustmentHintsDef::Never => match self.inlayHints_reborrowHints_enable() { ReborrowHintsDef::Always | ReborrowHintsDef::Mutable => { - ide::AdjustmentHints::ReborrowOnly + ide::AdjustmentHints::BorrowsOnly } ReborrowHintsDef::Never => ide::AdjustmentHints::Never, }, - AdjustmentHintsDef::Reborrow => ide::AdjustmentHints::ReborrowOnly, + AdjustmentHintsDef::Borrows => ide::AdjustmentHints::BorrowsOnly, }, + adjustment_hints_disable_reborrows: *self + .inlayHints_expressionAdjustmentHints_disableReborrows(), adjustment_hints_mode: match self.inlayHints_expressionAdjustmentHints_mode() { AdjustmentHintsModeDef::Prefix => ide::AdjustmentHintsMode::Prefix, AdjustmentHintsModeDef::Postfix => ide::AdjustmentHintsMode::Postfix, @@ -1915,8 +1944,9 @@ impl Config { fn insert_use_config(&self, source_root: Option) -> InsertUseConfig { InsertUseConfig { granularity: match self.imports_granularity_group(source_root) { - ImportGranularityDef::Preserve => ImportGranularity::Preserve, - ImportGranularityDef::Item => ImportGranularity::Item, + ImportGranularityDef::Item | ImportGranularityDef::Preserve => { + ImportGranularity::Item + } ImportGranularityDef::Crate => ImportGranularity::Crate, ImportGranularityDef::Module => ImportGranularity::Module, ImportGranularityDef::One => ImportGranularity::One, @@ -1948,6 +1978,7 @@ impl Config { pub fn highlighting_config(&self) -> HighlightConfig { HighlightConfig { strings: self.semanticHighlighting_strings_enable().to_owned(), + comments: self.semanticHighlighting_comments_enable().to_owned(), punctuation: self.semanticHighlighting_punctuation_enable().to_owned(), specialize_punctuation: self .semanticHighlighting_punctuation_specialization_enable() @@ -2438,6 +2469,12 @@ impl Config { } } + pub fn document_symbol(&self, source_root: Option) -> DocumentSymbolConfig { + DocumentSymbolConfig { + search_exclude_locals: *self.document_symbol_search_excludeLocals(source_root), + } + } + pub fn workspace_symbol(&self, source_root: Option) -> WorkspaceSymbolConfig { WorkspaceSymbolConfig { search_exclude_imports: *self.workspace_symbol_search_excludeImports(source_root), @@ -2806,7 +2843,8 @@ enum ReborrowHintsDef { #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "snake_case")] enum AdjustmentHintsDef { - Reborrow, + #[serde(alias = "reborrow")] + Borrows, #[serde(with = "true_or_always")] #[serde(untagged)] Always, @@ -3067,7 +3105,7 @@ macro_rules! _config_data { }) => { /// Default config values for this grouping. #[allow(non_snake_case)] - #[derive(Debug, Clone )] + #[derive(Debug, Clone)] struct $name { $($field: $ty,)* } impl_for_config_data!{ @@ -3467,13 +3505,23 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json }, "ImportGranularityDef" => set! { "type": "string", - "enum": ["preserve", "crate", "module", "item", "one"], - "enumDescriptions": [ - "Do not change the granularity of any imports and preserve the original structure written by the developer.", - "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.", - "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.", - "Flatten imports so that each has its own use statement.", - "Merge all imports into a single use statement as long as they have the same visibility and attributes." + "anyOf": [ + { + "enum": ["crate", "module", "item", "one"], + "enumDescriptions": [ + "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.", + "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.", + "Flatten imports so that each has its own use statement.", + "Merge all imports into a single use statement as long as they have the same visibility and attributes." + ], + }, + { + "enum": ["preserve"], + "enumDescriptions": [ + "Deprecated - unless `enforceGranularity` is `true`, the style of the current file is preferred over this setting. Behaves like `item`.", + ], + "deprecated": true, + } ], }, "ImportPrefixDef" => set! { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs index 438a2a0ba1ea1..4bfad98b39976 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics.rs @@ -26,6 +26,17 @@ pub struct DiagnosticsMapConfig { pub(crate) type DiagnosticsGeneration = usize; +#[derive(Debug, Clone, Default)] +pub(crate) struct WorkspaceFlycheckDiagnostic { + pub(crate) per_package: FxHashMap>, PackageFlycheckDiagnostic>, +} + +#[derive(Debug, Clone)] +pub(crate) struct PackageFlycheckDiagnostic { + generation: DiagnosticsGeneration, + per_file: FxHashMap>, +} + #[derive(Debug, Default, Clone)] pub(crate) struct DiagnosticCollection { // FIXME: should be FxHashMap> @@ -33,9 +44,7 @@ pub(crate) struct DiagnosticCollection { FxHashMap)>, pub(crate) native_semantic: FxHashMap)>, - // FIXME: should be Vec - pub(crate) check: - Vec>, FxHashMap>>>, + pub(crate) check: Vec, pub(crate) check_fixes: CheckFixes, changes: FxHashSet, /// Counter for supplying a new generation number for diagnostics. @@ -57,7 +66,7 @@ impl DiagnosticCollection { let Some(check) = self.check.get_mut(flycheck_id) else { return; }; - self.changes.extend(check.drain().flat_map(|(_, v)| v.into_keys())); + self.changes.extend(check.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys())); if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) { fixes.clear(); } @@ -66,7 +75,9 @@ impl DiagnosticCollection { pub(crate) fn clear_check_all(&mut self) { Arc::make_mut(&mut self.check_fixes).clear(); self.changes.extend( - self.check.iter_mut().flat_map(|it| it.drain().flat_map(|(_, v)| v.into_keys())), + self.check + .iter_mut() + .flat_map(|it| it.per_package.drain().flat_map(|(_, v)| v.per_file.into_keys())), ) } @@ -79,14 +90,59 @@ impl DiagnosticCollection { return; }; let package_id = Some(package_id); - if let Some(checks) = check.remove(&package_id) { - self.changes.extend(checks.into_keys()); + if let Some(checks) = check.per_package.remove(&package_id) { + self.changes.extend(checks.per_file.into_keys()); } if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) { fixes.remove(&package_id); } } + pub(crate) fn clear_check_older_than( + &mut self, + flycheck_id: usize, + generation: DiagnosticsGeneration, + ) { + if let Some(flycheck) = self.check.get_mut(flycheck_id) { + let mut packages = vec![]; + self.changes.extend( + flycheck + .per_package + .extract_if(|_, v| v.generation < generation) + .inspect(|(package_id, _)| packages.push(package_id.clone())) + .flat_map(|(_, v)| v.per_file.into_keys()), + ); + if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) { + for package in packages { + fixes.remove(&package); + } + } + } + } + + pub(crate) fn clear_check_older_than_for_package( + &mut self, + flycheck_id: usize, + package_id: Arc, + generation: DiagnosticsGeneration, + ) { + let Some(check) = self.check.get_mut(flycheck_id) else { + return; + }; + let package_id = Some(package_id); + let Some((_, checks)) = check + .per_package + .extract_if(|k, v| *k == package_id && v.generation < generation) + .next() + else { + return; + }; + self.changes.extend(checks.per_file.into_keys()); + if let Some(fixes) = Arc::make_mut(&mut self.check_fixes).get_mut(flycheck_id) { + fixes.remove(&package_id); + } + } + pub(crate) fn clear_native_for(&mut self, file_id: FileId) { self.native_syntax.remove(&file_id); self.native_semantic.remove(&file_id); @@ -96,19 +152,26 @@ impl DiagnosticCollection { pub(crate) fn add_check_diagnostic( &mut self, flycheck_id: usize, + generation: DiagnosticsGeneration, package_id: &Option>, file_id: FileId, diagnostic: lsp_types::Diagnostic, fix: Option>, ) { if self.check.len() <= flycheck_id { - self.check.resize_with(flycheck_id + 1, Default::default); + self.check.resize_with(flycheck_id + 1, WorkspaceFlycheckDiagnostic::default); + } + + let check = &mut self.check[flycheck_id]; + let package = check.per_package.entry(package_id.clone()).or_insert_with(|| { + PackageFlycheckDiagnostic { generation, per_file: FxHashMap::default() } + }); + // Getting message from old generation. Might happen in restarting checks. + if package.generation > generation { + return; } - let diagnostics = self.check[flycheck_id] - .entry(package_id.clone()) - .or_default() - .entry(file_id) - .or_default(); + package.generation = generation; + let diagnostics = package.per_file.entry(file_id).or_default(); for existing_diagnostic in diagnostics.iter() { if are_diagnostics_equal(existing_diagnostic, &diagnostic) { return; @@ -177,8 +240,8 @@ impl DiagnosticCollection { let check = self .check .iter() - .flat_map(|it| it.values()) - .filter_map(move |it| it.get(&file_id)) + .flat_map(|it| it.per_package.values()) + .filter_map(move |it| it.per_file.get(&file_id)) .flatten(); native_syntax.chain(native_semantic).chain(check) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs index 24c433610f1a3..4ec0c075dd5be 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs @@ -67,7 +67,7 @@ impl DiscoverCommand { cmd.args(args); Ok(DiscoverHandle { - _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone())?, + _handle: CommandHandle::spawn(cmd, DiscoverProjectParser, self.sender.clone(), None)?, span: info_span!("discover_command").entered(), }) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs index e4e0bcdc1cd08..b545106fe1cfb 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs @@ -1,7 +1,12 @@ //! Flycheck provides the functionality needed to run `cargo check` to provide //! LSP diagnostics based on the output of the command. -use std::{fmt, io, process::Command, time::Duration}; +use std::{ + fmt, io, + process::Command, + sync::atomic::{AtomicUsize, Ordering}, + time::Duration, +}; use cargo_metadata::PackageId; use crossbeam_channel::{Receiver, Sender, select_biased, unbounded}; @@ -18,7 +23,10 @@ pub(crate) use cargo_metadata::diagnostic::{ use toolchain::Tool; use triomphe::Arc; -use crate::command::{CargoParser, CommandHandle}; +use crate::{ + command::{CargoParser, CommandHandle}, + diagnostics::DiagnosticsGeneration, +}; #[derive(Clone, Debug, Default, PartialEq, Eq)] pub(crate) enum InvocationStrategy { @@ -96,11 +104,11 @@ pub(crate) enum FlycheckConfig { } impl FlycheckConfig { - pub(crate) fn invocation_strategy_once(&self) -> bool { + pub(crate) fn invocation_strategy(&self) -> InvocationStrategy { match self { - FlycheckConfig::CargoCommand { .. } => false, + FlycheckConfig::CargoCommand { .. } => InvocationStrategy::PerWorkspace, FlycheckConfig::CustomCommand { invocation_strategy, .. } => { - *invocation_strategy == InvocationStrategy::Once + invocation_strategy.clone() } } } @@ -138,36 +146,64 @@ pub(crate) struct FlycheckHandle { sender: Sender, _thread: stdx::thread::JoinHandle, id: usize, + generation: AtomicUsize, } impl FlycheckHandle { pub(crate) fn spawn( id: usize, + generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, sysroot_root: Option, workspace_root: AbsPathBuf, manifest_path: Option, ) -> FlycheckHandle { - let actor = - FlycheckActor::new(id, sender, config, sysroot_root, workspace_root, manifest_path); + let actor = FlycheckActor::new( + id, + generation, + sender, + config, + sysroot_root, + workspace_root, + manifest_path, + ); let (sender, receiver) = unbounded::(); let thread = stdx::thread::Builder::new(stdx::thread::ThreadIntent::Worker, format!("Flycheck{id}")) .spawn(move || actor.run(receiver)) .expect("failed to spawn thread"); - FlycheckHandle { id, sender, _thread: thread } + FlycheckHandle { id, generation: generation.into(), sender, _thread: thread } } /// Schedule a re-start of the cargo check worker to do a workspace wide check. pub(crate) fn restart_workspace(&self, saved_file: Option) { - self.sender.send(StateChange::Restart { package: None, saved_file, target: None }).unwrap(); + let generation = self.generation.fetch_add(1, Ordering::Relaxed) + 1; + self.sender + .send(StateChange::Restart { + generation, + scope: FlycheckScope::Workspace, + saved_file, + target: None, + }) + .unwrap(); } /// Schedule a re-start of the cargo check worker to do a package wide check. - pub(crate) fn restart_for_package(&self, package: String, target: Option) { + pub(crate) fn restart_for_package( + &self, + package: Arc, + target: Option, + workspace_deps: Option>>, + ) { + let generation = self.generation.fetch_add(1, Ordering::Relaxed) + 1; self.sender - .send(StateChange::Restart { package: Some(package), saved_file: None, target }) + .send(StateChange::Restart { + generation, + scope: FlycheckScope::Package { package, workspace_deps }, + saved_file: None, + target, + }) .unwrap(); } @@ -179,23 +215,36 @@ impl FlycheckHandle { pub(crate) fn id(&self) -> usize { self.id } + + pub(crate) fn generation(&self) -> DiagnosticsGeneration { + self.generation.load(Ordering::Relaxed) + } +} + +#[derive(Debug)] +pub(crate) enum ClearDiagnosticsKind { + All(ClearScope), + OlderThan(DiagnosticsGeneration, ClearScope), +} + +#[derive(Debug)] +pub(crate) enum ClearScope { + Workspace, + Package(Arc), } pub(crate) enum FlycheckMessage { /// Request adding a diagnostic with fixes included to a file AddDiagnostic { id: usize, + generation: DiagnosticsGeneration, workspace_root: Arc, diagnostic: Diagnostic, package_id: Option>, }, /// Request clearing all outdated diagnostics. - ClearDiagnostics { - id: usize, - /// The package whose diagnostics to clear, or if unspecified, all diagnostics. - package_id: Option>, - }, + ClearDiagnostics { id: usize, kind: ClearDiagnosticsKind }, /// Request check progress notification to client Progress { @@ -208,18 +257,23 @@ pub(crate) enum FlycheckMessage { impl fmt::Debug for FlycheckMessage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => f + FlycheckMessage::AddDiagnostic { + id, + generation, + workspace_root, + diagnostic, + package_id, + } => f .debug_struct("AddDiagnostic") .field("id", id) + .field("generation", generation) .field("workspace_root", workspace_root) .field("package_id", package_id) .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code)) .finish(), - FlycheckMessage::ClearDiagnostics { id, package_id } => f - .debug_struct("ClearDiagnostics") - .field("id", id) - .field("package_id", package_id) - .finish(), + FlycheckMessage::ClearDiagnostics { id, kind } => { + f.debug_struct("ClearDiagnostics").field("id", id).field("kind", kind).finish() + } FlycheckMessage::Progress { id, progress } => { f.debug_struct("Progress").field("id", id).field("progress", progress).finish() } @@ -236,8 +290,18 @@ pub(crate) enum Progress { DidFailToRestart(String), } +enum FlycheckScope { + Workspace, + Package { package: Arc, workspace_deps: Option>> }, +} + enum StateChange { - Restart { package: Option, saved_file: Option, target: Option }, + Restart { + generation: DiagnosticsGeneration, + scope: FlycheckScope, + saved_file: Option, + target: Option, + }, Cancel, } @@ -246,6 +310,7 @@ struct FlycheckActor { /// The workspace id of this flycheck instance. id: usize, + generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, manifest_path: Option, @@ -253,6 +318,7 @@ struct FlycheckActor { /// or the project root of the project. root: Arc, sysroot_root: Option, + scope: FlycheckScope, /// CargoHandle exists to wrap around the communication needed to be able to /// run `cargo check` without blocking. Currently the Rust standard library /// doesn't provide a way to read sub-process output without blocking, so we @@ -283,6 +349,7 @@ pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file"; impl FlycheckActor { fn new( id: usize, + generation: DiagnosticsGeneration, sender: Sender, config: FlycheckConfig, sysroot_root: Option, @@ -292,10 +359,12 @@ impl FlycheckActor { tracing::info!(%id, ?workspace_root, "Spawning flycheck"); FlycheckActor { id, + generation, sender, config, sysroot_root, root: Arc::new(workspace_root), + scope: FlycheckScope::Workspace, manifest_path, command_handle: None, command_receiver: None, @@ -327,7 +396,12 @@ impl FlycheckActor { tracing::debug!(flycheck_id = self.id, "flycheck cancelled"); self.cancel_check_process(); } - Event::RequestStateChange(StateChange::Restart { package, saved_file, target }) => { + Event::RequestStateChange(StateChange::Restart { + generation, + scope, + saved_file, + target, + }) => { // Cancel the previously spawned process self.cancel_check_process(); while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) { @@ -337,9 +411,11 @@ impl FlycheckActor { } } - let Some(command) = - self.check_command(package.as_deref(), saved_file.as_deref(), target) - else { + let command = self.check_command(&scope, saved_file.as_deref(), target); + self.scope = scope; + self.generation = generation; + + let Some(command) = command else { continue; }; @@ -347,7 +423,21 @@ impl FlycheckActor { tracing::debug!(?command, "will restart flycheck"); let (sender, receiver) = unbounded(); - match CommandHandle::spawn(command, CargoCheckParser, sender) { + match CommandHandle::spawn( + command, + CargoCheckParser, + sender, + match &self.config { + FlycheckConfig::CargoCommand { options, .. } => Some( + options + .target_dir + .as_deref() + .unwrap_or("target".as_ref()) + .join(format!("rust-analyzer/flycheck{}", self.id)), + ), + _ => None, + }, + ) { Ok(command_handle) => { tracing::debug!(command = formatted_command, "did restart flycheck"); self.command_handle = Some(command_handle); @@ -381,10 +471,55 @@ impl FlycheckActor { tracing::trace!(flycheck_id = self.id, "clearing diagnostics"); // We finished without receiving any diagnostics. // Clear everything for good measure - self.send(FlycheckMessage::ClearDiagnostics { - id: self.id, - package_id: None, - }); + match &self.scope { + FlycheckScope::Workspace => { + self.send(FlycheckMessage::ClearDiagnostics { + id: self.id, + kind: ClearDiagnosticsKind::All(ClearScope::Workspace), + }); + } + FlycheckScope::Package { package, workspace_deps } => { + for pkg in + std::iter::once(package).chain(workspace_deps.iter().flatten()) + { + self.send(FlycheckMessage::ClearDiagnostics { + id: self.id, + kind: ClearDiagnosticsKind::All(ClearScope::Package( + pkg.clone(), + )), + }); + } + } + } + } else if res.is_ok() { + // We clear diagnostics for packages on + // `[CargoCheckMessage::CompilerArtifact]` but there seem to be setups where + // cargo may not report an artifact to our runner at all. To handle such + // cases, clear stale diagnostics when flycheck completes successfully. + match &self.scope { + FlycheckScope::Workspace => { + self.send(FlycheckMessage::ClearDiagnostics { + id: self.id, + kind: ClearDiagnosticsKind::OlderThan( + self.generation, + ClearScope::Workspace, + ), + }); + } + FlycheckScope::Package { package, workspace_deps } => { + for pkg in + std::iter::once(package).chain(workspace_deps.iter().flatten()) + { + self.send(FlycheckMessage::ClearDiagnostics { + id: self.id, + kind: ClearDiagnosticsKind::OlderThan( + self.generation, + ClearScope::Package(pkg.clone()), + ), + }); + } + } + } } self.clear_diagnostics_state(); @@ -412,7 +547,7 @@ impl FlycheckActor { ); self.send(FlycheckMessage::ClearDiagnostics { id: self.id, - package_id: Some(package_id), + kind: ClearDiagnosticsKind::All(ClearScope::Package(package_id)), }); } } @@ -435,7 +570,9 @@ impl FlycheckActor { ); self.send(FlycheckMessage::ClearDiagnostics { id: self.id, - package_id: Some(package_id.clone()), + kind: ClearDiagnosticsKind::All(ClearScope::Package( + package_id.clone(), + )), }); } } else if self.diagnostics_received @@ -444,11 +581,12 @@ impl FlycheckActor { self.diagnostics_received = DiagnosticsReceived::YesAndClearedForAll; self.send(FlycheckMessage::ClearDiagnostics { id: self.id, - package_id: None, + kind: ClearDiagnosticsKind::All(ClearScope::Workspace), }); } self.send(FlycheckMessage::AddDiagnostic { id: self.id, + generation: self.generation, package_id, workspace_root: self.root.clone(), diagnostic, @@ -465,7 +603,7 @@ impl FlycheckActor { if let Some(command_handle) = self.command_handle.take() { tracing::debug!( command = ?command_handle, - "did cancel flycheck" + "did cancel flycheck" ); command_handle.cancel(); self.command_receiver.take(); @@ -484,7 +622,7 @@ impl FlycheckActor { /// return None. fn check_command( &self, - package: Option<&str>, + scope: &FlycheckScope, saved_file: Option<&AbsPath>, target: Option, ) -> Option { @@ -498,11 +636,12 @@ impl FlycheckActor { { cmd.env("RUSTUP_TOOLCHAIN", AsRef::::as_ref(sysroot_root)); } + cmd.env("CARGO_LOG", "cargo::core::compiler::fingerprint=info"); cmd.arg(command); - match package { - Some(pkg) => cmd.arg("-p").arg(pkg), - None => cmd.arg("--workspace"), + match scope { + FlycheckScope::Workspace => cmd.arg("--workspace"), + FlycheckScope::Package { package, .. } => cmd.arg("-p").arg(&package.repr), }; if let Some(tgt) = target { @@ -524,6 +663,7 @@ impl FlycheckActor { cmd.arg("--manifest-path"); cmd.arg(manifest_path); if manifest_path.extension() == Some("rs") { + cmd.env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly"); cmd.arg("-Zscript"); } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs index 2f1afba3634ef..ce6644f725ca6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs @@ -9,6 +9,7 @@ use std::{ time::{Duration, Instant}, }; +use cargo_metadata::PackageId; use crossbeam_channel::{Receiver, Sender, unbounded}; use hir::ChangeWithProcMacros; use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId}; @@ -183,6 +184,10 @@ pub(crate) struct GlobalState { /// this queue should run only *after* [`GlobalState::process_changes`] has /// been called. pub(crate) deferred_task_queue: TaskQueue, + /// HACK: Workaround for https://github.com/rust-lang/rust-analyzer/issues/19709 + /// This is marked true if we failed to load a crate root file at crate graph creation, + /// which will usually end up causing a bunch of incorrect diagnostics on startup. + pub(crate) incomplete_crate_graph: bool, } /// An immutable snapshot of the world's state at a point in time. @@ -298,6 +303,7 @@ impl GlobalState { discover_workspace_queue: OpQueue::default(), deferred_task_queue: task_queue, + incomplete_crate_graph: false, }; // Apply any required database inputs from the config. this.update_configuration(config); @@ -779,6 +785,7 @@ impl GlobalStateSnapshot { cargo_toml: package_data.manifest.clone(), crate_id, package: cargo.package_flag(package_data), + package_id: package_data.id.clone(), target: target_data.name.clone(), target_kind: target_data.kind, required_features: target_data.required_features.clone(), @@ -807,6 +814,27 @@ impl GlobalStateSnapshot { None } + pub(crate) fn all_workspace_dependencies_for_package( + &self, + package: &Arc, + ) -> Option>> { + for workspace in self.workspaces.iter() { + match &workspace.kind { + ProjectWorkspaceKind::Cargo { cargo, .. } + | ProjectWorkspaceKind::DetachedFile { cargo: Some((cargo, _, _)), .. } => { + let package = cargo.packages().find(|p| cargo[*p].id == *package)?; + + return cargo[package] + .all_member_deps + .as_ref() + .map(|deps| deps.iter().map(|dep| cargo[*dep].id.clone()).collect()); + } + _ => {} + } + } + None + } + pub(crate) fn file_exists(&self, file_id: FileId) -> bool { self.vfs.read().0.exists(file_id) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs index b25245dd884a4..10bbb0bb31d99 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/dispatch.rs @@ -141,7 +141,7 @@ impl RequestDispatcher<'_> { Result: Serialize, > + 'static, { - if !self.global_state.vfs_done { + if !self.global_state.vfs_done || self.global_state.incomplete_crate_graph { if let Some(lsp_server::Request { id, .. }) = self.req.take_if(|it| it.method == R::METHOD) { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs index e193ff77743d1..87be09dcbd275 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs @@ -1,9 +1,11 @@ //! This module is responsible for implementing handlers for Language Server //! Protocol. This module specifically handles notifications. -use std::ops::{Deref, Not as _}; +use std::{ + ops::{Deref, Not as _}, + panic::UnwindSafe, +}; -use ide_db::base_db::salsa::Cancelled; use itertools::Itertools; use lsp_types::{ CancelParams, DidChangeConfigurationParams, DidChangeTextDocumentParams, @@ -16,7 +18,7 @@ use vfs::{AbsPathBuf, ChangeKind, VfsPath}; use crate::{ config::{Config, ConfigChange}, - flycheck::Target, + flycheck::{InvocationStrategy, Target}, global_state::{FetchWorkspaceRequest, GlobalState}, lsp::{from_proto, utils::apply_document_changes}, lsp_ext::{self, RunFlycheckParams}, @@ -301,124 +303,171 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool { let file_id = state.vfs.read().0.file_id(&vfs_path); if let Some((file_id, vfs::FileExcluded::No)) = file_id { let world = state.snapshot(); - let invocation_strategy_once = state.config.flycheck(None).invocation_strategy_once(); + let invocation_strategy = state.config.flycheck(None).invocation_strategy(); let may_flycheck_workspace = state.config.flycheck_workspace(None); - let mut updated = false; - let task = move || -> std::result::Result<(), Cancelled> { - if invocation_strategy_once { - let saved_file = vfs_path.as_path().map(|p| p.to_owned()); - world.flycheck[0].restart_workspace(saved_file); - } - let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| { - let tgt_kind = it.target_kind(); - let (tgt_name, root, package) = match it { - TargetSpec::Cargo(c) => (c.target, c.workspace_root, c.package), - _ => return None, - }; - - let tgt = match tgt_kind { - project_model::TargetKind::Bin => Target::Bin(tgt_name), - project_model::TargetKind::Example => Target::Example(tgt_name), - project_model::TargetKind::Test => Target::Test(tgt_name), - project_model::TargetKind::Bench => Target::Benchmark(tgt_name), - _ => return Some((None, root, package)), - }; - - Some((Some(tgt), root, package)) - }); - tracing::debug!(?target, "flycheck target"); - // we have a specific non-library target, attempt to only check that target, nothing - // else will be affected - if let Some((target, root, package)) = target { - // trigger a package check if we have a non-library target as that can't affect - // anything else in the workspace OR if we're not allowed to check the workspace as - // the user opted into package checks then - let package_check_allowed = target.is_some() || !may_flycheck_workspace; - if package_check_allowed { - let workspace = world.workspaces.iter().position(|ws| match &ws.kind { - project_model::ProjectWorkspaceKind::Cargo { cargo, .. } - | project_model::ProjectWorkspaceKind::DetachedFile { - cargo: Some((cargo, _, _)), - .. - } => *cargo.workspace_root() == root, - _ => false, - }); - if let Some(idx) = workspace { - world.flycheck[idx].restart_for_package(package, target); - } + let task: Box ide::Cancellable<()> + Send + UnwindSafe> = + match invocation_strategy { + InvocationStrategy::Once => { + Box::new(move || { + // FIXME: Because triomphe::Arc's auto UnwindSafe impl requires that the inner type + // be UnwindSafe, and FlycheckHandle is not UnwindSafe, `word.flycheck` cannot + // be captured directly. std::sync::Arc has an UnwindSafe impl that only requires + // that the inner type be RefUnwindSafe, so if we were using that one we wouldn't + // have this problem. Remove the line below when triomphe::Arc has an UnwindSafe impl + // like std::sync::Arc's. + let world = world; + stdx::always!( + world.flycheck.len() == 1, + "should have exactly one flycheck handle when invocation strategy is once" + ); + let saved_file = vfs_path.as_path().map(ToOwned::to_owned); + world.flycheck[0].restart_workspace(saved_file); + Ok(()) + }) } - } - - if !may_flycheck_workspace { - return Ok(()); - } - - // Trigger flychecks for all workspaces that depend on the saved file - // Crates containing or depending on the saved file - let crate_ids = world - .analysis - .crates_for(file_id)? - .into_iter() - .flat_map(|id| world.analysis.transitive_rev_deps(id)) - .flatten() - .unique() - .collect::>(); - tracing::debug!(?crate_ids, "flycheck crate ids"); - let crate_root_paths: Vec<_> = crate_ids - .iter() - .filter_map(|&crate_id| { - world - .analysis - .crate_root(crate_id) - .map(|file_id| { - world.file_id_to_file_path(file_id).as_path().map(ToOwned::to_owned) - }) - .transpose() - }) - .collect::>()?; - let crate_root_paths: Vec<_> = crate_root_paths.iter().map(Deref::deref).collect(); - tracing::debug!(?crate_root_paths, "flycheck crate roots"); - - // Find all workspaces that have at least one target containing the saved file - let workspace_ids = - world.workspaces.iter().enumerate().filter(|(_, ws)| match &ws.kind { - project_model::ProjectWorkspaceKind::Cargo { cargo, .. } - | project_model::ProjectWorkspaceKind::DetachedFile { - cargo: Some((cargo, _, _)), - .. - } => cargo.packages().any(|pkg| { - cargo[pkg] - .targets + InvocationStrategy::PerWorkspace => { + Box::new(move || { + let target = TargetSpec::for_file(&world, file_id)?.and_then(|it| { + let tgt_kind = it.target_kind(); + let (tgt_name, root, package) = match it { + TargetSpec::Cargo(c) => (c.target, c.workspace_root, c.package_id), + _ => return None, + }; + + let tgt = match tgt_kind { + project_model::TargetKind::Bin => Target::Bin(tgt_name), + project_model::TargetKind::Example => Target::Example(tgt_name), + project_model::TargetKind::Test => Target::Test(tgt_name), + project_model::TargetKind::Bench => Target::Benchmark(tgt_name), + _ => return Some((None, root, package)), + }; + + Some((Some(tgt), root, package)) + }); + tracing::debug!(?target, "flycheck target"); + // we have a specific non-library target, attempt to only check that target, nothing + // else will be affected + let mut package_workspace_idx = None; + if let Some((target, root, package)) = target { + // trigger a package check if we have a non-library target as that can't affect + // anything else in the workspace OR if we're not allowed to check the workspace as + // the user opted into package checks then + let package_check_allowed = target.is_some() || !may_flycheck_workspace; + if package_check_allowed { + package_workspace_idx = + world.workspaces.iter().position(|ws| match &ws.kind { + project_model::ProjectWorkspaceKind::Cargo { + cargo, + .. + } + | project_model::ProjectWorkspaceKind::DetachedFile { + cargo: Some((cargo, _, _)), + .. + } => *cargo.workspace_root() == root, + _ => false, + }); + if let Some(idx) = package_workspace_idx { + let workspace_deps = + world.all_workspace_dependencies_for_package(&package); + world.flycheck[idx].restart_for_package( + package, + target, + workspace_deps, + ); + } + } + } + + if !may_flycheck_workspace { + return Ok(()); + } + + // Trigger flychecks for all workspaces that depend on the saved file + // Crates containing or depending on the saved file + let crate_ids: Vec<_> = world + .analysis + .crates_for(file_id)? + .into_iter() + .flat_map(|id| world.analysis.transitive_rev_deps(id)) + .flatten() + .unique() + .collect(); + tracing::debug!(?crate_ids, "flycheck crate ids"); + let crate_root_paths: Vec<_> = crate_ids .iter() - .any(|&it| crate_root_paths.contains(&cargo[it].root.as_path())) - }), - project_model::ProjectWorkspaceKind::Json(project) => project - .crates() - .any(|(_, krate)| crate_root_paths.contains(&krate.root_module.as_path())), - project_model::ProjectWorkspaceKind::DetachedFile { .. } => false, - }); - - let saved_file = vfs_path.as_path().map(|p| p.to_owned()); - - // Find and trigger corresponding flychecks - 'flychecks: for flycheck in world.flycheck.iter() { - for (id, _) in workspace_ids.clone() { - if id == flycheck.id() { - updated = true; - flycheck.restart_workspace(saved_file.clone()); - continue 'flychecks; - } - } - } - // No specific flycheck was triggered, so let's trigger all of them. - if !updated { - for flycheck in world.flycheck.iter() { - flycheck.restart_workspace(saved_file.clone()); + .filter_map(|&crate_id| { + world + .analysis + .crate_root(crate_id) + .map(|file_id| { + world + .file_id_to_file_path(file_id) + .as_path() + .map(ToOwned::to_owned) + }) + .transpose() + }) + .collect::>()?; + let crate_root_paths: Vec<_> = + crate_root_paths.iter().map(Deref::deref).collect(); + tracing::debug!(?crate_root_paths, "flycheck crate roots"); + + // Find all workspaces that have at least one target containing the saved file + let workspace_ids = + world.workspaces.iter().enumerate().filter(|&(idx, ws)| { + let ws_contains_file = match &ws.kind { + project_model::ProjectWorkspaceKind::Cargo { + cargo, .. + } + | project_model::ProjectWorkspaceKind::DetachedFile { + cargo: Some((cargo, _, _)), + .. + } => cargo.packages().any(|pkg| { + cargo[pkg].targets.iter().any(|&it| { + crate_root_paths.contains(&cargo[it].root.as_path()) + }) + }), + project_model::ProjectWorkspaceKind::Json(project) => { + project.crates().any(|(_, krate)| { + crate_root_paths.contains(&krate.root_module.as_path()) + }) + } + project_model::ProjectWorkspaceKind::DetachedFile { + .. + } => false, + }; + let is_pkg_ws = match package_workspace_idx { + Some(pkg_idx) => pkg_idx == idx, + None => false, + }; + ws_contains_file && !is_pkg_ws + }); + + let saved_file = vfs_path.as_path().map(ToOwned::to_owned); + let mut workspace_check_triggered = false; + // Find and trigger corresponding flychecks + 'flychecks: for flycheck in world.flycheck.iter() { + for (id, _) in workspace_ids.clone() { + if id == flycheck.id() { + workspace_check_triggered = true; + flycheck.restart_workspace(saved_file.clone()); + continue 'flychecks; + } + } + } + + // No specific flycheck was triggered, so let's trigger all of them. + if !workspace_check_triggered && package_workspace_idx.is_none() { + for flycheck in world.flycheck.iter() { + flycheck.restart_workspace(saved_file.clone()); + } + } + Ok(()) + }) } - } - Ok(()) - }; + }; + state.task_pool.handle.spawn_with_sender(stdx::thread::ThreadIntent::Worker, move |_| { if let Err(e) = std::panic::catch_unwind(task) { tracing::error!("flycheck task panicked: {e:?}") diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs index 25c0aac405e79..6cb28aecf748f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs @@ -8,8 +8,9 @@ use anyhow::Context; use base64::{Engine, prelude::BASE64_STANDARD}; use ide::{ AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve, - FilePosition, FileRange, HoverAction, HoverGotoTypeData, InlayFieldsToResolve, Query, - RangeInfo, ReferenceCategory, Runnable, RunnableKind, SingleResolve, SourceChange, TextEdit, + FilePosition, FileRange, FileStructureConfig, HoverAction, HoverGotoTypeData, + InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind, + SingleResolve, SourceChange, TextEdit, }; use ide_db::{FxHashMap, SymbolKind}; use itertools::Itertools; @@ -566,41 +567,47 @@ pub(crate) fn handle_document_symbol( let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); let line_index = snap.file_line_index(file_id)?; - let mut parents: Vec<(lsp_types::DocumentSymbol, Option)> = Vec::new(); + let mut symbols: Vec<(lsp_types::DocumentSymbol, Option)> = Vec::new(); - for symbol in snap.analysis.file_structure(file_id)? { + let config = snap.config.document_symbol(None); + + let structure_nodes = snap.analysis.file_structure( + &FileStructureConfig { exclude_locals: config.search_exclude_locals }, + file_id, + )?; + + for node in structure_nodes { let mut tags = Vec::new(); - if symbol.deprecated { + if node.deprecated { tags.push(SymbolTag::DEPRECATED) }; #[allow(deprecated)] - let doc_symbol = lsp_types::DocumentSymbol { - name: symbol.label, - detail: symbol.detail, - kind: to_proto::structure_node_kind(symbol.kind), + let symbol = lsp_types::DocumentSymbol { + name: node.label, + detail: node.detail, + kind: to_proto::structure_node_kind(node.kind), tags: Some(tags), - deprecated: Some(symbol.deprecated), - range: to_proto::range(&line_index, symbol.node_range), - selection_range: to_proto::range(&line_index, symbol.navigation_range), + deprecated: Some(node.deprecated), + range: to_proto::range(&line_index, node.node_range), + selection_range: to_proto::range(&line_index, node.navigation_range), children: None, }; - parents.push((doc_symbol, symbol.parent)); + symbols.push((symbol, node.parent)); } - // Builds hierarchy from a flat list, in reverse order (so that indices - // makes sense) + // Builds hierarchy from a flat list, in reverse order (so that the indices make sense) let document_symbols = { let mut acc = Vec::new(); - while let Some((mut node, parent_idx)) = parents.pop() { - if let Some(children) = &mut node.children { + while let Some((mut symbol, parent_idx)) = symbols.pop() { + if let Some(children) = &mut symbol.children { children.reverse(); } let parent = match parent_idx { None => &mut acc, - Some(i) => parents[i].0.children.get_or_insert_with(Vec::new), + Some(i) => symbols[i].0.children.get_or_insert_with(Vec::new), }; - parent.push(node); + parent.push(symbol); } acc.reverse(); acc @@ -610,7 +617,7 @@ pub(crate) fn handle_document_symbol( document_symbols.into() } else { let url = to_proto::url(https://github.com/&snap,%20file_id); - let mut symbol_information = Vec::::new(); + let mut symbol_information = Vec::new(); for symbol in document_symbols { flatten_document_symbol(&symbol, None, &url, &mut symbol_information); } @@ -647,7 +654,7 @@ pub(crate) fn handle_workspace_symbol( let _p = tracing::info_span!("handle_workspace_symbol").entered(); let config = snap.config.workspace_symbol(None); - let (all_symbols, libs) = decide_search_scope_and_kind(¶ms, &config); + let (all_symbols, libs) = decide_search_kind_and_scope(¶ms, &config); let query = { let query: String = params.query.chars().filter(|&c| c != '#' && c != '*').collect(); @@ -670,7 +677,7 @@ pub(crate) fn handle_workspace_symbol( return Ok(Some(lsp_types::WorkspaceSymbolResponse::Nested(res))); - fn decide_search_scope_and_kind( + fn decide_search_kind_and_scope( params: &WorkspaceSymbolParams, config: &WorkspaceSymbolConfig, ) -> (bool, bool) { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs index 0dea285e97bd4..44af8fbddf300 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs @@ -9,6 +9,8 @@ //! The `cli` submodule implements some batch-processing analysis, primarily as //! a debugging aid. +extern crate ra_ap_rustc_type_ir as rustc_type_ir; + /// Any toolchain less than this version will likely not work with rust-analyzer built from this revision. pub const MINIMUM_SUPPORTED_TOOLCHAIN_VERSION: semver::Version = semver::Version { major: 1, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs index 02757616d4ffd..333826a1790e4 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/from_proto.rs @@ -40,12 +40,13 @@ pub(crate) fn offset( })?; let col = TextSize::from(line_col.col); let clamped_len = col.min(line_range.len()); - if clamped_len < col { - tracing::error!( - "Position {line_col:?} column exceeds line length {}, clamping it", - u32::from(line_range.len()), - ); - } + // FIXME: The cause for this is likely our request retrying. Commented out as this log is just too chatty and very easy to trigger. + // if clamped_len < col { + // tracing::error!( + // "Position {line_col:?} column exceeds line length {}, clamping it", + // u32::from(line_range.len()), + // ); + // } Ok(line_range.start() + clamped_len) } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs index 292be1d5315de..d51ddb86d197f 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs @@ -61,7 +61,7 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { SymbolKind::Struct => lsp_types::SymbolKind::STRUCT, SymbolKind::Enum => lsp_types::SymbolKind::ENUM, SymbolKind::Variant => lsp_types::SymbolKind::ENUM_MEMBER, - SymbolKind::Trait | SymbolKind::TraitAlias => lsp_types::SymbolKind::INTERFACE, + SymbolKind::Trait => lsp_types::SymbolKind::INTERFACE, SymbolKind::Macro | SymbolKind::ProcMacro | SymbolKind::BuiltinAttr @@ -156,7 +156,6 @@ pub(crate) fn completion_item_kind( SymbolKind::Static => lsp_types::CompletionItemKind::VALUE, SymbolKind::Struct => lsp_types::CompletionItemKind::STRUCT, SymbolKind::Trait => lsp_types::CompletionItemKind::INTERFACE, - SymbolKind::TraitAlias => lsp_types::CompletionItemKind::INTERFACE, SymbolKind::TypeAlias => lsp_types::CompletionItemKind::STRUCT, SymbolKind::TypeParam => lsp_types::CompletionItemKind::TYPE_PARAMETER, SymbolKind::Union => lsp_types::CompletionItemKind::STRUCT, @@ -817,7 +816,6 @@ fn semantic_token_type_and_modifiers( SymbolKind::Union => types::UNION, SymbolKind::TypeAlias => types::TYPE_ALIAS, SymbolKind::Trait => types::INTERFACE, - SymbolKind::TraitAlias => types::INTERFACE, SymbolKind::Macro => types::MACRO, SymbolKind::ProcMacro => types::PROC_MACRO, SymbolKind::BuiltinAttr => types::BUILTIN_ATTRIBUTE, @@ -909,7 +907,6 @@ pub(crate) fn folding_range( | FoldKind::WhereClause | FoldKind::ReturnType | FoldKind::Array - | FoldKind::TraitAliases | FoldKind::ExternCrates | FoldKind::MatchArm | FoldKind::Function => None, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index 61c758d5e86e1..3e80e8b7bdfb5 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -20,7 +20,7 @@ use crate::{ config::Config, diagnostics::{DiagnosticsGeneration, NativeDiagnosticsFetchKind, fetch_native_diagnostics}, discover::{DiscoverArgument, DiscoverCommand, DiscoverProjectMessage}, - flycheck::{self, FlycheckMessage}, + flycheck::{self, ClearDiagnosticsKind, ClearScope, FlycheckMessage}, global_state::{ FetchBuildDataResponse, FetchWorkspaceRequest, FetchWorkspaceResponse, GlobalState, file_id_to_url, url_to_file_id, @@ -812,7 +812,7 @@ impl GlobalState { }; if let Some(state) = state { - self.report_progress("Building build-artifacts", state, msg, None, None); + self.report_progress("Building compile-time-deps", state, msg, None, None); } } Task::LoadProcMacros(progress) => { @@ -1008,7 +1008,13 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: FlycheckMessage) { match message { - FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic, package_id } => { + FlycheckMessage::AddDiagnostic { + id, + generation, + workspace_root, + diagnostic, + package_id, + } => { let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(None), @@ -1020,6 +1026,7 @@ impl GlobalState { match url_to_file_id(&self.vfs.read().0, &diag.url) { Ok(Some(file_id)) => self.diagnostics.add_check_diagnostic( id, + generation, &package_id, file_id, diag.diagnostic, @@ -1035,12 +1042,22 @@ impl GlobalState { }; } } - FlycheckMessage::ClearDiagnostics { id, package_id: None } => { - self.diagnostics.clear_check(id) - } - FlycheckMessage::ClearDiagnostics { id, package_id: Some(package_id) } => { - self.diagnostics.clear_check_for_package(id, package_id) - } + FlycheckMessage::ClearDiagnostics { + id, + kind: ClearDiagnosticsKind::All(ClearScope::Workspace), + } => self.diagnostics.clear_check(id), + FlycheckMessage::ClearDiagnostics { + id, + kind: ClearDiagnosticsKind::All(ClearScope::Package(package_id)), + } => self.diagnostics.clear_check_for_package(id, package_id), + FlycheckMessage::ClearDiagnostics { + id, + kind: ClearDiagnosticsKind::OlderThan(generation, ClearScope::Workspace), + } => self.diagnostics.clear_check_older_than(id, generation), + FlycheckMessage::ClearDiagnostics { + id, + kind: ClearDiagnosticsKind::OlderThan(generation, ClearScope::Package(package_id)), + } => self.diagnostics.clear_check_older_than_for_package(id, package_id, generation), FlycheckMessage::Progress { id, progress } => { let (state, message) = match progress { flycheck::Progress::DidStart => (Progress::Begin, None), diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs index aa38aa72d44eb..ca15e6a98e035 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs @@ -152,7 +152,9 @@ impl GlobalState { if self.fetch_build_data_error().is_err() { status.health |= lsp_ext::Health::Warning; message.push_str("Failed to run build scripts of some packages.\n\n"); - message.push_str("Please refer to the logs for more details on the errors."); + message.push_str( + "Please refer to the language server logs for more details on the errors.", + ); } if let Some(err) = &self.config_errors { status.health |= lsp_ext::Health::Warning; @@ -316,7 +318,7 @@ impl GlobalState { } } - let mut workspaces = linked_projects + let mut workspaces: Vec<_> = linked_projects .iter() .map(|project| match project { LinkedProject::ProjectManifest(manifest) => { @@ -337,7 +339,7 @@ impl GlobalState { Ok(workspace) } }) - .collect::>(); + .collect(); let mut i = 0; while i < workspaces.len() { @@ -739,13 +741,16 @@ impl GlobalState { }) .collect(); + self.incomplete_crate_graph = false; let (crate_graph, proc_macro_paths) = { // Create crate graph from all the workspaces let vfs = &self.vfs.read().0; let load = |path: &AbsPath| { let vfs_path = vfs::VfsPath::from(path.to_path_buf()); self.crate_graph_file_dependencies.insert(vfs_path.clone()); - vfs.file_id(&vfs_path).and_then(|(file_id, excluded)| { + let file_id = vfs.file_id(&vfs_path); + self.incomplete_crate_graph |= file_id.is_none(); + file_id.and_then(|(file_id, excluded)| { (excluded == vfs::FileExcluded::No).then_some(file_id) }) }; @@ -846,21 +851,17 @@ impl GlobalState { fn reload_flycheck(&mut self) { let _p = tracing::info_span!("GlobalState::reload_flycheck").entered(); let config = self.config.flycheck(None); - let sender = self.flycheck_sender.clone(); - let invocation_strategy = match config { - FlycheckConfig::CargoCommand { .. } => { - crate::flycheck::InvocationStrategy::PerWorkspace - } - FlycheckConfig::CustomCommand { ref invocation_strategy, .. } => { - invocation_strategy.clone() - } - }; + let sender = &self.flycheck_sender; + let invocation_strategy = config.invocation_strategy(); + let next_gen = + self.flycheck.iter().map(FlycheckHandle::generation).max().unwrap_or_default() + 1; self.flycheck = match invocation_strategy { crate::flycheck::InvocationStrategy::Once => { vec![FlycheckHandle::spawn( 0, - sender, + next_gen, + sender.clone(), config, None, self.config.root_path().clone(), @@ -898,6 +899,7 @@ impl GlobalState { .map(|(id, (root, manifest_path), sysroot_root)| { FlycheckHandle::spawn( id, + next_gen, sender.clone(), config.clone(), sysroot_root, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs index 7132e09146ebc..e532d155536c1 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/target_spec.rs @@ -2,12 +2,14 @@ use std::mem; +use cargo_metadata::PackageId; use cfg::{CfgAtom, CfgExpr}; use hir::sym; use ide::{Cancellable, Crate, FileId, RunnableKind, TestId}; use project_model::project_json::Runnable; use project_model::{CargoFeatures, ManifestPath, TargetKind}; use rustc_hash::FxHashSet; +use triomphe::Arc; use vfs::AbsPathBuf; use crate::global_state::GlobalStateSnapshot; @@ -52,6 +54,7 @@ pub(crate) struct CargoTargetSpec { pub(crate) workspace_root: AbsPathBuf, pub(crate) cargo_toml: ManifestPath, pub(crate) package: String, + pub(crate) package_id: Arc, pub(crate) target: String, pub(crate) target_kind: TargetKind, pub(crate) crate_id: Crate, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs index e7528dbc9396d..0c8658c75df0a 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs @@ -136,7 +136,12 @@ impl CargoTestHandle { } Ok(Self { - _handle: CommandHandle::spawn(cmd, CargoTestOutputParser::new(&test_target), sender)?, + _handle: CommandHandle::spawn( + cmd, + CargoTestOutputParser::new(&test_target), + sender, + None, + )?, }) } } diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs index 1b940c70da66b..5a4ad6f380f90 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/main.rs @@ -256,7 +256,7 @@ fn main() {} { "args": { "cargoArgs": ["test", "--package", "foo", "--test", "spam"], - "executableArgs": ["test_eggs", "--exact", "--show-output"], + "executableArgs": ["test_eggs", "--exact", "--nocapture"], "overrideCargo": null, "cwd": server.path().join("foo"), "workspaceRoot": server.path().join("foo") @@ -289,7 +289,7 @@ fn main() {} ], "executableArgs": [ "", - "--show-output" + "--nocapture" ] }, "kind": "cargo", @@ -1061,7 +1061,7 @@ fn main() { ), work_done_progress_params: Default::default(), }); - assert!(res.to_string().contains("&'static str")); + assert!(res.to_string().contains("&str")); let res = server.send_request::(HoverParams { text_document_position_params: TextDocumentPositionParams::new( @@ -1070,7 +1070,7 @@ fn main() { ), work_done_progress_params: Default::default(), }); - assert!(res.to_string().contains("&'static str")); + assert!(res.to_string().contains("&str")); server.request::( GotoDefinitionParams { diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs index 2bebb0c1b9700..3464a9644b19d 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/tests/slow-tests/support.rs @@ -97,6 +97,7 @@ impl Project<'_> { proc_macro_names, toolchain, target_data_layout: _, + target_arch: _, } = FixtureWithProjectMeta::parse(self.fixture); assert!(proc_macro_names.is_empty()); assert!(mini_core.is_none()); @@ -177,6 +178,7 @@ impl Project<'_> { proc_macro_names, toolchain, target_data_layout: _, + target_arch: _, } = FixtureWithProjectMeta::parse(self.fixture); assert!(proc_macro_names.is_empty()); assert!(mini_core.is_none()); diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index a9288ecd6fa1f..e803747998b54 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -485,8 +485,7 @@ register_has_name_ast_id! { MacroRules = name, Module = name, Static = name, - Trait = name, - TraitAlias = name + Trait = name } macro_rules! register_assoc_item_ast_id { diff --git a/src/tools/rust-analyzer/crates/span/src/hygiene.rs b/src/tools/rust-analyzer/crates/span/src/hygiene.rs index aef3fbf051775..6c363825aa185 100644 --- a/src/tools/rust-analyzer/crates/span/src/hygiene.rs +++ b/src/tools/rust-analyzer/crates/span/src/hygiene.rs @@ -67,6 +67,16 @@ const _: () = { self.parent.hash(state); } } + + impl zalsa_::HasJar for SyntaxContext { + type Jar = zalsa_struct_::JarImpl; + const KIND: zalsa_::JarKind = zalsa_::JarKind::Struct; + } + + zalsa_::register_jar! { + zalsa_::ErasedJar::erase::() + } + /// Key to use during hash lookups. Each field is some type that implements `Lookup` /// for the owned type. This permits interning with an `&str` when a `String` is required and so forth. #[derive(Hash)] @@ -98,21 +108,38 @@ const _: () = { salsa::plumbing::Location { file: file!(), line: line!() }; const DEBUG_NAME: &'static str = "SyntaxContextData"; const REVISIONS: std::num::NonZeroUsize = std::num::NonZeroUsize::MAX; + const PERSIST: bool = false; + type Fields<'a> = SyntaxContextData; type Struct<'a> = SyntaxContext; - } - impl SyntaxContext { - pub fn ingredient(db: &Db) -> &zalsa_struct_::IngredientImpl + + fn serialize(_: &Self::Fields<'_>, _: S) -> Result where - Db: ?Sized + zalsa_::Database, + S: zalsa_::serde::Serializer, + { + unimplemented!("attempted to serialize value that set `PERSIST` to false") + } + + fn deserialize<'de, D>(_: D) -> Result, D::Error> + where + D: zalsa_::serde::Deserializer<'de>, { + unimplemented!("attempted to deserialize value that cannot set `PERSIST` to false"); + } + } + + impl SyntaxContext { + pub fn ingredient(zalsa: &zalsa_::Zalsa) -> &zalsa_struct_::IngredientImpl { static CACHE: zalsa_::IngredientCache> = zalsa_::IngredientCache::new(); - CACHE.get_or_create(db.zalsa(), || { - db.zalsa() - .lookup_jar_by_type::>() - .get_or_create() - }) + + // SAFETY: `lookup_jar_by_type` returns a valid ingredient index, and the only + // ingredient created by our jar is the struct ingredient. + unsafe { + CACHE.get_or_create(zalsa, || { + zalsa.lookup_jar_by_type::>() + }) + } } } impl zalsa_::AsId for SyntaxContext { @@ -132,13 +159,14 @@ const _: () = { impl zalsa_::SalsaStructInDb for SyntaxContext { type MemoIngredientMap = salsa::plumbing::MemoIngredientSingletonIndex; - fn lookup_or_create_ingredient_index( - zalsa: &salsa::plumbing::Zalsa, - ) -> salsa::plumbing::IngredientIndices { - zalsa - .lookup_jar_by_type::>() - .get_or_create() - .into() + fn lookup_ingredient_index(aux: &zalsa_::Zalsa) -> salsa::plumbing::IngredientIndices { + aux.lookup_jar_by_type::>().into() + } + + fn entries(zalsa: &zalsa_::Zalsa) -> impl Iterator + '_ { + let _ingredient_index = + zalsa.lookup_jar_by_type::>(); + ::ingredient(zalsa).entries(zalsa).map(|entry| entry.key()) } #[inline] @@ -149,6 +177,18 @@ const _: () = { None } } + + #[inline] + unsafe fn memo_table( + zalsa: &zalsa_::Zalsa, + id: zalsa_::Id, + current_revision: zalsa_::Revision, + ) -> zalsa_::MemoTableWithTypes<'_> { + // SAFETY: Guaranteed by caller. + unsafe { + zalsa.table().memos::>(id, current_revision) + } + } } unsafe impl salsa::plumbing::Update for SyntaxContext { @@ -184,8 +224,11 @@ const _: () = { Edition: zalsa_::interned::HashEqLike, SyntaxContext: zalsa_::interned::HashEqLike, { - SyntaxContext::ingredient(db).intern( - db.as_dyn_database(), + let (zalsa, zalsa_local) = db.zalsas(); + + SyntaxContext::ingredient(zalsa).intern( + zalsa, + zalsa_local, StructKey::<'db>( outer_expn, outer_transparency, @@ -216,7 +259,8 @@ const _: () = { Db: ?Sized + zalsa_::Database, { let id = self.as_salsa_id()?; - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.outer_expn } @@ -225,7 +269,8 @@ const _: () = { Db: ?Sized + zalsa_::Database, { let Some(id) = self.as_salsa_id() else { return Transparency::Opaque }; - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.outer_transparency } @@ -235,7 +280,8 @@ const _: () = { { match self.as_salsa_id() { Some(id) => { - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.edition } None => Edition::from_u32(SyntaxContext::MAX_ID - self.into_u32()), @@ -248,7 +294,8 @@ const _: () = { { match self.as_salsa_id() { Some(id) => { - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.parent } None => self, @@ -262,7 +309,8 @@ const _: () = { { match self.as_salsa_id() { Some(id) => { - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.opaque } None => self, @@ -276,7 +324,8 @@ const _: () = { { match self.as_salsa_id() { Some(id) => { - let fields = SyntaxContext::ingredient(db).data(db.as_dyn_database(), id); + let zalsa = db.zalsa(); + let fields = SyntaxContext::ingredient(zalsa).data(zalsa, id); fields.opaque_and_semitransparent } None => self, diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs index 978c50d807bcc..5fa0074163713 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs @@ -187,11 +187,19 @@ pub fn is_upper_snake_case(s: &str) -> bool { } pub fn replace(buf: &mut String, from: char, to: &str) { - if !buf.contains(from) { + let replace_count = buf.chars().filter(|&ch| ch == from).count(); + if replace_count == 0 { return; } - // FIXME: do this in place. - *buf = buf.replace(from, to); + let from_len = from.len_utf8(); + let additional = to.len().saturating_sub(from_len); + buf.reserve(additional * replace_count); + + let mut end = buf.len(); + while let Some(i) = buf[..end].rfind(from) { + buf.replace_range(i..i + from_len, to); + end = i; + } } #[must_use] @@ -343,4 +351,34 @@ mod tests { "fn main() {\n return 92;\n}\n" ); } + + #[test] + fn test_replace() { + #[track_caller] + fn test_replace(src: &str, from: char, to: &str, expected: &str) { + let mut s = src.to_owned(); + replace(&mut s, from, to); + assert_eq!(s, expected, "from: {from:?}, to: {to:?}"); + } + + test_replace("", 'a', "b", ""); + test_replace("", 'a', "😀", ""); + test_replace("", '😀', "a", ""); + test_replace("a", 'a', "b", "b"); + test_replace("aa", 'a', "b", "bb"); + test_replace("ada", 'a', "b", "bdb"); + test_replace("a", 'a', "😀", "😀"); + test_replace("😀", '😀', "a", "a"); + test_replace("😀x", '😀', "a", "ax"); + test_replace("y😀x", '😀', "a", "yax"); + test_replace("a,b,c", ',', ".", "a.b.c"); + test_replace("a,b,c", ',', "..", "a..b..c"); + test_replace("a.b.c", '.', "..", "a..b..c"); + test_replace("a.b.c", '.', "..", "a..b..c"); + test_replace("a😀b😀c", '😀', ".", "a.b.c"); + test_replace("a.b.c", '.', "😀", "a😀b😀c"); + test_replace("a.b.c", '.', "😀😀", "a😀😀b😀😀c"); + test_replace(".a.b.c.", '.', "()", "()a()b()c()"); + test_replace(".a.b.c.", '.', "", "abc"); + } } diff --git a/src/tools/rust-analyzer/crates/stdx/src/thread.rs b/src/tools/rust-analyzer/crates/stdx/src/thread.rs index a34e9e4a65515..37b7a9f5edfa8 100644 --- a/src/tools/rust-analyzer/crates/stdx/src/thread.rs +++ b/src/tools/rust-analyzer/crates/stdx/src/thread.rs @@ -101,7 +101,6 @@ impl Drop for JoinHandle { } } -#[expect(clippy::min_ident_chars, reason = "trait impl")] impl fmt::Debug for JoinHandle { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("JoinHandle { .. }") diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram index 6d8a360d715b7..d73d60c51f0c8 100644 --- a/src/tools/rust-analyzer/crates/syntax/rust.ungram +++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram @@ -154,7 +154,6 @@ Item = | Static | Struct | Trait -| TraitAlias | TypeAlias | Union | Use @@ -306,11 +305,8 @@ Trait = Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name GenericParamList? - (':' TypeBoundList?)? WhereClause? AssocItemList - -TraitAlias = - Attr* Visibility? - 'trait' Name GenericParamList? '=' TypeBoundList? WhereClause? ';' + (((':' TypeBoundList?)? WhereClause? AssocItemList) | + ('=' TypeBoundList? WhereClause? ';')) AssocItemList = '{' Attr* AssocItem* '}' diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast.rs b/src/tools/rust-analyzer/crates/syntax/src/ast.rs index a9aeeedb6542e..aea99a4389b9b 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast.rs @@ -26,11 +26,12 @@ pub use self::{ generated::{nodes::*, tokens::*}, node_ext::{ AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind, - SlicePatComponents, StructKind, TraitOrAlias, TypeBoundKind, TypeOrConstParam, - VisibilityKind, + SlicePatComponents, StructKind, TypeBoundKind, TypeOrConstParam, VisibilityKind, }, operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp}, - token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix}, + token_ext::{ + AnyString, CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix, + }, traits::{ AttrDocCommentIter, DocCommentIter, HasArgList, HasAttrs, HasDocComments, HasGenericArgs, HasGenericParams, HasLoopBody, HasModuleItem, HasName, HasTypeBounds, HasVisibility, diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs index b50ce6442432d..1cd8146f68630 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs @@ -99,38 +99,10 @@ impl GenericParamsOwnerEdit for ast::Trait { fn get_or_create_where_clause(&self) -> ast::WhereClause { if self.where_clause().is_none() { - let position = match self.assoc_item_list() { - Some(items) => Position::before(items.syntax()), - None => Position::last_child_of(self.syntax()), - }; - create_where_clause(position); - } - self.where_clause().unwrap() - } -} - -impl GenericParamsOwnerEdit for ast::TraitAlias { - fn get_or_create_generic_param_list(&self) -> ast::GenericParamList { - match self.generic_param_list() { - Some(it) => it, - None => { - let position = if let Some(name) = self.name() { - Position::after(name.syntax) - } else if let Some(trait_token) = self.trait_token() { - Position::after(trait_token) - } else { - Position::last_child_of(self.syntax()) - }; - create_generic_param_list(position) - } - } - } - - fn get_or_create_where_clause(&self) -> ast::WhereClause { - if self.where_clause().is_none() { - let position = match self.semicolon_token() { - Some(tok) => Position::before(tok), - None => Position::last_child_of(self.syntax()), + let position = match (self.assoc_item_list(), self.semicolon_token()) { + (Some(items), _) => Position::before(items.syntax()), + (_, Some(tok)) => Position::before(tok), + (None, None) => Position::last_child_of(self.syntax()), }; create_where_clause(position); } @@ -273,28 +245,6 @@ pub trait AttrsOwnerEdit: ast::HasAttrs { } } } - - fn add_attr(&self, attr: ast::Attr) { - add_attr(self.syntax(), attr); - - fn add_attr(node: &SyntaxNode, attr: ast::Attr) { - let indent = IndentLevel::from_node(node); - attr.reindent_to(indent); - - let after_attrs_and_comments = node - .children_with_tokens() - .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR)) - .map_or(Position::first_child_of(node), Position::before); - - ted::insert_all( - after_attrs_and_comments, - vec![ - attr.syntax().clone().into(), - make::tokens::whitespace(&format!("\n{indent}")).into(), - ], - ) - } - } } impl AttrsOwnerEdit for T {} diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index ceb2866ebcdf7..d60196d492fc3 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -1614,29 +1614,15 @@ impl Trait { #[inline] pub fn assoc_item_list(&self) -> Option { support::child(&self.syntax) } #[inline] - pub fn auto_token(&self) -> Option { support::token(&self.syntax, T![auto]) } - #[inline] - pub fn trait_token(&self) -> Option { support::token(&self.syntax, T![trait]) } - #[inline] - pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } -} -pub struct TraitAlias { - pub(crate) syntax: SyntaxNode, -} -impl ast::HasAttrs for TraitAlias {} -impl ast::HasDocComments for TraitAlias {} -impl ast::HasGenericParams for TraitAlias {} -impl ast::HasName for TraitAlias {} -impl ast::HasVisibility for TraitAlias {} -impl TraitAlias { - #[inline] - pub fn type_bound_list(&self) -> Option { support::child(&self.syntax) } - #[inline] pub fn semicolon_token(&self) -> Option { support::token(&self.syntax, T![;]) } #[inline] pub fn eq_token(&self) -> Option { support::token(&self.syntax, T![=]) } #[inline] + pub fn auto_token(&self) -> Option { support::token(&self.syntax, T![auto]) } + #[inline] pub fn trait_token(&self) -> Option { support::token(&self.syntax, T![trait]) } + #[inline] + pub fn unsafe_token(&self) -> Option { support::token(&self.syntax, T![unsafe]) } } pub struct TryExpr { pub(crate) syntax: SyntaxNode, @@ -2107,7 +2093,6 @@ pub enum Item { Static(Static), Struct(Struct), Trait(Trait), - TraitAlias(TraitAlias), TypeAlias(TypeAlias), Union(Union), Use(Use), @@ -6801,42 +6786,6 @@ impl fmt::Debug for Trait { f.debug_struct("Trait").field("syntax", &self.syntax).finish() } } -impl AstNode for TraitAlias { - #[inline] - fn kind() -> SyntaxKind - where - Self: Sized, - { - TRAIT_ALIAS - } - #[inline] - fn can_cast(kind: SyntaxKind) -> bool { kind == TRAIT_ALIAS } - #[inline] - fn cast(syntax: SyntaxNode) -> Option { - if Self::can_cast(syntax.kind()) { - Some(Self { syntax }) - } else { - None - } - } - #[inline] - fn syntax(&self) -> &SyntaxNode { &self.syntax } -} -impl hash::Hash for TraitAlias { - fn hash(&self, state: &mut H) { self.syntax.hash(state); } -} -impl Eq for TraitAlias {} -impl PartialEq for TraitAlias { - fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } -} -impl Clone for TraitAlias { - fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } -} -impl fmt::Debug for TraitAlias { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TraitAlias").field("syntax", &self.syntax).finish() - } -} impl AstNode for TryExpr { #[inline] fn kind() -> SyntaxKind @@ -8471,10 +8420,6 @@ impl From for Item { #[inline] fn from(node: Trait) -> Item { Item::Trait(node) } } -impl From for Item { - #[inline] - fn from(node: TraitAlias) -> Item { Item::TraitAlias(node) } -} impl From for Item { #[inline] fn from(node: TypeAlias) -> Item { Item::TypeAlias(node) } @@ -8506,7 +8451,6 @@ impl AstNode for Item { | STATIC | STRUCT | TRAIT - | TRAIT_ALIAS | TYPE_ALIAS | UNION | USE @@ -8529,7 +8473,6 @@ impl AstNode for Item { STATIC => Item::Static(Static { syntax }), STRUCT => Item::Struct(Struct { syntax }), TRAIT => Item::Trait(Trait { syntax }), - TRAIT_ALIAS => Item::TraitAlias(TraitAlias { syntax }), TYPE_ALIAS => Item::TypeAlias(TypeAlias { syntax }), UNION => Item::Union(Union { syntax }), USE => Item::Use(Use { syntax }), @@ -8554,7 +8497,6 @@ impl AstNode for Item { Item::Static(it) => &it.syntax, Item::Struct(it) => &it.syntax, Item::Trait(it) => &it.syntax, - Item::TraitAlias(it) => &it.syntax, Item::TypeAlias(it) => &it.syntax, Item::Union(it) => &it.syntax, Item::Use(it) => &it.syntax, @@ -8984,7 +8926,6 @@ impl AstNode for AnyHasAttrs { | STMT_LIST | STRUCT | TRAIT - | TRAIT_ALIAS | TRY_EXPR | TUPLE_EXPR | TUPLE_FIELD @@ -9257,10 +9198,6 @@ impl From for AnyHasAttrs { #[inline] fn from(node: Trait) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } } } -impl From for AnyHasAttrs { - #[inline] - fn from(node: TraitAlias) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } } -} impl From for AnyHasAttrs { #[inline] fn from(node: TryExpr) -> AnyHasAttrs { AnyHasAttrs { syntax: node.syntax } } @@ -9330,7 +9267,6 @@ impl AstNode for AnyHasDocComments { | STATIC | STRUCT | TRAIT - | TRAIT_ALIAS | TUPLE_FIELD | TYPE_ALIAS | UNION @@ -9420,10 +9356,6 @@ impl From for AnyHasDocComments { #[inline] fn from(node: Trait) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } } } -impl From for AnyHasDocComments { - #[inline] - fn from(node: TraitAlias) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } } -} impl From for AnyHasDocComments { #[inline] fn from(node: TupleField) -> AnyHasDocComments { AnyHasDocComments { syntax: node.syntax } } @@ -9488,7 +9420,7 @@ impl ast::HasGenericParams for AnyHasGenericParams {} impl AstNode for AnyHasGenericParams { #[inline] fn can_cast(kind: SyntaxKind) -> bool { - matches!(kind, CONST | ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION) + matches!(kind, CONST | ENUM | FN | IMPL | STRUCT | TRAIT | TYPE_ALIAS | UNION) } #[inline] fn cast(syntax: SyntaxNode) -> Option { @@ -9536,10 +9468,6 @@ impl From for AnyHasGenericParams { #[inline] fn from(node: Trait) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } } } -impl From for AnyHasGenericParams { - #[inline] - fn from(node: TraitAlias) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } } -} impl From for AnyHasGenericParams { #[inline] fn from(node: TypeAlias) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } } @@ -9646,7 +9574,6 @@ impl AstNode for AnyHasName { | STATIC | STRUCT | TRAIT - | TRAIT_ALIAS | TYPE_ALIAS | TYPE_PARAM | UNION @@ -9739,10 +9666,6 @@ impl From for AnyHasName { #[inline] fn from(node: Trait) -> AnyHasName { AnyHasName { syntax: node.syntax } } } -impl From for AnyHasName { - #[inline] - fn from(node: TraitAlias) -> AnyHasName { AnyHasName { syntax: node.syntax } } -} impl From for AnyHasName { #[inline] fn from(node: TypeAlias) -> AnyHasName { AnyHasName { syntax: node.syntax } } @@ -9832,7 +9755,6 @@ impl AstNode for AnyHasVisibility { | STATIC | STRUCT | TRAIT - | TRAIT_ALIAS | TUPLE_FIELD | TYPE_ALIAS | UNION @@ -9910,10 +9832,6 @@ impl From for AnyHasVisibility { #[inline] fn from(node: Trait) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } } } -impl From for AnyHasVisibility { - #[inline] - fn from(node: TraitAlias) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } } -} impl From for AnyHasVisibility { #[inline] fn from(node: TupleField) -> AnyHasVisibility { AnyHasVisibility { syntax: node.syntax } } @@ -10639,11 +10557,6 @@ impl std::fmt::Display for Trait { std::fmt::Display::fmt(self.syntax(), f) } } -impl std::fmt::Display for TraitAlias { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(self.syntax(), f) - } -} impl std::fmt::Display for TryExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index daeb79cf081dc..051c5835571bc 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -190,6 +190,7 @@ fn ty_from_text(text: &str) -> ast::Type { } pub fn ty_alias( + attrs: impl IntoIterator, ident: &str, generic_param_list: Option, type_param_bounds: Option, @@ -200,6 +201,7 @@ pub fn ty_alias( let assignment_where = assignment_where.flatten(); quote! { TypeAlias { + #(#attrs "\n")* [type] " " Name { [IDENT ident] } #generic_param_list @@ -229,6 +231,23 @@ pub fn ty_fn_ptr>( } } +pub fn item_list(body: Option>) -> ast::ItemList { + let is_break_braces = body.is_some(); + let body_newline = if is_break_braces { "\n" } else { "" }; + let body_indent = if is_break_braces { " " } else { "" }; + + let body = match body { + Some(bd) => bd.iter().map(|elem| elem.to_string()).join("\n\n "), + None => String::new(), + }; + ast_from_text(&format!("mod C {{{body_newline}{body_indent}{body}{body_newline}}}")) +} + +pub fn mod_(name: ast::Name, body: Option) -> ast::Module { + let body = body.map_or(";".to_owned(), |body| format!(" {body}")); + ast_from_text(&format!("mod {name}{body}")) +} + pub fn assoc_item_list(body: Option>) -> ast::AssocItemList { let is_break_braces = body.is_some(); let body_newline = if is_break_braces { "\n".to_owned() } else { String::new() }; @@ -277,12 +296,16 @@ fn merge_where_clause( } pub fn impl_( + attrs: impl IntoIterator, generic_params: Option, generic_args: Option, path_type: ast::Type, where_clause: Option, body: Option, ) -> ast::Impl { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); + let gen_args = generic_args.map_or_else(String::new, |it| it.to_string()); let gen_params = generic_params.map_or_else(String::new, |it| it.to_string()); @@ -295,10 +318,11 @@ pub fn impl_( }; let body = body.map_or_else(|| format!("{{{body_newline}}}"), |it| it.to_string()); - ast_from_text(&format!("impl{gen_params} {path_type}{gen_args}{where_clause}{body}")) + ast_from_text(&format!("{attrs}impl{gen_params} {path_type}{gen_args}{where_clause}{body}")) } pub fn impl_trait( + attrs: impl IntoIterator, is_unsafe: bool, trait_gen_params: Option, trait_gen_args: Option, @@ -311,6 +335,8 @@ pub fn impl_trait( ty_where_clause: Option, body: Option, ) -> ast::Impl { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let is_unsafe = if is_unsafe { "unsafe " } else { "" }; let trait_gen_args = trait_gen_args.map(|args| args.to_string()).unwrap_or_default(); @@ -334,7 +360,7 @@ pub fn impl_trait( let body = body.map_or_else(|| format!("{{{body_newline}}}"), |it| it.to_string()); ast_from_text(&format!( - "{is_unsafe}impl{gen_params} {is_negative}{path_type}{trait_gen_args} for {ty}{type_gen_args}{where_clause}{body}" + "{attrs}{is_unsafe}impl{gen_params} {is_negative}{path_type}{trait_gen_args} for {ty}{type_gen_args}{where_clause}{body}" )) } @@ -452,12 +478,18 @@ pub fn use_tree_list(use_trees: impl IntoIterator) -> ast:: ast_from_text(&format!("use {{{use_trees}}};")) } -pub fn use_(visibility: Option, use_tree: ast::UseTree) -> ast::Use { +pub fn use_( + attrs: impl IntoIterator, + visibility: Option, + use_tree: ast::UseTree, +) -> ast::Use { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}use {use_tree};")) + ast_from_text(&format!("{attrs}{visibility}use {use_tree};")) } pub fn record_expr(path: ast::Path, fields: ast::RecordExprFieldList) -> ast::RecordExpr { @@ -946,16 +978,19 @@ pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt { } pub fn item_const( + attrs: impl IntoIterator, visibility: Option, name: ast::Name, ty: ast::Type, expr: ast::Expr, ) -> ast::Const { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}const {name}: {ty} = {expr};")) + ast_from_text(&format!("{attrs}{visibility}const {name}: {ty} = {expr};")) } pub fn item_static( @@ -1162,6 +1197,7 @@ pub fn variant( } pub fn fn_( + attrs: impl IntoIterator, visibility: Option, fn_name: ast::Name, type_params: Option, @@ -1174,6 +1210,8 @@ pub fn fn_( is_unsafe: bool, is_gen: bool, ) -> ast::Fn { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let type_params = match type_params { Some(type_params) => format!("{type_params}"), None => "".into(), @@ -1197,7 +1235,7 @@ pub fn fn_( let gen_literal = if is_gen { "gen " } else { "" }; ast_from_text(&format!( - "{visibility}{const_literal}{async_literal}{gen_literal}{unsafe_literal}fn {fn_name}{type_params}{params} {ret_type}{where_clause}{body}", + "{attrs}{visibility}{const_literal}{async_literal}{gen_literal}{unsafe_literal}fn {fn_name}{type_params}{params} {ret_type}{where_clause}{body}", )) } pub fn struct_( @@ -1206,23 +1244,29 @@ pub fn struct_( generic_param_list: Option, field_list: ast::FieldList, ) -> ast::Struct { - let semicolon = if matches!(field_list, ast::FieldList::TupleFieldList(_)) { ";" } else { "" }; + let (semicolon, ws) = + if matches!(field_list, ast::FieldList::TupleFieldList(_)) { (";", "") } else { ("", " ") }; let type_params = generic_param_list.map_or_else(String::new, |it| it.to_string()); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), }; - ast_from_text(&format!("{visibility}struct {strukt_name}{type_params}{field_list}{semicolon}",)) + ast_from_text(&format!( + "{visibility}struct {strukt_name}{type_params}{ws}{field_list}{semicolon}" + )) } pub fn enum_( + attrs: impl IntoIterator, visibility: Option, enum_name: ast::Name, generic_param_list: Option, where_clause: Option, variant_list: ast::VariantList, ) -> ast::Enum { + let attrs = + attrs.into_iter().fold(String::new(), |mut acc, attr| format_to_acc!(acc, "{}\n", attr)); let visibility = match visibility { None => String::new(), Some(it) => format!("{it} "), @@ -1232,7 +1276,7 @@ pub fn enum_( let where_clause = where_clause.map(|it| format!(" {it}")).unwrap_or_default(); ast_from_text(&format!( - "{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}" + "{attrs}{visibility}enum {enum_name}{generic_params}{where_clause} {variant_list}" )) } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs index 62a7d4df2cf6b..af741d100f680 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/node_ext.rs @@ -12,8 +12,8 @@ use rowan::{GreenNodeData, GreenTokenData}; use crate::{ NodeOrToken, SmolStr, SyntaxElement, SyntaxToken, T, TokenText, ast::{ - self, AstNode, AstToken, HasAttrs, HasGenericArgs, HasGenericParams, HasName, SyntaxNode, - support, + self, AstNode, AstToken, HasAttrs, HasGenericArgs, HasGenericParams, HasName, + HasTypeBounds, SyntaxNode, support, }, ted, }; @@ -880,51 +880,6 @@ impl AstNode for TypeOrConstParam { impl HasAttrs for TypeOrConstParam {} -#[derive(Debug, Clone)] -pub enum TraitOrAlias { - Trait(ast::Trait), - TraitAlias(ast::TraitAlias), -} - -impl TraitOrAlias { - pub fn name(&self) -> Option { - match self { - TraitOrAlias::Trait(x) => x.name(), - TraitOrAlias::TraitAlias(x) => x.name(), - } - } -} - -impl AstNode for TraitOrAlias { - fn can_cast(kind: SyntaxKind) -> bool - where - Self: Sized, - { - matches!(kind, SyntaxKind::TRAIT | SyntaxKind::TRAIT_ALIAS) - } - - fn cast(syntax: SyntaxNode) -> Option - where - Self: Sized, - { - let res = match syntax.kind() { - SyntaxKind::TRAIT => TraitOrAlias::Trait(ast::Trait { syntax }), - SyntaxKind::TRAIT_ALIAS => TraitOrAlias::TraitAlias(ast::TraitAlias { syntax }), - _ => return None, - }; - Some(res) - } - - fn syntax(&self) -> &SyntaxNode { - match self { - TraitOrAlias::Trait(it) => it.syntax(), - TraitOrAlias::TraitAlias(it) => it.syntax(), - } - } -} - -impl HasAttrs for TraitOrAlias {} - pub enum VisibilityKind { In(ast::Path), PubCrate, @@ -957,11 +912,10 @@ impl ast::Visibility { impl ast::LifetimeParam { pub fn lifetime_bounds(&self) -> impl Iterator { - self.syntax() - .children_with_tokens() - .filter_map(|it| it.into_token()) - .skip_while(|x| x.kind() != T![:]) - .filter(|it| it.kind() == T![lifetime_ident]) + self.type_bound_list() + .into_iter() + .flat_map(|it| it.bounds()) + .filter_map(|it| it.lifetime()?.lifetime_ident_token()) } } diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs index 738a26fed5d82..8bf27f967482b 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs @@ -2,8 +2,8 @@ use crate::{ AstNode, NodeOrToken, SyntaxKind, SyntaxNode, SyntaxToken, ast::{ - self, HasArgList, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, HasTypeBounds, - HasVisibility, RangeItem, make, + self, HasArgList, HasAttrs, HasGenericArgs, HasGenericParams, HasLoopBody, HasName, + HasTypeBounds, HasVisibility, RangeItem, make, }, syntax_editor::SyntaxMappingBuilder, }; @@ -107,8 +107,13 @@ impl SyntaxFactory { ast } - pub fn use_(&self, visibility: Option, use_tree: ast::UseTree) -> ast::Use { - make::use_(visibility, use_tree).clone_for_update() + pub fn use_( + &self, + attrs: impl IntoIterator, + visibility: Option, + use_tree: ast::UseTree, + ) -> ast::Use { + make::use_(attrs, visibility, use_tree).clone_for_update() } pub fn use_tree( @@ -840,16 +845,20 @@ impl SyntaxFactory { pub fn item_const( &self, + attrs: impl IntoIterator, visibility: Option, name: ast::Name, ty: ast::Type, expr: ast::Expr, ) -> ast::Const { - let ast = make::item_const(visibility.clone(), name.clone(), ty.clone(), expr.clone()) - .clone_for_update(); + let (attrs, attrs_input) = iterator_input(attrs); + let ast = + make::item_const(attrs, visibility.clone(), name.clone(), ty.clone(), expr.clone()) + .clone_for_update(); if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(attrs_input, ast.attrs().map(|attr| attr.syntax().clone())); if let Some(visibility) = visibility { builder.map_node( visibility.syntax().clone(), @@ -1067,6 +1076,7 @@ impl SyntaxFactory { pub fn item_enum( &self, + attrs: impl IntoIterator, visibility: Option, name: ast::Name, generic_param_list: Option, @@ -1074,6 +1084,7 @@ impl SyntaxFactory { variant_list: ast::VariantList, ) -> ast::Enum { let ast = make::enum_( + attrs, visibility.clone(), name.clone(), generic_param_list.clone(), @@ -1182,6 +1193,7 @@ impl SyntaxFactory { pub fn fn_( &self, + attrs: impl IntoIterator, visibility: Option, fn_name: ast::Name, type_params: Option, @@ -1194,7 +1206,9 @@ impl SyntaxFactory { is_unsafe: bool, is_gen: bool, ) -> ast::Fn { + let (attrs, input) = iterator_input(attrs); let ast = make::fn_( + attrs, visibility.clone(), fn_name.clone(), type_params.clone(), @@ -1210,6 +1224,7 @@ impl SyntaxFactory { if let Some(mut mapping) = self.mappings() { let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone()); + builder.map_children(input, ast.attrs().map(|attr| attr.syntax().clone())); if let Some(visibility) = visibility { builder.map_node( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs index 4afdda78a0e70..d9223e8216da3 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs @@ -151,10 +151,10 @@ impl QuoteOffsets { } pub trait IsString: AstToken { - const RAW_PREFIX: &'static str; - fn unescape(s: &str, callback: impl FnMut(Range, Result)); + fn raw_prefix(&self) -> &'static str; + fn unescape(&self, s: &str, callback: impl FnMut(Range, Result)); fn is_raw(&self) -> bool { - self.text().starts_with(Self::RAW_PREFIX) + self.text().starts_with(self.raw_prefix()) } fn quote_offsets(&self) -> Option { let text = self.text(); @@ -187,7 +187,7 @@ pub trait IsString: AstToken { let text = &self.text()[text_range_no_quotes - start]; let offset = text_range_no_quotes.start() - start; - Self::unescape(text, &mut |range: Range, unescaped_char| { + self.unescape(text, &mut |range: Range, unescaped_char| { if let Some((s, e)) = range.start.try_into().ok().zip(range.end.try_into().ok()) { cb(TextRange::new(s, e) + offset, unescaped_char); } @@ -204,8 +204,10 @@ pub trait IsString: AstToken { } impl IsString for ast::String { - const RAW_PREFIX: &'static str = "r"; - fn unescape(s: &str, cb: impl FnMut(Range, Result)) { + fn raw_prefix(&self) -> &'static str { + "r" + } + fn unescape(&self, s: &str, cb: impl FnMut(Range, Result)) { unescape_str(s, cb) } } @@ -246,8 +248,10 @@ impl ast::String { } impl IsString for ast::ByteString { - const RAW_PREFIX: &'static str = "br"; - fn unescape(s: &str, mut callback: impl FnMut(Range, Result)) { + fn raw_prefix(&self) -> &'static str { + "br" + } + fn unescape(&self, s: &str, mut callback: impl FnMut(Range, Result)) { unescape_byte_str(s, |range, res| callback(range, res.map(char::from))) } } @@ -288,10 +292,12 @@ impl ast::ByteString { } impl IsString for ast::CString { - const RAW_PREFIX: &'static str = "cr"; + fn raw_prefix(&self) -> &'static str { + "cr" + } // NOTE: This method should only be used for highlighting ranges. The unescaped // char/byte is not used. For simplicity, we return an arbitrary placeholder char. - fn unescape(s: &str, mut callback: impl FnMut(Range, Result)) { + fn unescape(&self, s: &str, mut callback: impl FnMut(Range, Result)) { unescape_c_str(s, |range, _res| callback(range, Ok('_'))) } } @@ -465,6 +471,74 @@ impl ast::Byte { } } +pub enum AnyString { + ByteString(ast::ByteString), + CString(ast::CString), + String(ast::String), +} + +impl AnyString { + pub fn value(&self) -> Result, EscapeError> { + fn from_utf8(s: Cow<'_, [u8]>) -> Result, EscapeError> { + match s { + Cow::Borrowed(s) => str::from_utf8(s) + .map_err(|_| EscapeError::NonAsciiCharInByte) + .map(Cow::Borrowed), + Cow::Owned(s) => String::from_utf8(s) + .map_err(|_| EscapeError::NonAsciiCharInByte) + .map(Cow::Owned), + } + } + + match self { + AnyString::String(s) => s.value(), + AnyString::ByteString(s) => s.value().and_then(from_utf8), + AnyString::CString(s) => s.value().and_then(from_utf8), + } + } +} + +impl ast::AstToken for AnyString { + fn can_cast(kind: crate::SyntaxKind) -> bool { + ast::String::can_cast(kind) + || ast::ByteString::can_cast(kind) + || ast::CString::can_cast(kind) + } + + fn cast(syntax: crate::SyntaxToken) -> Option { + ast::String::cast(syntax.clone()) + .map(Self::String) + .or_else(|| ast::ByteString::cast(syntax.clone()).map(Self::ByteString)) + .or_else(|| ast::CString::cast(syntax).map(Self::CString)) + } + + fn syntax(&self) -> &crate::SyntaxToken { + match self { + Self::ByteString(it) => it.syntax(), + Self::CString(it) => it.syntax(), + Self::String(it) => it.syntax(), + } + } +} + +impl IsString for AnyString { + fn raw_prefix(&self) -> &'static str { + match self { + AnyString::ByteString(s) => s.raw_prefix(), + AnyString::CString(s) => s.raw_prefix(), + AnyString::String(s) => s.raw_prefix(), + } + } + + fn unescape(&self, s: &str, callback: impl FnMut(Range, Result)) { + match self { + AnyString::ByteString(it) => it.unescape(s, callback), + AnyString::CString(it) => it.unescape(s, callback), + AnyString::String(it) => it.unescape(s, callback), + } + } +} + #[cfg(test)] mod tests { use rustc_apfloat::ieee::Quad as f128; diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs index 18f5015e9eabd..0b358878fcf23 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs @@ -618,6 +618,7 @@ mod tests { #[test] fn test_replace_token_in_parent() { let parent_fn = make::fn_( + None, None, make::name("it"), None, diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs index dc6130bd6415c..1c902893abc64 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_error.rs @@ -42,3 +42,5 @@ impl fmt::Display for SyntaxError { self.0.fmt(f) } } + +impl std::error::Error for SyntaxError {} diff --git a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs index 4413d2f222c15..a4549794db336 100644 --- a/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs +++ b/src/tools/rust-analyzer/crates/test-fixture/src/lib.rs @@ -1,10 +1,11 @@ //! A set of high-level utility fixture methods to use in tests. use std::{any::TypeId, mem, str::FromStr, sync}; +use base_db::target::TargetData; use base_db::{ Crate, CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CrateWorkspaceData, - DependencyBuilder, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabase, SourceRoot, - Version, VfsPath, salsa, + DependencyBuilder, Env, FileChange, FileSet, FxIndexMap, LangCrateOrigin, SourceDatabase, + SourceRoot, Version, VfsPath, salsa, }; use cfg::CfgOptions; use hir_expand::{ @@ -20,7 +21,6 @@ use hir_expand::{ }; use intern::{Symbol, sym}; use paths::AbsPathBuf; -use rustc_hash::FxHashMap; use span::{Edition, FileId, Span}; use stdx::itertools::Itertools; use test_utils::{ @@ -137,8 +137,11 @@ impl ChangeFixture { proc_macro_names, toolchain, target_data_layout, + target_arch, } = FixtureWithProjectMeta::parse(ra_fixture); - let target_data_layout = Ok(target_data_layout.into()); + let target_data_layout = target_data_layout.into(); + let target_arch = parse_target_arch(&target_arch); + let target = Ok(TargetData { arch: target_arch, data_layout: target_data_layout }); let toolchain = Some({ let channel = toolchain.as_deref().unwrap_or("stable"); Version::parse(&format!("1.76.0-{channel}")).unwrap() @@ -147,7 +150,7 @@ impl ChangeFixture { let mut files = Vec::new(); let mut crate_graph = CrateGraphBuilder::default(); - let mut crates = FxHashMap::default(); + let mut crates = FxIndexMap::default(); let mut crate_deps = Vec::new(); let mut default_crate_root: Option = None; let mut default_edition = Edition::CURRENT; @@ -164,8 +167,7 @@ impl ChangeFixture { let mut file_position = None; - let crate_ws_data = - Arc::new(CrateWorkspaceData { data_layout: target_data_layout, toolchain }); + let crate_ws_data = Arc::new(CrateWorkspaceData { target, toolchain }); // FIXME: This is less than ideal let proc_macro_cwd = Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())); @@ -249,37 +251,7 @@ impl ChangeFixture { file_id = FileId::from_raw(file_id.index() + 1); } - if crates.is_empty() { - let crate_root = default_crate_root - .expect("missing default crate root, specify a main.rs or lib.rs"); - crate_graph.add_crate_root( - crate_root, - default_edition, - Some(CrateName::new("ra_test_fixture").unwrap().into()), - None, - default_cfg.clone(), - Some(default_cfg), - default_env, - CrateOrigin::Local { repo: None, name: None }, - false, - proc_macro_cwd.clone(), - crate_ws_data.clone(), - ); - } else { - for (from, to, prelude) in crate_deps { - let from_id = crates[&from]; - let to_id = crates[&to]; - let sysroot = crate_graph[to_id].basic.origin.is_lang(); - crate_graph - .add_dep( - from_id, - DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot), - ) - .unwrap(); - } - } - - if let Some(mini_core) = mini_core { + let mini_core = mini_core.map(|mini_core| { let core_file = file_id; file_id = FileId::from_raw(file_id.index() + 1); @@ -289,8 +261,6 @@ impl ChangeFixture { source_change.change_file(core_file, Some(mini_core.source_code())); - let all_crates = crate_graph.iter().collect::>(); - let core_crate = crate_graph.add_crate_root( core_file, Edition::CURRENT, @@ -308,16 +278,58 @@ impl ChangeFixture { crate_ws_data.clone(), ); - for krate in all_crates { + ( + move || { + DependencyBuilder::with_prelude( + CrateName::new("core").unwrap(), + core_crate, + true, + true, + ) + }, + core_crate, + ) + }); + + if crates.is_empty() { + let crate_root = default_crate_root + .expect("missing default crate root, specify a main.rs or lib.rs"); + let root = crate_graph.add_crate_root( + crate_root, + default_edition, + Some(CrateName::new("ra_test_fixture").unwrap().into()), + None, + default_cfg.clone(), + Some(default_cfg), + default_env, + CrateOrigin::Local { repo: None, name: None }, + false, + proc_macro_cwd.clone(), + crate_ws_data.clone(), + ); + if let Some((mini_core, _)) = mini_core { + crate_graph.add_dep(root, mini_core()).unwrap(); + } + } else { + // Insert minicore first to match with `project-model::workspace` + if let Some((mini_core, core_crate)) = mini_core { + let all_crates = crate_graph.iter().collect::>(); + for krate in all_crates { + if krate == core_crate { + continue; + } + crate_graph.add_dep(krate, mini_core()).unwrap(); + } + } + + for (from, to, prelude) in crate_deps { + let from_id = crates[&from]; + let to_id = crates[&to]; + let sysroot = crate_graph[to_id].basic.origin.is_lang(); crate_graph .add_dep( - krate, - DependencyBuilder::with_prelude( - CrateName::new("core").unwrap(), - core_crate, - true, - true, - ), + from_id, + DependencyBuilder::with_prelude(to.clone(), to_id, prelude, sysroot), ) .unwrap(); } @@ -371,6 +383,8 @@ impl ChangeFixture { } } + let _ = file_id; + let root = match current_source_root_kind { SourceRootKind::Local => SourceRoot::new_local(mem::take(&mut file_set)), SourceRootKind::Library => SourceRoot::new_library(mem::take(&mut file_set)), @@ -386,6 +400,15 @@ impl ChangeFixture { } } +fn parse_target_arch(arch: &str) -> base_db::target::Arch { + use base_db::target::Arch::*; + match arch { + "wasm32" => Wasm32, + "wasm64" => Wasm64, + _ => Other, + } +} + fn default_test_proc_macros() -> Box<[(String, ProcMacro)]> { Box::new([ ( @@ -627,11 +650,23 @@ impl FileMeta { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum ForceNoneLangOrigin { + Yes, + No, +} + fn parse_crate( crate_str: String, current_source_root_kind: SourceRootKind, explicit_non_workspace_member: bool, ) -> (String, CrateOrigin, Option) { + let (crate_str, force_non_lang_origin) = if let Some(s) = crate_str.strip_prefix("r#") { + (s.to_owned(), ForceNoneLangOrigin::Yes) + } else { + (crate_str, ForceNoneLangOrigin::No) + }; + // syntax: // "my_awesome_crate" // "my_awesome_crate@0.0.1,http://example.com" @@ -646,16 +681,25 @@ fn parse_crate( let non_workspace_member = explicit_non_workspace_member || matches!(current_source_root_kind, SourceRootKind::Library); - let origin = match LangCrateOrigin::from(&*name) { - LangCrateOrigin::Other => { - let name = Symbol::intern(&name); - if non_workspace_member { - CrateOrigin::Library { repo, name } - } else { - CrateOrigin::Local { repo, name: Some(name) } + let origin = if force_non_lang_origin == ForceNoneLangOrigin::Yes { + let name = Symbol::intern(&name); + if non_workspace_member { + CrateOrigin::Library { repo, name } + } else { + CrateOrigin::Local { repo, name: Some(name) } + } + } else { + match LangCrateOrigin::from(&*name) { + LangCrateOrigin::Other => { + let name = Symbol::intern(&name); + if non_workspace_member { + CrateOrigin::Library { repo, name } + } else { + CrateOrigin::Local { repo, name: Some(name) } + } } + origin => CrateOrigin::Lang(origin), } - origin => CrateOrigin::Lang(origin), }; (name, origin, version) diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs index e830c6a7cf688..c024089a016f9 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs @@ -149,6 +149,8 @@ pub struct FixtureWithProjectMeta { /// You probably don't want to manually specify this. See LLVM manual for the /// syntax, if you must: pub target_data_layout: String, + /// Specifies the target architecture. + pub target_arch: String, } impl FixtureWithProjectMeta { @@ -178,6 +180,7 @@ impl FixtureWithProjectMeta { let mut toolchain = None; let mut target_data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128".to_owned(); + let mut target_arch = "x86_64".to_owned(); let mut mini_core = None; let mut res: Vec = Vec::new(); let mut proc_macro_names = vec![]; @@ -194,6 +197,12 @@ impl FixtureWithProjectMeta { fixture = remain; } + if let Some(meta) = fixture.strip_prefix("//- target_arch:") { + let (meta, remain) = meta.split_once('\n').unwrap(); + meta.trim().clone_into(&mut target_arch); + fixture = remain; + } + if let Some(meta) = fixture.strip_prefix("//- proc_macros:") { let (meta, remain) = meta.split_once('\n').unwrap(); proc_macro_names = meta.split(',').map(|it| it.trim().to_owned()).collect(); @@ -232,7 +241,14 @@ impl FixtureWithProjectMeta { } } - Self { fixture: res, mini_core, proc_macro_names, toolchain, target_data_layout } + Self { + fixture: res, + mini_core, + proc_macro_names, + toolchain, + target_data_layout, + target_arch, + } } //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo @@ -511,6 +527,7 @@ fn parse_fixture_gets_full_meta() { proc_macro_names, toolchain, target_data_layout: _, + target_arch: _, } = FixtureWithProjectMeta::parse( r#" //- toolchain: nightly diff --git a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs index 7b719b5dec754..696928b522f94 100644 --- a/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs +++ b/src/tools/rust-analyzer/crates/test-utils/src/minicore.rs @@ -35,7 +35,7 @@ //! error: fmt //! fmt: option, result, transmute, coerce_unsized, copy, clone, derive //! fmt_before_1_89_0: fmt -//! fn: tuple +//! fn: sized, tuple //! from: sized, result //! future: pin //! coroutine: pin @@ -55,7 +55,7 @@ //! panic: fmt //! phantom_data: //! pin: -//! pointee: copy, send, sync, ord, hash, unpin +//! pointee: copy, send, sync, ord, hash, unpin, phantom_data //! range: //! receiver: deref //! result: @@ -70,6 +70,7 @@ //! tuple: //! unpin: sized //! unsize: sized +//! write: fmt //! todo: panic //! unimplemented: panic //! column: @@ -168,6 +169,17 @@ pub mod marker { // region:phantom_data #[lang = "phantom_data"] pub struct PhantomData; + + // region:clone + impl Clone for PhantomData { + fn clone(&self) -> Self { Self } + } + // endregion:clone + + // region:copy + impl Copy for PhantomData {} + // endregion:copy + // endregion:phantom_data // region:discriminant @@ -325,6 +337,18 @@ pub mod clone { *self } } + + impl Clone for [T; 0] { + fn clone(&self) -> Self { + [] + } + } + + impl Clone for [T; 1] { + fn clone(&self) -> Self { + [self[0].clone()] + } + } // endregion:builtin_impls // region:derive @@ -491,6 +515,16 @@ pub mod ptr { #[lang = "metadata_type"] type Metadata: Copy + Send + Sync + Ord + Hash + Unpin; } + + #[lang = "dyn_metadata"] + pub struct DynMetadata { + _phantom: crate::marker::PhantomData, + } + + pub const fn metadata(ptr: *const T) -> ::Metadata { + loop {} + } + // endregion:pointee // region:non_null #[rustc_layout_scalar_valid_range_start(1)] @@ -1035,6 +1069,7 @@ pub mod ops { #[lang = "coroutine"] pub trait Coroutine { + #[lang = "coroutine_yield"] type Yield; #[lang = "coroutine_return"] type Return; @@ -1123,7 +1158,7 @@ pub mod fmt { pub struct Error; pub type Result = crate::result::Result<(), Error>; - pub struct Formatter<'a>; + pub struct Formatter<'a>(&'a ()); pub struct DebugTuple; pub struct DebugStruct; impl Formatter<'_> { @@ -1596,6 +1631,12 @@ pub mod iter { { loop {} } + fn collect>(self) -> B + where + Self: Sized, + { + loop {} + } // endregion:iterators } impl Iterator for &mut I { @@ -1665,10 +1706,13 @@ pub mod iter { loop {} } } + pub trait FromIterator: Sized { + fn from_iter>(iter: T) -> Self; + } } - pub use self::collect::IntoIterator; + pub use self::collect::{IntoIterator, FromIterator}; } - pub use self::traits::{IntoIterator, Iterator}; + pub use self::traits::{IntoIterator, FromIterator, Iterator}; } // endregion:iterator @@ -1769,6 +1813,26 @@ mod macros { } // endregion:panic + // region:write + #[macro_export] + macro_rules! write { + ($dst:expr, $($arg:tt)*) => { + $dst.write_fmt($crate::format_args!($($arg)*)) + }; + } + + #[macro_export] + #[allow_internal_unstable(format_args_nl)] + macro_rules! writeln { + ($dst:expr $(,)?) => { + $crate::write!($dst, "\n") + }; + ($dst:expr, $($arg:tt)*) => { + $dst.write_fmt($crate::format_args_nl!($($arg)*)) + }; + } + // endregion:write + // region:assert #[macro_export] #[rustc_builtin_macro] @@ -1944,7 +2008,7 @@ pub mod prelude { convert::AsRef, // :as_ref convert::{From, Into, TryFrom, TryInto}, // :from default::Default, // :default - iter::{IntoIterator, Iterator}, // :iterator + iter::{IntoIterator, Iterator, FromIterator}, // :iterator macros::builtin::{derive, derive_const}, // :derive marker::Copy, // :copy marker::Send, // :send diff --git a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs index 8b7bf1a806415..39319886cfe4a 100644 --- a/src/tools/rust-analyzer/crates/toolchain/src/lib.rs +++ b/src/tools/rust-analyzer/crates/toolchain/src/lib.rs @@ -71,6 +71,9 @@ impl Tool { } } +// Prevent rustup from automatically installing toolchains, see https://github.com/rust-lang/rust-analyzer/issues/20719. +pub const NO_RUSTUP_AUTO_INSTALL_ENV: (&str, &str) = ("RUSTUP_AUTO_INSTALL", "0"); + #[allow(clippy::disallowed_types)] /* generic parameter allows for FxHashMap */ pub fn command( cmd: impl AsRef, @@ -81,6 +84,7 @@ pub fn command( #[allow(clippy::disallowed_methods)] let mut cmd = Command::new(cmd); cmd.current_dir(working_directory); + cmd.env(NO_RUSTUP_AUTO_INSTALL_ENV.0, NO_RUSTUP_AUTO_INSTALL_ENV.1); for env in extra_env { match env { (key, Some(val)) => cmd.env(key, val), diff --git a/src/tools/rust-analyzer/docs/book/README.md b/src/tools/rust-analyzer/docs/book/README.md index 0a3161f3af38d..11f7e8f98ca56 100644 --- a/src/tools/rust-analyzer/docs/book/README.md +++ b/src/tools/rust-analyzer/docs/book/README.md @@ -8,6 +8,7 @@ To run the documentation site locally: ```shell cargo install mdbook +cargo install mdbook-toc cargo xtask codegen cd docs/book mdbook serve diff --git a/src/tools/rust-analyzer/docs/book/src/README.md b/src/tools/rust-analyzer/docs/book/src/README.md index 71f34e0346646..060bcf0cea399 100644 --- a/src/tools/rust-analyzer/docs/book/src/README.md +++ b/src/tools/rust-analyzer/docs/book/src/README.md @@ -1,13 +1,20 @@ # rust-analyzer -At its core, rust-analyzer is a **library** for semantic analysis of -Rust code as it changes over time. This manual focuses on a specific -usage of the library -- running it as part of a server that implements +rust-analyzer is a language server that provides IDE functionality for +writing Rust programs. You can use it with any editor that supports the [Language Server -Protocol](https://microsoft.github.io/language-server-protocol/) (LSP). -The LSP allows various code editors, like VS Code, Emacs or Vim, to -implement semantic features like completion or goto definition by -talking to an external language server process. +Protocol](https://microsoft.github.io/language-server-protocol/) (VS +Code, Vim, Emacs, Zed, etc). + +rust-analyzer features include go-to-definition, find-all-references, +refactorings and code completion. rust-analyzer also supports +integrated formatting (with rustfmt) and integrated diagnostics (with +rustc and clippy). + +Internally, rust-analyzer is structured as a set of libraries for +analyzing Rust code. See +[Architecture](https://rust-analyzer.github.io/book/contributing/architecture.html) +for more details. To improve this document, send a pull request: [https://github.com/rust-lang/rust-analyzer](https://github.com/rust-lang/rust-analyzer/blob/master/docs/book/README.md) diff --git a/src/tools/rust-analyzer/docs/book/src/SUMMARY.md b/src/tools/rust-analyzer/docs/book/src/SUMMARY.md index dffdae94a6e86..3fb46d59a4a50 100644 --- a/src/tools/rust-analyzer/docs/book/src/SUMMARY.md +++ b/src/tools/rust-analyzer/docs/book/src/SUMMARY.md @@ -23,3 +23,4 @@ - [Setup](contributing/setup.md) - [Style](contributing/style.md) - [Syntax](contributing/syntax.md) + - [Writing Tests](contributing/testing.md) diff --git a/src/tools/rust-analyzer/docs/book/src/configuration.md b/src/tools/rust-analyzer/docs/book/src/configuration.md index fd94a4221a927..708eecd43561c 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration.md @@ -13,7 +13,7 @@ Vim](./other_editors.md#coc-rust-analyzer) provide `rust-analyzer` specific conf UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`. -For the later category, it might help to know that the initial +For the latter category, it might help to know that the initial configuration is specified as a value of the `initializationOptions` field of the [`InitializeParams` message, in the LSP protocol](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize). @@ -46,6 +46,11 @@ To verify which configuration is actually used by `rust-analyzer`, set config-related messages. Logs should show both the JSON that `rust-analyzer` sees as well as the updated config. +(Work in progress:) It is also possible to place configuration in a +`rust-analyzer.toml` file. It should be located in the project root or in your +user configuration directory (e.g. `~/.config/rust-analyzer/`). This is a work in +progress, many configuration options aren't supported yet. + This is the list of config options `rust-analyzer` supports: {{#include configuration_generated.md}} diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md index 99a30d8f62138..d768993f501fc 100644 --- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md +++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md @@ -610,6 +610,13 @@ The warnings will be indicated by a blue squiggly underline in code and a blue i the `Problems Panel`. +## rust-analyzer.document.symbol.search.excludeLocals {#document.symbol.search.excludeLocals} + +Default: `true` + +Exclude all locals from document symbol search. + + ## rust-analyzer.files.exclude {#files.exclude} Default: `[]` @@ -952,6 +959,17 @@ Default: `"never"` Show enum variant discriminant hints. +## rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows {#inlayHints.expressionAdjustmentHints.disableReborrows} + +Default: `true` + +Disable reborrows in expression adjustments inlay hints. + +Reborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer. + +Note: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed. + + ## rust-analyzer.inlayHints.expressionAdjustmentHints.enable {#inlayHints.expressionAdjustmentHints.enable} Default: `"never"` @@ -1028,6 +1046,8 @@ Default: `25` Maximum length for inlay hints. Set to null to have an unlimited length. +**Note:** This is mostly a hint, and we don't guarantee to strictly follow the limit. + ## rust-analyzer.inlayHints.parameterHints.enable {#inlayHints.parameterHints.enable} @@ -1303,7 +1323,7 @@ tests or binaries. For example, it may be `--release`. Default: ```json [ - "--show-output" + "--nocapture" ] ``` @@ -1360,6 +1380,17 @@ Enables the use of rustfmt's unstable range formatting command for the available on a nightly build. +## rust-analyzer.semanticHighlighting.comments.enable {#semanticHighlighting.comments.enable} + +Default: `true` + +Use semantic tokens for comments. + +In some editors (e.g. vscode) semantic tokens override other highlighting grammars. +By disabling semantic tokens for comments, other grammars can be used to highlight +their contents. + + ## rust-analyzer.semanticHighlighting.doc.comment.inject.enable {#semanticHighlighting.doc.comment.inject.enable} Default: `true` diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/README.md b/src/tools/rust-analyzer/docs/book/src/contributing/README.md index 57c7a9c5996d1..ad2816b18ac14 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/README.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/README.md @@ -276,7 +276,7 @@ There are two sets of people with extra permissions: Feel free to request a review or assign any PR to a reviewer with the relevant expertise to bring the work to their attention. Don't feel pressured to review assigned PRs though. If you don't feel like reviewing for whatever reason, someone else will pick the review up (but please speak up if you don't feel like it)! -* The [rust-lang](https://github.com/rust-lang) team [t-rust-analyzer-contributors]([https://github.com/orgs/rust-analyzer/teams/triage](https://github.com/rust-lang/team/blob/master/teams/rust-analyzer-contributors.toml)). +* The [rust-lang](https://github.com/rust-lang) team [t-rust-analyzer-contributors](https://github.com/rust-lang/team/blob/master/teams/rust-analyzer-contributors.toml). This team has general triaging permissions allowing to label, close and re-open issues. ## Synchronizing subtree changes diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/guide.md b/src/tools/rust-analyzer/docs/book/src/contributing/guide.md index 2a2a39af2641c..d06840368ccbf 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/guide.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/guide.md @@ -235,7 +235,7 @@ of type `V`. Queries come in two basic varieties: intelligently) when we can re-use these memoized values and when we have to recompute them. -For further discussion, its important to understand one bit of "fairly +For further discussion, it's important to understand one bit of "fairly intelligently". Suppose we have two functions, `f1` and `f2`, and one input, `z`. We call `f1(X)` which in turn calls `f2(Y)` which inspects `i(Z)`. `i(Z)` returns some value `V1`, `f2` uses that and returns `R1`, `f1` uses that and diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md index 8c06f33a9f7bf..91154b6f1c87d 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/lsp-extensions.md @@ -455,7 +455,7 @@ interface TestItem { // A human readable name for this test label: string; // The kind of this test item. Based on the kind, - // an icon is chosen by the editor. + // an icon is chosen by the editor. kind: "package" | "module" | "test"; // True if this test may have children not available eagerly canResolveChildren: boolean; @@ -467,7 +467,7 @@ interface TestItem { // like debugging, this field is useful. // Note that this field includes some information about label and location as well, but // those exist just for keeping things in sync with other methods of running runnables - // (for example using one consistent name in the vscode's launch.json) so for any propose + // (for example using one consistent name in the vscode's launch.json) so for any purpose // other than running tests this field should not be used. runnable?: Runnable | undefined; }; @@ -475,11 +475,11 @@ interface TestItem { interface DiscoverTestResults { // The discovered tests. tests: TestItem[]; - // For each test which its id is in this list, the response + // For each test whose id is in this list, the response // contains all tests that are children of this test, and // client should remove old tests not included in the response. scope: string[] | undefined; - // For each file which its uri is in this list, the response + // For each file whose uri is in this list, the response // contains all tests that are located in this file, and // client should remove old tests not included in the response. scopeFile: lc.TextDocumentIdentifier[] | undefined; @@ -491,7 +491,7 @@ interface DiscoverTestResults { **Notification:** `DiscoverTestResults` This notification is sent from the server to the client when the -server detect changes in the existing tests. The `DiscoverTestResults` is +server detects changes in the existing tests. The `DiscoverTestResults` is the same as the one in `experimental/discoverTest` response. **Method:** `experimental/runTest` @@ -527,7 +527,7 @@ after this. This notification is sent from the client to the server when the user is no longer interested in the test results. The server should clean up its resources and send -a `experimental/endRunTest` when is done. +a `experimental/endRunTest` when it is done. **Method:** `experimental/changeTestState` @@ -648,8 +648,8 @@ interface ServerStatusParams { ``` This notification is sent from server to client. -The client can use it to display *persistent* status to the user (in modline). -It is similar to the `showMessage`, but is intended for stares rather than point-in-time events. +The client can use it to display *persistent* status to the user (in the mode line). +It is similar to the `showMessage`, but is intended for status rather than point-in-time events. Note that this functionality is intended primarily to inform the end user about the state of the server. In particular, it's valid for the client to completely ignore this extension. @@ -1070,13 +1070,13 @@ export interface RecursiveMemoryLayoutNode = { size: number; /// Alignment of the type in bytes alignment: number; - /// Offset of the type relative to its parent (or 0 if its the root) + /// Offset of the type relative to its parent (or 0 if it's the root) offset: number; - /// Index of the node's parent (or -1 if its the root) + /// Index of the node's parent (or -1 if it's the root) parent_idx: number; /// Index of the node's children (or -1 if it does not have children) children_start: number; - /// Number of child nodes (unspecified it does not have children) + /// Number of child nodes (unspecified if it does not have children) children_len: number; }; diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/style.md b/src/tools/rust-analyzer/docs/book/src/contributing/style.md index 746f3eb132117..fe09fb6c2fd52 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/style.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/style.md @@ -101,7 +101,7 @@ Including a description and GIF suitable for the changelog means less work for t ## Clippy -We use Clippy to improve the code, but if some lints annoy you, allow them in the [Cargo.toml](../../Cargo.toml) [workspace.lints.clippy] section. +We use Clippy to improve the code, but if some lints annoy you, allow them in the [Cargo.toml](https://github.com/rust-lang/rust-analyzer/blob/master/Cargo.toml) [workspace.lints.clippy] section. # Code diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/syntax.md b/src/tools/rust-analyzer/docs/book/src/contributing/syntax.md index 3dcd430cea5d5..93eed7228d05f 100644 --- a/src/tools/rust-analyzer/docs/book/src/contributing/syntax.md +++ b/src/tools/rust-analyzer/docs/book/src/contributing/syntax.md @@ -192,7 +192,7 @@ Modeling this with immutable trees is possible, but annoying. A function green tree is not super-convenient to use. The biggest problem is accessing parents (there are no parent pointers!). -But there are also "identify" issues. +But there are also "identity" issues. Let's say you want to write a code which builds a list of expressions in a file: `fn collect_expressions(file: GreenNode) -> HashSet`. For the input like diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/testing.md b/src/tools/rust-analyzer/docs/book/src/contributing/testing.md new file mode 100644 index 0000000000000..ccee9b847b6e1 --- /dev/null +++ b/src/tools/rust-analyzer/docs/book/src/contributing/testing.md @@ -0,0 +1,106 @@ +rust-analyzer's testing is based on *snapshot tests*: a test is a piece of input text, usually a Rust code, and some output text. There is then some testing helper that runs the feature on the input text and compares the result to the output text. + +rust-analyzer uses a combination of the crate [`expect-test`](https://docs.rs/expect-test) and a custom testing framework. + +This all may sound too abstract, so let's demonstrate with an example. + +Type inference tests are located at `crates/hir-ty/src/tests`. There are various test helpers you can use. One of the simplest is `check_no_mismatches()`: it is given a piece of Rust code (we'll talk more about Rust code in tests later) and asserts that there are no type mismatches in it, that is, one type was expected but another was found (for example, `let x: () = 1` is a type mismatch). Note that we determine type mismatches via rust-analyzer's own analysis, not via the compiler (this is what we are testing, after all), which means there are often missed mismatches and sometimes bogus ones as well. + +For example, the following test will fail: +```rust +#[test] +fn this_will_fail() { + check_no_mismatches( + r#" +fn main() { + let x: () = 1; +} + "#, + ); +} +``` + +Sometimes we want to check more that there are no type mismatches. For that we use other helpers. For example, often we want to assert that the type of some expression is some specific type. For that we use the `check_types()` function. It takes a Rust code string with custom annotation, that are common in our test suite. The general scheme of annotation is: + + - `$0` marks a position. What to do with it is determined by the testing helper. Commonly it denotes the cursor position in IDE tests (for example, hover). + - `$0...$0` marks a range, commonly a selection in IDE tests. + - `^...^`, commonly seen in a comment (`// ^^^^`), labels the line above. For example, the following will attach the label `hey` to the range of the variable name `cool`: + + ```rust + let cool; + // ^^^^ hey + ``` + +`check_types()` uses labels to assert type: when you attach a label to a range, `check_types()` assert that the type of this range will be what written in the label. + +It's all too abstract without an example: +```rust +#[test] +fn my_test() { + check_types( + r#" +fn main() { + let x = 1; + // ^ i32 +} + "#, + ); +} +``` +Here, we assert that the type of the variable `x` is `i32`. Which is true, of course, so the test will pass. + +Oftentimes it is convenient to assert the types of all of the expressions at once, and that brings us to the last kind of test. It uses `expect-test` to match an output text: +```rust +#[test] +fn my_test() { + check_infer( + r#" +fn main() { + let x = 1; +} + "#, + expect![[r#" + 10..28 '{ ...= 1; }': () + 20..21 'x': i32 + 24..25 '1': i32 + "#]], + ); +} +``` +The text inside the `expect![[]]` is determined by the helper, `check_infer()` in this case. For `check_infer()`, each line is a range in the source code (the range is counted in bytes and the source is trimmed, indentation is stripped), next to it there is the text in that range, or some part of it with `...` if it's too long, and finally comes the type of that range. + +The important feature of `expect-test` is that it allows easy update of the expectation. Say you changed something in the code, maybe fixed a bug, and the output in `expect![[]]` needs to change. Or maybe you are writing it from scratch. Writing it by hand is very tedious and prone to mistakes. But `expect-trait` has a magic. You can set the environment variable `UPDATE_EXPECT=1`, then run the test, and it will update automatically! Some editors (e.g. VSCode) make it even more convenient: on them, on the top of every test that uses `expect-test`, next to the usual `Run | Debug` buttons, rust-analyzer also shows an `Update Expect` button. Clicking it will run that test in updating mode. + +## Rust code in the tests + +The first thing that you probably already noticed is that the Rust code in the tests is syntax highlighted! In fact, it even uses semantic highlighting. rust-analyzer highlights strings "as if" they contain Rust code if they are passed to a parameter marked `#[rust_analyzer::rust_fixture]`, and rust-analyzer test helpers do that (in fact, this was designed for them). + +The syntax highlighting is very important, not just because it's nice to the eye: it's very easy to make mistakes in test code, and debugging that can be very hard. Often the test will just fail, printing an `{unknown}` type, and you'll have no clue what's going wrong. The syntax is the clue; if something isn't highlighted correctly, that probably means there is an error (there is one exception to this, which we'll discuss later). You can even set the semantic highlighting tag `unresolved_reference` to e.g. red, so you will see such things clearly. + +Still, often you won't know what's going wrong. Why you can't fix the test, or worse, you expect it to fail but it doesn't. You can try the code on a real IDE to be sure it works. Later we'll give some tips to fix the test. + +### The fixture + +The Rust code in a test is not, a fact, a single Rust file. It has a mini-language that allows you to express multiple files, multiple crates, different configs, and more. All options are documented in `crates/test-utils/src/fixture.rs`, but here are some of the common ones: + + - `//- minicore: flag1, flag2, ...`. This is by far the most common flag. Tests in rust-analyzer don't have access by default to any other type - not `Option`, not `Iterator`, not even `Sized`. This flag allows you to include parts of the `crates/test-utils/src/minicore.rs` file, which mimics `core`. All possible flags are listed at the top of `minicore` along with the flags they imply, then later you can see by `// region:flag` and `// endregion:flag` what code each flag enables. + - `// /path/to/file.rs crate:crate deps:dep_a,dep_b`. The first component is the filename of the code that follows (until the next file). It is required, but only if you supply this line. Other components in this line are optional. They include `crate:crate_name`, to start a new crate, or `deps:dep_a,dep_b`, to declare dependencies between crates. You can also declare modules as usual in Rust - just name your paths `/foo.rs` or `/foo/mod.rs`, declare `mod foo` and that's it! + +So the following snippet: +```rust +//- minicore: sized, fn +// /lib.rs crate:foo +pub mod bar; +// /bar.rs +pub struct Bar; +// /main.rs crate:main deps:foo +use foo::Bar; +``` +Declares two crates `foo` and `main` where `main` depends on `foo`, with dependency in `Sized` and the `FnX` traits from `core`, and a module of `foo` called `bar`. + +And as promised, here are some tips to make your test work: + + - If you use some type/trait, you must *always* include it in `minicore`. Note - not all types from core/std are available there, you can add new (under flags) if you need. And import them if they are not in the prelude. + - If you use unsized types (`dyn Trait`/slices), you may want to include some or all of the following `minicore` flags: `sized`, `unsize`, `coerce_unsized`, `dispatch_from_dyn`. + - If you use closures, consider including the `fn` minicore flag. Async closures need the `async_fn` flag. + - `sized` is commonly needed, consider adding it if you're stuck. diff --git a/src/tools/rust-analyzer/docs/book/src/faq.md b/src/tools/rust-analyzer/docs/book/src/faq.md index c87203309011b..8c143ab949357 100644 --- a/src/tools/rust-analyzer/docs/book/src/faq.md +++ b/src/tools/rust-analyzer/docs/book/src/faq.md @@ -5,3 +5,12 @@ rust-analyzer fails to resolve `None`, and thinks you are binding to a variable named `None`. That's usually a sign of a corrupted sysroot. Try removing and re-installing it: `rustup component remove rust-src` then `rustup component install rust-src`. + +### Rust Analyzer and Cargo compete over the build lock + +Rust Analyzer invokes Cargo in the background, and it can thus block manually executed +`cargo` commands from making progress (or vice-versa). In some cases, this can also cause +unnecessary recompilations caused by cache thrashing. To avoid this, you can configure +Rust Analyzer to use a [different target directory](./configuration.md#cargo.targetDir). +This will allow both the IDE and Cargo to make progress independently, at the cost of +increased disk space usage caused by the duplicated artifact directories. diff --git a/src/tools/rust-analyzer/editors/code/icon.png b/src/tools/rust-analyzer/editors/code/icon.png index 072090c6f4a1f..29a9679039010 100644 Binary files a/src/tools/rust-analyzer/editors/code/icon.png and b/src/tools/rust-analyzer/editors/code/icon.png differ diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json index 534c24be52e8d..e35a159cbc3fd 100644 --- a/src/tools/rust-analyzer/editors/code/package-lock.json +++ b/src/tools/rust-analyzer/editors/code/package-lock.json @@ -26,7 +26,7 @@ "@typescript-eslint/eslint-plugin": "^8.25.0", "@typescript-eslint/parser": "^8.25.0", "@vscode/test-electron": "^2.4.1", - "@vscode/vsce": "^3.2.2", + "@vscode/vsce": "^3.6.0", "esbuild": "^0.25.0", "eslint": "^9.21.0", "eslint-config-prettier": "^10.0.2", @@ -41,6 +41,23 @@ "vscode": "^1.93.0" } }, + "node_modules/@azu/format-text": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@azu/format-text/-/format-text-1.0.2.tgz", + "integrity": "sha512-Swi4N7Edy1Eqq82GxgEECXSSLyn6GOb5htRFPzBDdUkECGXtlf12ynO5oJSpWKPwCaUssOu7NfhDcCWpIC6Ywg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@azu/style-format": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azu/style-format/-/style-format-1.0.1.tgz", + "integrity": "sha512-AHcTojlNBdD/3/KxIKlg8sxIWHfOtQszLvOpagLTO+bjC3u7SAszu1lf//u7JJC50aUSH+BVWDD/KvaA6Gfn5g==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "@azu/format-text": "^1.0.1" + } + }, "node_modules/@azure/abort-controller": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", @@ -212,6 +229,31 @@ "node": ">=16" } }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", @@ -947,6 +989,217 @@ "node": ">= 8" } }, + "node_modules/@secretlint/config-creator": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/config-creator/-/config-creator-10.2.2.tgz", + "integrity": "sha512-BynOBe7Hn3LJjb3CqCHZjeNB09s/vgf0baBaHVw67w7gHF0d25c3ZsZ5+vv8TgwSchRdUCRrbbcq5i2B1fJ2QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/types": "^10.2.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/config-loader": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/config-loader/-/config-loader-10.2.2.tgz", + "integrity": "sha512-ndjjQNgLg4DIcMJp4iaRD6xb9ijWQZVbd9694Ol2IszBIbGPPkwZHzJYKICbTBmh6AH/pLr0CiCaWdGJU7RbpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/profiler": "^10.2.2", + "@secretlint/resolver": "^10.2.2", + "@secretlint/types": "^10.2.2", + "ajv": "^8.17.1", + "debug": "^4.4.1", + "rc-config-loader": "^4.1.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/config-loader/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@secretlint/config-loader/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@secretlint/core": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/core/-/core-10.2.2.tgz", + "integrity": "sha512-6rdwBwLP9+TO3rRjMVW1tX+lQeo5gBbxl1I5F8nh8bgGtKwdlCMhMKsBWzWg1ostxx/tIG7OjZI0/BxsP8bUgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/profiler": "^10.2.2", + "@secretlint/types": "^10.2.2", + "debug": "^4.4.1", + "structured-source": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/formatter": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/formatter/-/formatter-10.2.2.tgz", + "integrity": "sha512-10f/eKV+8YdGKNQmoDUD1QnYL7TzhI2kzyx95vsJKbEa8akzLAR5ZrWIZ3LbcMmBLzxlSQMMccRmi05yDQ5YDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/resolver": "^10.2.2", + "@secretlint/types": "^10.2.2", + "@textlint/linter-formatter": "^15.2.0", + "@textlint/module-interop": "^15.2.0", + "@textlint/types": "^15.2.0", + "chalk": "^5.4.1", + "debug": "^4.4.1", + "pluralize": "^8.0.0", + "strip-ansi": "^7.1.0", + "table": "^6.9.0", + "terminal-link": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/formatter/node_modules/chalk": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.5.0.tgz", + "integrity": "sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@secretlint/node": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/node/-/node-10.2.2.tgz", + "integrity": "sha512-eZGJQgcg/3WRBwX1bRnss7RmHHK/YlP/l7zOQsrjexYt6l+JJa5YhUmHbuGXS94yW0++3YkEJp0kQGYhiw1DMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/config-loader": "^10.2.2", + "@secretlint/core": "^10.2.2", + "@secretlint/formatter": "^10.2.2", + "@secretlint/profiler": "^10.2.2", + "@secretlint/source-creator": "^10.2.2", + "@secretlint/types": "^10.2.2", + "debug": "^4.4.1", + "p-map": "^7.0.3" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/profiler": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/profiler/-/profiler-10.2.2.tgz", + "integrity": "sha512-qm9rWfkh/o8OvzMIfY8a5bCmgIniSpltbVlUVl983zDG1bUuQNd1/5lUEeWx5o/WJ99bXxS7yNI4/KIXfHexig==", + "dev": true, + "license": "MIT" + }, + "node_modules/@secretlint/resolver": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/resolver/-/resolver-10.2.2.tgz", + "integrity": "sha512-3md0cp12e+Ae5V+crPQYGd6aaO7ahw95s28OlULGyclyyUtf861UoRGS2prnUrKh7MZb23kdDOyGCYb9br5e4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@secretlint/secretlint-formatter-sarif": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-formatter-sarif/-/secretlint-formatter-sarif-10.2.2.tgz", + "integrity": "sha512-ojiF9TGRKJJw308DnYBucHxkpNovDNu1XvPh7IfUp0A12gzTtxuWDqdpuVezL7/IP8Ua7mp5/VkDMN9OLp1doQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-sarif-builder": "^3.2.0" + } + }, + "node_modules/@secretlint/secretlint-rule-no-dotenv": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-rule-no-dotenv/-/secretlint-rule-no-dotenv-10.2.2.tgz", + "integrity": "sha512-KJRbIShA9DVc5Va3yArtJ6QDzGjg3PRa1uYp9As4RsyKtKSSZjI64jVca57FZ8gbuk4em0/0Jq+uy6485wxIdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/types": "^10.2.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/secretlint-rule-preset-recommend": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-rule-preset-recommend/-/secretlint-rule-preset-recommend-10.2.2.tgz", + "integrity": "sha512-K3jPqjva8bQndDKJqctnGfwuAxU2n9XNCPtbXVI5JvC7FnQiNg/yWlQPbMUlBXtBoBGFYp08A94m6fvtc9v+zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/source-creator": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/source-creator/-/source-creator-10.2.2.tgz", + "integrity": "sha512-h6I87xJfwfUTgQ7irWq7UTdq/Bm1RuQ/fYhA3dtTIAop5BwSFmZyrchph4WcoEvbN460BWKmk4RYSvPElIIvxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/types": "^10.2.2", + "istextorbinary": "^9.5.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/types": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/types/-/types-10.2.2.tgz", + "integrity": "sha512-Nqc90v4lWCXyakD6xNyNACBJNJ0tNCwj2WNk/7ivyacYHxiITVgmLUFXTBOeCdy79iz6HtN9Y31uw/jbLrdOAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@stylistic/eslint-plugin": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.1.0.tgz", @@ -984,6 +1237,136 @@ "eslint": ">=9.0.0" } }, + "node_modules/@textlint/ast-node-types": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-15.2.1.tgz", + "integrity": "sha512-20fEcLPsXg81yWpApv4FQxrZmlFF/Ta7/kz1HGIL+pJo5cSTmkc+eCki3GpOPZIoZk0tbJU8hrlwUb91F+3SNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/linter-formatter": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@textlint/linter-formatter/-/linter-formatter-15.2.1.tgz", + "integrity": "sha512-oollG/BHa07+mMt372amxHohteASC+Zxgollc1sZgiyxo4S6EuureV3a4QIQB0NecA+Ak3d0cl0WI/8nou38jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azu/format-text": "^1.0.2", + "@azu/style-format": "^1.0.1", + "@textlint/module-interop": "15.2.1", + "@textlint/resolver": "15.2.1", + "@textlint/types": "15.2.1", + "chalk": "^4.1.2", + "debug": "^4.4.1", + "js-yaml": "^3.14.1", + "lodash": "^4.17.21", + "pluralize": "^2.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "table": "^6.9.0", + "text-table": "^0.2.0" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/linter-formatter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/pluralize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-2.0.0.tgz", + "integrity": "sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/linter-formatter/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@textlint/module-interop": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-15.2.1.tgz", + "integrity": "sha512-b/C/ZNrm05n1ypymDknIcpkBle30V2ZgE3JVqQlA9PnQV46Ky510qrZk6s9yfKgA3m1YRnAw04m8xdVtqjq1qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/resolver": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@textlint/resolver/-/resolver-15.2.1.tgz", + "integrity": "sha512-FY3aK4tElEcOJVUsaMj4Zro4jCtKEEwUMIkDL0tcn6ljNcgOF7Em+KskRRk/xowFWayqDtdz5T3u7w/6fjjuJQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/types": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/@textlint/types/-/types-15.2.1.tgz", + "integrity": "sha512-zyqNhSatK1cwxDUgosEEN43hFh3WCty9Zm2Vm3ogU566IYegifwqN54ey/CiRy/DiO4vMcFHykuQnh2Zwp6LLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@textlint/ast-node-types": "15.2.1" + } + }, "node_modules/@tsconfig/strictest": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.5.tgz", @@ -1015,6 +1398,20 @@ "undici-types": "~6.20.0" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/vscode": { "version": "1.93.0", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.93.0.tgz", @@ -1220,16 +1617,20 @@ } }, "node_modules/@vscode/vsce": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.2.tgz", - "integrity": "sha512-4TqdUq/yKlQTHcQMk/DamR632bq/+IJDomSbexOMee/UAYWqYm0XHWA6scGslsCpzY+sCWEhhl0nqdOB0XW1kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.6.0.tgz", + "integrity": "sha512-u2ZoMfymRNJb14aHNawnXJtXHLXDVKc1oKZaH4VELKT/9iWKRVgtQOdwxCgtwSxJoqYvuK4hGlBWQJ05wxADhg==", "dev": true, "license": "MIT", "dependencies": { "@azure/identity": "^4.1.0", + "@secretlint/node": "^10.1.1", + "@secretlint/secretlint-formatter-sarif": "^10.1.1", + "@secretlint/secretlint-rule-no-dotenv": "^10.1.1", + "@secretlint/secretlint-rule-preset-recommend": "^10.1.1", "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", - "chalk": "^2.4.2", + "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.9", "cockatiel": "^3.1.2", "commander": "^12.1.0", @@ -1243,6 +1644,7 @@ "minimatch": "^3.0.3", "parse-semver": "^1.1.1", "read": "^1.0.7", + "secretlint": "^10.1.1", "semver": "^7.5.2", "tmp": "^0.2.3", "typed-rest-client": "^1.8.4", @@ -1486,6 +1888,22 @@ "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==", "license": "MIT" }, + "node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -1500,16 +1918,18 @@ } }, "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/argparse": { @@ -1519,6 +1939,16 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1564,6 +1994,22 @@ ], "license": "MIT" }, + "node_modules/binaryextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-6.11.0.tgz", + "integrity": "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/bl": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", @@ -1598,6 +2044,13 @@ "dev": true, "license": "ISC" }, + "node_modules/boundary": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/boundary/-/boundary-2.0.0.tgz", + "integrity": "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/brace-expansion": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", @@ -1720,18 +2173,20 @@ } }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/cheerio": { @@ -1845,39 +2300,6 @@ "node": ">=8" } }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/cliui/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1938,20 +2360,21 @@ } }, "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/combined-stream": { @@ -2469,9 +2892,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2685,6 +3108,23 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/editions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/editions/-/editions-6.22.0.tgz", + "integrity": "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "version-range": "^4.15.0" + }, + "engines": { + "ecmascript": ">= es5", + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -2730,6 +3170,19 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2829,16 +3282,6 @@ "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint": { "version": "9.21.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz", @@ -2964,22 +3407,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2991,43 +3418,6 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, "node_modules/eslint/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3041,16 +3431,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3064,19 +3444,6 @@ "node": "*" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/espree": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", @@ -3095,6 +3462,20 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", @@ -3213,6 +3594,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", @@ -3360,6 +3758,21 @@ "license": "MIT", "optional": true }, + "node_modules/fs-extra": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", + "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3492,6 +3905,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -3505,6 +3949,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3513,13 +3964,13 @@ "license": "MIT" }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/has-symbols": { @@ -3702,6 +4153,19 @@ "node": ">=0.8.19" } }, + "node_modules/index-to-position": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.1.0.tgz", + "integrity": "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -3872,6 +4336,24 @@ "dev": true, "license": "ISC" }, + "node_modules/istextorbinary": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-9.5.0.tgz", + "integrity": "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "binaryextensions": "^6.11.0", + "editions": "^6.21.0", + "textextensions": "^6.11.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/jackspeak": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz", @@ -3897,6 +4379,13 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3931,6 +4420,19 @@ "dev": true, "license": "MIT" }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -3938,6 +4440,19 @@ "dev": true, "license": "MIT" }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -4103,6 +4618,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -4159,6 +4681,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", @@ -4430,12 +4959,61 @@ "license": "MIT", "optional": true }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/node-sarif-builder": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.2.0.tgz", + "integrity": "sha512-kVIOdynrF2CRodHZeP/97Rh1syTUHBNiw17hUCIVhlhEsWlfJm19MuO56s4MdKbr22xWx6mzMnNAgXzVlIYM9Q==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -4661,6 +5239,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -4688,6 +5279,24 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-semver": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", @@ -4795,6 +5404,19 @@ "node": "20 || >=22" } }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -4802,6 +5424,13 @@ "dev": true, "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", @@ -4815,6 +5444,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", @@ -4962,6 +5601,19 @@ "rc": "cli.js" } }, + "node_modules/rc-config-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-4.1.3.tgz", + "integrity": "sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "js-yaml": "^4.1.0", + "json5": "^2.2.2", + "require-from-string": "^2.0.2" + } + }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -4986,6 +5638,39 @@ "node": ">=0.8" } }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/readable-stream": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", @@ -5018,6 +5703,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -5146,6 +5841,28 @@ "dev": true, "license": "ISC" }, + "node_modules/secretlint": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/secretlint/-/secretlint-10.2.2.tgz", + "integrity": "sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/config-creator": "^10.2.2", + "@secretlint/formatter": "^10.2.2", + "@secretlint/node": "^10.2.2", + "@secretlint/profiler": "^10.2.2", + "debug": "^4.4.1", + "globby": "^14.1.0", + "read-pkg": "^9.0.1" + }, + "bin": { + "secretlint": "bin/secretlint.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/semver": { "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", @@ -5326,6 +6043,80 @@ "simple-concat": "^1.0.0" } }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/stdin-discarder": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", @@ -5487,23 +6278,136 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/structured-source": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-4.0.0.tgz", + "integrity": "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boundary": "^2.0.0" + } + }, "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dev": true, "license": "MIT", "optional": true, @@ -5587,10 +6491,50 @@ "node": ">= 6" } }, + "node_modules/terminal-link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-4.0.0.tgz", + "integrity": "sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "supports-hyperlinks": "^3.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/textextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-6.11.0.tgz", + "integrity": "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.4.tgz", + "integrity": "sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==", "dev": true, "license": "MIT", "engines": { @@ -5667,6 +6611,19 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-rest-client": { "version": "1.8.11", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", @@ -5747,6 +6704,29 @@ "dev": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5781,6 +6761,30 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/version-range": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.15.0.tgz", + "integrity": "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==", + "dev": true, + "license": "Artistic-2.0", + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", @@ -5928,42 +6932,6 @@ "node": ">=8" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json index 470db244f14bd..70687238c854a 100644 --- a/src/tools/rust-analyzer/editors/code/package.json +++ b/src/tools/rust-analyzer/editors/code/package.json @@ -63,7 +63,7 @@ "@typescript-eslint/eslint-plugin": "^8.25.0", "@typescript-eslint/parser": "^8.25.0", "@vscode/test-electron": "^2.4.1", - "@vscode/vsce": "^3.2.2", + "@vscode/vsce": "^3.6.0", "esbuild": "^0.25.0", "eslint": "^9.21.0", "eslint-config-prettier": "^10.0.2", @@ -1585,6 +1585,16 @@ } } }, + { + "title": "Document", + "properties": { + "rust-analyzer.document.symbol.search.excludeLocals": { + "markdownDescription": "Exclude all locals from document symbol search.", + "default": true, + "type": "boolean" + } + } + }, { "title": "Files", "properties": { @@ -1999,19 +2009,30 @@ "markdownDescription": "How imports should be grouped into use statements.", "default": "crate", "type": "string", - "enum": [ - "preserve", - "crate", - "module", - "item", - "one" - ], - "enumDescriptions": [ - "Do not change the granularity of any imports and preserve the original structure written by the developer.", - "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.", - "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.", - "Flatten imports so that each has its own use statement.", - "Merge all imports into a single use statement as long as they have the same visibility and attributes." + "anyOf": [ + { + "enum": [ + "crate", + "module", + "item", + "one" + ], + "enumDescriptions": [ + "Merge imports from the same crate into a single use statement. Conversely, imports from different crates are split into separate statements.", + "Merge imports from the same module into a single use statement. Conversely, imports from different modules are split into separate statements.", + "Flatten imports so that each has its own use statement.", + "Merge all imports into a single use statement as long as they have the same visibility and attributes." + ] + }, + { + "enum": [ + "preserve" + ], + "enumDescriptions": [ + "Deprecated - unless `enforceGranularity` is `true`, the style of the current file is preferred over this setting. Behaves like `item`." + ], + "deprecated": true + } ] } } @@ -2199,6 +2220,16 @@ } } }, + { + "title": "Inlay Hints", + "properties": { + "rust-analyzer.inlayHints.expressionAdjustmentHints.disableReborrows": { + "markdownDescription": "Disable reborrows in expression adjustments inlay hints.\n\nReborrows are a pair of a builtin deref then borrow, i.e. `&*`. They are inserted by the compiler but are mostly useless to the programmer.\n\nNote: if the deref is not builtin (an overloaded deref), or the borrow is `&raw const`/`&raw mut`, they are not removed.", + "default": true, + "type": "boolean" + } + } + }, { "title": "Inlay Hints", "properties": { @@ -2335,7 +2366,7 @@ "title": "Inlay Hints", "properties": { "rust-analyzer.inlayHints.maxLength": { - "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.", + "markdownDescription": "Maximum length for inlay hints. Set to null to have an unlimited length.\n\n**Note:** This is mostly a hint, and we don't guarantee to strictly follow the limit.", "default": 25, "type": [ "null", @@ -2769,7 +2800,7 @@ "rust-analyzer.runnables.extraTestBinaryArgs": { "markdownDescription": "Additional arguments to be passed through Cargo to launched tests, benchmarks, or\ndoc-tests.\n\nUnless the launched target uses a\n[custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),\nthey will end up being interpreted as options to\n[`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).", "default": [ - "--show-output" + "--nocapture" ], "type": "array", "items": { @@ -2830,6 +2861,16 @@ } } }, + { + "title": "Semantic Highlighting", + "properties": { + "rust-analyzer.semanticHighlighting.comments.enable": { + "markdownDescription": "Use semantic tokens for comments.\n\nIn some editors (e.g. vscode) semantic tokens override other highlighting grammars.\nBy disabling semantic tokens for comments, other grammars can be used to highlight\ntheir contents.", + "default": true, + "type": "boolean" + } + } + }, { "title": "Semantic Highlighting", "properties": { diff --git a/src/tools/rust-analyzer/josh-sync.toml b/src/tools/rust-analyzer/josh-sync.toml index 51ff0d71e71a9..a12cfa1b5cbd5 100644 --- a/src/tools/rust-analyzer/josh-sync.toml +++ b/src/tools/rust-analyzer/josh-sync.toml @@ -1,2 +1,6 @@ repo = "rust-analyzer" filter = ":rev(55d9a533b309119c8acd13061581b43ae8840823:prefix=src/tools/rust-analyzer):/src/tools/rust-analyzer" + +[[post-pull]] +cmd = ["cargo", "fmt"] +commit-message = "Format code" diff --git a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml index 1fc1da50a0a03..f56a0de616376 100644 --- a/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml +++ b/src/tools/rust-analyzer/lib/lsp-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lsp-server" -version = "0.7.8" +version = "0.7.9" description = "Generic LSP server scaffold." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" @@ -16,9 +16,9 @@ crossbeam-channel.workspace = true [dev-dependencies] lsp-types = "=0.95" ctrlc = "3.4.7" -anyhow.workspace = true +anyhow.workspace = true rustc-hash.workspace = true -toolchain.workspace = true +toolchain.workspace = true [lints] workspace = true diff --git a/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs b/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs index 399d674e41d25..305008e69ae1a 100644 --- a/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs +++ b/src/tools/rust-analyzer/lib/lsp-server/src/msg.rs @@ -84,9 +84,9 @@ pub struct Response { // request id. We fail deserialization in that case, so we just // make this field mandatory. pub id: RequestId, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none", default)] pub result: Option, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none", default)] pub error: Option, } @@ -94,7 +94,7 @@ pub struct Response { pub struct ResponseError { pub code: i32, pub message: String, - #[serde(skip_serializing_if = "Option::is_none")] + #[serde(skip_serializing_if = "Option::is_none", default)] pub data: Option, } @@ -175,7 +175,7 @@ impl Message { let msg = match serde_json::from_str(&text) { Ok(msg) => msg, Err(e) => { - return Err(invalid_data!("malformed LSP payload: {:?}", e)); + return Err(invalid_data!("malformed LSP payload `{e:?}`: {text:?}")); } }; diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version index 2178caf63968a..c9529fde2363e 100644 --- a/src/tools/rust-analyzer/rust-version +++ b/src/tools/rust-analyzer/rust-version @@ -1 +1 @@ -733dab558992d902d6d17576de1da768094e2cf3 +fb24b04b096a980bffd80154f6aba22fd07cb3d9 diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index 824b38fc872d8..9bd87a7ef5fe0 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -1081,7 +1081,6 @@ fn extract_struct_traits(ast: &mut AstSrc) { "Enum", "Variant", "Trait", - "TraitAlias", "Module", "Static", "Const", diff --git a/src/tools/rust-analyzer/xtask/src/install.rs b/src/tools/rust-analyzer/xtask/src/install.rs index f0cc445dfa23f..b794f53e761e9 100644 --- a/src/tools/rust-analyzer/xtask/src/install.rs +++ b/src/tools/rust-analyzer/xtask/src/install.rs @@ -145,12 +145,12 @@ fn install_server(sh: &Shell, opts: ServerOpt) -> anyhow::Result<()> { ); if let Some(train_crate) = opts.pgo { + let target = detect_target(sh); let build_cmd = cmd!( sh, - "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --profile={profile} --locked --features force-always-assert {features...}" + "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target} --profile={profile} --locked --features force-always-assert {features...}" ); - let target = detect_target(sh); let profile = crate::pgo::gather_pgo_profile(sh, build_cmd, &target, train_crate)?; install_cmd = crate::pgo::apply_pgo_to_cmd(install_cmd, &profile); } diff --git a/src/tools/rust-analyzer/xtask/src/metrics.rs b/src/tools/rust-analyzer/xtask/src/metrics.rs index 6ff6a1b15310a..fd4b600b03470 100644 --- a/src/tools/rust-analyzer/xtask/src/metrics.rs +++ b/src/tools/rust-analyzer/xtask/src/metrics.rs @@ -16,13 +16,16 @@ type Unit = String; impl flags::Metrics { pub(crate) fn run(self, sh: &Shell) -> anyhow::Result<()> { let mut metrics = Metrics::new(sh)?; - if !Path::new("./target/rustc-perf").exists() { - sh.create_dir("./target/rustc-perf")?; - cmd!(sh, "git clone https://github.com/rust-lang/rustc-perf.git ./target/rustc-perf") - .run()?; + if !Path::new("./target/metrics/rustc-perf").exists() { + sh.create_dir("./target/metrics/rustc-perf")?; + cmd!( + sh, + "git clone https://github.com/rust-lang/rustc-perf.git ./target/metrics/rustc-perf" + ) + .run()?; } { - let _d = sh.push_dir("./target/rustc-perf"); + let _d = sh.push_dir("./target/metrics/rustc-perf"); let revision = &metrics.perf_revision; cmd!(sh, "git reset --hard {revision}").run()?; } @@ -88,11 +91,12 @@ impl Metrics { cmd!( sh, - "git clone --depth=1 --branch 1.76.0 https://github.com/rust-lang/rust.git --single-branch" + "git clone --depth=1 --branch 1.76.0 https://github.com/rust-lang/rust.git --single-branch ./target/metrics/rust" ) .run()?; - let output = cmd!(sh, "./target/release/rust-analyzer rustc-tests ./rust").read()?; + let output = + cmd!(sh, "./target/release/rust-analyzer rustc-tests ./target/metrics/rust").read()?; for (metric, value, unit) in parse_metrics(&output) { self.report(metric, value, unit.into()); } @@ -106,7 +110,7 @@ impl Metrics { self.measure_analysis_stats_path( sh, bench, - &format!("./target/rustc-perf/collector/compile-benchmarks/{bench}"), + &format!("./target/metrics/rustc-perf/collector/compile-benchmarks/{bench}"), ) } fn measure_analysis_stats_path( @@ -156,7 +160,7 @@ struct Host { impl Metrics { fn new(sh: &Shell) -> anyhow::Result { - let host = Host::new(sh)?; + let host = Host::new(sh).unwrap_or_else(|_| Host::unknown()); let timestamp = SystemTime::now(); let revision = cmd!(sh, "git rev-parse HEAD").read()?; let perf_revision = "a584462e145a0c04760fd9391daefb4f6bd13a99".into(); @@ -187,9 +191,13 @@ impl Metrics { } impl Host { + fn unknown() -> Host { + Host { os: "unknown".into(), cpu: "unknown".into(), mem: "unknown".into() } + } + fn new(sh: &Shell) -> anyhow::Result { if cfg!(not(target_os = "linux")) { - return Ok(Host { os: "unknown".into(), cpu: "unknown".into(), mem: "unknown".into() }); + return Ok(Host::unknown()); } let os = read_field(sh, "/etc/os-release", "PRETTY_NAME=")?.trim_matches('"').to_owned(); diff --git a/src/tools/rust-analyzer/xtask/src/pgo.rs b/src/tools/rust-analyzer/xtask/src/pgo.rs index 7f7b3311d9626..0c6f499811a24 100644 --- a/src/tools/rust-analyzer/xtask/src/pgo.rs +++ b/src/tools/rust-analyzer/xtask/src/pgo.rs @@ -53,14 +53,23 @@ pub(crate) fn gather_pgo_profile<'a>( // Merge profiles into a single file let merged_profile = pgo_dir.join("merged.profdata"); - let profile_files = std::fs::read_dir(pgo_dir)?.filter_map(|entry| { - let entry = entry.ok()?; - if entry.path().extension() == Some(OsStr::new("profraw")) { - Some(entry.path().to_str().unwrap().to_owned()) - } else { - None - } - }); + let profile_files = std::fs::read_dir(pgo_dir)? + .filter_map(|entry| { + let entry = entry.ok()?; + if entry.path().extension() == Some(OsStr::new("profraw")) { + Some(entry.path().to_str().unwrap().to_owned()) + } else { + None + } + }) + .collect::>(); + + if profile_files.is_empty() { + anyhow::bail!( + "rust-analyzer analysis-stats produced no pgo files. This is a bug in rust-analyzer; please file an issue." + ); + } + cmd!(sh, "{llvm_profdata} merge {profile_files...} -o {merged_profile}").run().context( "cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?", )?; diff --git a/src/tools/rust-analyzer/xtask/src/tidy.rs b/src/tools/rust-analyzer/xtask/src/tidy.rs index f91192b0076ba..0462835f0675a 100644 --- a/src/tools/rust-analyzer/xtask/src/tidy.rs +++ b/src/tools/rust-analyzer/xtask/src/tidy.rs @@ -235,6 +235,10 @@ impl TidyDocs { return; } + if is_ported_from_rustc(path, &["crates/hir-ty/src/next_solver"]) { + return; + } + let first_line = match text.lines().next() { Some(it) => it, None => return, @@ -290,6 +294,11 @@ fn is_exclude_dir(p: &Path, dirs_to_exclude: &[&str]) -> bool { .any(|it| dirs_to_exclude.contains(&it)) } +fn is_ported_from_rustc(p: &Path, dirs_to_exclude: &[&str]) -> bool { + let p = p.strip_prefix(project_root()).unwrap(); + dirs_to_exclude.iter().any(|exclude| p.starts_with(exclude)) +} + #[derive(Default)] struct TidyMarks { hits: HashSet, diff --git a/src/tools/rustc-perf b/src/tools/rustc-perf index dde879cf1087c..c0301bc44d175 160000 --- a/src/tools/rustc-perf +++ b/src/tools/rustc-perf @@ -1 +1 @@ -Subproject commit dde879cf1087cb34a32287bd8ccc4d545bb9fee5 +Subproject commit c0301bc44d175b9b2c5442b25049475c39d7700c diff --git a/src/tools/rustdoc-gui-test/Cargo.toml b/src/tools/rustdoc-gui-test/Cargo.toml index 8d958ac94f30e..f7384a98f8565 100644 --- a/src/tools/rustdoc-gui-test/Cargo.toml +++ b/src/tools/rustdoc-gui-test/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] build_helper = { path = "../../build_helper" } -camino = "1" compiletest = { path = "../compiletest" } getopts = "0.2" walkdir = "2" diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs index 5062c2597f15e..cd10882fc2269 100644 --- a/src/tools/rustdoc-gui-test/src/main.rs +++ b/src/tools/rustdoc-gui-test/src/main.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use build_helper::npm; use build_helper::util::try_run; -use compiletest::directives::TestProps; +use compiletest::rustdoc_gui_test::RustdocGuiTestProps; use config::Config; mod config; @@ -43,13 +43,7 @@ fn main() -> Result<(), ()> { .current_dir(path); if let Some(librs) = find_librs(entry.path()) { - let compiletest_c = compiletest::common::Config::incomplete_for_rustdoc_gui_test(); - - let test_props = TestProps::from_file( - &camino::Utf8PathBuf::try_from(librs).unwrap(), - None, - &compiletest_c, - ); + let test_props = RustdocGuiTestProps::from_file(&librs); if !test_props.compile_flags.is_empty() { cargo.env("RUSTDOCFLAGS", test_props.compile_flags.join(" ")); diff --git a/src/tools/rustfmt/src/config/mod.rs b/src/tools/rustfmt/src/config/mod.rs index 6b63108c037eb..525953bf4458b 100644 --- a/src/tools/rustfmt/src/config/mod.rs +++ b/src/tools/rustfmt/src/config/mod.rs @@ -516,7 +516,6 @@ mod test { #[allow(dead_code)] mod mock { use super::super::*; - use crate::config_option_with_style_edition_default; use rustfmt_config_proc_macro::config_type; #[config_type] diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 75e468b35256c..a2e89c10a4803 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -836,8 +836,7 @@ pub(crate) fn format_impl( let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1224,8 +1223,7 @@ pub(crate) fn format_trait( let option = WhereClauseOption::snuggled(&generics_str); let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), where_on_new_line, @@ -1350,8 +1348,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let where_str = rewrite_where_clause( context, - &self.generics.where_clause.predicates, - self.generics.where_clause.span, + &self.generics.where_clause, context.config.brace_style(), shape, false, @@ -1621,8 +1618,7 @@ fn format_tuple_struct( let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, offset.block_only()), false, @@ -1691,7 +1687,7 @@ struct TyAliasRewriteInfo<'c, 'g>( &'c RewriteContext<'c>, Indent, &'g ast::Generics, - ast::TyAliasWhereClauses, + &'g ast::WhereClause, symbol::Ident, Span, ); @@ -1712,13 +1708,13 @@ pub(crate) fn rewrite_type_alias<'a>( ref generics, ref bounds, ref ty, - where_clauses, + ref after_where_clause, } = *ty_alias_kind; let ty_opt = ty.as_ref(); let rhs_hi = ty .as_ref() - .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi()); - let rw_info = &TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span); + .map_or(generics.where_clause.span.hi(), |ty| ty.span.hi()); + let rw_info = &TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span); let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. @@ -1762,11 +1758,7 @@ fn rewrite_ty( vis: &ast::Visibility, ) -> RewriteResult { let mut result = String::with_capacity(128); - let TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span) = *rw_info; - let (before_where_predicates, after_where_predicates) = generics - .where_clause - .predicates - .split_at(where_clauses.split); + let TyAliasRewriteInfo(context, indent, generics, after_where_clause, ident, span) = *rw_info; result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1804,8 +1796,7 @@ fn rewrite_ty( } let before_where_clause_str = rewrite_where_clause( context, - before_where_predicates, - where_clauses.before.span, + &generics.where_clause, context.config.brace_style(), Shape::legacy(where_budget, indent), false, @@ -1820,9 +1811,9 @@ fn rewrite_ty( // If there are any where clauses, add a newline before the assignment. // If there is a before where clause, do not indent, but if there is // only an after where clause, additionally indent the type. - if !before_where_predicates.is_empty() { + if !generics.where_clause.predicates.is_empty() { result.push_str(&indent.to_string_with_newline(context.config)); - } else if !after_where_predicates.is_empty() { + } else if !after_where_clause.predicates.is_empty() { result.push_str( &indent .block_indent(context.config) @@ -1835,7 +1826,7 @@ fn rewrite_ty( let comment_span = context .snippet_provider .opt_span_before(span, "=") - .map(|op_lo| mk_sp(where_clauses.before.span.hi(), op_lo)); + .map(|op_lo| mk_sp(generics.where_clause.span.hi(), op_lo)); let lhs = match comment_span { Some(comment_span) @@ -1846,7 +1837,7 @@ fn rewrite_ty( .unknown_error()?, ) => { - let comment_shape = if !before_where_predicates.is_empty() { + let comment_shape = if !generics.where_clause.predicates.is_empty() { Shape::indented(indent, context.config) } else { let shape = Shape::indented(indent, context.config); @@ -1869,7 +1860,7 @@ fn rewrite_ty( // 1 = `;` unless there's a trailing where clause let shape = Shape::indented(indent, context.config); - let shape = if after_where_predicates.is_empty() { + let shape = if after_where_clause.predicates.is_empty() { Shape::indented(indent, context.config) .sub_width(1) .max_width_error(shape.width, span)? @@ -1881,12 +1872,11 @@ fn rewrite_ty( result }; - if !after_where_predicates.is_empty() { + if !after_where_clause.predicates.is_empty() { let option = WhereClauseOption::new(true, WhereClauseSpace::Newline); let after_where_clause_str = rewrite_where_clause( context, - after_where_predicates, - where_clauses.after.span, + &after_where_clause, context.config.brace_style(), Shape::indented(indent, context.config), false, @@ -2728,8 +2718,7 @@ fn rewrite_fn_base( } let where_clause_str = rewrite_where_clause( context, - &where_clause.predicates, - where_clause.span, + &where_clause, context.config.brace_style(), Shape::indented(indent, context.config), true, @@ -3158,8 +3147,7 @@ fn rewrite_bounds_on_where_clause( fn rewrite_where_clause( context: &RewriteContext<'_>, - predicates: &[ast::WherePredicate], - where_span: Span, + where_clause: &ast::WhereClause, brace_style: BraceStyle, shape: Shape, on_new_line: bool, @@ -3168,6 +3156,12 @@ fn rewrite_where_clause( span_end_before_where: BytePos, where_clause_option: WhereClauseOption, ) -> RewriteResult { + let ast::WhereClause { + ref predicates, + span: where_span, + has_where_token: _, + } = *where_clause; + if predicates.is_empty() { return Ok(String::new()); } @@ -3354,8 +3348,7 @@ fn format_generics( } let where_clause_str = rewrite_where_clause( context, - &generics.where_clause.predicates, - generics.where_clause.span, + &generics.where_clause, brace_style, Shape::legacy(budget, offset.block_only()), true, diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index 724d7a09e4afa..c063990dfa0b1 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -61,7 +61,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { Pat, NonterminalKind::Pat(PatParam { inferred: false }), |parser: &mut Parser<'b>| parser.parse_pat_no_top_alt(None, None), - |x: Box| Some(x) + |x: ast::Pat| Some(Box::new(x)) ); // `parse_item` returns `Option>`. parse_macro_arg!( diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index 848bd0766e786..fa9a3e33914b6 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -504,7 +504,7 @@ impl Rewrite for PatField { #[derive(Debug)] pub(crate) enum TuplePatField<'a> { - Pat(&'a Box), + Pat(&'a ast::Pat), Dotdot(Span), } @@ -561,7 +561,7 @@ pub(crate) fn can_be_overflowed_pat( } fn rewrite_tuple_pat( - pats: &[Box], + pats: &[ast::Pat], path_str: Option, span: Span, context: &RewriteContext<'_>, diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 5dce9a0c8d0f2..242d8c23113c3 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -1099,7 +1099,7 @@ impl Rewrite for ast::TyPat { } Ok(s) } - ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), + ast::TyPatKind::NotNull | ast::TyPatKind::Err(_) => Err(RewriteError::Unknown), } } } diff --git a/src/tools/tidy/Readme.md b/src/tools/tidy/Readme.md new file mode 100644 index 0000000000000..fc9dc6350e92d --- /dev/null +++ b/src/tools/tidy/Readme.md @@ -0,0 +1,112 @@ +# Tidy +Tidy is the Rust project's custom internal linter and a crucial part of our testing and continuous integration (CI) infrastructure. It is designed to enforce a consistent style and formatting across the entire codebase, but its role extends beyond simple linting. Tidy also helps with infrastructure, policy, and documentation, ensuring the project remains organized, functional, and... tidy. + +This document will cover how to use tidy, the specific checks tidy performs, and using tidy directives to manage its behavior. By understanding and utilizing tidy, you can help us maintain the high standards of the Rust project. +## Tidy Checks +### Style and Code Quality +These lints focus on enforcing consistent formatting, style, and general code health. +* [`alphabetical`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/alphabetical/index.html): Checks that lists are sorted alphabetically +* [`style`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/style/index.html): Check to enforce various stylistic guidelines on the Rust codebase. +* [`filenames`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/filenames/index.html): Check to prevent invalid characters in file names. +* [`pal`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/pal/index.html): Check to enforce rules about platform-specific code in std. +* [`target_policy`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/target_policy/index.html): Check for target tier policy compliance. +* [`error_codes`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/error_codes/index.html): Check to ensure error codes are properly documented and tested. + +### Infrastructure +These checks focus on the integrity of the project's dependencies, internal tools, and documentation. +* [`bins`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/bins/index.html): Prevent stray binaries from being checked into the source tree. +* [`fluent_alphabetical`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/fluent_alphabetical/index.html) / [`fluent_period`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/fluent_period/index.html) / [`fluent_used`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/fluent_used/index.html): Various checks related to [Fluent](https://github.com/projectfluent) for localization and natural language translation. +* [`deps`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/deps/index.html) / [`extdeps`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/extdeps/index.html): Check for valid licenses and sources for external dependencies. +* [`gcc_submodule`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/gcc_submodule/index.html): Check that the `src/gcc` submodule version is valid. +* [`triagebot`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/triagebot/index.html): Check to ensure paths mentioned in `triagebot.toml` exist in the project. +* [`x_version`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/x_version/index.html): Validates the current version of the `x` tool. + +* [`edition`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/edition/index.html) / [`features`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/features/index.html): Check for a valid Rust edition and proper ordering of unstable features. +* [`rustdoc_css_themes`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/rustdoc_css_themes/index.html) / [`rustdoc_templates`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/rustdoc_templates/index.html): Verify that Rust documentation templates and themes are correct. +* [`unstable_book`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/unstable_book/index.html): Synchronizes the unstable book with unstable features. +### Testing +These checks ensure that tests are correctly structured, cleaned up, and free of common errors. +* [`tests_placement`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/tests_placement/index.html) / [`unit_tests`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/unit_tests/index.html): Verify that tests are located in the correct directories and are not using improper attributes. +* [`known_bug`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/known_bug/index.html) / [`unknown_revision`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/unknown_revision/index.html): Ensure that test directives and annotations are used correctly. +* [`debug_artifacts`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/debug_artifacts/index.html) / [`mir_opt_tests`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/mir_opt_tests/index.html): Prevent unnecessary artifacts and stale files in test directories. +* [`tests_revision_unpaired_stdout_stderr`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/tests_revision_unpaired_stdout_stderr/index.html) / [`ui_tests`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/ui_tests/index.html): Check for unpaired or stray test output files. +* [`target_specific_tests`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/target_specific_tests/index.html): Check to ensure that all target specific tests (those that require a --target flag) also require the pre-requisite LLVM components to run. +* [`rustdoc_gui_tests`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/rustdoc_gui_tests/index.html): Checks that rustdoc gui tests start with a small description +* [`rustdoc_json`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/rustdoc_json/index.html): Verify that `FORMAT_VERSION` is in sync with `rust-json-types`. +## Using Tidy + +Tidy is used in a number of different ways. +* Every time `./x test` is used tidy will run automatically. + +* On every pull request, tidy will run automatically during CI checks. +* Optionally, with the use of git-hooks, tidy can run locally on every push. This can be setup with `./x setup`. See the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/building/suggested.html#installing-a-pre-push-hook) for more information. + +You can run tidy manually with: + +`./x test tidy` + +To first run the relevant formatter and then run tidy you can add `--bless`. + +`./x test tidy --bless` +### Extra Checks +[`extra_checks`](https://doc.rust-lang.org/nightly/nightly-rustc/tidy/extra_checks/index.html) are optional checks primarily focused on other file types and programming languages. + +Example usage: + +`./x test tidy --extra-checks=py,cpp,js,spellcheck` + +All options for `--extra-checks`: +* `cpp`, `cpp:fmt` +* `py`, `py:lint`, `py:fmt` +* `js`, `js:lint`, `js:fmt`, `js:typecheck` +* `shell`, `shell:lint` +* `spellcheck` + +Default values for tidy's `extra-checks` can be set in `bootstrap.toml`. For example, `build.tidy-extra-checks = "js,py"`. + +Any argument without a suffix (eg. `py` or `js`) will include all possible checks. For example, `--extra-checks=js` is the same as `extra-checks=js:lint,js:fmt,js:typecheck`. + +Any argument can be prefixed with `auto:` to only run if relevant files are modified (eg. `--extra-checks=auto:py`). + +A specific configuration file or folder can be passed to tidy after a double dash (`--extra-checks=py -- foo.py`) + +## Tidy Directives + +Tidy directives are special comments that help tidy operate. + +Tidy directives can be used in the following types of comments: +* `// ` +* `# ` +* `/* {...} */` +* `` + +You might find yourself needing to ignore a specific tidy style check and can do so with: +* `ignore-tidy-cr` +* `ignore-tidy-undocumented-unsafe` +* `ignore-tidy-tab` +* `ignore-tidy-linelength` +* `ignore-tidy-filelength` + +* `ignore-tidy-end-whitespace` +* `ignore-tidy-trailing-newlines` +* `ignore-tidy-leading-newlines` +* `ignore-tidy-copyright` +* `ignore-tidy-dbg` +* `ignore-tidy-odd-backticks` +* `ignore-tidy-todo` + +Some checks, like `alphabetical`, require a tidy directive to use: +``` +// tidy-alphabetical-start +fn aaa() {} +fn eee() {} +fn z() {} +// tidy-alphabetical-end +``` +While not exactly a tidy directive, // TODO will fail tidy and make sure you can't merge a PR with unfinished work. + +### Test Specific Directives + +`target-specific-tests` can be ignored with `// ignore-tidy-target-specific-tests` + +Tidy's `unknown_revision` check can be suppressed by adding the revision name to `//@ unused-revision-names:{revision}` or with `//@ unused-revision-names:*`. diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 9ddce72510693..3845e2269e9b2 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -24,6 +24,7 @@ use std::fmt::Display; use std::iter::Peekable; use std::path::Path; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[cfg(test)] @@ -43,8 +44,7 @@ const END_MARKER: &str = "tidy-alphabetical-end"; fn check_section<'a>( file: impl Display, lines: impl Iterator, - err: &mut dyn FnMut(&str) -> std::io::Result<()>, - bad: &mut bool, + check: &mut RunningCheck, ) { let mut prev_line = String::new(); let mut first_indent = None; @@ -56,12 +56,10 @@ fn check_section<'a>( } if line.contains(START_MARKER) { - tidy_error_ext!( - err, - bad, + check.error(format!( "{file}:{} found `{START_MARKER}` expecting `{END_MARKER}`", idx + 1 - ); + )); return; } @@ -104,45 +102,44 @@ fn check_section<'a>( let prev_line_trimmed_lowercase = prev_line.trim_start_matches(' '); if version_sort(trimmed_line, prev_line_trimmed_lowercase).is_lt() { - tidy_error_ext!(err, bad, "{file}:{}: line not in alphabetical order", idx + 1); + check.error(format!("{file}:{}: line not in alphabetical order", idx + 1)); } prev_line = line; } - tidy_error_ext!(err, bad, "{file}: reached end of file expecting `{END_MARKER}`") + check.error(format!("{file}: reached end of file expecting `{END_MARKER}`")); } fn check_lines<'a>( file: &impl Display, mut lines: impl Iterator, - err: &mut dyn FnMut(&str) -> std::io::Result<()>, - bad: &mut bool, + check: &mut RunningCheck, ) { while let Some((idx, line)) = lines.next() { if line.contains(END_MARKER) { - tidy_error_ext!( - err, - bad, + check.error(format!( "{file}:{} found `{END_MARKER}` expecting `{START_MARKER}`", idx + 1 - ) + )); } if line.contains(START_MARKER) { - check_section(file, &mut lines, err, bad); + check_section(file, &mut lines, check); } } } -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("alphabetical").path(path)); + let skip = |path: &_, _is_dir| filter_dirs(path) || path.ends_with("tidy/src/alphabetical/tests.rs"); walk(path, skip, &mut |entry, contents| { let file = &entry.path().display(); let lines = contents.lines().enumerate(); - check_lines(file, lines, &mut crate::tidy_error, bad) + check_lines(file, lines, &mut check) }); } diff --git a/src/tools/tidy/src/alphabetical/tests.rs b/src/tools/tidy/src/alphabetical/tests.rs index 4d05bc33cedc3..3e0dd798ab9df 100644 --- a/src/tools/tidy/src/alphabetical/tests.rs +++ b/src/tools/tidy/src/alphabetical/tests.rs @@ -1,19 +1,22 @@ -use std::io::Write; -use std::str::from_utf8; +use std::path::Path; -use super::*; +use crate::alphabetical::check_lines; +use crate::diagnostics::{TidyCtx, TidyFlags}; #[track_caller] fn test(lines: &str, name: &str, expected_msg: &str, expected_bad: bool) { - let mut actual_msg = Vec::new(); - let mut actual_bad = false; - let mut err = |args: &_| { - write!(&mut actual_msg, "{args}")?; - Ok(()) - }; - check_lines(&name, lines.lines().enumerate(), &mut err, &mut actual_bad); - assert_eq!(expected_msg, from_utf8(&actual_msg).unwrap()); - assert_eq!(expected_bad, actual_bad); + let tidy_ctx = TidyCtx::new(Path::new("/"), false, TidyFlags::default()); + let mut check = tidy_ctx.start_check("alphabetical-test"); + check_lines(&name, lines.lines().enumerate(), &mut check); + + assert_eq!(expected_bad, check.is_bad()); + let errors = check.get_errors(); + if expected_bad { + assert_eq!(errors.len(), 1); + assert_eq!(expected_msg, errors[0]); + } else { + assert!(errors.is_empty()); + } } #[track_caller] diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index a18f549844b86..2dcbd8e9b38a2 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -12,11 +12,13 @@ pub use os_impl::*; mod os_impl { use std::path::Path; + use crate::diagnostics::TidyCtx; + pub fn check_filesystem_support(_sources: &[&Path], _output: &Path) -> bool { return false; } - pub fn check(_path: &Path, _bad: &mut bool) {} + pub fn check(_path: &Path, _tidy_ctx: TidyCtx) {} } #[cfg(unix)] @@ -36,6 +38,8 @@ mod os_impl { use FilesystemSupport::*; + use crate::diagnostics::TidyCtx; + fn is_executable(path: &Path) -> std::io::Result { Ok(path.metadata()?.mode() & 0o111 != 0) } @@ -106,14 +110,16 @@ mod os_impl { } #[cfg(unix)] - pub fn check(path: &Path, bad: &mut bool) { + pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("bins"); + use std::ffi::OsStr; const ALLOWED: &[&str] = &["configure", "x"]; for p in RI_EXCLUSION_LIST { if !path.join(Path::new(p)).exists() { - tidy_error!(bad, "rust-installer test bins missed: {p}"); + check.error(format!("rust-installer test bins missed: {p}")); } } @@ -153,7 +159,7 @@ mod os_impl { }); let path_bytes = rel_path.as_os_str().as_bytes(); if output.status.success() && output.stdout.starts_with(path_bytes) { - tidy_error!(bad, "binary checked into source: {}", file.display()); + check.error(format!("binary checked into source: {}", file.display())); } } }, diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs index 645534cc82738..a1a0f37f7844b 100644 --- a/src/tools/tidy/src/debug_artifacts.rs +++ b/src/tools/tidy/src/debug_artifacts.rs @@ -2,24 +2,25 @@ use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, filter_not_rust, walk}; const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test"; -pub fn check(test_dir: &Path, bad: &mut bool) { +pub fn check(test_dir: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("debug_artifacts").path(test_dir)); + walk( test_dir, |path, _is_dir| filter_dirs(path) || filter_not_rust(path), &mut |entry, contents| { for (i, line) in contents.lines().enumerate() { if line.contains("borrowck_graphviz_postflow") { - tidy_error!( - bad, - "{}:{}: {}", + check.error(format!( + "{}:{}: {GRAPHVIZ_POSTFLOW_MSG}", entry.path().display(), - i + 1, - GRAPHVIZ_POSTFLOW_MSG - ); + i + 1 + )); } } }, diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index a980476140077..6a1721df1642e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -9,6 +9,8 @@ use build_helper::ci::CiEnv; use cargo_metadata::semver::Version; use cargo_metadata::{Metadata, Package, PackageId}; +use crate::diagnostics::{RunningCheck, TidyCtx}; + #[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] mod proc_macro_deps; @@ -17,71 +19,165 @@ mod proc_macro_deps; #[rustfmt::skip] const LICENSES: &[&str] = &[ // tidy-alphabetical-start - "(MIT OR Apache-2.0) AND Unicode-3.0", // unicode_ident (1.0.14) - "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident (1.0.12) "0BSD OR MIT OR Apache-2.0", // adler2 license - "0BSD", "Apache-2.0 / MIT", "Apache-2.0 OR ISC OR MIT", "Apache-2.0 OR MIT", "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license - "Apache-2.0", "Apache-2.0/MIT", "BSD-2-Clause OR Apache-2.0 OR MIT", // zerocopy + "BSD-2-Clause OR MIT OR Apache-2.0", + "BSD-3-Clause/MIT", + "CC0-1.0 OR MIT-0 OR Apache-2.0", "ISC", "MIT / Apache-2.0", "MIT AND (MIT OR Apache-2.0)", "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)", // compiler-builtins - "MIT OR Apache-2.0 OR LGPL-2.1-or-later", // r-efi, r-efi-alloc + "MIT OR Apache-2.0 OR BSD-1-Clause", + "MIT OR Apache-2.0 OR LGPL-2.1-or-later", // r-efi, r-efi-alloc; LGPL is not acceptable, but we use it under MIT OR Apache-2.0 "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros "MIT OR Apache-2.0", "MIT OR Zlib OR Apache-2.0", // miniz_oxide "MIT", "MIT/Apache-2.0", - "Unicode-3.0", // icu4x - "Unicode-DFS-2016", // tinystr "Unlicense OR MIT", "Unlicense/MIT", + // tidy-alphabetical-end +]; + +/// These are licenses that are allowed for rustc, tools, etc. But not for the runtime! +#[rustfmt::skip] +const LICENSES_TOOLS: &[&str] = &[ + // tidy-alphabetical-start + "(Apache-2.0 OR MIT) AND BSD-3-Clause", + "(MIT OR Apache-2.0) AND Unicode-3.0", // unicode_ident (1.0.14) + "(MIT OR Apache-2.0) AND Unicode-DFS-2016", // unicode_ident (1.0.12) + "0BSD", + "Apache-2.0 AND ISC", + "Apache-2.0 OR BSL-1.0", // BSL is not acceptable, but we use it under Apache-2.0 + "Apache-2.0 WITH LLVM-exception", + "Apache-2.0", + "BSD-2-Clause", + "BSD-3-Clause", + "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception", + "CC0-1.0", + "Unicode-3.0", // icu4x + "Unicode-DFS-2016", // tinystr "Zlib OR Apache-2.0 OR MIT", // tinyvec + "Zlib", // tidy-alphabetical-end ]; type ExceptionList = &'static [(&'static str, &'static str)]; +#[derive(Clone, Copy)] +pub(crate) struct WorkspaceInfo<'a> { + /// Path to the directory containing the workspace root Cargo.toml file. + pub(crate) path: &'a str, + /// The list of license exceptions. + pub(crate) exceptions: ExceptionList, + /// Optionally: + /// * A list of crates for which dependencies need to be explicitly allowed. + /// * The list of allowed dependencies. + /// * The source code location of the allowed dependencies list + crates_and_deps: Option<(&'a [&'a str], &'a [&'a str], ListLocation)>, + /// Submodules required for the workspace + pub(crate) submodules: &'a [&'a str], +} + /// The workspaces to check for licensing and optionally permitted dependencies. -/// -/// Each entry consists of a tuple with the following elements: -/// -/// * The path to the workspace root Cargo.toml file. -/// * The list of license exceptions. -/// * Optionally a tuple of: -/// * A list of crates for which dependencies need to be explicitly allowed. -/// * The list of allowed dependencies. -/// * Submodules required for the workspace. // FIXME auto detect all cargo workspaces -pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, &[&str])] = &[ +pub(crate) const WORKSPACES: &[WorkspaceInfo<'static>] = &[ // The root workspace has to be first for check_rustfix to work. - (".", EXCEPTIONS, Some((&["rustc-main"], PERMITTED_RUSTC_DEPENDENCIES)), &[]), - ("library", EXCEPTIONS_STDLIB, Some((&["sysroot"], PERMITTED_STDLIB_DEPENDENCIES)), &[]), - // Outside of the alphabetical section because rustfmt formats it using multiple lines. - ( - "compiler/rustc_codegen_cranelift", - EXCEPTIONS_CRANELIFT, - Some((&["rustc_codegen_cranelift"], PERMITTED_CRANELIFT_DEPENDENCIES)), - &[], - ), - // tidy-alphabetical-start - ("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None, &[]), - ("src/bootstrap", EXCEPTIONS_BOOTSTRAP, None, &[]), - ("src/tools/cargo", EXCEPTIONS_CARGO, None, &["src/tools/cargo"]), - //("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored - //("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored - ("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None, &[]), - ("src/tools/rustbook", EXCEPTIONS_RUSTBOOK, None, &["src/doc/book", "src/doc/reference"]), - ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None, &["src/tools/rustc-perf"]), - ("src/tools/test-float-parse", EXCEPTIONS, None, &[]), - ("tests/run-make-cargo/uefi-qemu/uefi_qemu_test", EXCEPTIONS_UEFI_QEMU_TEST, None, &[]), - // tidy-alphabetical-end + WorkspaceInfo { + path: ".", + exceptions: EXCEPTIONS, + crates_and_deps: Some(( + &["rustc-main"], + PERMITTED_RUSTC_DEPENDENCIES, + PERMITTED_RUSTC_DEPS_LOCATION, + )), + submodules: &[], + }, + WorkspaceInfo { + path: "library", + exceptions: EXCEPTIONS_STDLIB, + crates_and_deps: Some(( + &["sysroot"], + PERMITTED_STDLIB_DEPENDENCIES, + PERMITTED_STDLIB_DEPS_LOCATION, + )), + submodules: &[], + }, + WorkspaceInfo { + path: "compiler/rustc_codegen_cranelift", + exceptions: EXCEPTIONS_CRANELIFT, + crates_and_deps: Some(( + &["rustc_codegen_cranelift"], + PERMITTED_CRANELIFT_DEPENDENCIES, + PERMITTED_CRANELIFT_DEPS_LOCATION, + )), + submodules: &[], + }, + WorkspaceInfo { + path: "compiler/rustc_codegen_gcc", + exceptions: EXCEPTIONS_GCC, + crates_and_deps: None, + submodules: &[], + }, + WorkspaceInfo { + path: "src/bootstrap", + exceptions: EXCEPTIONS_BOOTSTRAP, + crates_and_deps: None, + submodules: &[], + }, + WorkspaceInfo { + path: "src/tools/cargo", + exceptions: EXCEPTIONS_CARGO, + crates_and_deps: None, + submodules: &["src/tools/cargo"], + }, + // FIXME uncomment once all deps are vendored + // WorkspaceInfo { + // path: "src/tools/miri/test-cargo-miri", + // crates_and_deps: None + // submodules: &[], + // }, + // WorkspaceInfo { + // path: "src/tools/miri/test_dependencies", + // crates_and_deps: None, + // submodules: &[], + // } + WorkspaceInfo { + path: "src/tools/rust-analyzer", + exceptions: EXCEPTIONS_RUST_ANALYZER, + crates_and_deps: None, + submodules: &[], + }, + WorkspaceInfo { + path: "src/tools/rustbook", + exceptions: EXCEPTIONS_RUSTBOOK, + crates_and_deps: None, + submodules: &["src/doc/book", "src/doc/reference"], + }, + WorkspaceInfo { + path: "src/tools/rustc-perf", + exceptions: EXCEPTIONS_RUSTC_PERF, + crates_and_deps: None, + submodules: &["src/tools/rustc-perf"], + }, + WorkspaceInfo { + path: "src/tools/test-float-parse", + exceptions: EXCEPTIONS, + crates_and_deps: None, + submodules: &[], + }, + WorkspaceInfo { + path: "tests/run-make-cargo/uefi-qemu/uefi_qemu_test", + exceptions: EXCEPTIONS_UEFI_QEMU_TEST, + crates_and_deps: None, + submodules: &[], + }, ]; /// These are exceptions to Rust's permissive licensing policy, and @@ -91,19 +187,8 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>, #[rustfmt::skip] const EXCEPTIONS: ExceptionList = &[ // tidy-alphabetical-start - ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc - ("arrayref", "BSD-2-Clause"), // rustc - ("blake3", "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception"), // rustc ("colored", "MPL-2.0"), // rustfmt - ("constant_time_eq", "CC0-1.0 OR MIT-0 OR Apache-2.0"), // rustc - ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) - ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) - ("foldhash", "Zlib"), // rustc ("option-ext", "MPL-2.0"), // cargo-miri (via `directories`) - ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), // rustc (license is the same as LLVM uses) - ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 // cargo/... (because of serde) - ("self_cell", "Apache-2.0"), // rustc (fluent translations) - ("wasi-preview1-component-adapter-provider", "Apache-2.0 WITH LLVM-exception"), // rustc // tidy-alphabetical-end ]; @@ -120,57 +205,22 @@ const EXCEPTIONS_STDLIB: ExceptionList = &[ const EXCEPTIONS_CARGO: ExceptionList = &[ // tidy-alphabetical-start - ("arrayref", "BSD-2-Clause"), ("bitmaps", "MPL-2.0+"), - ("blake3", "CC0-1.0 OR Apache-2.0 OR Apache-2.0 WITH LLVM-exception"), - ("ciborium", "Apache-2.0"), - ("ciborium-io", "Apache-2.0"), - ("ciborium-ll", "Apache-2.0"), - ("constant_time_eq", "CC0-1.0 OR MIT-0 OR Apache-2.0"), - ("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"), - ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), - ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), - ("foldhash", "Zlib"), ("im-rc", "MPL-2.0+"), - ("libz-rs-sys", "Zlib"), - ("normalize-line-endings", "Apache-2.0"), - ("openssl", "Apache-2.0"), - ("ring", "Apache-2.0 AND ISC"), - ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 - ("similar", "Apache-2.0"), ("sized-chunks", "MPL-2.0+"), - ("subtle", "BSD-3-Clause"), - ("supports-hyperlinks", "Apache-2.0"), - ("unicode-bom", "Apache-2.0"), - ("zlib-rs", "Zlib"), // tidy-alphabetical-end ]; const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ // tidy-alphabetical-start - ("dissimilar", "Apache-2.0"), - ("foldhash", "Zlib"), - ("notify", "CC0-1.0"), ("option-ext", "MPL-2.0"), - ("pulldown-cmark-to-cmark", "Apache-2.0"), - ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"), - ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0 - ("scip", "Apache-2.0"), // tidy-alphabetical-end ]; const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ // tidy-alphabetical-start - ("alloc-no-stdlib", "BSD-3-Clause"), - ("alloc-stdlib", "BSD-3-Clause"), - ("brotli", "BSD-3-Clause/MIT"), - ("brotli-decompressor", "BSD-3-Clause/MIT"), - ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), ("inferno", "CDDL-1.0"), ("option-ext", "MPL-2.0"), - ("ryu", "Apache-2.0 OR BSL-1.0"), - ("snap", "BSD-3-Clause"), - ("subtle", "BSD-3-Clause"), // tidy-alphabetical-end ]; @@ -180,36 +230,10 @@ const EXCEPTIONS_RUSTBOOK: ExceptionList = &[ ("cssparser-macros", "MPL-2.0"), ("dtoa-short", "MPL-2.0"), ("mdbook", "MPL-2.0"), - ("ryu", "Apache-2.0 OR BSL-1.0"), // tidy-alphabetical-end ]; -const EXCEPTIONS_CRANELIFT: ExceptionList = &[ - // tidy-alphabetical-start - ("cranelift-assembler-x64", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-assembler-x64-meta", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-bitset", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-codegen-meta", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-codegen-shared", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-control", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-entity", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-frontend", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-isle", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-jit", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-module", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-native", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-object", "Apache-2.0 WITH LLVM-exception"), - ("cranelift-srcgen", "Apache-2.0 WITH LLVM-exception"), - ("foldhash", "Zlib"), - ("mach2", "BSD-2-Clause OR MIT OR Apache-2.0"), - ("regalloc2", "Apache-2.0 WITH LLVM-exception"), - ("target-lexicon", "Apache-2.0 WITH LLVM-exception"), - ("wasmtime-jit-icache-coherence", "Apache-2.0 WITH LLVM-exception"), - ("wasmtime-math", "Apache-2.0 WITH LLVM-exception"), - // tidy-alphabetical-end -]; +const EXCEPTIONS_CRANELIFT: ExceptionList = &[]; const EXCEPTIONS_GCC: ExceptionList = &[ // tidy-alphabetical-start @@ -218,15 +242,24 @@ const EXCEPTIONS_GCC: ExceptionList = &[ // tidy-alphabetical-end ]; -const EXCEPTIONS_BOOTSTRAP: ExceptionList = &[ - ("ryu", "Apache-2.0 OR BSL-1.0"), // through serde. BSL is not acceptble, but we use it under Apache-2.0 -]; +const EXCEPTIONS_BOOTSTRAP: ExceptionList = &[]; -const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[ - ("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptable, but we use it under MIT OR Apache-2.0 -]; +const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[]; -const PERMITTED_DEPS_LOCATION: &str = concat!(file!(), ":", line!()); +#[derive(Clone, Copy)] +struct ListLocation { + path: &'static str, + line: u32, +} + +/// Creates a [`ListLocation`] for the current location (with an additional offset to the actual list start); +macro_rules! location { + (+ $offset:literal) => { + ListLocation { path: file!(), line: line!() + $offset } + }; +} + +const PERMITTED_RUSTC_DEPS_LOCATION: ListLocation = location!(+6); /// Crates rustc is allowed to depend on. Avoid adding to the list if possible. /// @@ -238,7 +271,11 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "aho-corasick", "allocator-api2", // FIXME: only appears in Cargo.lock due to https://github.com/rust-lang/cargo/issues/10801 "annotate-snippets", + "anstream", "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", "ar_archive_writer", "arrayref", "arrayvec", @@ -250,6 +287,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "cc", "cfg-if", "cfg_aliases", + "colorchoice", "constant_time_eq", "cpufeatures", "crc32fast", @@ -276,6 +314,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "expect-test", "fallible-iterator", // dependency of `thorin` "fastrand", + "find-msvc-tools", "flate2", "fluent-bundle", "fluent-langneg", @@ -298,6 +337,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "indexmap", "intl-memoizer", "intl_pluralrules", + "is_terminal_polyfill", "itertools", "itoa", "jiff", @@ -322,6 +362,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "object", "odht", "once_cell", + "once_cell_polyfill", "overload", "parking_lot", "parking_lot_core", @@ -366,6 +407,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "scopeguard", "self_cell", "serde", + "serde_core", "serde_derive", "serde_derive_internals", "serde_json", @@ -382,7 +424,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "syn", "synstructure", "tempfile", - "termcolor", "termize", "thin-vec", "thiserror", @@ -414,6 +455,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "unicode-security", "unicode-width", "unicode-xid", + "utf8parse", "valuable", "version_check", "wasi", @@ -421,7 +463,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "wasmparser", "winapi", "winapi-i686-pc-windows-gnu", - "winapi-util", "winapi-x86_64-pc-windows-gnu", "windows", "windows-collections", @@ -458,6 +499,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-end ]; +const PERMITTED_STDLIB_DEPS_LOCATION: ListLocation = location!(+2); + const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-start "addr2line", @@ -474,6 +517,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "libc", "memchr", "miniz_oxide", + "moto-rt", "object", "r-efi", "r-efi-alloc", @@ -484,6 +528,7 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ "rustc-literal-escaper", "shlex", "unwinding", + "vex-sdk", "wasi", "windows-sys", "windows-targets", @@ -499,6 +544,8 @@ const PERMITTED_STDLIB_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-end ]; +const PERMITTED_CRANELIFT_DEPS_LOCATION: ListLocation = location!(+2); + const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-start "allocator-api2", @@ -568,37 +615,48 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("deps"); + let bless = tidy_ctx.is_bless_enabled(); + let mut checked_runtime_licenses = false; - check_proc_macro_dep_list(root, cargo, bless, bad); + check_proc_macro_dep_list(root, cargo, bless, &mut check); - for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES { + for &WorkspaceInfo { path, exceptions, crates_and_deps, submodules } in WORKSPACES { if has_missing_submodule(root, submodules) { continue; } - if !root.join(workspace).join("Cargo.lock").exists() { - tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock"); + if !root.join(path).join("Cargo.lock").exists() { + check.error(format!("the `{path}` workspace doesn't have a Cargo.lock")); continue; } let mut cmd = cargo_metadata::MetadataCommand::new(); cmd.cargo_path(cargo) - .manifest_path(root.join(workspace).join("Cargo.toml")) + .manifest_path(root.join(path).join("Cargo.toml")) .features(cargo_metadata::CargoOpt::AllFeatures) .other_options(vec!["--locked".to_owned()]); let metadata = t!(cmd.exec()); - check_license_exceptions(&metadata, workspace, exceptions, bad); - if let Some((crates, permitted_deps)) = permitted_deps { - check_permitted_dependencies(&metadata, workspace, permitted_deps, crates, bad); + check_license_exceptions(&metadata, path, exceptions, &mut check); + if let Some((crates, permitted_deps, location)) = crates_and_deps { + let descr = crates.get(0).unwrap_or(&path); + check_permitted_dependencies( + &metadata, + descr, + permitted_deps, + crates, + location, + &mut check, + ); } - if workspace == "library" { - check_runtime_license_exceptions(&metadata, bad); - check_runtime_no_duplicate_dependencies(&metadata, bad); - check_runtime_no_proc_macros(&metadata, bad); + if path == "library" { + check_runtime_license_exceptions(&metadata, &mut check); + check_runtime_no_duplicate_dependencies(&metadata, &mut check); + check_runtime_no_proc_macros(&metadata, &mut check); checked_runtime_licenses = true; } } @@ -609,7 +667,7 @@ pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { } /// Ensure the list of proc-macro crate transitive dependencies is up to date -fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { +fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, check: &mut RunningCheck) { let mut cmd = cargo_metadata::MetadataCommand::new(); cmd.cargo_path(cargo) .manifest_path(root.join("Cargo.toml")) @@ -656,22 +714,22 @@ pub static CRATES: &[&str] = &[ ) .unwrap(); } else { - let old_bad = *bad; + let mut error_found = false; for missing in proc_macro_deps.difference(&expected) { - tidy_error!( - bad, + error_found = true; + check.error(format!( "proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`", - ); + )); } for extra in expected.difference(&proc_macro_deps) { - tidy_error!( - bad, + error_found = true; + check.error(format!( "`{extra}` is registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", - ); + )); } - if *bad != old_bad { - eprintln!("Run `./x.py test tidy --bless` to regenerate the list"); + if error_found { + check.message("Run `./x.py test tidy --bless` to regenerate the list"); } } } @@ -693,7 +751,7 @@ pub fn has_missing_submodule(root: &Path, submodules: &[&str]) -> bool { /// /// Unlike for tools we don't allow exceptions to the `LICENSES` list for the runtime with the sole /// exception of `fortanix-sgx-abi` which is only used on x86_64-fortanix-unknown-sgx. -fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) { +fn check_runtime_license_exceptions(metadata: &Metadata, check: &mut RunningCheck) { for pkg in &metadata.packages { if pkg.source.is_none() { // No need to check local packages. @@ -702,7 +760,8 @@ fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) { let license = match &pkg.license { Some(license) => license, None => { - tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id); + check + .error(format!("dependency `{}` does not define a license expression", pkg.id)); continue; } }; @@ -715,7 +774,7 @@ fn check_runtime_license_exceptions(metadata: &Metadata, bad: &mut bool) { continue; } - tidy_error!(bad, "invalid license `{}` in `{}`", license, pkg.id); + check.error(format!("invalid license `{}` in `{}`", license, pkg.id)); } } } @@ -727,41 +786,41 @@ fn check_license_exceptions( metadata: &Metadata, workspace: &str, exceptions: &[(&str, &str)], - bad: &mut bool, + check: &mut RunningCheck, ) { // Validate the EXCEPTIONS list hasn't changed. for (name, license) in exceptions { // Check that the package actually exists. if !metadata.packages.iter().any(|p| *p.name == *name) { - tidy_error!( - bad, - "could not find exception package `{}` in workspace `{workspace}`\n\ + check.error(format!( + "could not find exception package `{name}` in workspace `{workspace}`\n\ Remove from EXCEPTIONS list if it is no longer used.", - name - ); + )); } // Check that the license hasn't changed. for pkg in metadata.packages.iter().filter(|p| *p.name == *name) { match &pkg.license { None => { - tidy_error!( - bad, + check.error(format!( "dependency exception `{}` in workspace `{workspace}` does not declare a license expression", pkg.id - ); + )); } Some(pkg_license) => { if pkg_license.as_str() != *license { - println!( - "dependency exception `{name}` license in workspace `{workspace}` has changed" - ); - println!(" previously `{license}` now `{pkg_license}`"); - println!(" update EXCEPTIONS for the new license"); - *bad = true; + check.error(format!(r#"dependency exception `{name}` license in workspace `{workspace}` has changed + previously `{license}` now `{pkg_license}` + update EXCEPTIONS for the new license +"#)); } } } } + if LICENSES.contains(license) || LICENSES_TOOLS.contains(license) { + check.error(format!( + "dependency exception `{name}` is not necessary. `{license}` is an allowed license" + )); + } } let exception_names: Vec<_> = exceptions.iter().map(|(name, _license)| *name).collect(); @@ -778,26 +837,23 @@ fn check_license_exceptions( let license = match &pkg.license { Some(license) => license, None => { - tidy_error!( - bad, + check.error(format!( "dependency `{}` in workspace `{workspace}` does not define a license expression", pkg.id - ); + )); continue; } }; - if !LICENSES.contains(&license.as_str()) { - tidy_error!( - bad, + if !LICENSES.contains(&license.as_str()) && !LICENSES_TOOLS.contains(&license.as_str()) { + check.error(format!( "invalid license `{}` for package `{}` in workspace `{workspace}`", - license, - pkg.id - ); + license, pkg.id + )); } } } -fn check_runtime_no_duplicate_dependencies(metadata: &Metadata, bad: &mut bool) { +fn check_runtime_no_duplicate_dependencies(metadata: &Metadata, check: &mut RunningCheck) { let mut seen_pkgs = HashSet::new(); for pkg in &metadata.packages { if pkg.source.is_none() { @@ -808,25 +864,23 @@ fn check_runtime_no_duplicate_dependencies(metadata: &Metadata, bad: &mut bool) // depends on two version of (one for the `wasm32-wasip1` target and // another for the `wasm32-wasip2` target). if pkg.name.to_string() != "wasi" && !seen_pkgs.insert(&*pkg.name) { - tidy_error!( - bad, + check.error(format!( "duplicate package `{}` is not allowed for the standard library", pkg.name - ); + )); } } } -fn check_runtime_no_proc_macros(metadata: &Metadata, bad: &mut bool) { +fn check_runtime_no_proc_macros(metadata: &Metadata, check: &mut RunningCheck) { for pkg in &metadata.packages { if pkg.targets.iter().any(|target| target.is_proc_macro()) { - tidy_error!( - bad, + check.error(format!( "proc macro `{}` is not allowed as standard library dependency.\n\ Using proc macros in the standard library would break cross-compilation \ as proc-macros don't get shipped for the host tuple.", pkg.name - ); + )); } } } @@ -840,7 +894,8 @@ fn check_permitted_dependencies( descr: &str, permitted_dependencies: &[&'static str], restricted_dependency_crates: &[&'static str], - bad: &mut bool, + permitted_location: ListLocation, + check: &mut RunningCheck, ) { let mut has_permitted_dep_error = false; let mut deps = HashSet::new(); @@ -862,11 +917,10 @@ fn check_permitted_dependencies( } } if !deps.iter().any(|dep_id| compare(pkg_from_id(metadata, dep_id), permitted)) { - tidy_error!( - bad, + check.error(format!( "could not find allowed package `{permitted}`\n\ Remove from PERMITTED_DEPENDENCIES list if it is no longer used.", - ); + )); has_permitted_dep_error = true; } } @@ -893,14 +947,14 @@ fn check_permitted_dependencies( false }; if !is_eq { - tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id); + check.error(format!("Dependency for {descr} not explicitly permitted: {}", dep.id)); has_permitted_dep_error = true; } } } if has_permitted_dep_error { - eprintln!("Go to `{PERMITTED_DEPS_LOCATION}` for the list."); + eprintln!("Go to `{}:{}` for the list.", permitted_location.path, permitted_location.line); } } diff --git a/src/tools/tidy/src/diagnostics.rs b/src/tools/tidy/src/diagnostics.rs new file mode 100644 index 0000000000000..1e25f862522e8 --- /dev/null +++ b/src/tools/tidy/src/diagnostics.rs @@ -0,0 +1,274 @@ +use std::collections::HashSet; +use std::fmt::{Display, Formatter}; +use std::path::{Path, PathBuf}; +use std::sync::{Arc, Mutex}; + +use termcolor::{Color, WriteColor}; + +#[derive(Clone, Default)] +///CLI flags used by tidy. +pub struct TidyFlags { + ///Applies style and formatting changes during a tidy run. + bless: bool, +} + +impl TidyFlags { + pub fn new(cfg_args: &[String]) -> Self { + let mut flags = Self::default(); + + for arg in cfg_args { + match arg.as_str() { + "--bless" => flags.bless = true, + _ => continue, + } + } + flags + } +} + +/// Collects diagnostics from all tidy steps, and contains shared information +/// that determines how should message and logs be presented. +/// +/// Since checks are executed in parallel, the context is internally synchronized, to avoid +/// all checks to lock it explicitly. +#[derive(Clone)] +pub struct TidyCtx { + tidy_flags: TidyFlags, + diag_ctx: Arc>, +} + +impl TidyCtx { + pub fn new(root_path: &Path, verbose: bool, tidy_flags: TidyFlags) -> Self { + Self { + diag_ctx: Arc::new(Mutex::new(DiagCtxInner { + running_checks: Default::default(), + finished_checks: Default::default(), + root_path: root_path.to_path_buf(), + verbose, + })), + tidy_flags, + } + } + + pub fn is_bless_enabled(&self) -> bool { + self.tidy_flags.bless + } + + pub fn start_check>(&self, id: Id) -> RunningCheck { + let mut id = id.into(); + + let mut ctx = self.diag_ctx.lock().unwrap(); + + // Shorten path for shorter diagnostics + id.path = match id.path { + Some(path) => Some(path.strip_prefix(&ctx.root_path).unwrap_or(&path).to_path_buf()), + None => None, + }; + + ctx.start_check(id.clone()); + RunningCheck { + id, + bad: false, + ctx: self.diag_ctx.clone(), + #[cfg(test)] + errors: vec![], + } + } + + pub fn into_failed_checks(self) -> Vec { + let ctx = Arc::into_inner(self.diag_ctx).unwrap().into_inner().unwrap(); + assert!(ctx.running_checks.is_empty(), "Some checks are still running"); + ctx.finished_checks.into_iter().filter(|c| c.bad).collect() + } +} + +struct DiagCtxInner { + running_checks: HashSet, + finished_checks: HashSet, + verbose: bool, + root_path: PathBuf, +} + +impl DiagCtxInner { + fn start_check(&mut self, id: CheckId) { + if self.has_check_id(&id) { + panic!("Starting a check named `{id:?}` for the second time"); + } + + self.running_checks.insert(id); + } + + fn finish_check(&mut self, check: FinishedCheck) { + assert!( + self.running_checks.remove(&check.id), + "Finishing check `{:?}` that was not started", + check.id + ); + + if check.bad { + output_message("FAIL", Some(&check.id), Some(COLOR_ERROR)); + } else if self.verbose { + output_message("OK", Some(&check.id), Some(COLOR_SUCCESS)); + } + + self.finished_checks.insert(check); + } + + fn has_check_id(&self, id: &CheckId) -> bool { + self.running_checks + .iter() + .chain(self.finished_checks.iter().map(|c| &c.id)) + .any(|c| c == id) + } +} + +/// Identifies a single step +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +pub struct CheckId { + pub name: String, + pub path: Option, +} + +impl CheckId { + pub fn new(name: &'static str) -> Self { + Self { name: name.to_string(), path: None } + } + + pub fn path(self, path: &Path) -> Self { + Self { path: Some(path.to_path_buf()), ..self } + } +} + +impl From<&'static str> for CheckId { + fn from(name: &'static str) -> Self { + Self::new(name) + } +} + +impl Display for CheckId { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.name)?; + if let Some(path) = &self.path { + write!(f, " ({})", path.display())?; + } + Ok(()) + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub struct FinishedCheck { + id: CheckId, + bad: bool, +} + +impl FinishedCheck { + pub fn id(&self) -> &CheckId { + &self.id + } +} + +/// Represents a single tidy check, identified by its `name`, running. +pub struct RunningCheck { + id: CheckId, + bad: bool, + ctx: Arc>, + #[cfg(test)] + errors: Vec, +} + +impl RunningCheck { + /// Creates a new instance of a running check without going through the diag + /// context. + /// Useful if you want to run some functions from tidy without configuring + /// diagnostics. + pub fn new_noop() -> Self { + let ctx = TidyCtx::new(Path::new(""), false, TidyFlags::default()); + ctx.start_check("noop") + } + + /// Immediately output an error and mark the check as failed. + pub fn error(&mut self, msg: T) { + self.mark_as_bad(); + let msg = msg.to_string(); + output_message(&msg, Some(&self.id), Some(COLOR_ERROR)); + #[cfg(test)] + self.errors.push(msg); + } + + /// Immediately output a warning. + pub fn warning(&mut self, msg: T) { + output_message(&msg.to_string(), Some(&self.id), Some(COLOR_WARNING)); + } + + /// Output an informational message + pub fn message(&mut self, msg: T) { + output_message(&msg.to_string(), Some(&self.id), None); + } + + /// Output a message only if verbose output is enabled. + pub fn verbose_msg(&mut self, msg: T) { + if self.is_verbose_enabled() { + self.message(msg); + } + } + + /// Has an error already occured for this check? + pub fn is_bad(&self) -> bool { + self.bad + } + + /// Is verbose output enabled? + pub fn is_verbose_enabled(&self) -> bool { + self.ctx.lock().unwrap().verbose + } + + #[cfg(test)] + pub fn get_errors(&self) -> Vec { + self.errors.clone() + } + + fn mark_as_bad(&mut self) { + self.bad = true; + } +} + +impl Drop for RunningCheck { + fn drop(&mut self) { + self.ctx.lock().unwrap().finish_check(FinishedCheck { id: self.id.clone(), bad: self.bad }) + } +} + +pub const COLOR_SUCCESS: Color = Color::Green; +pub const COLOR_ERROR: Color = Color::Red; +pub const COLOR_WARNING: Color = Color::Yellow; + +/// Output a message to stderr. +/// The message can be optionally scoped to a certain check, and it can also have a certain color. +pub fn output_message(msg: &str, id: Option<&CheckId>, color: Option) { + use std::io::Write; + + use termcolor::{ColorChoice, ColorSpec, StandardStream}; + + let mut stderr = StandardStream::stderr(ColorChoice::Auto); + if let Some(color) = &color { + stderr.set_color(ColorSpec::new().set_fg(Some(*color))).unwrap(); + } + + match id { + Some(id) => { + write!(&mut stderr, "tidy [{}", id.name).unwrap(); + if let Some(path) = &id.path { + write!(&mut stderr, " ({})", path.display()).unwrap(); + } + write!(&mut stderr, "]").unwrap(); + } + None => { + write!(&mut stderr, "tidy").unwrap(); + } + } + if color.is_some() { + stderr.set_color(&ColorSpec::new()).unwrap(); + } + + writeln!(&mut stderr, ": {msg}").unwrap(); +} diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 08f6a3909f806..de21846ab1883 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -2,9 +2,11 @@ use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("edition").path(path)); walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap(); @@ -23,11 +25,10 @@ pub fn check(path: &Path, bad: &mut bool) { // Check that all packages use the 2021 edition. Virtual workspaces don't allow setting an // edition, so these shouldn't be checked. if is_package && !is_current_edition { - tidy_error!( - bad, + check.error(format!( "{} doesn't have `edition = \"2021\"` or `edition = \"2024\"` on a separate line", file.display() - ); + )); } }); } diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index 65aa89fe80169..9150d36339c87 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -22,6 +22,7 @@ use std::path::Path; use regex::Regex; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk, walk_many}; const ERROR_CODES_PATH: &str = "compiler/rustc_error_codes/src/lib.rs"; @@ -35,71 +36,50 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E07 const IGNORE_UI_TEST_CHECK: &[&str] = &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"]; -macro_rules! verbose_print { - ($verbose:expr, $($fmt:tt)*) => { - if $verbose { - println!("{}", format_args!($($fmt)*)); - } - }; -} - -pub fn check( - root_path: &Path, - search_paths: &[&Path], - verbose: bool, - ci_info: &crate::CiInfo, - bad: &mut bool, -) { - let mut errors = Vec::new(); +pub fn check(root_path: &Path, search_paths: &[&Path], ci_info: &crate::CiInfo, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("error_codes"); // Check that no error code explanation was removed. - check_removed_error_code_explanation(ci_info, bad); + check_removed_error_code_explanation(ci_info, &mut check); // Stage 1: create list - let error_codes = extract_error_codes(root_path, &mut errors); - if verbose { - println!("Found {} error codes", error_codes.len()); - println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); - } + let error_codes = extract_error_codes(root_path, &mut check); + check.verbose_msg(format!("Found {} error codes", error_codes.len())); + check.verbose_msg(format!("Highest error code: `{}`", error_codes.iter().max().unwrap())); // Stage 2: check list has docs - let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut errors, verbose); + let no_longer_emitted = check_error_codes_docs(root_path, &error_codes, &mut check); // Stage 3: check list has UI tests - check_error_codes_tests(root_path, &error_codes, &mut errors, verbose, &no_longer_emitted); + check_error_codes_tests(root_path, &error_codes, &mut check, &no_longer_emitted); // Stage 4: check list is emitted by compiler - check_error_codes_used(search_paths, &error_codes, &mut errors, &no_longer_emitted, verbose); - - // Print any errors. - for error in errors { - tidy_error!(bad, "{}", error); - } + check_error_codes_used(search_paths, &error_codes, &mut check, &no_longer_emitted); } -fn check_removed_error_code_explanation(ci_info: &crate::CiInfo, bad: &mut bool) { +fn check_removed_error_code_explanation(ci_info: &crate::CiInfo, check: &mut RunningCheck) { let Some(base_commit) = &ci_info.base_commit else { - eprintln!("Skipping error code explanation removal check"); + check.verbose_msg("Skipping error code explanation removal check"); return; }; let Some(diff) = crate::git_diff(base_commit, "--name-status") else { - *bad = true; - eprintln!("removed error code explanation tidy check: Failed to run git diff"); + check.error(format!("removed error code explanation: Failed to run git diff")); return; }; if diff.lines().any(|line| { line.starts_with('D') && line.contains("compiler/rustc_error_codes/src/error_codes/") }) { - *bad = true; - eprintln!("tidy check error: Error code explanations should never be removed!"); - eprintln!("Take a look at E0001 to see how to handle it."); + check.error(format!( + r#"Error code explanations should never be removed! +Take a look at E0001 to see how to handle it."# + )); return; } - println!("No error code explanation was removed!"); + check.verbose_msg("No error code explanation was removed!"); } /// Stage 1: Parses a list of error codes from `error_codes.rs`. -fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec { +fn extract_error_codes(root_path: &Path, check: &mut RunningCheck) -> Vec { let path = root_path.join(Path::new(ERROR_CODES_PATH)); let file = fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); @@ -117,7 +97,7 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec) -> Vec) -> Vec) -> Vec) -> Vec) -> Vec, - verbose: bool, + check: &mut RunningCheck, ) -> Vec { let docs_path = root_path.join(Path::new(ERROR_DOCS_PATH)); @@ -184,7 +164,7 @@ fn check_error_codes_docs( // Error if the file isn't markdown. if path.extension() != Some(OsStr::new("md")) { - errors.push(format!( + check.error(format!( "Found unexpected non-markdown file in error code docs directory: {}", path.display() )); @@ -196,7 +176,7 @@ fn check_error_codes_docs( let err_code = filename.unwrap().0; // `unwrap` is ok because we know the filename is in the correct format. if error_codes.iter().all(|e| e != err_code) { - errors.push(format!( + check.error(format!( "Found valid file `{}` in error code docs directory without corresponding \ entry in `rustc_error_codes/src/lib.rs`", path.display() @@ -208,11 +188,10 @@ fn check_error_codes_docs( check_explanation_has_doctest(contents, err_code); if emit_ignore_warning { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Error code `{err_code}` uses the ignore header. This should not be used, add the error code to the \ `IGNORE_DOCTEST_CHECK` constant instead." - ); + )); } if no_longer_emitted { @@ -220,11 +199,10 @@ fn check_error_codes_docs( } if !found_code_example { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Error code `{err_code}` doesn't have a code example, all error codes are expected to have one \ (even if untested)." - ); + )); return; } @@ -232,12 +210,12 @@ fn check_error_codes_docs( // Check that the explanation has a doctest, and if it shouldn't, that it doesn't if !found_proper_doctest && !test_ignored { - errors.push(format!( + check.error(format!( "`{}` doesn't use its own error code in compile_fail example", path.display(), )); } else if found_proper_doctest && test_ignored { - errors.push(format!( + check.error(format!( "`{}` has a compile_fail doctest with its own error code, it shouldn't \ be listed in `IGNORE_DOCTEST_CHECK`", path.display(), @@ -289,8 +267,7 @@ fn check_explanation_has_doctest(explanation: &str, err_code: &str) -> (bool, bo fn check_error_codes_tests( root_path: &Path, error_codes: &[String], - errors: &mut Vec, - verbose: bool, + check: &mut RunningCheck, no_longer_emitted: &[String], ) { let tests_path = root_path.join(Path::new(ERROR_TESTS_PATH)); @@ -299,15 +276,14 @@ fn check_error_codes_tests( let test_path = tests_path.join(format!("{code}.stderr")); if !test_path.exists() && !IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Error code `{code}` needs to have at least one UI test in the `tests/error-codes/` directory`!" - ); + )); continue; } if IGNORE_UI_TEST_CHECK.contains(&code.as_str()) { if test_path.exists() { - errors.push(format!( + check.error(format!( "Error code `{code}` has a UI test in `tests/ui/error-codes/{code}.rs`, it shouldn't be listed in `EXEMPTED_FROM_TEST`!" )); } @@ -317,11 +293,10 @@ fn check_error_codes_tests( let file = match fs::read_to_string(&test_path) { Ok(file) => file, Err(err) => { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Failed to read UI test file (`{}`) for `{code}` but the file exists. The test is assumed to work:\n{err}", test_path.display() - ); + )); continue; } }; @@ -343,10 +318,9 @@ fn check_error_codes_tests( } if !found_code { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Error code `{code}` has a UI test file, but doesn't contain its own error code!" - ); + )); } } } @@ -355,9 +329,8 @@ fn check_error_codes_tests( fn check_error_codes_used( search_paths: &[&Path], error_codes: &[String], - errors: &mut Vec, + check: &mut RunningCheck, no_longer_emitted: &[String], - verbose: bool, ) { // Search for error codes in the form `E0123`. let regex = Regex::new(r#"\bE\d{4}\b"#).unwrap(); @@ -384,7 +357,7 @@ fn check_error_codes_used( if !error_codes.contains(&error_code) { // This error code isn't properly defined, we must error. - errors.push(format!("Error code `{error_code}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`.")); + check.error(format!("Error code `{error_code}` is used in the compiler but not defined and documented in `compiler/rustc_error_codes/src/lib.rs`.")); continue; } @@ -397,7 +370,7 @@ fn check_error_codes_used( for code in error_codes { if !found_codes.contains(code) && !no_longer_emitted.contains(code) { - errors.push(format!( + check.error(format!( "Error code `{code}` exists, but is not emitted by the compiler!\n\ Please mark the code as no longer emitted by adding the following note to the top of the `EXXXX.md` file:\n\ `#### Note: this error code is no longer emitted by the compiler`\n\ @@ -406,10 +379,9 @@ fn check_error_codes_used( } if found_codes.contains(code) && no_longer_emitted.contains(code) { - verbose_print!( - verbose, + check.verbose_msg(format!( "warning: Error code `{code}` is used when it's marked as \"no longer emitted\"" - ); + )); } } } diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index bc217a55cc199..19c773d12f7fa 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -3,6 +3,9 @@ use std::fs; use std::path::Path; +use crate::deps::WorkspaceInfo; +use crate::diagnostics::TidyCtx; + /// List of allowed sources for packages. const ALLOWED_SOURCES: &[&str] = &[ r#""registry+https://github.com/rust-lang/crates.io-index""#, @@ -12,23 +15,25 @@ const ALLOWED_SOURCES: &[&str] = &[ /// Checks for external package sources. `root` is the path to the directory that contains the /// workspace `Cargo.toml`. -pub fn check(root: &Path, bad: &mut bool) { - for &(workspace, _, _, submodules) in crate::deps::WORKSPACES { +pub fn check(root: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("extdeps"); + + for &WorkspaceInfo { path, submodules, .. } in crate::deps::WORKSPACES { if crate::deps::has_missing_submodule(root, submodules) { continue; } // FIXME check other workspaces too // `Cargo.lock` of rust. - let path = root.join(workspace).join("Cargo.lock"); + let lockfile = root.join(path).join("Cargo.lock"); - if !path.exists() { - tidy_error!(bad, "the `{workspace}` workspace doesn't have a Cargo.lock"); + if !lockfile.exists() { + check.error(format!("the `{path}` workspace doesn't have a Cargo.lock")); continue; } // Open and read the whole file. - let cargo_lock = t!(fs::read_to_string(&path)); + let cargo_lock = t!(fs::read_to_string(&lockfile)); // Process each line. for line in cargo_lock.lines() { @@ -42,7 +47,7 @@ pub fn check(root: &Path, bad: &mut bool) { // Ensure source is allowed. if !ALLOWED_SOURCES.contains(&source) { - tidy_error!(bad, "invalid source: {}", source); + check.error(format!("invalid source: {}", source)); } } } diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs index a6b50b5ca4701..a45af7fcf1580 100644 --- a/src/tools/tidy/src/extra_checks/mod.rs +++ b/src/tools/tidy/src/extra_checks/mod.rs @@ -24,6 +24,7 @@ use std::str::FromStr; use std::{fmt, fs, io}; use crate::CiInfo; +use crate::diagnostics::TidyCtx; mod rustdoc_js; @@ -51,11 +52,12 @@ pub fn check( tools_path: &Path, npm: &Path, cargo: &Path, - bless: bool, extra_checks: Option<&str>, pos_args: &[String], - bad: &mut bool, + tidy_ctx: TidyCtx, ) { + let mut check = tidy_ctx.start_check("extra_checks"); + if let Err(e) = check_impl( root_path, outdir, @@ -64,11 +66,11 @@ pub fn check( tools_path, npm, cargo, - bless, extra_checks, pos_args, + &tidy_ctx, ) { - tidy_error!(bad, "{e}"); + check.error(e); } } @@ -80,12 +82,13 @@ fn check_impl( tools_path: &Path, npm: &Path, cargo: &Path, - bless: bool, extra_checks: Option<&str>, pos_args: &[String], + tidy_ctx: &TidyCtx, ) -> Result<(), Error> { let show_diff = std::env::var("TIDY_PRINT_DIFF").is_ok_and(|v| v.eq_ignore_ascii_case("true") || v == "1"); + let bless = tidy_ctx.is_bless_enabled(); // Split comma-separated args up let mut lint_args = match extra_checks { @@ -618,7 +621,7 @@ fn spellcheck_runner( args: &[&str], ) -> Result<(), Error> { let bin_path = - crate::ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", "1.34.0")?; + crate::ensure_version_or_cargo_install(outdir, cargo, "typos-cli", "typos", "1.38.1")?; match Command::new(bin_path).current_dir(src_root).args(args).status() { Ok(status) => { if status.success() { diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 6618ba24be609..08061bd834e3c 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -16,6 +16,7 @@ use std::num::NonZeroU32; use std::path::{Path, PathBuf}; use std::{fmt, fs}; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, filter_not_rust, walk, walk_many}; #[cfg(test)] @@ -91,13 +92,14 @@ pub fn check( tests_path: &Path, compiler_path: &Path, lib_path: &Path, - bad: &mut bool, - verbose: bool, + tidy_ctx: TidyCtx, ) -> CollectedFeatures { - let mut features = collect_lang_features(compiler_path, bad); + let mut check = tidy_ctx.start_check("features"); + + let mut features = collect_lang_features(compiler_path, &mut check); assert!(!features.is_empty()); - let lib_features = get_and_check_lib_features(lib_path, bad, &features); + let lib_features = get_and_check_lib_features(lib_path, &mut check, &features); assert!(!lib_features.is_empty()); walk_many( @@ -121,7 +123,7 @@ pub fn check( for (i, line) in contents.lines().enumerate() { let mut err = |msg: &str| { - tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg); + check.error(format!("{}:{}: {}", file.display(), i + 1, msg)); }; let gate_test_str = "gate-test-"; @@ -175,7 +177,7 @@ pub fn check( } if !gate_untested.is_empty() { - tidy_error!(bad, "Found {} features without a gate test.", gate_untested.len()); + check.error(format!("Found {} features without a gate test.", gate_untested.len())); } let (version, channel) = get_version_and_channel(src_path); @@ -189,39 +191,32 @@ pub fn check( let file = feature.file.display(); let line = feature.line; if since > version && since != Version::CurrentPlaceholder { - tidy_error!( - bad, + check.error(format!( "{file}:{line}: The stabilization version {since} of {kind} feature `{feature_name}` is newer than the current {version}" - ); + )); } if channel == "nightly" && since == version { - tidy_error!( - bad, + check.error(format!( "{file}:{line}: The stabilization version {since} of {kind} feature `{feature_name}` is written out but should be {}", version::VERSION_PLACEHOLDER - ); + )); } if channel != "nightly" && since == Version::CurrentPlaceholder { - tidy_error!( - bad, + check.error(format!( "{file}:{line}: The placeholder use of {kind} feature `{feature_name}` is not allowed on the {channel} channel", - ); + )); } } - if *bad { - return CollectedFeatures { lib: lib_features, lang: features }; - } - - if verbose { + if !check.is_bad() && check.is_verbose_enabled() { let mut lines = Vec::new(); lines.extend(format_features(&features, "lang")); lines.extend(format_features(&lib_features, "lib")); - lines.sort(); - for line in lines { - println!("* {line}"); - } + + check.verbose_msg( + lines.into_iter().map(|l| format!("* {l}")).collect::>().join("\n"), + ); } CollectedFeatures { lib: lib_features, lang: features } @@ -275,15 +270,20 @@ fn test_filen_gate<'f>(filen_underscore: &'f str, features: &mut Features) -> Op None } -pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features { +pub fn collect_lang_features(base_compiler_path: &Path, check: &mut RunningCheck) -> Features { let mut features = Features::new(); - collect_lang_features_in(&mut features, base_compiler_path, "accepted.rs", bad); - collect_lang_features_in(&mut features, base_compiler_path, "removed.rs", bad); - collect_lang_features_in(&mut features, base_compiler_path, "unstable.rs", bad); + collect_lang_features_in(&mut features, base_compiler_path, "accepted.rs", check); + collect_lang_features_in(&mut features, base_compiler_path, "removed.rs", check); + collect_lang_features_in(&mut features, base_compiler_path, "unstable.rs", check); features } -fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, bad: &mut bool) { +fn collect_lang_features_in( + features: &mut Features, + base: &Path, + file: &str, + check: &mut RunningCheck, +) { let path = base.join("rustc_feature").join("src").join(file); let contents = t!(fs::read_to_string(&path)); @@ -315,13 +315,11 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba if line.starts_with(FEATURE_GROUP_START_PREFIX) { if in_feature_group { - tidy_error!( - bad, - "{}:{}: \ + check.error(format!( + "{}:{line_number}: \ new feature group is started without ending the previous one", - path.display(), - line_number, - ); + path.display() + )); } in_feature_group = true; @@ -353,14 +351,10 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba let since = match since_str.parse() { Ok(since) => Some(since), Err(err) => { - tidy_error!( - bad, - "{}:{}: failed to parse since: {} ({:?})", - path.display(), - line_number, - since_str, - err, - ); + check.error(format!( + "{}:{line_number}: failed to parse since: {since_str} ({err:?})", + path.display() + )); None } }; @@ -371,13 +365,10 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba let correct_index = match prev_names.binary_search(&name) { Ok(_) => { // This only occurs when the feature name has already been declared. - tidy_error!( - bad, - "{}:{}: duplicate feature {}", - path.display(), - line_number, - name, - ); + check.error(format!( + "{}:{line_number}: duplicate feature {name}", + path.display() + )); // skip any additional checks for this line continue; } @@ -398,14 +389,10 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba ) }; - tidy_error!( - bad, - "{}:{}: feature {} is not sorted by feature name (should be {})", + check.error(format!( + "{}:{line_number}: feature {name} is not sorted by feature name (should be {correct_placement})", path.display(), - line_number, - name, - correct_placement, - ); + )); } prev_names.push(name); } @@ -413,13 +400,10 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba let issue_str = parts.next().unwrap().trim(); let tracking_issue = if issue_str.starts_with("None") { if level == Status::Unstable && !next_feature_omits_tracking_issue { - tidy_error!( - bad, - "{}:{}: no tracking issue for feature {}", + check.error(format!( + "{}:{line_number}: no tracking issue for feature {name}", path.display(), - line_number, - name, - ); + )); } None } else { @@ -428,13 +412,11 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba }; match features.entry(name.to_owned()) { Entry::Occupied(e) => { - tidy_error!( - bad, - "{}:{} feature {name} already specified with status '{}'", + check.error(format!( + "{}:{line_number} feature {name} already specified with status '{}'", path.display(), - line_number, e.get().level, - ); + )); } Entry::Vacant(e) => { e.insert(Feature { @@ -458,7 +440,7 @@ fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, ba fn get_and_check_lib_features( base_src_path: &Path, - bad: &mut bool, + check: &mut RunningCheck, lang_features: &Features, ) -> Features { let mut lib_features = Features::new(); @@ -469,16 +451,12 @@ fn get_and_check_lib_features( && f.tracking_issue != s.tracking_issue && f.level != Status::Accepted { - tidy_error!( - bad, - "{}:{}: feature gate {} has inconsistent `issue`: \"{}\" mismatches the {} `issue` of \"{}\"", + check.error(format!( + "{}:{line}: feature gate {name} has inconsistent `issue`: \"{}\" mismatches the {display} `issue` of \"{}\"", file.display(), - line, - name, f.tracking_issue_display(), - display, s.tracking_issue_display(), - ); + )); } }; check_features(&f, lang_features, "corresponding lang feature"); @@ -486,7 +464,7 @@ fn get_and_check_lib_features( lib_features.insert(name.to_owned(), f); } Err(msg) => { - tidy_error!(bad, "{}:{}: {}", file.display(), line, msg); + check.error(format!("{}:{line}: {msg}", file.display())); } }); lib_features diff --git a/src/tools/tidy/src/filenames.rs b/src/tools/tidy/src/filenames.rs index 53115f4eaa41b..a355588fd99ca 100644 --- a/src/tools/tidy/src/filenames.rs +++ b/src/tools/tidy/src/filenames.rs @@ -10,7 +10,10 @@ use std::path::Path; use std::process::Command; -pub fn check(root_path: &Path, bad: &mut bool) { +use crate::diagnostics::TidyCtx; + +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("filenames"); let stat_output = Command::new("git") .arg("-C") .arg(root_path) @@ -20,20 +23,17 @@ pub fn check(root_path: &Path, bad: &mut bool) { .stdout; for filename in stat_output.split(|&b| b == 0) { match str::from_utf8(filename) { - Err(_) => tidy_error!( - bad, + Err(_) => check.error(format!( r#"non-UTF8 file names are not supported: "{}""#, String::from_utf8_lossy(filename), - ), - Ok(name) if name.chars().any(|c| c.is_control()) => tidy_error!( - bad, + )), + Ok(name) if name.chars().any(|c| c.is_control()) => check.error(format!( r#"control characters are not supported in file names: "{}""#, String::from_utf8_lossy(filename), - ), - Ok(name) if name.contains(':') => tidy_error!( - bad, + )), + Ok(name) if name.contains(':') => check.error(format!( r#"":" is not supported in file names because of Windows compatibility: "{name}""#, - ), + )), _ => (), } } diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs index 48d14a37514bd..7583241ea638a 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -5,8 +5,11 @@ use std::fs::OpenOptions; use std::io::Write; use std::path::Path; +use fluent_syntax::ast::Entry; +use fluent_syntax::parser; use regex::Regex; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn message() -> &'static Regex { @@ -14,42 +17,40 @@ fn message() -> &'static Regex { } fn is_fluent(path: &Path) -> bool { - path.extension().is_some_and(|ext| ext == "flt") + path.extension().is_some_and(|ext| ext == "ftl") } fn check_alphabetic( filename: &str, fluent: &str, - bad: &mut bool, + check: &mut RunningCheck, all_defined_msgs: &mut HashMap, ) { - let mut matches = message().captures_iter(fluent).peekable(); - while let Some(m) = matches.next() { - let name = m.get(1).unwrap(); - if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { - tidy_error!( - bad, - "{filename}: message `{}` is already defined in {}", - name.as_str(), - defined_filename, - ); - } + let Ok(resource) = parser::parse(fluent) else { + panic!("Errors encountered while parsing fluent file `{filename}`"); + }; - all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned()); + let mut prev: Option<&str> = None; - if let Some(next) = matches.peek() { - let next = next.get(1).unwrap(); - if name.as_str() > next.as_str() { - tidy_error!( - bad, - "{filename}: message `{}` appears before `{}`, but is alphabetically later than it -run `./x.py test tidy --bless` to sort the file correctly", - name.as_str(), - next.as_str() - ); + for entry in &resource.body { + if let Entry::Message(msg) = entry { + let name: &str = msg.id.name; + if let Some(defined_filename) = all_defined_msgs.get(name) { + check.error(format!( + "{filename}: message `{name}` is already defined in {defined_filename}", + )); + } else { + all_defined_msgs.insert(name.to_string(), filename.to_owned()); } - } else { - break; + if let Some(prev) = prev + && prev > name + { + check.error(format!( + "{filename}: message `{prev}` appears before `{name}`, but is alphabetically \ +later than it. Run `./x.py test tidy --bless` to sort the file correctly", + )); + } + prev = Some(name); } } } @@ -57,7 +58,7 @@ run `./x.py test tidy --bless` to sort the file correctly", fn sort_messages( filename: &str, fluent: &str, - bad: &mut bool, + check: &mut RunningCheck, all_defined_msgs: &mut HashMap, ) -> String { let mut chunks = vec![]; @@ -65,12 +66,10 @@ fn sort_messages( for line in fluent.lines() { if let Some(name) = message().find(line) { if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { - tidy_error!( - bad, - "{filename}: message `{}` is already defined in {}", + check.error(format!( + "{filename}: message `{}` is already defined in {defined_filename}", name.as_str(), - defined_filename, - ); + )); } all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned()); @@ -88,7 +87,10 @@ fn sort_messages( out } -pub fn check(path: &Path, bless: bool, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_alphabetical").path(path)); + let bless = tidy_ctx.is_bless_enabled(); + let mut all_defined_msgs = HashMap::new(); walk( path, @@ -98,7 +100,7 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) { let sorted = sort_messages( ent.path().to_str().unwrap(), contents, - bad, + &mut check, &mut all_defined_msgs, ); if sorted != contents { @@ -110,12 +112,14 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) { check_alphabetic( ent.path().to_str().unwrap(), contents, - bad, + &mut check, &mut all_defined_msgs, ); } }, ); - crate::fluent_used::check(path, all_defined_msgs, bad); + assert!(!all_defined_msgs.is_empty()); + + crate::fluent_used::check(path, all_defined_msgs, tidy_ctx); } diff --git a/src/tools/tidy/src/fluent_lowercase.rs b/src/tools/tidy/src/fluent_lowercase.rs index 13f0319909e17..690b733a5b648 100644 --- a/src/tools/tidy/src/fluent_lowercase.rs +++ b/src/tools/tidy/src/fluent_lowercase.rs @@ -4,6 +4,7 @@ use std::path::Path; use fluent_syntax::ast::{Entry, Message, PatternElement}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[rustfmt::skip] @@ -34,7 +35,7 @@ fn is_allowed_capitalized_word(msg: &str) -> bool { }) } -fn check_lowercase(filename: &str, contents: &str, bad: &mut bool) { +fn check_lowercase(filename: &str, contents: &str, check: &mut RunningCheck) { let (Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents); for entry in &parse.body { @@ -45,20 +46,20 @@ fn check_lowercase(filename: &str, contents: &str, bad: &mut bool) { && value.chars().next().is_some_and(char::is_uppercase) && !is_allowed_capitalized_word(value) { - tidy_error!( - bad, + check.error(format!( "{filename}: message `{value}` starts with an uppercase letter. Fix it or add it to `ALLOWED_CAPITALIZED_WORDS`" - ); + )); } } } -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_lowercase").path(path)); walk( path, |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), &mut |ent, contents| { - check_lowercase(ent.path().to_str().unwrap(), contents, bad); + check_lowercase(ent.path().to_str().unwrap(), contents, &mut check); }, ); } diff --git a/src/tools/tidy/src/fluent_period.rs b/src/tools/tidy/src/fluent_period.rs index 836b5699289f2..e7d59e2ce2a9c 100644 --- a/src/tools/tidy/src/fluent_period.rs +++ b/src/tools/tidy/src/fluent_period.rs @@ -4,6 +4,7 @@ use std::path::Path; use fluent_syntax::ast::{Entry, PatternElement}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn filter_fluent(path: &Path) -> bool { @@ -20,7 +21,7 @@ const ALLOWLIST: &[&str] = &[ "incremental_corrupt_file", ]; -fn check_period(filename: &str, contents: &str, bad: &mut bool) { +fn check_period(filename: &str, contents: &str, check: &mut RunningCheck) { if filename.contains("codegen") { // FIXME: Too many codegen messages have periods right now... return; @@ -40,7 +41,7 @@ fn check_period(filename: &str, contents: &str, bad: &mut bool) { if value.ends_with(".") && !value.ends_with("...") { let ll = find_line(contents, value); let name = m.id.name; - tidy_error!(bad, "{filename}:{ll}: message `{name}` ends in a period"); + check.error(format!("{filename}:{ll}: message `{name}` ends in a period")); } } @@ -56,7 +57,7 @@ fn check_period(filename: &str, contents: &str, bad: &mut bool) { { let ll = find_line(contents, value); let name = attr.id.name; - tidy_error!(bad, "{filename}:{ll}: attr `{name}` ends in a period"); + check.error(format!("{filename}:{ll}: attr `{name}` ends in a period")); } } } @@ -74,12 +75,14 @@ fn find_line(haystack: &str, needle: &str) -> usize { 1 } -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_period").path(path)); + walk( path, |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), &mut |ent, contents| { - check_period(ent.path().to_str().unwrap(), contents, bad); + check_period(ent.path().to_str().unwrap(), contents, &mut check); }, ); } diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs index 909bf482ddfce..75da1d7ea49d7 100644 --- a/src/tools/tidy/src/fluent_used.rs +++ b/src/tools/tidy/src/fluent_used.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; fn filter_used_messages( @@ -27,13 +28,15 @@ fn filter_used_messages( } } -pub fn check(path: &Path, mut all_defined_msgs: HashMap, bad: &mut bool) { +pub fn check(path: &Path, mut all_defined_msgs: HashMap, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("fluent_used").path(path)); + let mut msgs_appear_only_once = HashMap::new(); walk(path, |path, _| filter_dirs(path), &mut |_, contents| { filter_used_messages(contents, &mut all_defined_msgs, &mut msgs_appear_only_once); }); for (name, filename) in msgs_appear_only_once { - tidy_error!(bad, "{filename}: message `{}` is not used", name,); + check.error(format!("{filename}: message `{name}` is not used")); } } diff --git a/src/tools/tidy/src/gcc_submodule.rs b/src/tools/tidy/src/gcc_submodule.rs index 217eaf1758c48..46b816f5c9d0e 100644 --- a/src/tools/tidy/src/gcc_submodule.rs +++ b/src/tools/tidy/src/gcc_submodule.rs @@ -4,7 +4,11 @@ use std::path::Path; use std::process::Command; -pub fn check(root_path: &Path, compiler_path: &Path, bad: &mut bool) { +use crate::diagnostics::TidyCtx; + +pub fn check(root_path: &Path, compiler_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("gcc_submodule"); + let cg_gcc_version_path = compiler_path.join("rustc_codegen_gcc/libgccjit.version"); let cg_gcc_version = std::fs::read_to_string(&cg_gcc_version_path) .unwrap_or_else(|_| { @@ -26,7 +30,7 @@ pub fn check(root_path: &Path, compiler_path: &Path, bad: &mut bool) { // Git is not available or we are in a tarball if !git_output.status.success() { - eprintln!("Cannot figure out the SHA of the GCC submodule"); + check.message("Cannot figure out the SHA of the GCC submodule"); return; } @@ -43,12 +47,11 @@ pub fn check(root_path: &Path, compiler_path: &Path, bad: &mut bool) { // The SHA can start with + if the submodule is modified or - if it is not checked out. let gcc_submodule_sha = git_output.trim_start_matches(['+', '-']); if gcc_submodule_sha != cg_gcc_version { - *bad = true; - eprintln!( + check.error(format!( r#"Commit SHA of the src/gcc submodule (`{gcc_submodule_sha}`) does not match the required GCC version of the GCC codegen backend (`{cg_gcc_version}`). Make sure to set the src/gcc submodule to commit {cg_gcc_version}. The GCC codegen backend commit is configured at {}."#, cg_gcc_version_path.display(), - ); + )); } } diff --git a/src/tools/tidy/src/known_bug.rs b/src/tools/tidy/src/known_bug.rs index e1921715ab922..e6038341ba966 100644 --- a/src/tools/tidy/src/known_bug.rs +++ b/src/tools/tidy/src/known_bug.rs @@ -2,9 +2,11 @@ use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::*; -pub fn check(filepath: &Path, bad: &mut bool) { +pub fn check(filepath: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("known_bug").path(filepath)); walk(filepath, |path, _is_dir| filter_not_rust(path), &mut |entry, contents| { let file: &Path = entry.path(); @@ -19,11 +21,10 @@ pub fn check(filepath: &Path, bad: &mut bool) { [.., "tests", "crashes", "auxiliary", _aux_file_rs] ) && !contents.lines().any(|line| line.starts_with("//@ known-bug: ")) { - tidy_error!( - bad, + check.error(format!( "{} crash/ice test does not have a \"//@ known-bug: \" directive", file.display() - ); + )); } }); } diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 2a9c3963d2d86..756f9790e04ad 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -11,7 +11,8 @@ use std::{env, io}; use build_helper::ci::CiEnv; use build_helper::git::{GitConfig, get_closest_upstream_commit}; use build_helper::stage0_parser::{Stage0Config, parse_stage0_file}; -use termcolor::WriteColor; + +use crate::diagnostics::{RunningCheck, TidyCtx}; macro_rules! static_regex { ($re:literal) => {{ @@ -43,35 +44,6 @@ macro_rules! t { }; } -macro_rules! tidy_error { - ($bad:expr, $($fmt:tt)*) => ({ - $crate::tidy_error(&format_args!($($fmt)*).to_string()).expect("failed to output error"); - *$bad = true; - }); -} - -macro_rules! tidy_error_ext { - ($tidy_error:path, $bad:expr, $($fmt:tt)*) => ({ - $tidy_error(&format_args!($($fmt)*).to_string()).expect("failed to output error"); - *$bad = true; - }); -} - -fn tidy_error(args: &str) -> std::io::Result<()> { - use std::io::Write; - - use termcolor::{Color, ColorChoice, ColorSpec, StandardStream}; - - let mut stderr = StandardStream::stdout(ColorChoice::Auto); - stderr.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?; - - write!(&mut stderr, "tidy error")?; - stderr.set_color(&ColorSpec::new())?; - - writeln!(&mut stderr, ": {args}")?; - Ok(()) -} - pub struct CiInfo { pub git_merge_commit_email: String, pub nightly_branch: String, @@ -80,7 +52,9 @@ pub struct CiInfo { } impl CiInfo { - pub fn new(bad: &mut bool) -> Self { + pub fn new(tidy_ctx: TidyCtx) -> Self { + let mut check = tidy_ctx.start_check("CI history"); + let stage0 = parse_stage0_file(); let Stage0Config { nightly_branch, git_merge_commit_email, .. } = stage0.config; @@ -93,11 +67,14 @@ impl CiInfo { let base_commit = match get_closest_upstream_commit(None, &info.git_config(), info.ci_env) { Ok(Some(commit)) => Some(commit), Ok(None) => { - info.error_if_in_ci("no base commit found", bad); + info.error_if_in_ci("no base commit found", &mut check); None } Err(error) => { - info.error_if_in_ci(&format!("failed to retrieve base commit: {error}"), bad); + info.error_if_in_ci( + &format!("failed to retrieve base commit: {error}"), + &mut check, + ); None } }; @@ -112,12 +89,11 @@ impl CiInfo { } } - pub fn error_if_in_ci(&self, msg: &str, bad: &mut bool) { + pub fn error_if_in_ci(&self, msg: &str, check: &mut RunningCheck) { if self.ci_env.is_running_in_ci() { - *bad = true; - eprintln!("tidy check error: {msg}"); + check.error(msg); } else { - eprintln!("tidy check warning: {msg}. Some checks will be skipped."); + check.warning(format!("{msg}. Some checks will be skipped.")); } } } @@ -191,12 +167,16 @@ pub fn ensure_version_or_cargo_install( bin_name: &str, version: &str, ) -> io::Result { + let tool_root_dir = build_dir.join("misc-tools"); + let tool_bin_dir = tool_root_dir.join("bin"); + let bin_path = tool_bin_dir.join(bin_name).with_extension(env::consts::EXE_EXTENSION); + // ignore the process exit code here and instead just let the version number check fail. // we also importantly don't return if the program wasn't installed, // instead we want to continue to the fallback. 'ck: { // FIXME: rewrite as if-let chain once this crate is 2024 edition. - let Ok(output) = Command::new(bin_name).arg("--version").output() else { + let Ok(output) = Command::new(&bin_path).arg("--version").output() else { break 'ck; }; let Ok(s) = str::from_utf8(&output.stdout) else { @@ -206,18 +186,16 @@ pub fn ensure_version_or_cargo_install( break 'ck; }; if v == version { - return Ok(PathBuf::from(bin_name)); + return Ok(bin_path); } } - let tool_root_dir = build_dir.join("misc-tools"); - let tool_bin_dir = tool_root_dir.join("bin"); eprintln!("building external tool {bin_name} from package {pkg_name}@{version}"); // use --force to ensure that if the required version is bumped, we update it. // use --target-dir to ensure we have a build cache so repeated invocations aren't slow. // modify PATH so that cargo doesn't print a warning telling the user to modify the path. - let cargo_exit_code = Command::new(cargo) - .args(["install", "--locked", "--force", "--quiet"]) + let mut cmd = Command::new(cargo); + cmd.args(["install", "--locked", "--force", "--quiet"]) .arg("--root") .arg(&tool_root_dir) .arg("--target-dir") @@ -230,14 +208,19 @@ pub fn ensure_version_or_cargo_install( .chain(std::iter::once(tool_bin_dir.clone())), ) .expect("build dir contains invalid char"), - ) - .env("RUSTFLAGS", "-Copt-level=0") - .spawn()? - .wait()?; + ); + + // On CI, we set opt-level flag for quicker installation. + // Since lower opt-level decreases the tool's performance, + // we don't set this option on local. + if CiEnv::is_ci() { + cmd.env("RUSTFLAGS", "-Copt-level=0"); + } + + let cargo_exit_code = cmd.spawn()?.wait()?; if !cargo_exit_code.success() { return Err(io::Error::other("cargo install failed")); } - let bin_path = tool_bin_dir.join(bin_name); assert!( matches!(bin_path.try_exists(), Ok(true)), "cargo install did not produce the expected binary" @@ -250,6 +233,7 @@ pub mod alphabetical; pub mod bins; pub mod debug_artifacts; pub mod deps; +pub mod diagnostics; pub mod edition; pub mod error_codes; pub mod extdeps; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index f9e82341b7aa5..94c24f11ed12f 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -8,10 +8,10 @@ use std::collections::VecDeque; use std::num::NonZeroUsize; use std::path::PathBuf; use std::str::FromStr; -use std::sync::atomic::{AtomicBool, Ordering}; use std::thread::{self, ScopedJoinHandle, scope}; use std::{env, process}; +use tidy::diagnostics::{COLOR_ERROR, COLOR_SUCCESS, TidyCtx, TidyFlags, output_message}; use tidy::*; fn main() { @@ -46,13 +46,12 @@ fn main() { None => (&args[..], [].as_slice()), }; let verbose = cfg_args.iter().any(|s| *s == "--verbose"); - let bless = cfg_args.iter().any(|s| *s == "--bless"); let extra_checks = cfg_args.iter().find(|s| s.starts_with("--extra-checks=")).map(String::as_str); - let mut bad = false; - let ci_info = CiInfo::new(&mut bad); - let bad = std::sync::Arc::new(AtomicBool::new(bad)); + let tidy_flags = TidyFlags::new(cfg_args); + let tidy_ctx = TidyCtx::new(&root_path, verbose, tidy_flags); + let ci_info = CiInfo::new(tidy_ctx.clone()); let drain_handles = |handles: &mut VecDeque>| { // poll all threads for completion before awaiting the oldest one @@ -87,12 +86,9 @@ fn main() { (@ $p:ident, name=$name:expr $(, $args:expr)* ) => { drain_handles(&mut handles); + let tidy_ctx = tidy_ctx.clone(); let handle = thread::Builder::new().name($name).spawn_scoped(s, || { - let mut flag = false; - $p::check($($args, )* &mut flag); - if (flag) { - bad.store(true, Ordering::Relaxed); - } + $p::check($($args, )* tidy_ctx); }).unwrap(); handles.push_back(handle); } @@ -101,15 +97,15 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo, bless); + check!(deps, &root_path, &cargo); check!(extdeps, &root_path); // Checks over tests. check!(tests_placement, &root_path); check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); - check!(ui_tests, &root_path, bless); - check!(mir_opt_tests, &tests_path, bless); + check!(ui_tests, &root_path); + check!(mir_opt_tests, &tests_path); check!(rustdoc_gui_tests, &tests_path); check!(rustdoc_css_themes, &librustdoc_path); check!(rustdoc_templates, &librustdoc_path); @@ -118,8 +114,8 @@ fn main() { check!(unknown_revision, &tests_path); // Checks that only make sense for the compiler. - check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose, &ci_info); - check!(fluent_alphabetical, &compiler_path, bless); + check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], &ci_info); + check!(fluent_alphabetical, &compiler_path); check!(fluent_period, &compiler_path); check!(fluent_lowercase, &compiler_path); check!(target_policy, &root_path); @@ -155,25 +151,12 @@ fn main() { check!(x_version, &root_path, &cargo); check!(triagebot, &root_path); - check!(filenames, &root_path); let collected = { drain_handles(&mut handles); - let mut flag = false; - let r = features::check( - &src_path, - &tests_path, - &compiler_path, - &library_path, - &mut flag, - verbose, - ); - if flag { - bad.store(true, Ordering::Relaxed); - } - r + features::check(&src_path, &tests_path, &compiler_path, &library_path, tidy_ctx.clone()) }; check!(unstable_book, &src_path, collected); @@ -186,14 +169,27 @@ fn main() { &tools_path, &npm, &cargo, - bless, extra_checks, pos_args ); }); - if bad.load(Ordering::Relaxed) { - eprintln!("some tidy checks failed"); + let failed_checks = tidy_ctx.into_failed_checks(); + if !failed_checks.is_empty() { + let mut failed: Vec = + failed_checks.into_iter().map(|c| c.id().to_string()).collect(); + failed.sort(); + output_message( + &format!( + "The following check{} failed: {}", + if failed.len() > 1 { "s" } else { "" }, + failed.join(", ") + ), + None, + Some(COLOR_ERROR), + ); process::exit(1); + } else { + output_message("All tidy checks succeeded", None, Some(COLOR_SUCCESS)); } } diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index 6119eb58383e3..afc1dc2a1860b 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -5,9 +5,10 @@ use std::path::{Path, PathBuf}; use miropt_test_tools::PanicStrategy; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::walk_no_read; -fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) { +fn check_unused_files(path: &Path, bless: bool, check: &mut RunningCheck) { let mut rs_files = Vec::::new(); let mut output_files = HashSet::::new(); @@ -37,18 +38,17 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) { for extra in output_files { if !bless { - tidy_error!( - bad, + check.error(format!( "the following output file is not associated with any mir-opt test, you can remove it: {}", extra.display() - ); + )); } else { let _ = std::fs::remove_file(extra); } } } -fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) { +fn check_dash_files(path: &Path, bless: bool, check: &mut RunningCheck) { for file in walkdir::WalkDir::new(path.join("mir-opt")) .into_iter() .filter_map(Result::ok) @@ -60,11 +60,10 @@ fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) { && name.contains('-') { if !bless { - tidy_error!( - bad, + check.error(format!( "mir-opt test files should not have dashes in them: {}", path.display() - ); + )); } else { let new_name = name.replace('-', "_"); let mut new_path = path.to_owned(); @@ -75,7 +74,10 @@ fn check_dash_files(path: &Path, bless: bool, bad: &mut bool) { } } -pub fn check(path: &Path, bless: bool, bad: &mut bool) { - check_unused_files(path, bless, bad); - check_dash_files(path, bless, bad); +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("mir_opt_tests").path(path)); + let bless = tidy_ctx.is_bless_enabled(); + + check_unused_files(path, bless, &mut check); + check_dash_files(path, bless, &mut check); } diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 5b8b44429bbc0..dfca2cda9a0f8 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -32,6 +32,7 @@ use std::path::Path; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::walk::{filter_dirs, walk}; // Paths that may contain platform-specific code. @@ -53,6 +54,7 @@ const EXCEPTION_PATHS: &[&str] = &[ // core::ffi contains platform-specific type and linkage configuration "library/core/src/ffi/mod.rs", "library/core/src/ffi/primitives.rs", + "library/core/src/os", // Platform-specific public interfaces "library/std/src/sys", // Platform-specific code for std lives here. "library/std/src/os", // Platform-specific public interfaces // Temporary `std` exceptions @@ -66,7 +68,9 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/std/src/io/error.rs", // Repr unpacked needed for UEFI ]; -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("pal").path(path)); + // Sanity check that the complex parsing here works. let mut saw_target_arch = false; let mut saw_cfg_bang = false; @@ -87,7 +91,7 @@ pub fn check(path: &Path, bad: &mut bool) { return; } - check_cfgs(contents, file, bad, &mut saw_target_arch, &mut saw_cfg_bang); + check_cfgs(contents, file, &mut check, &mut saw_target_arch, &mut saw_cfg_bang); }); assert!(saw_target_arch); @@ -97,7 +101,7 @@ pub fn check(path: &Path, bad: &mut bool) { fn check_cfgs( contents: &str, file: &Path, - bad: &mut bool, + check: &mut RunningCheck, saw_target_arch: &mut bool, saw_cfg_bang: &mut bool, ) { @@ -114,7 +118,7 @@ fn check_cfgs( Ok(_) => unreachable!(), Err(i) => i + 1, }; - tidy_error!(bad, "{}:{}: platform-specific cfg: {}", file.display(), line, cfg); + check.error(format!("{}:{line}: platform-specific cfg: {cfg}", file.display())); }; for (idx, cfg) in cfgs { diff --git a/src/tools/tidy/src/rustdoc_css_themes.rs b/src/tools/tidy/src/rustdoc_css_themes.rs index af36f9ba58e0d..f3aecc15cd9ac 100644 --- a/src/tools/tidy/src/rustdoc_css_themes.rs +++ b/src/tools/tidy/src/rustdoc_css_themes.rs @@ -3,7 +3,11 @@ use std::path::Path; -pub fn check(librustdoc_path: &Path, bad: &mut bool) { +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; + +pub fn check(librustdoc_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_css_themes").path(librustdoc_path)); + let rustdoc_css = "html/static/css/rustdoc.css"; let noscript_css = "html/static/css/noscript.css"; let rustdoc_css_contents = std::fs::read_to_string(librustdoc_path.join(rustdoc_css)) @@ -14,13 +18,13 @@ pub fn check(librustdoc_path: &Path, bad: &mut bool) { "light", rustdoc_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())), noscript_css_contents.lines().enumerate().map(|(i, l)| (i + 1, l.trim())), - bad, + &mut check, ); compare_themes_from_files( "dark", rustdoc_css_contents.lines().enumerate(), noscript_css_contents.lines().enumerate(), - bad, + &mut check, ); } @@ -28,7 +32,7 @@ fn compare_themes_from_files<'a>( name: &str, mut rustdoc_css_lines: impl Iterator, mut noscript_css_lines: impl Iterator, - bad: &mut bool, + check: &mut RunningCheck, ) { let begin_theme_pat = format!("/* Begin theme: {name}"); let mut found_theme = None; @@ -38,10 +42,9 @@ fn compare_themes_from_files<'a>( continue; } if let Some(found_theme) = found_theme { - tidy_error!( - bad, + check.error(format!( "rustdoc.css contains two {name} themes on lines {rustdoc_css_line_number} and {found_theme}", - ); + )); return; } found_theme = Some(rustdoc_css_line_number); @@ -50,14 +53,13 @@ fn compare_themes_from_files<'a>( continue; } if let Some(found_theme_noscript) = found_theme_noscript { - tidy_error!( - bad, + check.error(format!( "noscript.css contains two {name} themes on lines {noscript_css_line_number} and {found_theme_noscript}", - ); + )); return; } found_theme_noscript = Some(noscript_css_line_number); - compare_themes(name, &mut rustdoc_css_lines, &mut noscript_css_lines, bad); + compare_themes(name, &mut rustdoc_css_lines, &mut noscript_css_lines, check); } } } @@ -66,7 +68,7 @@ fn compare_themes<'a>( name: &str, rustdoc_css_lines: impl Iterator, noscript_css_lines: impl Iterator, - bad: &mut bool, + check: &mut RunningCheck, ) { let end_theme_pat = format!("/* End theme: {name}"); for ( @@ -90,12 +92,11 @@ fn compare_themes<'a>( break; } if rustdoc_css_line != noscript_css_line { - tidy_error!( - bad, - "noscript.css:{noscript_css_line_number} and rustdoc.css:{rustdoc_css_line_number} contain copies of {name} theme that are not the same", - ); - eprintln!("- {noscript_css_line}"); - eprintln!("+ {rustdoc_css_line}"); + check.error(format!( + r#"noscript.css:{noscript_css_line_number} and rustdoc.css:{rustdoc_css_line_number} contain copies of {name} theme that are not the same +- {noscript_css_line} ++ {rustdoc_css_line}"#, + )); return; } } diff --git a/src/tools/tidy/src/rustdoc_gui_tests.rs b/src/tools/tidy/src/rustdoc_gui_tests.rs index 3b995f219d269..848250e18e74a 100644 --- a/src/tools/tidy/src/rustdoc_gui_tests.rs +++ b/src/tools/tidy/src/rustdoc_gui_tests.rs @@ -2,18 +2,21 @@ use std::path::Path; -pub fn check(path: &Path, bad: &mut bool) { +use crate::diagnostics::{CheckId, TidyCtx}; + +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_gui_tests").path(path)); + crate::walk::walk( &path.join("rustdoc-gui"), |p, is_dir| !is_dir && p.extension().is_none_or(|e| e != "goml"), &mut |entry, content| { for line in content.lines() { if !line.starts_with("// ") { - tidy_error!( - bad, + check.error(format!( "{}: rustdoc-gui tests must start with a small description", entry.path().display(), - ); + )); return; } else if line.starts_with("// ") { let parts = line[2..].trim(); diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs index 722e1ebd0cad2..b8fb04f2d4e1f 100644 --- a/src/tools/tidy/src/rustdoc_json.rs +++ b/src/tools/tidy/src/rustdoc_json.rs @@ -4,21 +4,26 @@ use std::path::Path; use std::str::FromStr; +use crate::diagnostics::{CheckId, TidyCtx}; + const RUSTDOC_JSON_TYPES: &str = "src/rustdoc-json-types"; -pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) { - println!("Checking tidy rustdoc_json..."); +pub fn check(src_path: &Path, ci_info: &crate::CiInfo, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_json").path(src_path)); + let Some(base_commit) = &ci_info.base_commit else { - eprintln!("No base commit, skipping rustdoc_json check"); + check.verbose_msg("No base commit, skipping rustdoc_json check"); return; }; // First we check that `src/rustdoc-json-types` was modified. - if !crate::files_modified(ci_info, |p| p == RUSTDOC_JSON_TYPES) { + if !crate::files_modified(ci_info, |p| p.starts_with(RUSTDOC_JSON_TYPES)) { // `rustdoc-json-types` was not modified so nothing more to check here. - println!("`rustdoc-json-types` was not modified."); return; } + + check.message("`rustdoc-json-types` modified, checking format version"); + // Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated. match crate::git_diff(base_commit, src_path.join("rustdoc-json-types")) { Some(output) => { @@ -45,34 +50,29 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) { } } if format_version_updated != latest_feature_comment_updated { - *bad = true; - if latest_feature_comment_updated { - eprintln!( - "error in `rustdoc_json` tidy check: `Latest feature` comment was updated \ - whereas `FORMAT_VERSION` wasn't in `{RUSTDOC_JSON_TYPES}/lib.rs`" - ); + let msg = if latest_feature_comment_updated { + format!( + "`Latest feature` comment was updated whereas `FORMAT_VERSION` wasn't in `{RUSTDOC_JSON_TYPES}/lib.rs`" + ) } else { - eprintln!( - "error in `rustdoc_json` tidy check: `Latest feature` comment was not \ - updated whereas `FORMAT_VERSION` was in `{RUSTDOC_JSON_TYPES}/lib.rs`" - ); - } + format!( + "`Latest feature` comment was not updated whereas `FORMAT_VERSION` was in `{RUSTDOC_JSON_TYPES}/lib.rs`" + ) + }; + check.error(msg); } match (new_version, old_version) { (Some(new_version), Some(old_version)) if new_version != old_version + 1 => { - *bad = true; - eprintln!( - "error in `rustdoc_json` tidy check: invalid `FORMAT_VERSION` increase in \ - `{RUSTDOC_JSON_TYPES}/lib.rs`, should be `{}`, found `{new_version}`", + check.error(format!( + "invalid `FORMAT_VERSION` increase in `{RUSTDOC_JSON_TYPES}/lib.rs`, should be `{}`, found `{new_version}`", old_version + 1, - ); + )); } _ => {} } } None => { - *bad = true; - eprintln!("error: failed to run `git diff` in rustdoc_json check"); + check.error("failed to run `git diff` in rustdoc_json check"); } } } diff --git a/src/tools/tidy/src/rustdoc_templates.rs b/src/tools/tidy/src/rustdoc_templates.rs index 597290a6a9a8d..faeb95a92b763 100644 --- a/src/tools/tidy/src/rustdoc_templates.rs +++ b/src/tools/tidy/src/rustdoc_templates.rs @@ -6,12 +6,15 @@ use std::path::Path; use ignore::DirEntry; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::walk; // Array containing `("beginning of tag", "end of tag")`. const TAGS: &[(&str, &str)] = &[("{#", "#}"), ("{%", "%}"), ("{{", "}}")]; -pub fn check(librustdoc_path: &Path, bad: &mut bool) { +pub fn check(librustdoc_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("rustdoc_templates").path(librustdoc_path)); + walk( &librustdoc_path.join("html/templates"), |path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("html")), @@ -46,12 +49,11 @@ pub fn check(librustdoc_path: &Path, bad: &mut bool) { }) { // It seems like ending this line with a jinja tag is not needed after all. - tidy_error!( - bad, + check.error(format!( "`{}` at line {}: unneeded `{{# #}}` tag at the end of the line", path.path().display(), pos + 1, - ); + )); } continue; } @@ -67,12 +69,11 @@ pub fn check(librustdoc_path: &Path, bad: &mut bool) { }) { None => { // No it's not, let's error. - tidy_error!( - bad, + check.error(format!( "`{}` at line {}: missing `{{# #}}` at the end of the line", path.path().display(), pos + 1, - ); + )); } Some(end_tag) => { // We skip the tag. diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index fca097c091b75..7bb424d926c26 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -24,6 +24,7 @@ use std::sync::LazyLock; use regex::RegexSetBuilder; use rustc_hash::FxHashMap; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; #[cfg(test)] @@ -338,7 +339,9 @@ fn is_unexplained_ignore(extension: &str, line: &str) -> bool { true } -pub fn check(path: &Path, bad: &mut bool) { +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("style").path(path)); + fn skip(path: &Path, is_dir: bool) -> bool { if path.file_name().is_some_and(|name| name.to_string_lossy().starts_with(".#")) { // vim or emacs temporary file @@ -391,7 +394,7 @@ pub fn check(path: &Path, bad: &mut bool) { }); if contents.is_empty() { - tidy_error!(bad, "{}: empty file", file.display()); + check.error(format!("{}: empty file", file.display())); } let extension = file.extension().unwrap().to_string_lossy(); @@ -467,7 +470,7 @@ pub fn check(path: &Path, bad: &mut bool) { } let mut err = |msg: &str| { - tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg); + check.error(format!("{}:{}: {msg}", file.display(), i + 1)); }; if trimmed.contains("dbg!") @@ -611,7 +614,7 @@ pub fn check(path: &Path, bad: &mut bool) { && backtick_count % 2 == 1 { let mut err = |msg: &str| { - tidy_error!(bad, "{}:{start_line}: {msg}", file.display()); + check.error(format!("{}:{start_line}: {msg}", file.display())); }; let block_len = (i + 1) - start_line; if block_len == 1 { @@ -632,12 +635,12 @@ pub fn check(path: &Path, bad: &mut bool) { } if leading_new_lines { let mut err = |_| { - tidy_error!(bad, "{}: leading newline", file.display()); + check.error(format!("{}: leading newline", file.display())); }; suppressible_tidy_err!(err, skip_leading_newlines, "missing leading newline"); } let mut err = |msg: &str| { - tidy_error!(bad, "{}: {}", file.display(), msg); + check.error(format!("{}: {}", file.display(), msg)); }; match trailing_new_lines { 0 => suppressible_tidy_err!(err, skip_trailing_newlines, "missing trailing newline"), @@ -650,38 +653,36 @@ pub fn check(path: &Path, bad: &mut bool) { }; if lines > LINES { let mut err = |_| { - tidy_error!( - bad, - "{}: too many lines ({}) (add `// \ + check.error(format!( + "{}: too many lines ({lines}) (add `// \ ignore-tidy-filelength` to the file to suppress this error)", file.display(), - lines - ); + )); }; suppressible_tidy_err!(err, skip_file_length, ""); } if let Directive::Ignore(false) = skip_cr { - tidy_error!(bad, "{}: ignoring CR characters unnecessarily", file.display()); + check.error(format!("{}: ignoring CR characters unnecessarily", file.display())); } if let Directive::Ignore(false) = skip_tab { - tidy_error!(bad, "{}: ignoring tab characters unnecessarily", file.display()); + check.error(format!("{}: ignoring tab characters unnecessarily", file.display())); } if let Directive::Ignore(false) = skip_end_whitespace { - tidy_error!(bad, "{}: ignoring trailing whitespace unnecessarily", file.display()); + check.error(format!("{}: ignoring trailing whitespace unnecessarily", file.display())); } if let Directive::Ignore(false) = skip_trailing_newlines { - tidy_error!(bad, "{}: ignoring trailing newlines unnecessarily", file.display()); + check.error(format!("{}: ignoring trailing newlines unnecessarily", file.display())); } if let Directive::Ignore(false) = skip_leading_newlines { - tidy_error!(bad, "{}: ignoring leading newlines unnecessarily", file.display()); + check.error(format!("{}: ignoring leading newlines unnecessarily", file.display())); } if let Directive::Ignore(false) = skip_copyright { - tidy_error!(bad, "{}: ignoring copyright unnecessarily", file.display()); + check.error(format!("{}: ignoring copyright unnecessarily", file.display())); } // We deliberately do not warn about these being unnecessary, // that would just lead to annoying churn. let _unused = skip_line_length; let _unused = skip_file_length; - }) + }); } diff --git a/src/tools/tidy/src/target_policy.rs b/src/tools/tidy/src/target_policy.rs index 550932dbfdc38..83fbe6a0d8dae 100644 --- a/src/tools/tidy/src/target_policy.rs +++ b/src/tools/tidy/src/target_policy.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; use std::path::Path; +use crate::diagnostics::TidyCtx; use crate::walk::{filter_not_rust, walk}; const TARGET_DEFINITIONS_PATH: &str = "compiler/rustc_target/src/spec/targets/"; @@ -23,7 +24,9 @@ const EXCEPTIONS: &[&str] = &[ "xtensa_esp32s3_espidf", ]; -pub fn check(root_path: &Path, bad: &mut bool) { +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("target_policy"); + let mut targets_to_find = HashSet::new(); let definitions_path = root_path.join(TARGET_DEFINITIONS_PATH); @@ -55,7 +58,7 @@ pub fn check(root_path: &Path, bad: &mut bool) { for target in targets_to_find { if !EXCEPTIONS.contains(&target.as_str()) { - tidy_error!(bad, "{ASSEMBLY_LLVM_TEST_PATH}: missing assembly test for {target}") + check.error(format!("{ASSEMBLY_LLVM_TEST_PATH}: missing assembly test for {target}")); } } } diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index b2d5f259eb2db..159d7278bb62e 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -4,6 +4,7 @@ use std::collections::BTreeMap; use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::iter_header::{HeaderLine, iter_header}; use crate::walk::filter_not_rust; @@ -16,7 +17,9 @@ struct RevisionInfo<'a> { llvm_components: Option>, } -pub fn check(tests_path: &Path, bad: &mut bool) { +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("target-specific-tests").path(tests_path)); + crate::walk::walk(tests_path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| { if content.contains("// ignore-tidy-target-specific-tests") { return; @@ -44,8 +47,7 @@ pub fn check(tests_path: &Path, bad: &mut bool) { } else if let Some((arch, _)) = v.split_once("-") { info.target_arch.replace(Some(arch)); } else { - eprintln!("{file}: seems to have a malformed --target value"); - *bad = true; + check.error(format!("{file}: seems to have a malformed --target value")); } } }); @@ -62,25 +64,22 @@ pub fn check(tests_path: &Path, bad: &mut bool) { (Some(target_arch), None) => { let llvm_component = target_arch.map_or_else(|| "".to_string(), arch_to_llvm_component); - eprintln!( + check.error(format!( "{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set" - ); - *bad = true; + )); } (None, Some(_)) => { - eprintln!( + check.error(format!( "{file}: revision {rev} should not specify `{LLVM_COMPONENTS_HEADER}` as it doesn't need `--target`" - ); - *bad = true; + )); } (Some(target_arch), Some(llvm_components)) => { if let Some(target_arch) = target_arch { let llvm_component = arch_to_llvm_component(target_arch); if !llvm_components.contains(&llvm_component.as_str()) { - eprintln!( + check.error(format!( "{file}: revision {rev} should specify `{LLVM_COMPONENTS_HEADER} {llvm_component}` as it has `--target` set" - ); - *bad = true; + )); } } } diff --git a/src/tools/tidy/src/tests_placement.rs b/src/tools/tidy/src/tests_placement.rs index 9d0057df8bcd8..18b00608fdce5 100644 --- a/src/tools/tidy/src/tests_placement.rs +++ b/src/tools/tidy/src/tests_placement.rs @@ -1,15 +1,18 @@ use std::path::Path; +use crate::diagnostics::TidyCtx; + const FORBIDDEN_PATH: &str = "src/test"; const ALLOWED_PATH: &str = "tests"; -pub fn check(root_path: impl AsRef, bad: &mut bool) { - if root_path.as_ref().join(FORBIDDEN_PATH).exists() { - tidy_error!( - bad, +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("tests_placement"); + + if root_path.join(FORBIDDEN_PATH).exists() { + check.error(format!( "Tests have been moved, please move them from {} to {}", - root_path.as_ref().join(FORBIDDEN_PATH).display(), - root_path.as_ref().join(ALLOWED_PATH).display() - ) + root_path.join(FORBIDDEN_PATH).display(), + root_path.join(ALLOWED_PATH).display() + )); } } diff --git a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs index 02412b6f190e8..4d9cb55138afa 100644 --- a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs +++ b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs @@ -4,6 +4,7 @@ use std::collections::{BTreeMap, BTreeSet}; use std::ffi::OsStr; use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::iter_header::*; use crate::walk::*; @@ -21,7 +22,10 @@ const IGNORES: &[&str] = &[ const EXTENSIONS: &[&str] = &["stdout", "stderr"]; const SPECIAL_TEST: &str = "tests/ui/command/need-crate-arg-ignore-tidy.x.rs"; -pub fn check(tests_path: impl AsRef, bad: &mut bool) { +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx + .start_check(CheckId::new("tests_revision_unpaired_stdout_stderr").path(tests_path)); + // Recurse over subdirectories under `tests/` walk_dir(tests_path.as_ref(), filter, &mut |entry| { // We are inspecting a folder. Collect the paths to interesting files `.rs`, `.stderr`, @@ -122,12 +126,11 @@ pub fn check(tests_path: impl AsRef, bad: &mut bool) { [] | [_] => return, [_, _] if !expected_revisions.is_empty() => { // Found unrevisioned output files for a revisioned test. - tidy_error!( - bad, + check.error(format!( "found unrevisioned output file `{}` for a revisioned test `{}`", sibling.display(), test_path.display(), - ); + )); } [_, _] => return, [_, found_revision, .., extension] => { @@ -138,13 +141,12 @@ pub fn check(tests_path: impl AsRef, bad: &mut bool) { { // Found some unexpected revision-esque component that is not a known // compare-mode or expected revision. - tidy_error!( - bad, + check.error(format!( "found output file `{}` for unexpected revision `{}` of test `{}`", sibling.display(), found_revision, test_path.display() - ); + )); } } } diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs index 6f25ed616fac7..01401c94d7309 100644 --- a/src/tools/tidy/src/triagebot.rs +++ b/src/tools/tidy/src/triagebot.rs @@ -4,7 +4,10 @@ use std::path::Path; use toml::Value; -pub fn check(path: &Path, bad: &mut bool) { +use crate::diagnostics::TidyCtx; + +pub fn check(path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("triagebot"); let triagebot_path = path.join("triagebot.toml"); // This check is mostly to catch broken path filters *within* `triagebot.toml`, and not enforce @@ -30,17 +33,14 @@ pub fn check(path: &Path, bad: &mut bool) { let full_path = path.join(clean_path); if !full_path.exists() { - tidy_error!( - bad, - "triagebot.toml [mentions.*] contains path '{}' which doesn't exist", - clean_path - ); + check.error(format!( + "triagebot.toml [mentions.*] contains path '{clean_path}' which doesn't exist" + )); } } } else { - tidy_error!( - bad, - "triagebot.toml missing [mentions.*] section, this wrong for rust-lang/rust repo." + check.error( + "triagebot.toml missing [mentions.*] section, this wrong for rust-lang/rust repo.", ); } @@ -55,16 +55,13 @@ pub fn check(path: &Path, bad: &mut bool) { let full_path = path.join(clean_path); if !full_path.exists() { - tidy_error!( - bad, - "triagebot.toml [assign.owners] contains path '{}' which doesn't exist", - clean_path - ); + check.error(format!( + "triagebot.toml [assign.owners] contains path '{clean_path}' which doesn't exist" + )); } } } else { - tidy_error!( - bad, + check.error( "triagebot.toml missing [assign.owners] section, this wrong for rust-lang/rust repo." ); } @@ -86,12 +83,9 @@ pub fn check(path: &Path, bad: &mut bool) { // Handle both file and directory paths if !full_path.exists() { - tidy_error!( - bad, - "triagebot.toml [autolabel.{}] contains trigger_files path '{}' which doesn't exist", - label, - file_str - ); + check.error(format!( + "triagebot.toml [autolabel.{label}] contains trigger_files path '{file_str}' which doesn't exist", + )); } } } diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 5bf966b658c63..45c2e76d1c1c0 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,13 +7,17 @@ use std::fs; use std::io::Write; use std::path::{Path, PathBuf}; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; + const ISSUES_TXT_HEADER: &str = r#"============================================================ ⚠️⚠️⚠️NOTHING SHOULD EVER BE ADDED TO THIS LIST⚠️⚠️⚠️ ============================================================ "#; -pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { +pub fn check(root_path: &Path, tidy_ctx: TidyCtx) { let path = &root_path.join("tests"); + let mut check = tidy_ctx.start_check(CheckId::new("ui_tests").path(path)); + let bless = tidy_ctx.is_bless_enabled(); // the list of files in ui tests that are allowed to start with `issue-XXXX` // BTreeSet because we would like a stable ordering so --bless works @@ -33,16 +37,15 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { .collect(); if !is_sorted && !bless { - tidy_error!( - bad, + check.error( "`src/tools/tidy/src/issues.txt` is not in order, mostly because you modified it manually, please only update it with command `x test tidy --bless`" ); } - deny_new_top_level_ui_tests(bad, &path.join("ui")); + deny_new_top_level_ui_tests(&mut check, &path.join("ui")); - let remaining_issue_names = recursively_check_ui_tests(bad, path, &allowed_issue_names); + let remaining_issue_names = recursively_check_ui_tests(&mut check, path, &allowed_issue_names); // if there are any file names remaining, they were moved on the fs. // our data must remain up to date, so it must be removed from issues.txt @@ -64,45 +67,42 @@ pub fn check(root_path: &Path, bless: bool, bad: &mut bool) { for file_name in remaining_issue_names { let mut p = PathBuf::from(path); p.push(file_name); - tidy_error!( - bad, + check.error(format!( "file `{}` no longer exists and should be removed from the exclusions in `src/tools/tidy/src/issues.txt`", p.display() - ); + )); } } } -fn deny_new_top_level_ui_tests(bad: &mut bool, tests_path: &Path) { +fn deny_new_top_level_ui_tests(check: &mut RunningCheck, tests_path: &Path) { // See where we propose banning adding // new ui tests *directly* under `tests/ui/`. For more context, see: // // - // - - let top_level_ui_tests = walkdir::WalkDir::new(tests_path) - .min_depth(1) - .max_depth(1) + let top_level_ui_tests = ignore::WalkBuilder::new(tests_path) + .max_depth(Some(1)) .follow_links(false) - .same_file_system(true) - .into_iter() + .build() .flatten() .filter(|e| { let file_name = e.file_name(); file_name != ".gitattributes" && file_name != "README.md" }) - .filter(|e| !e.file_type().is_dir()); + .filter(|e| !e.file_type().is_some_and(|f| f.is_dir())); + for entry in top_level_ui_tests { - tidy_error!( - bad, - "ui tests should be added under meaningful subdirectories: `{}`", + check.error(format!( + "ui tests should be added under meaningful subdirectories: `{}`, see https://github.com/rust-lang/compiler-team/issues/902", entry.path().display() - ) + )); } } fn recursively_check_ui_tests<'issues>( - bad: &mut bool, + check: &mut RunningCheck, path: &Path, allowed_issue_names: &'issues BTreeSet<&'issues str>, ) -> BTreeSet<&'issues str> { @@ -113,19 +113,19 @@ fn recursively_check_ui_tests<'issues>( crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| { let file_path = entry.path(); if let Some(ext) = file_path.extension().and_then(OsStr::to_str) { - check_unexpected_extension(bad, file_path, ext); + check_unexpected_extension(check, file_path, ext); // NB: We do not use file_stem() as some file names have multiple `.`s and we // must strip all of them. let testname = file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0; if ext == "stderr" || ext == "stdout" || ext == "fixed" { - check_stray_output_snapshot(bad, file_path, testname); - check_empty_output_snapshot(bad, file_path); + check_stray_output_snapshot(check, file_path, testname); + check_empty_output_snapshot(check, file_path); } deny_new_nondescriptive_test_names( - bad, + check, path, &mut remaining_issue_names, file_path, @@ -137,7 +137,7 @@ fn recursively_check_ui_tests<'issues>( remaining_issue_names } -fn check_unexpected_extension(bad: &mut bool, file_path: &Path, ext: &str) { +fn check_unexpected_extension(check: &mut RunningCheck, file_path: &Path, ext: &str) { const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files "stderr", // expected stderr file, corresponds to a rs file @@ -178,11 +178,11 @@ fn check_unexpected_extension(bad: &mut bool, file_path: &Path, ext: &str) { if !(EXPECTED_TEST_FILE_EXTENSIONS.contains(&ext) || EXTENSION_EXCEPTION_PATHS.iter().any(|path| file_path.ends_with(path))) { - tidy_error!(bad, "file {} has unexpected extension {}", file_path.display(), ext); + check.error(format!("file {} has unexpected extension {}", file_path.display(), ext)); } } -fn check_stray_output_snapshot(bad: &mut bool, file_path: &Path, testname: &str) { +fn check_stray_output_snapshot(check: &mut RunningCheck, file_path: &Path, testname: &str) { // Test output filenames have one of the formats: // ``` // $testname.stderr @@ -197,20 +197,20 @@ fn check_stray_output_snapshot(bad: &mut bool, file_path: &Path, testname: &str) if !file_path.with_file_name(testname).with_extension("rs").exists() && !testname.contains("ignore-tidy") { - tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path); + check.error(format!("Stray file with UI testing output: {:?}", file_path)); } } -fn check_empty_output_snapshot(bad: &mut bool, file_path: &Path) { +fn check_empty_output_snapshot(check: &mut RunningCheck, file_path: &Path) { if let Ok(metadata) = fs::metadata(file_path) && metadata.len() == 0 { - tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path); + check.error(format!("Empty file with UI testing output: {:?}", file_path)); } } fn deny_new_nondescriptive_test_names( - bad: &mut bool, + check: &mut RunningCheck, path: &Path, remaining_issue_names: &mut BTreeSet<&str>, file_path: &Path, @@ -231,11 +231,10 @@ fn deny_new_nondescriptive_test_names( if !remaining_issue_names.remove(stripped_path.as_str()) && !stripped_path.starts_with("ui/issues/") { - tidy_error!( - bad, + check.error(format!( "file `tests/{stripped_path}` must begin with a descriptive name, consider `{{reason}}-issue-{issue_n}.rs`", issue_n = &test_name[1], - ); + )); } } } diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index 7396310ed37c9..74b6c4a3845a6 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -11,9 +11,12 @@ use std::path::Path; +use crate::diagnostics::{CheckId, TidyCtx}; use crate::walk::{filter_dirs, walk}; -pub fn check(root_path: &Path, stdlib: bool, bad: &mut bool) { +pub fn check(root_path: &Path, stdlib: bool, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("unit_tests").path(root_path)); + let skip = move |path: &Path, is_dir| { let file_name = path.file_name().unwrap_or_default(); @@ -92,14 +95,11 @@ pub fn check(root_path: &Path, stdlib: bool, bad: &mut bool) { .to_owned() }; let name = if is_test() { "test" } else { "bench" }; - tidy_error!( - bad, - "`{}:{}` contains `#[{}]`; {}", + check.error(format!( + "`{}:{}` contains `#[{name}]`; {explanation}", path.display(), i + 1, - name, - explanation, - ); + )); return; } } diff --git a/src/tools/tidy/src/unknown_revision.rs b/src/tools/tidy/src/unknown_revision.rs index 0ba05c80a791b..43de6ee18b4de 100644 --- a/src/tools/tidy/src/unknown_revision.rs +++ b/src/tools/tidy/src/unknown_revision.rs @@ -12,12 +12,14 @@ use std::sync::OnceLock; use ignore::DirEntry; use regex::Regex; +use crate::diagnostics::{CheckId, RunningCheck, TidyCtx}; use crate::iter_header::{HeaderLine, iter_header}; use crate::walk::{filter_dirs, filter_not_rust, walk}; -pub fn check(tests_path: impl AsRef, bad: &mut bool) { +pub fn check(tests_path: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("unknown_revision").path(tests_path)); walk( - tests_path.as_ref(), + tests_path, |path, is_dir| { filter_dirs(path) || filter_not_rust(path) || { // Auxiliary source files for incremental tests can refer to revisions @@ -25,11 +27,11 @@ pub fn check(tests_path: impl AsRef, bad: &mut bool) { is_dir && path.file_name().is_some_and(|name| name == "auxiliary") } }, - &mut |entry, contents| visit_test_file(entry, contents, bad), + &mut |entry, contents| visit_test_file(entry, contents, &mut check), ); } -fn visit_test_file(entry: &DirEntry, contents: &str, bad: &mut bool) { +fn visit_test_file(entry: &DirEntry, contents: &str, check: &mut RunningCheck) { let mut revisions = HashSet::new(); let mut unused_revision_names = HashSet::new(); @@ -68,10 +70,9 @@ fn visit_test_file(entry: &DirEntry, contents: &str, bad: &mut bool) { // Fail if any revision names appear in both places, since that's probably a mistake. for rev in revisions.intersection(&unused_revision_names).copied().collect::>() { - tidy_error!( - bad, + check.error(format!( "revision name [{rev}] appears in both `revisions` and `unused-revision-names` in {path}" - ); + )); } // Compute the set of revisions that were mentioned but not declared, @@ -84,7 +85,7 @@ fn visit_test_file(entry: &DirEntry, contents: &str, bad: &mut bool) { bad_revisions.sort(); for (line_number, rev) in bad_revisions { - tidy_error!(bad, "unknown revision [{rev}] at {path}:{line_number}"); + check.error(format!("unknown revision [{rev}] at {path}:{line_number}")); } } diff --git a/src/tools/tidy/src/unstable_book.rs b/src/tools/tidy/src/unstable_book.rs index 0ed954d48deb1..cfaf56ae7b641 100644 --- a/src/tools/tidy/src/unstable_book.rs +++ b/src/tools/tidy/src/unstable_book.rs @@ -2,6 +2,7 @@ use std::collections::BTreeSet; use std::fs; use std::path::{Path, PathBuf}; +use crate::diagnostics::{RunningCheck, TidyCtx}; use crate::features::{CollectedFeatures, Features, Status}; pub const PATH_STR: &str = "doc/unstable-book"; @@ -75,19 +76,18 @@ fn collect_unstable_book_lib_features_section_file_names(base_src_path: &Path) - } /// Would switching underscores for dashes work? -fn maybe_suggest_dashes(names: &BTreeSet, feature_name: &str, bad: &mut bool) { +fn maybe_suggest_dashes(names: &BTreeSet, feature_name: &str, check: &mut RunningCheck) { let with_dashes = feature_name.replace('_', "-"); if names.contains(&with_dashes) { - tidy_error!( - bad, - "the file `{}.md` contains underscores; use dashes instead: `{}.md`", - feature_name, - with_dashes, - ); + check.error(format!( + "the file `{feature_name}.md` contains underscores; use dashes instead: `{with_dashes}.md`", + )); } } -pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) { +pub fn check(path: &Path, features: CollectedFeatures, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check("unstable_book"); + let lang_features = features.lang; let lib_features = features .lib @@ -108,26 +108,22 @@ pub fn check(path: &Path, features: CollectedFeatures, bad: &mut bool) { // Check for Unstable Book sections that don't have a corresponding unstable feature for feature_name in &unstable_book_lib_features_section_file_names - &unstable_lib_feature_names { - tidy_error!( - bad, - "The Unstable Book has a 'library feature' section '{}' which doesn't \ - correspond to an unstable library feature", - feature_name - ); - maybe_suggest_dashes(&unstable_lib_feature_names, &feature_name, bad); + check.error(format!( + "The Unstable Book has a 'library feature' section '{feature_name}' which doesn't \ + correspond to an unstable library feature" + )); + maybe_suggest_dashes(&unstable_lib_feature_names, &feature_name, &mut check); } // Check for Unstable Book sections that don't have a corresponding unstable feature. for feature_name in &unstable_book_lang_features_section_file_names - &unstable_lang_feature_names { - tidy_error!( - bad, - "The Unstable Book has a 'language feature' section '{}' which doesn't \ - correspond to an unstable language feature", - feature_name - ); - maybe_suggest_dashes(&unstable_lang_feature_names, &feature_name, bad); + check.error(format!( + "The Unstable Book has a 'language feature' section '{feature_name}' which doesn't \ + correspond to an unstable language feature" + )); + maybe_suggest_dashes(&unstable_lang_feature_names, &feature_name, &mut check); } // List unstable features that don't have Unstable Book sections. diff --git a/src/tools/tidy/src/x_version.rs b/src/tools/tidy/src/x_version.rs index 9f7f43c4000b1..28fd725cd3e23 100644 --- a/src/tools/tidy/src/x_version.rs +++ b/src/tools/tidy/src/x_version.rs @@ -3,12 +3,18 @@ use std::process::{Command, Stdio}; use semver::Version; -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { +use crate::diagnostics::{CheckId, TidyCtx}; + +pub fn check(root: &Path, cargo: &Path, tidy_ctx: TidyCtx) { + let mut check = tidy_ctx.start_check(CheckId::new("x_version").path(root)); let cargo_list = Command::new(cargo).args(["install", "--list"]).stdout(Stdio::piped()).spawn(); let child = match cargo_list { Ok(child) => child, - Err(e) => return tidy_error!(bad, "failed to run `cargo`: {}", e), + Err(e) => { + check.error(format!("failed to run `cargo`: {e}")); + return; + } }; let cargo_list = child.wait_with_output().unwrap(); @@ -47,13 +53,10 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { ) } } else { - tidy_error!( - bad, - "Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`" - ) + check.error("Unable to parse the latest version of `x` at `src/tools/x/Cargo.toml`") } } else { - tidy_error!(bad, "failed to check version of `x`: {}", cargo_list.status) + check.error(format!("failed to check version of `x`: {}", cargo_list.status)) } } diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index a7c6173d88c48..16550f83003dc 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -5,6 +5,7 @@ use std::env; use std::fs::{self, write}; use std::path::Path; +use tidy::diagnostics::RunningCheck; use tidy::features::{Features, collect_env_vars, collect_lang_features, collect_lib_features}; use tidy::t; use tidy::unstable_book::{ @@ -122,7 +123,7 @@ fn main() { let src_path = Path::new(&src_path_str); let dest_path = Path::new(&dest_path_str); - let lang_features = collect_lang_features(compiler_path, &mut false); + let lang_features = collect_lang_features(compiler_path, &mut RunningCheck::new_noop()); let lib_features = collect_lib_features(library_path) .into_iter() .filter(|&(ref name, _)| !lang_features.contains_key(name)) diff --git a/src/tools/wasm-component-ld/Cargo.toml b/src/tools/wasm-component-ld/Cargo.toml index 3def2391a13f6..235e934b55412 100644 --- a/src/tools/wasm-component-ld/Cargo.toml +++ b/src/tools/wasm-component-ld/Cargo.toml @@ -10,4 +10,4 @@ name = "wasm-component-ld" path = "src/main.rs" [dependencies] -wasm-component-ld = "0.5.17" +wasm-component-ld = "0.5.18" diff --git a/src/version b/src/version index 6979a6c0661bf..7f229af964764 100644 --- a/src/version +++ b/src/version @@ -1 +1 @@ -1.91.0 +1.92.0 diff --git a/tests/assembly-llvm/aarch64-pointer-auth.rs b/tests/assembly-llvm/aarch64-pointer-auth.rs index 56a26df469f35..e1ca6d775813d 100644 --- a/tests/assembly-llvm/aarch64-pointer-auth.rs +++ b/tests/assembly-llvm/aarch64-pointer-auth.rs @@ -1,10 +1,13 @@ // Test that PAC instructions are emitted when branch-protection is specified. //@ add-core-stubs -//@ revisions: PACRET PAUTHLR_NOP PAUTHLR +//@ revisions: GCS PACRET PAUTHLR_NOP PAUTHLR //@ assembly-output: emit-asm //@ needs-llvm-components: aarch64 //@ compile-flags: --target aarch64-unknown-linux-gnu +//@ [GCS] min-llvm-version: 21 +//@ [GCS] ignore-apple (XCode version needs updating) +//@ [GCS] compile-flags: -Z branch-protection=gcs //@ [PACRET] compile-flags: -Z branch-protection=pac-ret,leaf //@ [PAUTHLR_NOP] compile-flags: -Z branch-protection=pac-ret,pc,leaf //@ [PAUTHLR] compile-flags: -C target-feature=+pauth-lr -Z branch-protection=pac-ret,pc,leaf @@ -17,6 +20,7 @@ extern crate minicore; use minicore::*; +// GCS: .aeabi_attribute 2, 1 // Tag_Feature_GCS // PACRET: hint #25 // PACRET: hint #29 // PAUTHLR_NOP: hint #25 diff --git a/tests/assembly-llvm/asm/powerpc-types.rs b/tests/assembly-llvm/asm/powerpc-types.rs index 4291e4c02f3be..c3a0fc4cfa971 100644 --- a/tests/assembly-llvm/asm/powerpc-types.rs +++ b/tests/assembly-llvm/asm/powerpc-types.rs @@ -223,6 +223,94 @@ check!(vreg_f32, f32, vreg, "vmr"); #[cfg(vsx)] check!(vreg_f64, f64, vreg, "vmr"); +// powerpc_vsx-LABEL: vsreg_i8x16: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i8x16: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_i8x16, i8x16, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i16x8: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i16x8: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_i16x8, i16x8, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i32x4: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i32x4: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_i32x4, i32x4, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i64x2: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i64x2: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_i64x2, i64x2, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32x4: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32x4: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_f32x4, f32x4, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64x2: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64x2: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_f64x2, f64x2, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_f32, f32, vsreg, "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp {{[0-9]+}}, {{[0-9]+}} +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check!(vsreg_f64, f64, vsreg, "xvsqrtdp"); + // CHECK-LABEL: reg_i8_r0: // CHECK: #APP // CHECK: mr 0, 0 @@ -472,3 +560,179 @@ check_reg!(vreg_f32_v18, f32, "18", "v18", "vmr"); // powerpc64_vsx: #NO_APP #[cfg(vsx)] check_reg!(vreg_f64_v18, f64, "18", "v18", "vmr"); + +// powerpc_vsx-LABEL: vsreg_i8x16_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i8x16_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i8x16_vs0, i8x16, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i16x8_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i16x8_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i16x8_vs0, i16x8, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i32x4_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i32x4_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i32x4_vs0, i32x4, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i64x2_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i64x2_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i64x2_vs0, i64x2, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32x4_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32x4_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f32x4_vs0, f32x4, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64x2_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64x2_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f64x2_vs0, f64x2, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f32_vs0, f32, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64_vs0: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 0, 0 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64_vs0: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 0, 0 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f64_vs0, f64, "0", "vs0", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i8x16_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i8x16_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i8x16_v40, i8x16, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i16x8_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i16x8_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i16x8_v40, i16x8, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i32x4_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i32x4_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i32x4_v40, i32x4, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_i64x2_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_i64x2_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_i64x2_v40, i64x2, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32x4_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32x4_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f32x4_v40, f32x4, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64x2_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64x2_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f64x2_v40, f64x2, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f32_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f32_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f32_v40, f32, "40", "vs40", "xvsqrtdp"); + +// powerpc_vsx-LABEL: vsreg_f64_v40: +// powerpc_vsx: #APP +// powerpc_vsx: xvsqrtdp 40, 40 +// powerpc_vsx: #NO_APP +// powerpc64_vsx-LABEL: vsreg_f64_v40: +// powerpc64_vsx: #APP +// powerpc64_vsx: xvsqrtdp 40, 40 +// powerpc64_vsx: #NO_APP +#[cfg(vsx)] +check_reg!(vsreg_f64_v40, f64, "40", "vs40", "xvsqrtdp"); diff --git a/tests/assembly-llvm/naked-functions/wasm32.rs b/tests/assembly-llvm/naked-functions/wasm32.rs index 77547e82041fe..4bf04dd392341 100644 --- a/tests/assembly-llvm/naked-functions/wasm32.rs +++ b/tests/assembly-llvm/naked-functions/wasm32.rs @@ -21,6 +21,7 @@ use minicore::*; // CHECK: .functype nop () -> () // CHECK-NOT: .size // CHECK: end_function +// CHECK-LABEL: .Lfunc_end_nop: #[no_mangle] #[unsafe(naked)] extern "C" fn nop() { diff --git a/tests/assembly-llvm/riscv-soft-abi-with-float-features.rs b/tests/assembly-llvm/riscv-soft-abi-with-float-features.rs index 72cbd3841c123..085ea9facd065 100644 --- a/tests/assembly-llvm/riscv-soft-abi-with-float-features.rs +++ b/tests/assembly-llvm/riscv-soft-abi-with-float-features.rs @@ -2,9 +2,6 @@ //@ assembly-output: emit-asm //@ compile-flags: --target riscv64imac-unknown-none-elf -Ctarget-feature=+f,+d //@ needs-llvm-components: riscv -//@ revisions: LLVM-PRE-20 LLVM-POST-20 -//@ [LLVM-PRE-20] max-llvm-major-version: 19 -//@ [LLVM-POST-20] min-llvm-version: 20 #![feature(no_core, lang_items, f16)] #![crate_type = "lib"] @@ -28,11 +25,8 @@ pub extern "C" fn read_f16(x: &f16) -> f16 { // CHECK-LABEL: read_f32 #[no_mangle] pub extern "C" fn read_f32(x: &f32) -> f32 { - // LLVM-PRE-20: flw fa5, 0(a0) - // LLVM-PRE-20-NEXT: fmv.x.w a0, fa5 - // LLVM-PRE-20-NEXT: ret - // LLVM-POST-20: lw a0, 0(a0) - // LLVM-POST-20-NEXT: ret + // CHECK: lw a0, 0(a0) + // CHECK-NEXT: ret *x } diff --git a/tests/assembly-llvm/targets/targets-elf.rs b/tests/assembly-llvm/targets/targets-elf.rs index b5c116cdfef0d..e26c213837066 100644 --- a/tests/assembly-llvm/targets/targets-elf.rs +++ b/tests/assembly-llvm/targets/targets-elf.rs @@ -586,6 +586,9 @@ //@ revisions: wasm32_wasip2 //@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2 //@ [wasm32_wasip2] needs-llvm-components: webassembly +//@ revisions: wasm32_wasip3 +//@ [wasm32_wasip3] compile-flags: --target wasm32-wasip3 +//@ [wasm32_wasip3] needs-llvm-components: webassembly //@ revisions: wasm32_wali_linux_musl //@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl //@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly @@ -658,6 +661,9 @@ //@ revisions: x86_64_unknown_managarm_mlibc //@ [x86_64_unknown_managarm_mlibc] compile-flags: --target x86_64-unknown-managarm-mlibc //@ [x86_64_unknown_managarm_mlibc] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_motor +//@ [x86_64_unknown_motor] compile-flags: --target x86_64-unknown-motor +//@ [x86_64_unknown_motor] needs-llvm-components: x86 //@ revisions: x86_64_unknown_netbsd //@ [x86_64_unknown_netbsd] compile-flags: --target x86_64-unknown-netbsd //@ [x86_64_unknown_netbsd] needs-llvm-components: x86 diff --git a/tests/assembly-llvm/x86-return-float.rs b/tests/assembly-llvm/x86-return-float.rs index 4db93f68485a3..1b283c2759b3a 100644 --- a/tests/assembly-llvm/x86-return-float.rs +++ b/tests/assembly-llvm/x86-return-float.rs @@ -1,9 +1,6 @@ //@ assembly-output: emit-asm // FIXME(#114479): LLVM miscompiles loading and storing `f32` and `f64` when SSE is disabled. -// There's no compiletest directive to ignore a test on i586 only, so just always explicitly enable -// SSE2. -// Use the same target CPU as `i686` so that LLVM orders the instructions in the same order. -//@ compile-flags: -Ctarget-feature=+sse2 -Ctarget-cpu=pentium4 +// (As of #136758, this test cross-compiles to selected i686 targets only, which have SSE.) // Force frame pointers to make ASM more consistent between targets //@ compile-flags: -C force-frame-pointers // At opt-level=3, LLVM can merge two movss into one movsd, and we aren't testing for that. diff --git a/tests/assembly-llvm/x86_64-bigint-helpers.rs b/tests/assembly-llvm/x86_64-bigint-helpers.rs index c5efda58fd668..9d998a31cf306 100644 --- a/tests/assembly-llvm/x86_64-bigint-helpers.rs +++ b/tests/assembly-llvm/x86_64-bigint-helpers.rs @@ -2,7 +2,6 @@ //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -Copt-level=3 -C target-cpu=x86-64-v4 //@ compile-flags: -C llvm-args=-x86-asm-syntax=intel -//@ min-llvm-version: 20 #![no_std] #![feature(bigint_helper_methods)] @@ -45,7 +44,7 @@ pub unsafe extern "sysv64" fn bigint_chain_borrowing_sub( n: usize, mut carry: bool, ) -> bool { - // CHECK: mov [[TEMP:r..]], qword ptr [rsi + 8*[[IND:r..]] + 8] + // CHECK: mov [[TEMP:r.+]], qword ptr [rsi + 8*[[IND:r.+]] + 8] // CHECK: sbb [[TEMP]], qword ptr [rdx + 8*[[IND]] + 8] // CHECK: mov qword ptr [rdi + 8*[[IND]] + 8], [[TEMP]] // CHECK: mov [[TEMP]], qword ptr [rsi + 8*[[IND]] + 16] diff --git a/tests/assembly-llvm/x86_64-cmp.rs b/tests/assembly-llvm/x86_64-cmp.rs index 26c9013d96fc5..1f1fe7fd00520 100644 --- a/tests/assembly-llvm/x86_64-cmp.rs +++ b/tests/assembly-llvm/x86_64-cmp.rs @@ -1,12 +1,6 @@ -//@ revisions: LLVM-PRE-20-DEBUG LLVM-20-DEBUG LLVM-PRE-20-OPTIM LLVM-20-OPTIM -//@ [LLVM-PRE-20-DEBUG] compile-flags: -C opt-level=0 -//@ [LLVM-PRE-20-DEBUG] max-llvm-major-version: 19 -//@ [LLVM-20-DEBUG] compile-flags: -C opt-level=0 -//@ [LLVM-20-DEBUG] min-llvm-version: 20 -//@ [LLVM-PRE-20-OPTIM] compile-flags: -C opt-level=3 -//@ [LLVM-PRE-20-OPTIM] max-llvm-major-version: 19 -//@ [LLVM-20-OPTIM] compile-flags: -C opt-level=3 -//@ [LLVM-20-OPTIM] min-llvm-version: 20 +//@ revisions: DEBUG OPTIM +//@ [DEBUG] compile-flags: -C opt-level=0 +//@ [OPTIM] compile-flags: -C opt-level=3 //@ assembly-output: emit-asm //@ compile-flags: --crate-type=lib -C llvm-args=-x86-asm-syntax=intel //@ only-x86_64 @@ -19,61 +13,22 @@ use std::intrinsics::three_way_compare; #[no_mangle] // CHECK-LABEL: signed_cmp: pub fn signed_cmp(a: i16, b: i16) -> std::cmp::Ordering { - // LLVM-PRE-20-DEBUG: cmp - // LLVM-PRE-20-DEBUG: setg - // LLVM-PRE-20-DEBUG: and - // LLVM-PRE-20-DEBUG: cmp - // LLVM-PRE-20-DEBUG: setl - // LLVM-PRE-20-DEBUG: and - // LLVM-PRE-20-DEBUG: sub - // - // LLVM-20-DEBUG: sub - // LLVM-20-DEBUG: setl - // LLVM-20-DEBUG: setg - // LLVM-20-DEBUG: sub - // LLVM-20-DEBUG: ret - - // LLVM-PRE-20-OPTIM: xor - // LLVM-PRE-20-OPTIM: cmp - // LLVM-PRE-20-OPTIM: setne - // LLVM-PRE-20-OPTIM: mov - // LLVM-PRE-20-OPTIM: cmovge - // LLVM-PRE-20-OPTIM: ret - // - // LLVM-20-OPTIM: cmp - // LLVM-20-OPTIM: setl - // LLVM-20-OPTIM: setg - // LLVM-20-OPTIM: sub - // LLVM-20-OPTIM: ret + // DEBUG: sub + // OPTIM: cmp + // CHECK: setl + // CHECK: setg + // CHECK: sub + // CHECK: ret three_way_compare(a, b) } #[no_mangle] // CHECK-LABEL: unsigned_cmp: pub fn unsigned_cmp(a: u16, b: u16) -> std::cmp::Ordering { - // LLVM-PRE-20-DEBUG: cmp - // LLVM-PRE-20-DEBUG: seta - // LLVM-PRE-20-DEBUG: and - // LLVM-PRE-20-DEBUG: cmp - // LLVM-PRE-20-DEBUG: setb - // LLVM-PRE-20-DEBUG: and - // LLVM-PRE-20-DEBUG: sub - // - // LLVM-20-DEBUG: sub - // LLVM-20-DEBUG: seta - // LLVM-20-DEBUG: sbb - // LLVM-20-DEBUG: ret - - // LLVM-PRE-20-OPTIM: xor - // LLVM-PRE-20-OPTIM: cmp - // LLVM-PRE-20-OPTIM: setne - // LLVM-PRE-20-OPTIM: mov - // LLVM-PRE-20-OPTIM: cmovae - // LLVM-PRE-20-OPTIM: ret - // - // LLVM-20-OPTIM: cmp - // LLVM-20-OPTIM: seta - // LLVM-20-OPTIM: sbb - // LLVM-20-OPTIM: ret + // DEBUG: sub + // OPTIM: cmp + // CHECK: seta + // CHECK: sbb + // CHECK: ret three_way_compare(a, b) } diff --git a/tests/codegen-llvm/asm/powerpc-clobbers.rs b/tests/codegen-llvm/asm/powerpc-clobbers.rs index f7fc7eea5d506..9d8204fa3be9a 100644 --- a/tests/codegen-llvm/asm/powerpc-clobbers.rs +++ b/tests/codegen-llvm/asm/powerpc-clobbers.rs @@ -56,13 +56,59 @@ pub unsafe fn v0_clobber() { asm!("", out("v0") _, options(nostack, nomem, preserves_flags)); } -// Output format depends on the availability of altivec. +// Output format depends on the availability of vsx. +// CHECK-LABEL: @vs32_clobber +// powerpc: call void asm sideeffect "", "~{vs32}"() +// powerpc64: call void asm sideeffect "", "~{vs32}"() +// powerpc64le: call <4 x i32> asm sideeffect "", "=&{vs32}"() +// aix64: call <4 x i32> asm sideeffect "", "=&{vs32}"() +#[no_mangle] +pub unsafe fn vs32_clobber() { + asm!("", out("vs32") _, options(nostack, nomem, preserves_flags)); +} + +// Output format depends on the availability of altivec and vsx // CHECK-LABEL: @clobber_abi -// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() -// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{xer}"() +// powerpc: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64le: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// aix64: asm sideeffect "", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() #[no_mangle] pub unsafe fn clobber_abi() { asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); } + +// CHECK-LABEL: @clobber_no_preserves_flags +// CHECK: call void asm sideeffect "nop", ""() +#[no_mangle] +pub unsafe fn clobber_no_preserves_flags() { + // Use a nop to prevent aliasing of identical functions here. + asm!("nop", options(nostack, nomem)); +} + +// CHECK-LABEL: @cr0_clobber_no_preserves_flags +// CHECK: call void asm sideeffect "nop; nop", "~{cr0}"() +#[no_mangle] +pub unsafe fn cr0_clobber_no_preserves_flags() { + // Use nop; nop to prevent aliasing of identical functions here. + asm!("nop; nop", out("cr0") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @clobber_preservesflags +// CHECK: call void asm sideeffect "", "~{memory}"() +#[no_mangle] +pub unsafe fn clobber_preservesflags() { + asm!("", options(nostack, preserves_flags)); +} + +// Output format depends on the availability of altivec and vsx +// CHECK-LABEL: @clobber_abi_no_preserves_flags +#[no_mangle] +// powerpc: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{vs0},~{vs1},~{vs2},~{vs3},~{vs4},~{vs5},~{vs6},~{vs7},~{vs8},~{vs9},~{vs10},~{vs11},~{vs12},~{vs13},~{vs14},~{vs15},~{vs16},~{vs17},~{vs18},~{vs19},~{vs20},~{vs21},~{vs22},~{vs23},~{vs24},~{vs25},~{vs26},~{vs27},~{vs28},~{vs29},~{vs30},~{vs31},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// powerpc64le: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +// aix64: asm sideeffect "nop", "={r0},={r3},={r4},={r5},={r6},={r7},={r8},={r9},={r10},={r11},={r12},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},={f8},={f9},={f10},={f11},={f12},={f13},={vs0},={vs1},={vs2},={vs3},={vs4},={vs5},={vs6},={vs7},={vs8},={vs9},={vs10},={vs11},={vs12},={vs13},={vs14},={vs15},={vs16},={vs17},={vs18},={vs19},={vs20},={vs21},={vs22},={vs23},={vs24},={vs25},={vs26},={vs27},={vs28},={vs29},={vs30},={vs31},={v0},={v1},={v2},={v3},={v4},={v5},={v6},={v7},={v8},={v9},={v10},={v11},={v12},={v13},={v14},={v15},={v16},={v17},={v18},={v19},~{cr0},~{cr1},~{cr5},~{cr6},~{cr7},~{ctr},~{lr},~{xer}"() +pub unsafe fn clobber_abi_no_preserves_flags() { + // Use a nop to prevent aliasing of identical functions here. + asm!("nop", clobber_abi("C"), options(nostack, nomem)); +} diff --git a/tests/codegen-llvm/asm/readonly-not-pure.rs b/tests/codegen-llvm/asm/readonly-not-pure.rs new file mode 100644 index 0000000000000..a3c0e276c7f5e --- /dev/null +++ b/tests/codegen-llvm/asm/readonly-not-pure.rs @@ -0,0 +1,48 @@ +//@ add-core-stubs +//@ compile-flags: -Copt-level=3 --target x86_64-unknown-linux-gnu +//@ needs-llvm-components: x86 + +#![crate_type = "rlib"] +#![feature(no_core)] +#![no_core] + +// Test that when an inline assembly block specifies `readonly` but not `pure`, a detailed +// `MemoryEffects` is provided to LLVM: this assembly block is not allowed to perform writes, +// but it may have side-effects. + +extern crate minicore; +use minicore::*; + +pub static mut VAR: i32 = 0; + +// CHECK-LABEL: @no_options +// CHECK: call i32 asm +#[no_mangle] +pub unsafe fn no_options() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored); + VAR +} + +// CHECK-LABEL: @readonly_pure +// CHECK-NOT: call i32 asm +#[no_mangle] +pub unsafe fn readonly_pure() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored, options(pure, readonly)); + VAR +} + +// CHECK-LABEL: @readonly_not_pure +// CHECK: call i32 asm {{.*}} #[[ATTR:[0-9]+]] +#[no_mangle] +pub unsafe fn readonly_not_pure() -> i32 { + VAR = 1; + let _ignored: i32; + asm!("mov {0}, 1", out(reg) _ignored, options(readonly)); + VAR +} + +// CHECK: attributes #[[ATTR]] = { nounwind memory(read, inaccessiblemem: readwrite) } diff --git a/tests/codegen-llvm/asm/riscv-clobbers.rs b/tests/codegen-llvm/asm/riscv-clobbers.rs index e55b6731098e7..0f235ddcdcc85 100644 --- a/tests/codegen-llvm/asm/riscv-clobbers.rs +++ b/tests/codegen-llvm/asm/riscv-clobbers.rs @@ -17,7 +17,7 @@ extern crate minicore; use minicore::*; // CHECK-LABEL: @flags_clobber -// CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"() +// CHECK: call void asm sideeffect "", "~{fflags},~{vtype},~{vl},~{vxsat},~{vxrm}"() #[no_mangle] pub unsafe fn flags_clobber() { asm!("", options(nostack, nomem)); diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs new file mode 100644 index 0000000000000..5c8126898a8d7 --- /dev/null +++ b/tests/codegen-llvm/autodiff/abi_handling.rs @@ -0,0 +1,210 @@ +//@ revisions: debug release + +//@[debug] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=0 -Clto=fat +//@[release] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// This test checks that Rust types are lowered to LLVM-IR types in a way +// we expect and Enzyme can handle. We explicitly check release mode to +// ensure that LLVM's O3 pipeline doesn't rewrite function signatures +// into forms that Enzyme can't process correctly. + +#![feature(autodiff)] + +use std::autodiff::{autodiff_forward, autodiff_reverse}; + +#[derive(Copy, Clone)] +struct Input { + x: f32, + y: f32, +} + +#[derive(Copy, Clone)] +struct Wrapper { + z: f32, +} + +#[derive(Copy, Clone)] +struct NestedInput { + x: f32, + y: Wrapper, +} + +fn square(x: f32) -> f32 { + x * x +} + +// CHECK-LABEL: ; abi_handling::df1 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0) +// release-NEXT: define internal fastcc float +// release-SAME: (float %x.0.val, float %x.4.val) + +// CHECK-LABEL: ; abi_handling::f1 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.val, float %x.4.val) +#[autodiff_forward(df1, Dual, Dual)] +#[inline(never)] +fn f1(x: &[f32; 2]) -> f32 { + x[0] + x[1] +} + +// CHECK-LABEL: ; abi_handling::df2 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr %f, float %x, float %dret) +// release-NEXT: define internal fastcc float +// release-SAME: (float noundef %x) + +// CHECK-LABEL: ; abi_handling::f2 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr %f, float %x) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %x) +#[autodiff_reverse(df2, Const, Active, Active)] +#[inline(never)] +fn f2(f: fn(f32) -> f32, x: f32) -> f32 { + f(x) +} + +// CHECK-LABEL: ; abi_handling::df3 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float %x.0.val) + +// CHECK-LABEL: ; abi_handling::f3 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x, ptr align 4 %y) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.val) +#[autodiff_forward(df3, Dual, Dual, Dual)] +#[inline(never)] +fn f3<'a>(x: &'a f32, y: &'a f32) -> f32 { + *x * *y +} + +// CHECK-LABEL: ; abi_handling::df4 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %x.0, float %x.1, float %bx_0.0, float %bx_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float noundef %x.0, float noundef %x.1) + +// CHECK-LABEL: ; abi_handling::f4 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %x.0, float %x.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %x.0, float noundef %x.1) +#[autodiff_forward(df4, Dual, Dual)] +#[inline(never)] +fn f4(x: (f32, f32)) -> f32 { + x.0 * x.1 +} + +// CHECK-LABEL: ; abi_handling::df5 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float noundef %i.0, float noundef %i.1) + +// CHECK-LABEL: ; abi_handling::f5 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %i.0, float %i.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %i.0, float noundef %i.1) +#[autodiff_forward(df5, Dual, Dual)] +#[inline(never)] +fn f5(i: Input) -> f32 { + i.x + i.y +} + +// CHECK-LABEL: ; abi_handling::df6 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (float %i.0, float %i.1, float %bi_0.0, float %bi_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: float noundef %i.0, float noundef %i.1 +// release-SAME: float noundef %bi_0.0, float noundef %bi_0.1 + +// CHECK-LABEL: ; abi_handling::f6 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (float %i.0, float %i.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float noundef %i.0, float noundef %i.1) +#[autodiff_forward(df6, Dual, Dual)] +#[inline(never)] +fn f6(i: NestedInput) -> f32 { + i.x + i.y.z * i.y.z +} + +// CHECK-LABEL: ; abi_handling::df7 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal { float, float } +// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1, ptr align 4 %bx_0.0, ptr align 4 %bx_0.1) +// release-NEXT: define internal fastcc { float, float } +// release-SAME: (float %x.0.0.val, float %x.1.0.val) + +// CHECK-LABEL: ; abi_handling::f7 +// CHECK-NEXT: Function Attrs +// debug-NEXT: define internal float +// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1) +// release-NEXT: define internal fastcc noundef float +// release-SAME: (float %x.0.0.val, float %x.1.0.val) +#[autodiff_forward(df7, Dual, Dual)] +#[inline(never)] +fn f7(x: (&f32, &f32)) -> f32 { + x.0 * x.1 +} + +fn main() { + let x = std::hint::black_box(2.0); + let y = std::hint::black_box(3.0); + let z = std::hint::black_box(4.0); + static Y: f32 = std::hint::black_box(3.2); + + let in_f1 = [x, y]; + dbg!(f1(&in_f1)); + let res_f1 = df1(&in_f1, &[1.0, 0.0]); + dbg!(res_f1); + + dbg!(f2(square, x)); + let res_f2 = df2(square, x, 1.0); + dbg!(res_f2); + + dbg!(f3(&x, &Y)); + let res_f3 = df3(&x, &Y, &1.0, &0.0); + dbg!(res_f3); + + let in_f4 = (x, y); + dbg!(f4(in_f4)); + let res_f4 = df4(in_f4, (1.0, 0.0)); + dbg!(res_f4); + + let in_f5 = Input { x, y }; + dbg!(f5(in_f5)); + let res_f5 = df5(in_f5, Input { x: 1.0, y: 0.0 }); + dbg!(res_f5); + + let in_f6 = NestedInput { x, y: Wrapper { z: y } }; + dbg!(f6(in_f6)); + let res_f6 = df6(in_f6, NestedInput { x, y: Wrapper { z } }); + dbg!(res_f6); + + let in_f7 = (&x, &y); + dbg!(f7(in_f7)); + let res_f7 = df7(in_f7, (&1.0, &0.0)); + dbg!(res_f7); +} diff --git a/tests/codegen-llvm/autodiff/autodiffv2.rs b/tests/codegen-llvm/autodiff/autodiffv2.rs index 85aed6a183b63..c24a374148c34 100644 --- a/tests/codegen-llvm/autodiff/autodiffv2.rs +++ b/tests/codegen-llvm/autodiff/autodiffv2.rs @@ -18,11 +18,6 @@ // but each shadow argument is `width` times larger (thus 16 and 20 elements here). // `d_square3` instead takes `width` (4) shadow arguments, which are all the same size as the // original function arguments. -// -// FIXME(autodiff): We currently can't test `d_square1` and `d_square3` in the same file, since they -// generate the same dummy functions which get merged by LLVM, breaking pieces of our pipeline which -// try to rewrite the dummy functions later. We should consider to change to pure declarations both -// in our frontend and in the llvm backend to avoid these issues. #![feature(autodiff)] @@ -30,7 +25,7 @@ use std::autodiff::autodiff_forward; // CHECK: ; #[no_mangle] -//#[autodiff(d_square1, Forward, Dual, Dual)] +#[autodiff_forward(d_square1, Dual, Dual)] #[autodiff_forward(d_square2, 4, Dualv, Dualv)] #[autodiff_forward(d_square3, 4, Dual, Dual)] fn square(x: &[f32], y: &mut [f32]) { @@ -79,25 +74,25 @@ fn main() { let mut dy3_4 = std::hint::black_box(vec![0.0; 5]); // scalar. - //d_square1(&x1, &z1, &mut y1, &mut dy1_1); - //d_square1(&x1, &z2, &mut y2, &mut dy1_2); - //d_square1(&x1, &z3, &mut y3, &mut dy1_3); - //d_square1(&x1, &z4, &mut y4, &mut dy1_4); + d_square1(&x1, &z1, &mut y1, &mut dy1_1); + d_square1(&x1, &z2, &mut y2, &mut dy1_2); + d_square1(&x1, &z3, &mut y3, &mut dy1_3); + d_square1(&x1, &z4, &mut y4, &mut dy1_4); // assert y1 == y2 == y3 == y4 - //for i in 0..5 { - // assert_eq!(y1[i], y2[i]); - // assert_eq!(y1[i], y3[i]); - // assert_eq!(y1[i], y4[i]); - //} + for i in 0..5 { + assert_eq!(y1[i], y2[i]); + assert_eq!(y1[i], y3[i]); + assert_eq!(y1[i], y4[i]); + } // batch mode A) d_square2(&x1, &z5, &mut y5, &mut dy2); // assert y1 == y2 == y3 == y4 == y5 - //for i in 0..5 { - // assert_eq!(y1[i], y5[i]); - //} + for i in 0..5 { + assert_eq!(y1[i], y5[i]); + } // batch mode B) d_square3(&x1, &z1, &z2, &z3, &z4, &mut y6, &mut dy3_1, &mut dy3_2, &mut dy3_3, &mut dy3_4); diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs index 306a6ed9d1f4f..0ff6134bc07d5 100644 --- a/tests/codegen-llvm/autodiff/batched.rs +++ b/tests/codegen-llvm/autodiff/batched.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme // @@ -23,7 +23,7 @@ fn square(x: &f32) -> f32 { } // d_square2 -// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'") +// CHECK: define internal [4 x float] @fwddiffe4square(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") // CHECK-NEXT: start: // CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 // CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 @@ -33,23 +33,28 @@ fn square(x: &f32) -> f32 { // CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 // CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 // CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %4 = fmul float %"_2'ipl", 2.000000e+00 -// CHECK-NEXT: %5 = fmul fast float %4, %x.0.val -// CHECK-NEXT: %6 = insertvalue [4 x float] undef, float %5, 0 -// CHECK-NEXT: %7 = fmul float %"_2'ipl1", 2.000000e+00 -// CHECK-NEXT: %8 = fmul fast float %7, %x.0.val -// CHECK-NEXT: %9 = insertvalue [4 x float] %6, float %8, 1 -// CHECK-NEXT: %10 = fmul float %"_2'ipl2", 2.000000e+00 -// CHECK-NEXT: %11 = fmul fast float %10, %x.0.val -// CHECK-NEXT: %12 = insertvalue [4 x float] %9, float %11, 2 -// CHECK-NEXT: %13 = fmul float %"_2'ipl3", 2.000000e+00 -// CHECK-NEXT: %14 = fmul fast float %13, %x.0.val -// CHECK-NEXT: %15 = insertvalue [4 x float] %12, float %14, 3 -// CHECK-NEXT: ret [4 x float] %15 +// CHECK-NEXT: %_2 = load float, ptr %x, align 4 +// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 +// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 +// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 +// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 +// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 +// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 +// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 +// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 +// CHECK-NEXT: %12 = fadd fast float %4, %8 +// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 +// CHECK-NEXT: %14 = fadd fast float %5, %9 +// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 +// CHECK-NEXT: %16 = fadd fast float %6, %10 +// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 +// CHECK-NEXT: %18 = fadd fast float %7, %11 +// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 +// CHECK-NEXT: ret [4 x float] %19 // CHECK-NEXT: } // d_square3, the extra float is the original return value (x * x) -// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.1(float %x.0.val, [4 x ptr] %"x'") +// CHECK: define internal { float, [4 x float] } @fwddiffe4square.1(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") // CHECK-NEXT: start: // CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 // CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 @@ -59,22 +64,27 @@ fn square(x: &f32) -> f32 { // CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 // CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 // CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_0 = fmul float %x.0.val, %x.0.val -// CHECK-NEXT: %4 = fmul float %"_2'ipl", 2.000000e+00 -// CHECK-NEXT: %5 = fmul fast float %4, %x.0.val -// CHECK-NEXT: %6 = insertvalue [4 x float] undef, float %5, 0 -// CHECK-NEXT: %7 = fmul float %"_2'ipl1", 2.000000e+00 -// CHECK-NEXT: %8 = fmul fast float %7, %x.0.val -// CHECK-NEXT: %9 = insertvalue [4 x float] %6, float %8, 1 -// CHECK-NEXT: %10 = fmul float %"_2'ipl2", 2.000000e+00 -// CHECK-NEXT: %11 = fmul fast float %10, %x.0.val -// CHECK-NEXT: %12 = insertvalue [4 x float] %9, float %11, 2 -// CHECK-NEXT: %13 = fmul float %"_2'ipl3", 2.000000e+00 -// CHECK-NEXT: %14 = fmul fast float %13, %x.0.val -// CHECK-NEXT: %15 = insertvalue [4 x float] %12, float %14, 3 -// CHECK-NEXT: %16 = insertvalue { float, [4 x float] } undef, float %_0, 0 -// CHECK-NEXT: %17 = insertvalue { float, [4 x float] } %16, [4 x float] %15, 1 -// CHECK-NEXT: ret { float, [4 x float] } %17 +// CHECK-NEXT: %_2 = load float, ptr %x, align 4 +// CHECK-NEXT: %_0 = fmul float %_2, %_2 +// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 +// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 +// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 +// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 +// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 +// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 +// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 +// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 +// CHECK-NEXT: %12 = fadd fast float %4, %8 +// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 +// CHECK-NEXT: %14 = fadd fast float %5, %9 +// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 +// CHECK-NEXT: %16 = fadd fast float %6, %10 +// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 +// CHECK-NEXT: %18 = fadd fast float %7, %11 +// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 +// CHECK-NEXT: %20 = insertvalue { float, [4 x float] } undef, float %_0, 0 +// CHECK-NEXT: %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1 +// CHECK-NEXT: ret { float, [4 x float] } %21 // CHECK-NEXT: } fn main() { diff --git a/tests/codegen-llvm/autodiff/identical_fnc.rs b/tests/codegen-llvm/autodiff/identical_fnc.rs index 6066f8cb34fb9..1c18e7acc4b63 100644 --- a/tests/codegen-llvm/autodiff/identical_fnc.rs +++ b/tests/codegen-llvm/autodiff/identical_fnc.rs @@ -32,9 +32,9 @@ fn square2(x: &f64) -> f64 { // CHECK-NOT:br // CHECK-NOT:ret // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) +// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square17hcb5768e95528c35fE(double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) +// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) fn main() { let x = std::hint::black_box(3.0); diff --git a/tests/codegen-llvm/autodiff/scalar.rs b/tests/codegen-llvm/autodiff/scalar.rs index 55b989f920da3..53672a89230ab 100644 --- a/tests/codegen-llvm/autodiff/scalar.rs +++ b/tests/codegen-llvm/autodiff/scalar.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme #![feature(autodiff)] diff --git a/tests/codegen-llvm/autodiff/sret.rs b/tests/codegen-llvm/autodiff/sret.rs index dbc253ce89434..498cd3fea012d 100644 --- a/tests/codegen-llvm/autodiff/sret.rs +++ b/tests/codegen-llvm/autodiff/sret.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme diff --git a/tests/codegen-llvm/autodiff/typetree.rs b/tests/codegen-llvm/autodiff/typetree.rs new file mode 100644 index 0000000000000..1cb0c2fb68be3 --- /dev/null +++ b/tests/codegen-llvm/autodiff/typetree.rs @@ -0,0 +1,33 @@ +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +// Test that basic autodiff still works with our TypeTree infrastructure +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_simple, Duplicated, Active)] +#[no_mangle] +#[inline(never)] +fn simple(x: &f64) -> f64 { + 2.0 * x +} + +// CHECK-LABEL: @simple +// CHECK: fmul double + +// The derivative function should be generated normally +// CHECK-LABEL: diffesimple +// CHECK: fadd fast double + +fn main() { + let x = std::hint::black_box(3.0); + let output = simple(&x); + assert_eq!(6.0, output); + + let mut df_dx = 0.0; + let output_ = d_simple(&x, &mut df_dx, 1.0); + assert_eq!(output, output_); + assert_eq!(2.0, df_dx); +} diff --git a/tests/codegen-llvm/autodiff/void_ret.rs b/tests/codegen-llvm/autodiff/void_ret.rs new file mode 100644 index 0000000000000..98c6b98eef4e3 --- /dev/null +++ b/tests/codegen-llvm/autodiff/void_ret.rs @@ -0,0 +1,41 @@ +//@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C no-prepopulate-passes -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme + +#![feature(autodiff)] +use std::autodiff::*; + +// Usually we would store the return value of the differentiated function. +// However, if the return type is void or an empty struct, +// we don't need to store anything. Verify this, since it caused a bug. + +// CHECK:; void_ret::main +// CHECK-NEXT: ; Function Attrs: +// CHECK-NEXT: define internal +// CHECK-NOT: store {} undef, ptr undef +// CHECK: ret void + +#[autodiff_reverse(bar, Duplicated, Duplicated)] +pub fn foo(r: &[f64; 10], res: &mut f64) { + let mut output = [0.0; 10]; + output[0] = r[0]; + output[1] = r[1] * r[2]; + output[2] = r[4] * r[5]; + output[3] = r[2] * r[6]; + output[4] = r[1] * r[7]; + output[5] = r[2] * r[8]; + output[6] = r[1] * r[9]; + output[7] = r[5] * r[6]; + output[8] = r[5] * r[7]; + output[9] = r[4] * r[8]; + *res = output.iter().sum(); +} +fn main() { + let inputs = Box::new([3.1; 10]); + let mut d_inputs = Box::new([0.0; 10]); + let mut res = Box::new(0.0); + let mut d_res = Box::new(1.0); + + bar(&inputs, &mut d_inputs, &mut res, &mut d_res); + dbg!(&d_inputs); +} diff --git a/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs new file mode 100644 index 0000000000000..3c35d003c8af6 --- /dev/null +++ b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs @@ -0,0 +1,27 @@ +#![crate_type = "lib"] +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +#[link(name = "Foundation", kind = "framework")] +unsafe extern "C" {} + +#[inline(always)] +pub fn inline_get_object_class() -> objc::Class { + objc::class!("NSObject") +} + +#[inline(always)] +pub fn inline_get_alloc_selector() -> objc::SEL { + objc::selector!("alloc") +} + +#[inline(never)] +pub fn never_inline_get_string_class() -> objc::Class { + objc::class!("NSString") +} + +#[inline(never)] +pub fn never_inline_get_init_selector() -> objc::SEL { + objc::selector!("init") +} diff --git a/tests/codegen-llvm/bpf-abi-indirect-return.rs b/tests/codegen-llvm/bpf-abi-indirect-return.rs new file mode 100644 index 0000000000000..b5787cc83a2b4 --- /dev/null +++ b/tests/codegen-llvm/bpf-abi-indirect-return.rs @@ -0,0 +1,43 @@ +// Checks that results larger than one register are returned indirectly +//@ only-bpf +//@ needs-llvm-components: bpf +//@ compile-flags: --target bpfel-unknown-none + +#![no_std] +#![no_main] + +#[no_mangle] +fn outer(a: u64) -> u64 { + let v = match inner_res(a) { + Ok(v) => v, + Err(()) => 0, + }; + + inner_big(v).a[0] as u64 +} + +// CHECK-LABEL: define {{.*}} @_ZN{{.*}}inner_res{{.*}}E( +// CHECK-SAME: ptr{{[^,]*}}, +// CHECK-SAME: i64{{[^)]*}} +#[inline(never)] +fn inner_res(a: u64) -> Result { + if a == 0 { Err(()) } else { Ok(a + 1) } +} + +struct Big { + a: [u16; 32], + b: u64, +} + +// CHECK-LABEL: define {{.*}} @_ZN{{.*}}inner_big{{.*}}E( +// CHECK-SAME: ptr{{[^,]*}}, +// CHECK-SAME: i64{{[^)]*}} +#[inline(never)] +fn inner_big(a: u64) -> Big { + Big { a: [a as u16; 32], b: 42 } +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/codegen-llvm/branch-protection.rs b/tests/codegen-llvm/branch-protection.rs index d67e494cc0d65..f92259c941cef 100644 --- a/tests/codegen-llvm/branch-protection.rs +++ b/tests/codegen-llvm/branch-protection.rs @@ -1,9 +1,10 @@ // Test that the correct module flags are emitted with different branch protection flags. //@ add-core-stubs -//@ revisions: BTI PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE +//@ revisions: BTI GCS PACRET LEAF BKEY PAUTHLR PAUTHLR_BKEY PAUTHLR_LEAF PAUTHLR_BTI NONE //@ needs-llvm-components: aarch64 //@ [BTI] compile-flags: -Z branch-protection=bti +//@ [GCS] compile-flags: -Z branch-protection=gcs //@ [PACRET] compile-flags: -Z branch-protection=pac-ret //@ [LEAF] compile-flags: -Z branch-protection=pac-ret,leaf //@ [BKEY] compile-flags: -Z branch-protection=pac-ret,b-key @@ -32,6 +33,9 @@ pub fn test() {} // BTI: !"sign-return-address-all", i32 0 // BTI: !"sign-return-address-with-bkey", i32 0 +// GCS: attributes [[ATTR]] = {{.*}} "guarded-control-stack" +// GCS: !"guarded-control-stack", i32 1 + // PACRET: attributes [[ATTR]] = {{.*}} "sign-return-address"="non-leaf" // PACRET-SAME: "sign-return-address-key"="a_key" // PACRET: !"branch-target-enforcement", i32 0 diff --git a/tests/codegen-llvm/c-variadic-lifetime.rs b/tests/codegen-llvm/c-variadic-lifetime.rs index 5b2f8af18c817..c6d3602ef51a0 100644 --- a/tests/codegen-llvm/c-variadic-lifetime.rs +++ b/tests/codegen-llvm/c-variadic-lifetime.rs @@ -8,7 +8,7 @@ #[unsafe(no_mangle)] unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { - // CHECK: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %args) + // CHECK: call void @llvm.lifetime.start.p0({{(i64 [0-9]+, )?}}ptr nonnull %args) // CHECK: call void @llvm.va_start.p0(ptr nonnull %args) let b = args.arg::(); @@ -17,5 +17,5 @@ unsafe extern "C" fn variadic(a: f64, mut args: ...) -> f64 { a + b + c // CHECK: call void @llvm.va_end.p0(ptr nonnull %args) - // CHECK: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %args) + // CHECK: call void @llvm.lifetime.end.p0({{(i64 [0-9]+, )?}}ptr nonnull %args) } diff --git a/tests/codegen-llvm/cold-attribute.rs b/tests/codegen-llvm/cold-attribute.rs new file mode 100644 index 0000000000000..92b4280eaf27e --- /dev/null +++ b/tests/codegen-llvm/cold-attribute.rs @@ -0,0 +1,78 @@ +// Checks that the cold attribute adds the llvm cold attribute. +// +//@ reference: attributes.codegen.cold.intro +//@ reference: attributes.codegen.cold.trait +//@ edition:2024 +//@ compile-flags: -Copt-level=0 + +#![crate_type = "lib"] + +// CHECK-LABEL: ; cold_attribute::free_function +// CHECK-NEXT: Function Attrs: cold {{.*}} +#[cold] +pub fn free_function() {} + +// CHECK-LABEL: ; cold_attribute::async_block +// CHECK-NEXT: Function Attrs: cold {{.*}} +#[cold] +pub async fn async_block() { + async fn x(f: impl Future) { + f.await; + } + x( + // CHECK-LABEL: ; cold_attribute::async_block::{{{{closure}}}}::{{{{closure}}}} + // CHECK-NEXT: Function Attrs: cold {{.*}} + #[cold] + async {}, + ) + .await; +} + +pub fn closure() { + fn x(f: impl Fn()) { + f() + } + x( + // CHECK-LABEL: ; cold_attribute::closure::{{{{closure}}}} + // CHECK-NEXT: Function Attrs: cold {{.*}} + #[cold] + || {}, + ); +} + +pub struct S; + +impl S { + // CHECK-LABEL: ; cold_attribute::S::method + // CHECK-NEXT: Function Attrs: cold {{.*}} + #[cold] + pub fn method(&self) {} +} + +pub trait Trait { + // CHECK-LABEL: ; cold_attribute::Trait::trait_fn + // CHECK-NEXT: Function Attrs: cold {{.*}} + #[cold] + fn trait_fn(&self) {} + + #[cold] + fn trait_fn_overridden(&self) {} + + fn impl_fn(&self); +} + +impl Trait for S { + // CHECK-LABEL: ; ::impl_fn + // CHECK-NEXT: Function Attrs: cold {{.*}} + #[cold] + fn impl_fn(&self) { + self.trait_fn(); + } + + // This does not have #[cold], and does not inherit the cold attribute from the trait. + // CHECK-LABEL: ; ::trait_fn_overridden + // CHECK: ; Function Attrs: + // CHECK-NOT: cold + // CHECK: define + fn trait_fn_overridden(&self) {} +} diff --git a/tests/codegen-llvm/common_prim_int_ptr.rs b/tests/codegen-llvm/common_prim_int_ptr.rs index 53716adccbf21..2c906e86bd736 100644 --- a/tests/codegen-llvm/common_prim_int_ptr.rs +++ b/tests/codegen-llvm/common_prim_int_ptr.rs @@ -11,7 +11,7 @@ #[no_mangle] pub fn insert_int(x: usize) -> Result> { // CHECK: start: - // CHECK-NEXT: %[[WO_PROV:.+]] = getelementptr i8, ptr null, [[USIZE:i[0-9]+]] %x + // CHECK-NEXT: %[[WO_PROV:.+]] = inttoptr [[USIZE:i[0-9]+]] %x to ptr // CHECK-NEXT: %[[R:.+]] = insertvalue { [[USIZE]], ptr } { [[USIZE]] 0, ptr poison }, ptr %[[WO_PROV]], 1 // CHECK-NEXT: ret { [[USIZE]], ptr } %[[R]] Ok(x) diff --git a/tests/codegen-llvm/comparison-operators-2-struct.rs b/tests/codegen-llvm/comparison-operators-2-struct.rs index e179066ebfd72..d44f92f511b64 100644 --- a/tests/codegen-llvm/comparison-operators-2-struct.rs +++ b/tests/codegen-llvm/comparison-operators-2-struct.rs @@ -1,5 +1,4 @@ //@ compile-flags: -C opt-level=1 -//@ min-llvm-version: 20 // The `derive(PartialOrd)` for a 2-field type doesn't override `lt`/`le`/`gt`/`ge`. // This double-checks that the `Option` intermediate values used diff --git a/tests/codegen-llvm/comparison-operators-2-tuple.rs b/tests/codegen-llvm/comparison-operators-2-tuple.rs index 6a7e489c82dd9..37a7c5dfdaf04 100644 --- a/tests/codegen-llvm/comparison-operators-2-tuple.rs +++ b/tests/codegen-llvm/comparison-operators-2-tuple.rs @@ -1,5 +1,4 @@ //@ compile-flags: -C opt-level=1 -Z merge-functions=disabled -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/darwin-no-objc.rs b/tests/codegen-llvm/darwin-no-objc.rs new file mode 100644 index 0000000000000..fda3671fb6d84 --- /dev/null +++ b/tests/codegen-llvm/darwin-no-objc.rs @@ -0,0 +1,52 @@ +// Test that we don't generate Objective-C definitions or image info unnecessarily. + +//@ add-core-stubs +//@ revisions: i686_apple_darwin +//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin +//@ [i686_apple_darwin] needs-llvm-components: x86 +//@ revisions: x86_64_macos +//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin +//@ [x86_64_macos] needs-llvm-components: x86 +//@ revisions: aarch64_macos +//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin +//@ [aarch64_macos] needs-llvm-components: aarch64 +//@ revisions: i386_ios +//@ [i386_ios] compile-flags: --target i386-apple-ios +//@ [i386_ios] needs-llvm-components: x86 +//@ revisions: x86_64_ios +//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios +//@ [x86_64_ios] needs-llvm-components: x86 +//@ revisions: armv7s_ios +//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios +//@ [armv7s_ios] needs-llvm-components: arm +//@ revisions: aarch64_ios +//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios +//@ [aarch64_ios] needs-llvm-components: aarch64 +//@ revisions: aarch64_ios_sim +//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim +//@ [aarch64_ios_sim] needs-llvm-components: aarch64 + +#![crate_type = "lib"] +#![feature(no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn foo() {} + +// CHECK-NOT: %struct._class_t +// CHECK-NOT: %struct._objc_module +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @"OBJC_CLASS_$_{{[0-9A-Z_a-z]+}}" +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ +// CHECK-NOT: @OBJC_MODULES + +// CHECK-NOT: !"Objective-C Version" +// CHECK-NOT: !"Objective-C Image Info Version" +// CHECK-NOT: !"Objective-C Image Info Section" +// CHECK-NOT: !"Objective-C Is Simulated" +// CHECK-NOT: !"Objective-C Class Properties" diff --git a/tests/codegen-llvm/darwin-objc-abi-v1.rs b/tests/codegen-llvm/darwin-objc-abi-v1.rs new file mode 100644 index 0000000000000..0fc1de9332ac4 --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-abi-v1.rs @@ -0,0 +1,100 @@ +// ignore-tidy-linelength +//@ add-core-stubs +//@ revisions: i686_apple_darwin +//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin +//@ [i686_apple_darwin] needs-llvm-components: x86 + +#![crate_type = "lib"] +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn get_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_class_again() -> *mut () { + // Codegen should de-duplicate this class with the one from get_class above. + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector_again() -> *mut () { + // Codegen should de-duplicate this selector with the one from get_selector above. + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "OtherClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "otherMethod"] + safe static VAL: *mut (); + } + VAL +} + +// CHECK: %struct._objc_module = type { i32, i32, ptr, ptr } + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [8 x i8] c"MyClass\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4 +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @OBJC_CLASS_REFERENCES_ + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [11 x i8] c"OtherClass\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 + +// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1 +// CHECK: @OBJC_MODULES = private global %struct._objc_module { i32 7, i32 16, ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, ptr null }, section "__OBJC,__module_info,regular,no_dead_strip", align 4 + +// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"} +// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/darwin-objc-abi-v2.rs b/tests/codegen-llvm/darwin-objc-abi-v2.rs new file mode 100644 index 0000000000000..f142371d5825b --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-abi-v2.rs @@ -0,0 +1,185 @@ +// ignore-tidy-linelength +//@ add-core-stubs +//@ revisions: x86_64_macos +//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin +//@ [x86_64_macos] needs-llvm-components: x86 +//@ revisions: aarch64_macos +//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin +//@ [aarch64_macos] needs-llvm-components: aarch64 +//@ revisions: i386_ios +//@ [i386_ios] compile-flags: --target i386-apple-ios +//@ [i386_ios] needs-llvm-components: x86 +//@ revisions: x86_64_ios +//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios +//@ [x86_64_ios] needs-llvm-components: x86 +//@ revisions: armv7s_ios +//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios +//@ [armv7s_ios] needs-llvm-components: arm +//@ revisions: aarch64_ios +//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios +//@ [aarch64_ios] needs-llvm-components: aarch64 +//@ revisions: aarch64_ios_sim +//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim +//@ [aarch64_ios_sim] needs-llvm-components: aarch64 + +#![crate_type = "lib"] +#![feature(no_core, lang_items, rustc_attrs)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[no_mangle] +pub fn get_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_class_again() -> *mut () { + // Codegen should de-duplicate this class with the one from get_class above. + unsafe extern "C" { + #[rustc_objc_class = "MyClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_selector_again() -> *mut () { + // Codegen should de-duplicate this selector with the one from get_selector above. + unsafe extern "C" { + #[rustc_objc_selector = "myMethod"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_class() -> *mut () { + unsafe extern "C" { + #[rustc_objc_class = "OtherClass"] + safe static VAL: *mut (); + } + VAL +} + +#[no_mangle] +pub fn get_other_selector() -> *mut () { + unsafe extern "C" { + #[rustc_objc_selector = "otherMethod"] + safe static VAL: *mut (); + } + VAL +} + +// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr } + +// CHECK: @"OBJC_CLASS_$_MyClass" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 +// CHECK-NOT: @"OBJC_CLASS_$_MyClass" +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_ + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 +// CHECK-NOT: @OBJC_METH_VAR_NAME_ +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_ + +// CHECK: @"OBJC_CLASS_$_OtherClass" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_OtherClass", section "__DATA,__objc_classrefs,regular,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK-NOT: @OBJC_CLASS_NAME_ +// CHECK-NOT: @OBJC_MODULES + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, +// x86_64_macos-SAME: align 8 +// aarch64_macos-SAME: align 8 +// i386_ios-SAME: align 4 +// x86_64_ios-SAME: align 8 +// armv7s_ios-SAME: align 4 +// aarch64_ios-SAME: align 8 +// aarch64_ios_sim-SAME: align 8 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} + +// x86_64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// i386_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// x86_64_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// armv7s_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// aarch64_ios_sim: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/darwin-objc-cross-crate.rs b/tests/codegen-llvm/darwin-objc-cross-crate.rs new file mode 100644 index 0000000000000..74ad9a27346d1 --- /dev/null +++ b/tests/codegen-llvm/darwin-objc-cross-crate.rs @@ -0,0 +1,58 @@ +// Test that Objective-C class and selector references inlined across crates +// get defined in this CGU but non-inline references don't. + +// ignore-tidy-linelength +//@ aux-build: darwin_objc_aux.rs +//@ revisions: x86_64_macos aarch64_macos +//@ [x86_64_macos] only-x86_64-apple-darwin +//@ [aarch64_macos] only-aarch64-apple-darwin + +#![crate_type = "lib"] +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +extern crate darwin_objc_aux as aux; + +#[no_mangle] +pub fn get_object_class() -> objc::Class { + aux::inline_get_object_class() +} + +#[no_mangle] +pub fn get_alloc_selector() -> objc::SEL { + aux::inline_get_alloc_selector() +} + +#[no_mangle] +pub fn get_string_class() -> objc::Class { + aux::never_inline_get_string_class() +} + +#[no_mangle] +pub fn get_init_selector() -> objc::SEL { + aux::never_inline_get_init_selector() +} + +// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr } + +// CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t +// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSObject", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8 + +// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [6 x i8] c"alloc\00", section "__TEXT,__objc_methname,cstring_literals", align 1 +// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8 + +// CHECK-NOT: @"OBJC_CLASS_$_NSString" = external global %struct._class_t +// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSString" + +// CHECK-NOT: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [5 x i8] c"init\00" +// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}} + +// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", align 8 +// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 8 + +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"} +// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32} +// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64} diff --git a/tests/codegen-llvm/debug-fndef-size.rs b/tests/codegen-llvm/debug-fndef-size.rs index 8f716c34e7b74..02629bd748c45 100644 --- a/tests/codegen-llvm/debug-fndef-size.rs +++ b/tests/codegen-llvm/debug-fndef-size.rs @@ -16,5 +16,5 @@ pub fn main() { // CHECK: %compare.dbg.spill = alloca [0 x i8], align 1 // CHECK: dbg{{.}}declare({{(metadata )?}}ptr %compare.dbg.spill, {{(metadata )?}}![[VAR:.*]], {{(metadata )?}}!DIExpression() -// CHECK: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 8, dwarfAddressSpace: {{.*}}) -// CHECK: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 8) +// CHECK-DAG: ![[TYPE:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, name: "fn(&i32, &i32) -> core::cmp::Ordering", baseType: !{{.*}}, align: 8, dwarfAddressSpace: {{.*}}) +// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "compare", scope: !{{.*}}, file: !{{.*}}, line: {{.*}}, type: ![[TYPE]], align: 8) diff --git a/tests/codegen-llvm/debuginfo-dse.rs b/tests/codegen-llvm/debuginfo-dse.rs new file mode 100644 index 0000000000000..fd0c9f1c676f1 --- /dev/null +++ b/tests/codegen-llvm/debuginfo-dse.rs @@ -0,0 +1,362 @@ +//@ compile-flags: -Copt-level=3 -g -Zverify-llvm-ir -Zmerge-functions=disabled +//@ revisions: CODEGEN OPTIMIZED +//@[CODEGEN] compile-flags: -Cno-prepopulate-passes +//@ only-64bit +// ignore-tidy-linelength + +#![crate_type = "lib"] +#![feature(repr_simd, rustc_attrs)] + +// The pass mode is direct and the backend represent is scalar. +type Scalar = i32; // scalar(i32) +type Scalar_Ref = &'static i32; // scalar(ptr) + +// The pass modes are pair and the backend represents are scalar pair. +type Tuple_Scalar_Scalar = (i32, i32); +struct Tuple_Ref_Scalar(&'static i32, i32); +struct Tuple_ArrayRef_Scalar(&'static [i32; 16], i32); // pair(ptr, i32) +impl Default for Tuple_ArrayRef_Scalar { + fn default() -> Tuple_ArrayRef_Scalar { + Tuple_ArrayRef_Scalar(&[0; 16], 0) + } +} +struct Tuple_Scalar_ArrayRef(i32, &'static [i32; 16]); // pair(i32, ptr) +impl Default for Tuple_Scalar_ArrayRef { + fn default() -> Tuple_Scalar_ArrayRef { + Tuple_Scalar_ArrayRef(0, &[0; 16]) + } +} +// The pass mode is indirect and the backend represent is memory. +type Tuple_SliceRef_Scalar = (&'static [i32], i32); + +// The pass mode is pair and the backend represent is scalar pair. +type SliceRef = &'static [i32]; // pair(ptr, i32) +// The pass mode is indirect and the backend represent is memory. +type Array = [i32; 16]; +// The pass mode is direct and the backend represent is scalar. +type ArrayRef = &'static [i32; 16]; + +// The pass mode is indirect and the backend represent is memory. +type Typle_i32_i64_i8 = (i32, i64, i8); +// The pass mode is indirect and the backend represent is memory. +#[repr(C)] +struct Aggregate_i32_Array_i8(i32, &'static [i32; 16], i8); + +type ZST = (); + +impl Default for Aggregate_i32_Array_i8 { + fn default() -> Aggregate_i32_Array_i8 { + Aggregate_i32_Array_i8(0, &[0; 16], 0) + } +} +// The pass mode is cast and the backend represent is scalar. +#[derive(Default)] +struct Aggregate_4xi8(i8, i8, i8, i8); // scalar(i32) + +// The pass mode is indirect and the backend represent is simd vector. +#[repr(simd)] +struct Simd_i32x4([i32; 4]); + +unsafe extern "Rust" { + #[rustc_nounwind] + safe fn opaque_fn(); + #[rustc_nounwind] + safe fn opaque_ptr(_: *const core::ffi::c_void); +} + +#[inline(never)] +#[rustc_nounwind] +fn opaque_use(p: &T) { + opaque_ptr(&raw const p as *const _); +} + +#[inline(never)] +#[rustc_nounwind] +fn opaque_read() -> T { + core::hint::black_box(T::default()) +} + +#[unsafe(no_mangle)] +fn local_var() { + // CHECK-LABEL: define{{( dso_local)?}} void @local_var + let local_var_scalar: Scalar = opaque_read(); + opaque_use(&local_var_scalar); + let dead_local_var_scalar: Scalar = opaque_read(); + let local_var_aggregate_4xi8: Aggregate_4xi8 = opaque_read(); + opaque_use(&local_var_aggregate_4xi8); + let local_var_aggregate_i32_array_i8: Aggregate_i32_Array_i8 = opaque_read(); + opaque_use(&local_var_aggregate_i32_array_i8); + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr %local_var_scalar, [[ref_local_var_scalar:![0-9]+]], !DIExpression() + let ref_local_var_scalar = &local_var_scalar; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_dead_local_var_scalar:![0-9]+]], !DIExpression() + let ref_dead_local_var_scalar = &dead_local_var_scalar; + // CHECK-NEXT: #dbg_value(ptr %local_var_aggregate_4xi8, [[ref_local_var_aggregate_4xi8:![0-9]+]], !DIExpression() + let ref_local_var_aggregate_4xi8 = &local_var_aggregate_4xi8; + // CHECK-NEXT: #dbg_value(ptr %local_var_aggregate_4xi8, [[ref_0_local_var_aggregate_4xi8:![0-9]+]], !DIExpression() + let ref_0_local_var_aggregate_4xi8 = &local_var_aggregate_4xi8.0; + // CHECK-NEXT: #dbg_value(ptr %local_var_aggregate_4xi8, [[ref_2_local_var_aggregate_4xi8:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 2, DW_OP_stack_value) + let ref_2_local_var_aggregate_4xi8 = &local_var_aggregate_4xi8.2; + // This introduces an extra load instruction. + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_1_1_local_var_aggregate_i32_array_i8:![0-9]+]], !DIExpression() + let ref_1_1_local_var_aggregate_i32_array_i8 = &local_var_aggregate_i32_array_i8.1[1]; + // CHECK-NEXT: #dbg_value(ptr %local_var_aggregate_i32_array_i8, [[ref_2_local_var_aggregate_i32_array_i8:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value) + let ref_2_local_var_aggregate_i32_array_i8 = &local_var_aggregate_i32_array_i8.2; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +#[unsafe(no_mangle)] +fn zst(zst: ZST, zst_ref: &ZST) { + // CHECK-LABEL: define{{( dso_local)?}} void @zst + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_zst:![0-9]+]], !DIExpression() + let ref_zst = &zst; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_zst_ref:![0-9]+]], !DIExpression() + let ref_zst_ref = &zst_ref; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +// It only makes sense if the argument is a reference and it refer to projections. +#[unsafe(no_mangle)] +fn direct( + scalar: Scalar, + scalar_ref: Scalar_Ref, + array_ref: ArrayRef, + aggregate_4xi8_ref: &Aggregate_4xi8, +) { + // CHECK-LABEL: define{{( dso_local)?}} void @direct + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_scalar:![0-9]+]], !DIExpression() + let ref_scalar = &scalar; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_scalar_ref:![0-9]+]], !DIExpression() + let ref_scalar_ref = &scalar_ref; + // CHECK-NEXT: #dbg_value(ptr %array_ref, [[ref_0_array_ref:![0-9]+]], !DIExpression() + let ref_0_array_ref = &array_ref[0]; + // CHECK-NEXT: #dbg_value(ptr %array_ref, [[ref_1_array_ref:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value) + let ref_1_array_ref = &array_ref[1]; + // CHECK-NEXT: #dbg_value(ptr %aggregate_4xi8_ref, [[ref_1_aggregate_4xi8_ref:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value) + let ref_1_aggregate_4xi8_ref = &aggregate_4xi8_ref.1; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +// Arguments are passed through registers, the final values are poison. +#[unsafe(no_mangle)] +fn cast(aggregate_4xi8: Aggregate_4xi8) { + // CHECK-LABEL: define{{( dso_local)?}} void @cast(i32 %0) + // CHECK: call void @opaque_fn() + opaque_fn(); + // The temporary allocated variable is eliminated. + // CODEGEN-NEXT: #dbg_value(ptr %aggregate_4xi8, [[ref_aggregate_4xi8:![0-9]+]], !DIExpression() + // OPTIMIZED-NEXT: #dbg_value(ptr undef, [[ref_aggregate_4xi8:![0-9]+]], !DIExpression() + let ref_aggregate_4xi8 = &aggregate_4xi8; + // CODEGEN-NEXT: #dbg_value(ptr %aggregate_4xi8, [[ref_0_aggregate_4xi8:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value) + // OPTIMIZED-NEXT: #dbg_value(ptr undef, [[ref_0_aggregate_4xi8:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value) + let ref_0_aggregate_4xi8 = &aggregate_4xi8.1; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +// Arguments are passed indirectly via a pointer. +// The reference of argument is the pointer itself. +#[unsafe(no_mangle)] +fn indirect( + tuple_sliceref_scalar: Tuple_SliceRef_Scalar, + array: Array, + typle_i32_i64_i8: Typle_i32_i64_i8, + simd_i32x4: Simd_i32x4, +) { + // CHECK-LABEL: define{{( dso_local)?}} void @indirect + // CHECK-SAME: (ptr{{.*}} %tuple_sliceref_scalar, ptr{{.*}} %array, ptr{{.*}} %typle_i32_i64_i8, ptr{{.*}} %simd_i32x4) + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr %tuple_sliceref_scalar, [[ref_tuple_sliceref_scalar:![0-9]+]], !DIExpression() + let ref_tuple_sliceref_scalar = &tuple_sliceref_scalar; + // CHECK-NEXT: #dbg_value(ptr %tuple_sliceref_scalar, [[ref_1_tuple_sliceref_scalar:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_stack_value) + let ref_1_tuple_sliceref_scalar = &tuple_sliceref_scalar.1; + // CHECK-NEXT: #dbg_value(ptr %array, [[ref_1_array:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value) + let ref_1_array = &array[1]; + // CHECK-NEXT: #dbg_value(ptr %typle_i32_i64_i8, [[ref_1_typle_i32_i64_i8:![0-9]+]], !DIExpression() + let ref_1_typle_i32_i64_i8 = &typle_i32_i64_i8.1; + // CHECK-NEXT: #dbg_value(ptr %simd_i32x4, [[ref_simd_i32x4:![0-9]+]], !DIExpression() + let ref_simd_i32x4 = &simd_i32x4; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +// They are different MIR statements, but they have the same LLVM IR statement due to the ABI of arguments. +// Both `direct_ref` and `indirect_byval` are passed as a pointer here. +#[unsafe(no_mangle)] +fn direct_ref_and_indirect( + direct_ref: &Aggregate_i32_Array_i8, + indirect_byval: Aggregate_i32_Array_i8, +) { + // CHECK-LABEL: define{{( dso_local)?}} void @direct_ref_and_indirect + // CHECK-SAME: (ptr{{.*}} %direct_ref, ptr{{.*}} %indirect_byval) + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_direct_ref:![0-9]+]], !DIExpression() + let ref_direct_ref: &&Aggregate_i32_Array_i8 = &direct_ref; + // CHECK-NEXT: #dbg_value(ptr %direct_ref, [[ref_1_direct_ref:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value) + let ref_1_direct_ref = &direct_ref.1; + // CHECK-NEXT: #dbg_value(ptr %indirect_byval, [[ref_indirect_byval:![0-9]+]], !DIExpression() + let ref_indirect_byval: &Aggregate_i32_Array_i8 = &indirect_byval; + // CHECK-NEXT: #dbg_value(ptr %indirect_byval, [[ref_1_indirect_byval:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_stack_value) + let ref_1_indirect_byval = &indirect_byval.1; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +#[unsafe(no_mangle)] +fn pair( + tuple_scalar_scalar: Tuple_Scalar_Scalar, + tuple_ref_scalar: Tuple_Ref_Scalar, + tuple_arrayref_scalar: Tuple_ArrayRef_Scalar, + tuple_scalar_arrayref: Tuple_Scalar_ArrayRef, + sliceref: SliceRef, +) { + // CHECK-LABEL: define{{( dso_local)?}} void @pair + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_0_tuple_scalar_scalar:![0-9]+]], !DIExpression() + let ref_0_tuple_scalar_scalar = &tuple_scalar_scalar.0; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_0_tuple_ref_scalar:![0-9]+]], !DIExpression() + let ref_0_tuple_ref_scalar = &tuple_ref_scalar.0; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_1_tuple_ref_scalar:![0-9]+]], !DIExpression() + let ref_1_tuple_ref_scalar = &tuple_ref_scalar.1; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_0_tuple_arrayref_scalar:![0-9]+]], !DIExpression() + let ref_0_tuple_arrayref_scalar = &tuple_arrayref_scalar.0; + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_1_tuple_arrayref_scalar:![0-9]+]], !DIExpression() + let ref_1_tuple_arrayref_scalar = &tuple_arrayref_scalar.1; + // FIXME: This can be a valid value. + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_0_1_tuple_arrayref_scalar:![0-9]+]], !DIExpression() + let ref_0_1_tuple_arrayref_scalar = &tuple_arrayref_scalar.0[1]; + // FIXME: This can be a valid value. + // CHECK-NEXT: #dbg_value(ptr poison, [[ref_1_1_tuple_scalar_arrayref:![0-9]+]], !DIExpression() + let ref_1_1_tuple_scalar_arrayref = &tuple_scalar_arrayref.1[1]; + // CHECK: #dbg_value(ptr %sliceref.0, [[ref_1_sliceref:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 4, DW_OP_stack_value) + let ref_1_sliceref = &sliceref[1]; + // CHECK: call void @opaque_fn() + opaque_fn(); +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct Foo(i32, i64, i32); + +#[repr(C)] +pub struct Bar<'a> { + a: i32, + b: i64, + foo: &'a Foo, +} + +#[unsafe(no_mangle)] +pub fn dead_first(dead_first_foo: &Foo) -> &i32 { + // CHECK-LABEL: def {{.*}} ptr @dead_first + // CHECK-SAME: (ptr {{.*}} [[ARG_dead_first_foo:%.*]]) + // CODEGEN: #dbg_declare(ptr %dead_first_foo.dbg.spill, [[ARG_dead_first_foo:![0-9]+]], !DIExpression() + // OPTIMIZED: #dbg_value(ptr %dead_first_foo, [[ARG_dead_first_foo:![0-9]+]], !DIExpression() + // CHECK: #dbg_value(ptr %dead_first_foo, [[VAR_dead_first_v0:![0-9]+]], !DIExpression() + // CHECK: %dead_first_v0 = getelementptr{{.*}} i8, ptr %dead_first_foo, i64 16 + // CODEGEN: #dbg_declare(ptr %dead_first_v0.dbg.spill, [[VAR_dead_first_v0]], !DIExpression() + // OPTIMIZED: #dbg_value(ptr %dead_first_v0, [[VAR_dead_first_v0]], !DIExpression() + let mut dead_first_v0 = &dead_first_foo.0; + dead_first_v0 = &dead_first_foo.2; + dead_first_v0 +} + +#[unsafe(no_mangle)] +pub fn fragment(fragment_v1: Foo, mut fragment_v2: Foo) -> Foo { + // CHECK-LABEL: define{{( dso_local)?}} void @fragment + // CHECK-SAME: (ptr {{.*}}, ptr {{.*}} [[ARG_fragment_v1:%.*]], ptr {{.*}} [[ARG_fragment_v2:%.*]]) + // CHECK: #dbg_declare(ptr [[ARG_fragment_v1]] + // CHECK-NEXT: #dbg_declare(ptr [[ARG_fragment_v2]] + // CHECK-NEXT: #dbg_value(ptr [[ARG_fragment_v2]], [[VAR_fragment_f:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 64) + // CHECK-NEXT: #dbg_value(ptr [[ARG_fragment_v1]], [[VAR_fragment_f:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 64, 64) + let fragment_f = || { + fragment_v2 = fragment_v1; + }; + fragment_v2 = fragment_v1; + fragment_v2 +} + +#[unsafe(no_mangle)] +pub fn deref(bar: Bar) -> i32 { + // CHECK-LABEL: define{{.*}} i32 @deref + // We are unable to represent dereference within this expression. + // CHECK: #dbg_value(ptr poison, [[VAR_deref_dead:![0-9]+]], !DIExpression() + let deref_dead = &bar.foo.2; + bar.a +} + +#[unsafe(no_mangle)] +fn index(slice: &[i32; 4], idx: usize) -> i32 { + // CHECK-LABEL: define{{.*}} i32 @index + // CHECK: call void @opaque_fn() + opaque_fn(); + // CHECK: #dbg_value(ptr poison, [[VAR_index_from_var:![0-9]+]], !DIExpression() + let index_from_var = &slice[idx]; + // CHECK: #dbg_value(ptr %slice, [[VAR_const_index_from_start:![0-9]+]], !DIExpression() + // CHECK-NEXT: #dbg_value(ptr poison, [[VAR_const_index_from_end:![0-9]+]], !DIExpression() + let [ref const_index_from_start, .., ref const_index_from_end] = slice[..] else { + return 0; + }; + slice[0] +} + +// CHECK-DAG: [[ref_local_var_scalar]] = !DILocalVariable(name: "ref_local_var_scalar" +// CHECK-DAG: [[ref_dead_local_var_scalar]] = !DILocalVariable(name: "ref_dead_local_var_scalar" +// CHECK-DAG: [[ref_local_var_aggregate_4xi8]] = !DILocalVariable(name: "ref_local_var_aggregate_4xi8" +// CHECK-DAG: [[ref_0_local_var_aggregate_4xi8]] = !DILocalVariable(name: "ref_0_local_var_aggregate_4xi8" +// CHECK-DAG: [[ref_2_local_var_aggregate_4xi8]] = !DILocalVariable(name: "ref_2_local_var_aggregate_4xi8" +// CHECK-DAG: [[ref_1_1_local_var_aggregate_i32_array_i8]] = !DILocalVariable(name: "ref_1_1_local_var_aggregate_i32_array_i8" +// CHECK-DAG: [[ref_2_local_var_aggregate_i32_array_i8]] = !DILocalVariable(name: "ref_2_local_var_aggregate_i32_array_i8" + +// CHECK-DAG: [[ref_zst]] = !DILocalVariable(name: "ref_zst" +// CHECK-DAG: [[ref_zst_ref]] = !DILocalVariable(name: "ref_zst_ref" + +// CHECK-DAG: [[ref_scalar]] = !DILocalVariable(name: "ref_scalar" +// CHECK-DAG: [[ref_scalar_ref]] = !DILocalVariable(name: "ref_scalar_ref" +// CHECK-DAG: [[ref_0_array_ref]] = !DILocalVariable(name: "ref_0_array_ref" +// CHECK-DAG: [[ref_1_array_ref]] = !DILocalVariable(name: "ref_1_array_ref" +// CHECK-DAG: [[ref_1_aggregate_4xi8_ref]] = !DILocalVariable(name: "ref_1_aggregate_4xi8_ref" + +// CHECK-DAG: [[ref_aggregate_4xi8]] = !DILocalVariable(name: "ref_aggregate_4xi8" +// CHECK-DAG: [[ref_0_aggregate_4xi8]] = !DILocalVariable(name: "ref_0_aggregate_4xi8" + +// CHECK-DAG: [[ref_tuple_sliceref_scalar]] = !DILocalVariable(name: "ref_tuple_sliceref_scalar" +// CHECK-DAG: [[ref_1_tuple_sliceref_scalar]] = !DILocalVariable(name: "ref_1_tuple_sliceref_scalar" +// CHECK-DAG: [[ref_1_array]] = !DILocalVariable(name: "ref_1_array" +// CHECK-DAG: [[ref_1_typle_i32_i64_i8]] = !DILocalVariable(name: "ref_1_typle_i32_i64_i8" +// CHECK-DAG: [[ref_simd_i32x4]] = !DILocalVariable(name: "ref_simd_i32x4" + +// CHECK-DAG: [[ref_direct_ref]] = !DILocalVariable(name: "ref_direct_ref" +// CHECK-DAG: [[ref_1_direct_ref]] = !DILocalVariable(name: "ref_1_direct_ref" +// CHECK-DAG: [[ref_indirect_byval]] = !DILocalVariable(name: "ref_indirect_byval" +// CHECK-DAG: [[ref_1_indirect_byval]] = !DILocalVariable(name: "ref_1_indirect_byval" + +// CHECK-DAG: [[ref_0_tuple_scalar_scalar]] = !DILocalVariable(name: "ref_0_tuple_scalar_scalar" +// CHECK-DAG: [[ref_0_tuple_ref_scalar]] = !DILocalVariable(name: "ref_0_tuple_ref_scalar" +// CHECK-DAG: [[ref_1_tuple_ref_scalar]] = !DILocalVariable(name: "ref_1_tuple_ref_scalar" +// CHECK-DAG: [[ref_0_tuple_arrayref_scalar]] = !DILocalVariable(name: "ref_0_tuple_arrayref_scalar" +// CHECK-DAG: [[ref_1_tuple_arrayref_scalar]] = !DILocalVariable(name: "ref_1_tuple_arrayref_scalar" +// CHECK-DAG: [[ref_0_1_tuple_arrayref_scalar]] = !DILocalVariable(name: "ref_0_1_tuple_arrayref_scalar" +// CHECK-DAG: [[ref_1_1_tuple_scalar_arrayref]] = !DILocalVariable(name: "ref_1_1_tuple_scalar_arrayref" +// CHECK-DAG: [[ref_1_sliceref]] = !DILocalVariable(name: "ref_1_sliceref" + +// CHECK-DAG: [[ARG_dead_first_foo]] = !DILocalVariable(name: "dead_first_foo" +// CHECK-DAG: [[VAR_dead_first_v0]] = !DILocalVariable(name: "dead_first_v0" + +// CHECK-DAG: [[VAR_fragment_f]] = !DILocalVariable(name: "fragment_f" + +// CHECK-DAG: [[VAR_deref_dead]] = !DILocalVariable(name: "deref_dead" + +// CHECK-DAG: [[VAR_index_from_var]] = !DILocalVariable(name: "index_from_var" +// CHECK-DAG: [[VAR_const_index_from_start]] = !DILocalVariable(name: "const_index_from_start" +// CHECK-DAG: [[VAR_const_index_from_end]] = !DILocalVariable(name: "const_index_from_end" diff --git a/tests/codegen-llvm/deduced-param-attrs.rs b/tests/codegen-llvm/deduced-param-attrs.rs index 34504c80fad1b..f99615cbe6d42 100644 --- a/tests/codegen-llvm/deduced-param-attrs.rs +++ b/tests/codegen-llvm/deduced-param-attrs.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Copt-level=3 +//@ compile-flags: -Copt-level=3 -Cno-prepopulate-passes #![crate_type = "lib"] #![allow(internal_features)] @@ -28,7 +28,9 @@ pub fn use_big_struct_immutably(big_struct: BigStruct) { // The by-value parameter for this big struct can't be marked readonly, because we mutate it. // -// CHECK-NOT: @use_big_struct_mutably({{.*}} readonly {{.*}} %big_struct) +// CHECK: @use_big_struct_mutably( +// CHECK-NOT: readonly +// CHECK-SAME: %big_struct) #[no_mangle] pub fn use_big_struct_mutably(mut big_struct: BigStruct) { big_struct.blah[987] = 654; @@ -38,7 +40,9 @@ pub fn use_big_struct_mutably(mut big_struct: BigStruct) { // The by-value parameter for this big struct can't be marked readonly, because it contains // UnsafeCell. // -// CHECK-NOT: @use_big_cell_container({{.*}} readonly {{.*}} %big_cell_container) +// CHECK: @use_big_cell_container( +// CHECK-NOT: readonly +// CHECK-SAME: %big_cell_container) #[no_mangle] pub fn use_big_cell_container(big_cell_container: BigCellContainer) { hint::black_box(&big_cell_container); @@ -47,14 +51,31 @@ pub fn use_big_cell_container(big_cell_container: BigCellContainer) { // Make sure that we don't mistakenly mark a big struct as `readonly` when passed through a generic // type parameter if it contains UnsafeCell. // -// CHECK-NOT: @use_something({{.*}} readonly {{.*}} %something) +// CHECK: @use_something( +// CHECK-NOT: readonly +// CHECK-SAME: %something) #[no_mangle] #[inline(never)] pub fn use_something(something: T) { hint::black_box(&something); } +// Make sure that we still mark a big `Freeze` struct as `readonly` when passed through a generic +// type parameter. +// +// CHECK: @use_something_freeze( +// CHECK-SAME: readonly +// CHECK-SAME: %x) +#[no_mangle] +#[inline(never)] +pub fn use_something_freeze(x: T) {} + #[no_mangle] pub fn forward_big_cell_container(big_cell_container: BigCellContainer) { use_something(big_cell_container) } + +#[no_mangle] +pub fn forward_big_container(big_struct: BigStruct) { + use_something_freeze(big_struct) +} diff --git a/tests/codegen-llvm/enum/enum-aggregate.rs b/tests/codegen-llvm/enum/enum-aggregate.rs index f58d7ef12b661..89517008c6374 100644 --- a/tests/codegen-llvm/enum/enum-aggregate.rs +++ b/tests/codegen-llvm/enum/enum-aggregate.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -//@ min-llvm-version: 19 //@ only-64bit #![crate_type = "lib"] @@ -71,7 +70,7 @@ fn make_ok_ptr(x: NonNull) -> Result, usize> { fn make_ok_int(x: usize) -> Result> { // CHECK-LABEL: { i64, ptr } @make_ok_int(i64 %x) // CHECK-NEXT: start: - // CHECK-NEXT: %[[NOPROV:.+]] = getelementptr i8, ptr null, i64 %x + // CHECK-NEXT: %[[NOPROV:.+]] = inttoptr i64 %x to ptr // CHECK-NEXT: %[[R:.+]] = insertvalue { i64, ptr } { i64 0, ptr poison }, ptr %[[NOPROV]], 1 // CHECK-NEXT: ret { i64, ptr } %[[R]] Ok(x) diff --git a/tests/codegen-llvm/enum/enum-discriminant-eq.rs b/tests/codegen-llvm/enum/enum-discriminant-eq.rs index a1ab5e5c6e2ec..68cd58643e84e 100644 --- a/tests/codegen-llvm/enum/enum-discriminant-eq.rs +++ b/tests/codegen-llvm/enum/enum-discriminant-eq.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled -//@ min-llvm-version: 20 //@ only-64bit //@ revisions: LLVM20 LLVM21 //@ [LLVM21] min-llvm-version: 21 diff --git a/tests/codegen-llvm/global-allocator-attributes.rs b/tests/codegen-llvm/global-allocator-attributes.rs new file mode 100644 index 0000000000000..472ca77207500 --- /dev/null +++ b/tests/codegen-llvm/global-allocator-attributes.rs @@ -0,0 +1,41 @@ +//@ compile-flags: -C opt-level=3 +#![crate_type = "lib"] + +mod foobar { + use std::alloc::{GlobalAlloc, Layout}; + + struct Allocator; + + unsafe impl GlobalAlloc for Allocator { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_alloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,uninitialized,aligned") allocsize(0){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc(i[[SIZE:[0-9]+]] {{.*}}%size, i[[SIZE]] allocalign{{.*}} %align) + panic!() + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + // CHECK-LABEL: ; __rustc::__rust_dealloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("free"){{.*}} + // CHECK-NEXT: define{{.*}} void @{{.*}}__rust_dealloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] {{.*}} %align) + panic!() + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_realloc + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("realloc,aligned") allocsize(3){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_realloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align, i[[SIZE]] {{.*}} %new_size) + panic!() + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + // CHECK-LABEL: ; __rustc::__rust_alloc_zeroed + // CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,zeroed,aligned") allocsize(0){{.*}} + // CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc_zeroed(i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align) + panic!() + } + } + + #[global_allocator] + static GLOBAL: Allocator = Allocator; +} diff --git a/tests/codegen-llvm/gpu_offload/gpu_host.rs b/tests/codegen-llvm/gpu_offload/gpu_host.rs index 513e27426bc0e..fac4054d1b7ff 100644 --- a/tests/codegen-llvm/gpu_offload/gpu_host.rs +++ b/tests/codegen-llvm/gpu_offload/gpu_host.rs @@ -21,16 +21,15 @@ fn main() { } // CHECK: %struct.__tgt_offload_entry = type { i64, i16, i16, i32, ptr, ptr, i64, i64, ptr } -// CHECK: %struct.__tgt_kernel_arguments = type { i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, i64, i64, [3 x i32], [3 x i32], i32 } // CHECK: %struct.ident_t = type { i32, i32, i32, i32, ptr } // CHECK: %struct.__tgt_bin_desc = type { i32, ptr, ptr, ptr } +// CHECK: %struct.__tgt_kernel_arguments = type { i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, i64, i64, [3 x i32], [3 x i32], i32 } // CHECK: @.offload_sizes.1 = private unnamed_addr constant [1 x i64] [i64 1024] -// CHECK: @.offload_maptypes.1 = private unnamed_addr constant [1 x i64] [i64 3] +// CHECK: @.offload_maptypes.1 = private unnamed_addr constant [1 x i64] [i64 35] // CHECK: @.kernel_1.region_id = weak unnamed_addr constant i8 0 // CHECK: @.offloading.entry_name.1 = internal unnamed_addr constant [9 x i8] c"kernel_1\00", section ".llvm.rodata.offloading", align 1 -// CHECK: @.offloading.entry.kernel_1 = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @.kernel_1.region_id, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section ".omp_offloading_entries", align 1 -// CHECK: @my_struct_global2 = external global %struct.__tgt_kernel_arguments +// CHECK: @.offloading.entry.kernel_1 = weak constant %struct.__tgt_offload_entry { i64 0, i16 1, i16 1, i32 0, ptr @.kernel_1.region_id, ptr @.offloading.entry_name.1, i64 0, i64 0, ptr null }, section "llvm_offload_entries", align 8 // CHECK: @0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1 // CHECK: @1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 22, ptr @0 }, align 8 @@ -43,34 +42,61 @@ fn main() { // CHECK-NEXT: %.offload_baseptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_ptrs = alloca [1 x ptr], align 8 // CHECK-NEXT: %.offload_sizes = alloca [1 x i64], align 8 -// CHECK-NEXT: %x.addr = alloca ptr, align 8 -// CHECK-NEXT: store ptr %x, ptr %x.addr, align 8 -// CHECK-NEXT: %1 = load ptr, ptr %x.addr, align 8 -// CHECK-NEXT: %2 = getelementptr inbounds float, ptr %1, i32 0 +// CHECK-NEXT: %kernel_args = alloca %struct.__tgt_kernel_arguments, align 8 // CHECK: call void @llvm.memset.p0.i64(ptr align 8 %EmptyDesc, i8 0, i64 32, i1 false) +// CHECK-NEXT: %1 = getelementptr inbounds float, ptr %x, i32 0 // CHECK-NEXT: call void @__tgt_register_lib(ptr %EmptyDesc) // CHECK-NEXT: call void @__tgt_init_all_rtls() -// CHECK-NEXT: %3 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 +// CHECK-NEXT: %2 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 +// CHECK-NEXT: store ptr %x, ptr %2, align 8 +// CHECK-NEXT: %3 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 // CHECK-NEXT: store ptr %1, ptr %3, align 8 -// CHECK-NEXT: %4 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 -// CHECK-NEXT: store ptr %2, ptr %4, align 8 -// CHECK-NEXT: %5 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 -// CHECK-NEXT: store i64 1024, ptr %5, align 8 -// CHECK-NEXT: %6 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 -// CHECK-NEXT: %7 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 -// CHECK-NEXT: %8 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 -// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr @1, i64 -1, i32 1, ptr %6, ptr %7, ptr %8, ptr @.offload_maptypes.1, ptr null, ptr null) -// CHECK-NEXT: call void @kernel_1(ptr noalias noundef nonnull align 4 dereferenceable(1024) %x) -// CHECK-NEXT: %9 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 -// CHECK-NEXT: %10 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 -// CHECK-NEXT: %11 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 -// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr @1, i64 -1, i32 1, ptr %9, ptr %10, ptr %11, ptr @.offload_maptypes.1, ptr null, ptr null) +// CHECK-NEXT: %4 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 +// CHECK-NEXT: store i64 1024, ptr %4, align 8 +// CHECK-NEXT: %5 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 +// CHECK-NEXT: %6 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 +// CHECK-NEXT: %7 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_begin_mapper(ptr @1, i64 -1, i32 1, ptr %5, ptr %6, ptr %7, ptr @.offload_maptypes.1, ptr null, ptr null) +// CHECK-NEXT: %8 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 0 +// CHECK-NEXT: store i32 3, ptr %8, align 4 +// CHECK-NEXT: %9 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 1 +// CHECK-NEXT: store i32 1, ptr %9, align 4 +// CHECK-NEXT: %10 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 2 +// CHECK-NEXT: store ptr %5, ptr %10, align 8 +// CHECK-NEXT: %11 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 3 +// CHECK-NEXT: store ptr %6, ptr %11, align 8 +// CHECK-NEXT: %12 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 4 +// CHECK-NEXT: store ptr %7, ptr %12, align 8 +// CHECK-NEXT: %13 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 5 +// CHECK-NEXT: store ptr @.offload_maptypes.1, ptr %13, align 8 +// CHECK-NEXT: %14 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 6 +// CHECK-NEXT: store ptr null, ptr %14, align 8 +// CHECK-NEXT: %15 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 7 +// CHECK-NEXT: store ptr null, ptr %15, align 8 +// CHECK-NEXT: %16 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 8 +// CHECK-NEXT: store i64 0, ptr %16, align 8 +// CHECK-NEXT: %17 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 9 +// CHECK-NEXT: store i64 0, ptr %17, align 8 +// CHECK-NEXT: %18 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 10 +// CHECK-NEXT: store [3 x i32] [i32 2097152, i32 0, i32 0], ptr %18, align 4 +// CHECK-NEXT: %19 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 11 +// CHECK-NEXT: store [3 x i32] [i32 256, i32 0, i32 0], ptr %19, align 4 +// CHECK-NEXT: %20 = getelementptr inbounds %struct.__tgt_kernel_arguments, ptr %kernel_args, i32 0, i32 12 +// CHECK-NEXT: store i32 0, ptr %20, align 4 +// CHECK-NEXT: %21 = call i32 @__tgt_target_kernel(ptr @1, i64 -1, i32 2097152, i32 256, ptr @.kernel_1.region_id, ptr %kernel_args) +// CHECK-NEXT: %22 = getelementptr inbounds [1 x ptr], ptr %.offload_baseptrs, i32 0, i32 0 +// CHECK-NEXT: %23 = getelementptr inbounds [1 x ptr], ptr %.offload_ptrs, i32 0, i32 0 +// CHECK-NEXT: %24 = getelementptr inbounds [1 x i64], ptr %.offload_sizes, i32 0, i32 0 +// CHECK-NEXT: call void @__tgt_target_data_end_mapper(ptr @1, i64 -1, i32 1, ptr %22, ptr %23, ptr %24, ptr @.offload_maptypes.1, ptr null, ptr null) // CHECK-NEXT: call void @__tgt_unregister_lib(ptr %EmptyDesc) // CHECK: store ptr %x, ptr %0, align 8 // CHECK-NEXT: call void asm sideeffect "", "r,~{memory}"(ptr nonnull %0) // CHECK: ret void // CHECK-NEXT: } +// CHECK: Function Attrs: nounwind +// CHECK: declare i32 @__tgt_target_kernel(ptr, i64, i32, i32, ptr, ptr) + #[unsafe(no_mangle)] #[inline(never)] pub fn kernel_1(x: &mut [f32; 256]) { diff --git a/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs b/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs new file mode 100644 index 0000000000000..299c3bf8847b2 --- /dev/null +++ b/tests/codegen-llvm/int-ptr-int-enum-miscompile.rs @@ -0,0 +1,22 @@ +// This is a regression test for https://github.com/rust-lang/rust/issues/147265. + +//@ compile-flags: -Copt-level=3 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn mk_result(a: usize) -> Result { + // CHECK-LABEL: @mk_result + // CHECK-NOT: unreachable + // CHECK: load i8, + // CHECK-NOT: unreachable + match g(a) { + Ok(b) => Ok(unsafe { *(b as *const u8) }), + Err(c) => Err(c), + } +} + +#[cold] +fn g(a: usize) -> Result { + Ok(a) +} diff --git a/tests/codegen-llvm/integer-cmp.rs b/tests/codegen-llvm/integer-cmp.rs index 812fa8e4a4244..2233a575f8e70 100644 --- a/tests/codegen-llvm/integer-cmp.rs +++ b/tests/codegen-llvm/integer-cmp.rs @@ -1,9 +1,6 @@ // This is test for more optimal Ord implementation for integers. // See for more info. -//@ revisions: llvm-pre-20 llvm-20 -//@ [llvm-20] min-llvm-version: 20 -//@ [llvm-pre-20] max-llvm-major-version: 19 //@ compile-flags: -C opt-level=3 -Zmerge-functions=disabled #![crate_type = "lib"] @@ -13,50 +10,29 @@ use std::cmp::Ordering; // CHECK-LABEL: @cmp_signed #[no_mangle] pub fn cmp_signed(a: i64, b: i64) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.scmp.i8.i64 - // llvm-pre-20: icmp slt - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.scmp.i8.i64 a.cmp(&b) } // CHECK-LABEL: @cmp_unsigned #[no_mangle] pub fn cmp_unsigned(a: u32, b: u32) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32 a.cmp(&b) } // CHECK-LABEL: @cmp_char #[no_mangle] pub fn cmp_char(a: char, b: char) -> Ordering { - // llvm-20: call{{.*}} i8 @llvm.ucmp.i8.i32 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 + // CHECK: call{{.*}} i8 @llvm.ucmp.i8.i32 a.cmp(&b) } // CHECK-LABEL: @cmp_tuple #[no_mangle] pub fn cmp_tuple(a: (i16, u16), b: (i16, u16)) -> Ordering { - // llvm-20-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16 - // llvm-20-DAG: call{{.*}} i8 @llvm.scmp.i8.i16 - // llvm-20: ret i8 - // llvm-pre-20: icmp slt - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 - // llvm-pre-20: icmp ult - // llvm-pre-20: icmp ne - // llvm-pre-20: zext i1 - // llvm-pre-20: select i1 - // llvm-pre-20: select i1 + // CHECK-DAG: call{{.*}} i8 @llvm.ucmp.i8.i16 + // CHECK-DAG: call{{.*}} i8 @llvm.scmp.i8.i16 + // CHECK: ret i8 a.cmp(&b) } diff --git a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs index 4bec579831dc4..255f20e6ff640 100644 --- a/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs +++ b/tests/codegen-llvm/intrinsic-no-unnamed-attr.rs @@ -7,7 +7,5 @@ use std::intrinsics::sqrtf32; // CHECK: @llvm.sqrt.f32(float) #{{[0-9]*}} fn main() { - unsafe { - sqrtf32(0.0f32); - } + sqrtf32(0.0f32); } diff --git a/tests/codegen-llvm/intrinsics/three_way_compare.rs b/tests/codegen-llvm/intrinsics/three_way_compare.rs index 95fcb636f7cab..89bf69561e9a1 100644 --- a/tests/codegen-llvm/intrinsics/three_way_compare.rs +++ b/tests/codegen-llvm/intrinsics/three_way_compare.rs @@ -2,7 +2,6 @@ //@ [DEBUG] compile-flags: -C opt-level=0 //@ [OPTIM] compile-flags: -C opt-level=3 //@ compile-flags: -C no-prepopulate-passes -//@ min-llvm-version: 20 #![crate_type = "lib"] #![feature(core_intrinsics)] diff --git a/tests/codegen-llvm/intrinsics/transmute-niched.rs b/tests/codegen-llvm/intrinsics/transmute-niched.rs index a886d9eee5909..8c647655f65bb 100644 --- a/tests/codegen-llvm/intrinsics/transmute-niched.rs +++ b/tests/codegen-llvm/intrinsics/transmute-niched.rs @@ -249,7 +249,7 @@ pub unsafe fn check_four_or_eight_to_nonnull(x: FourOrEight) -> NonNull { // OPT: call void @llvm.assume(i1 %1) // CHECK-NOT: icmp // CHECK-NOT: assume - // CHECK: %[[RET:.+]] = getelementptr i8, ptr null, i64 %x + // CHECK: %[[RET:.+]] = inttoptr i64 %x to ptr // CHECK-NEXT: ret ptr %[[RET]] transmute(x) diff --git a/tests/codegen-llvm/intrinsics/transmute.rs b/tests/codegen-llvm/intrinsics/transmute.rs index e327c100d7ddd..b86c6df3267e4 100644 --- a/tests/codegen-llvm/intrinsics/transmute.rs +++ b/tests/codegen-llvm/intrinsics/transmute.rs @@ -303,7 +303,7 @@ pub unsafe fn check_pair_with_bool(x: (u8, bool)) -> (bool, i8) { pub unsafe fn check_float_to_pointer(x: f64) -> *const () { // CHECK-NOT: alloca // CHECK: %0 = bitcast double %x to i64 - // CHECK: %_0 = getelementptr i8, ptr null, i64 %0 + // CHECK: %_0 = inttoptr i64 %0 to ptr // CHECK: ret ptr %_0 transmute(x) } @@ -378,7 +378,7 @@ pub unsafe fn check_issue_110005(x: (usize, bool)) -> Option> { // CHECK-LABEL: @check_pair_to_dst_ref( #[no_mangle] pub unsafe fn check_pair_to_dst_ref<'a>(x: (usize, usize)) -> &'a [u8] { - // CHECK: %_0.0 = getelementptr i8, ptr null, i64 %x.0 + // CHECK: %_0.0 = inttoptr i64 %x.0 to ptr // CHECK: %0 = icmp ne ptr %_0.0, null // CHECK: call void @llvm.assume(i1 %0) // CHECK: %1 = insertvalue { ptr, i64 } poison, ptr %_0.0, 0 diff --git a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs index bdf021092fda4..fc4b0341a31bc 100644 --- a/tests/codegen-llvm/issues/and-masked-comparison-131162.rs +++ b/tests/codegen-llvm/issues/and-masked-comparison-131162.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs new file mode 100644 index 0000000000000..b97729fa14657 --- /dev/null +++ b/tests/codegen-llvm/issues/cows-dont-have-branches-117763.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Copt-level=3 +//@ needs-deterministic-layouts + +// Currently Vec and &[T] have layouts that start with (pointer, len) +// which makes the conversion branchless. +// A nice-to-have property, not guaranteed. +#![crate_type = "cdylib"] + +// CHECK-LABEL: @branchless_cow_slices +#[no_mangle] +pub fn branchless_cow_slices<'a>(cow: &'a std::borrow::Cow<'a, [u8]>) -> &'a [u8] { + // CHECK-NOT: br + // CHECK-NOT: select + // CHECK-NOT: icmp + // CHECK: ret { ptr, {{i32|i64}} } + &*cow +} diff --git a/tests/codegen-llvm/issues/issue-101082.rs b/tests/codegen-llvm/issues/issue-101082.rs index 8d15921ddb4e1..0c1f90f951a72 100644 --- a/tests/codegen-llvm/issues/issue-101082.rs +++ b/tests/codegen-llvm/issues/issue-101082.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Copt-level=3 //@ revisions: host x86-64 x86-64-v3 -//@ min-llvm-version: 20 //@[host] ignore-x86_64 diff --git a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs index 853a1ff36b109..a0b453fac8e93 100644 --- a/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs +++ b/tests/codegen-llvm/issues/issue-122600-ptr-discriminant-update.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -22,8 +25,8 @@ pub unsafe fn update(s: *mut State) { // CHECK-NOT: memcpy // CHECK-NOT: 75{{3|4}} - // CHECK: %[[TAG:.+]] = load i8, ptr %s, align 1 - // CHECK-NEXT: trunc nuw i8 %[[TAG]] to i1 + // old: %[[TAG:.+]] = load i8, ptr %s, align 1 + // old-NEXT: trunc nuw i8 %[[TAG]] to i1 // CHECK-NOT: load // CHECK-NOT: store diff --git a/tests/codegen-llvm/issues/issue-129795.rs b/tests/codegen-llvm/issues/issue-129795.rs index dc64ee35c97e5..7a928389fab2d 100644 --- a/tests/codegen-llvm/issues/issue-129795.rs +++ b/tests/codegen-llvm/issues/issue-129795.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] // Ensure that a modulo operation with an operand that is known to be diff --git a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs index 4d3fa4993ef72..4c4eebeabb5fa 100644 --- a/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs +++ b/tests/codegen-llvm/issues/iter-max-no-unwrap-failed-129583.rs @@ -3,7 +3,6 @@ // use a larger value to prevent unrolling. //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs index 35acf765d690c..b686f8c4b3acb 100644 --- a/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs +++ b/tests/codegen-llvm/issues/looping-over-ne-bytes-133528.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] /// Ensure the function is properly optimized diff --git a/tests/codegen-llvm/lib-optimizations/slice_fill.rs b/tests/codegen-llvm/lib-optimizations/slice_fill.rs new file mode 100644 index 0000000000000..2d924ebf726d8 --- /dev/null +++ b/tests/codegen-llvm/lib-optimizations/slice_fill.rs @@ -0,0 +1,28 @@ +//@ compile-flags: -Copt-level=3 +#![crate_type = "lib"] + +use std::mem::MaybeUninit; + +// CHECK-LABEL: @slice_fill_pass_undef +#[no_mangle] +pub fn slice_fill_pass_undef(s: &mut [MaybeUninit], v: MaybeUninit) { + // CHECK: tail call void @llvm.memset.{{.*}}(ptr nonnull align 1 %s.0, i8 %v, {{.*}} %s.1, i1 false) + // CHECK: ret + s.fill(v); +} + +// CHECK-LABEL: @slice_fill_uninit +#[no_mangle] +pub fn slice_fill_uninit(s: &mut [MaybeUninit]) { + // CHECK-NOT: call + // CHECK: ret void + s.fill(MaybeUninit::uninit()); +} + +// CHECK-LABEL: @slice_wide_memset +#[no_mangle] +pub fn slice_wide_memset(s: &mut [u16]) { + // CHECK: tail call void @llvm.memset.{{.*}}(ptr nonnull align 2 %s.0, i8 -1 + // CHECK: ret + s.fill(0xFFFF); +} diff --git a/tests/codegen-llvm/option-niche-eq.rs b/tests/codegen-llvm/option-niche-eq.rs index 3900cb79aa2ab..e9c3fa2407e7e 100644 --- a/tests/codegen-llvm/option-niche-eq.rs +++ b/tests/codegen-llvm/option-niche-eq.rs @@ -1,5 +1,4 @@ //@ revisions: REGULAR LLVM21 -//@ min-llvm-version: 20 //@ compile-flags: -Copt-level=3 -Zmerge-functions=disabled //@ [LLVM21] min-llvm-version: 21 #![crate_type = "lib"] diff --git a/tests/codegen-llvm/pattern_type_symbols.rs b/tests/codegen-llvm/pattern_type_symbols.rs index e86a9ef27de1b..a90262ff12d21 100644 --- a/tests/codegen-llvm/pattern_type_symbols.rs +++ b/tests/codegen-llvm/pattern_type_symbols.rs @@ -16,7 +16,7 @@ pub fn bar() { // CHECK: call pattern_type_symbols::foo:: // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_ foo::(); - // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999])> - // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_EEB2_ + // CHECK: call pattern_type_symbols::foo:: + // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooWmRm0_m3b9ac9ff_EB2_ foo::(); } diff --git a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs index 561f081c700ea..ffff4b359947d 100644 --- a/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs +++ b/tests/codegen-llvm/rust-abi-arch-specific-adjustment.rs @@ -1,15 +1,19 @@ +//@ add-core-stubs //@ compile-flags: -Copt-level=3 -C no-prepopulate-passes //@ revisions: riscv64 loongarch64 -//@[riscv64] only-riscv64 //@[riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu //@[riscv64] needs-llvm-components: riscv -//@[loongarch64] only-loongarch64 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu //@[loongarch64] needs-llvm-components: loongarch #![crate_type = "lib"] +#![feature(no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; #[no_mangle] // riscv64: define noundef i8 @arg_attr_u8(i8 noundef zeroext %x) diff --git a/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs b/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs new file mode 100644 index 0000000000000..604b4c8c2f8a5 --- /dev/null +++ b/tests/codegen-llvm/sanitizer/kcfi/fn-ptr-reify-shim.rs @@ -0,0 +1,74 @@ +//@ add-core-stubs +//@ revisions: aarch64 x86_64 +//@ [aarch64] compile-flags: --target aarch64-unknown-none +//@ [aarch64] needs-llvm-components: aarch64 +//@ [x86_64] compile-flags: --target x86_64-unknown-none +//@ [x86_64] needs-llvm-components: x86 +//@ compile-flags: -Ctarget-feature=-crt-static -Zsanitizer=kcfi -Cno-prepopulate-passes -Copt-level=0 + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +// A `ReifyShim` should only be created when the trait is dyn-compatible. + +extern crate minicore; +use minicore::*; + +trait DynCompatible { + fn dyn_name(&self) -> &'static str; + + fn dyn_name_default(&self) -> &'static str { + let _ = self; + "dyn_default" + } +} + +// Not dyn-compatible because the `Self: Sized` bound is missing. +trait NotDynCompatible { + fn not_dyn_name() -> &'static str; + + fn not_dyn_name_default() -> &'static str { + "not_dyn_default" + } +} + +struct S; + +impl DynCompatible for S { + fn dyn_name(&self) -> &'static str { + "dyn_compatible" + } +} + +impl NotDynCompatible for S { + fn not_dyn_name() -> &'static str { + "not_dyn_compatible" + } +} + +#[no_mangle] +pub fn main() { + let s = S; + + // `DynCompatible` is indeed dyn-compatible. + let _: &dyn DynCompatible = &s; + + // CHECK: call ::dyn_name{{.*}}reify.shim.fnptr + let dyn_name = S::dyn_name as fn(&S) -> &str; + let _unused = dyn_name(&s); + + // CHECK: call fn_ptr_reify_shim::DynCompatible::dyn_name_default{{.*}}reify.shim.fnptr + let dyn_name_default = S::dyn_name_default as fn(&S) -> &str; + let _unused = dyn_name_default(&s); + + // Check using $ (end-of-line) that these calls do not contain `reify.shim.fnptr`. + + // CHECK: call ::not_dyn_name{{$}} + let not_dyn_name = S::not_dyn_name as fn() -> &'static str; + let _unused = not_dyn_name(); + + // CHECK: call fn_ptr_reify_shim::NotDynCompatible::not_dyn_name_default{{$}} + let not_dyn_name_default = S::not_dyn_name_default as fn() -> &'static str; + let _unused = not_dyn_name_default(); +} diff --git a/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs b/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs index 2c8cdc919b85d..31f59ee01decb 100644 --- a/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs +++ b/tests/codegen-llvm/sanitizer/kcfi/naked-function.rs @@ -15,8 +15,9 @@ use minicore::*; struct Thing; trait MyTrait { + // NOTE: this test assumes that this trait is dyn-compatible. #[unsafe(naked)] - extern "C" fn my_naked_function() { + extern "C" fn my_naked_function(&self) { // the real function is defined // CHECK: .globl // CHECK-SAME: my_naked_function @@ -34,13 +35,13 @@ impl MyTrait for Thing {} #[unsafe(no_mangle)] pub fn main() { // Trick the compiler into generating an indirect call. - const F: extern "C" fn() = Thing::my_naked_function; + const F: extern "C" fn(&Thing) = Thing::my_naked_function; // main calls the shim function // CHECK: call void // CHECK-SAME: my_naked_function // CHECK-SAME: reify.shim.fnptr - (F)(); + (F)(&Thing); } // CHECK: declare !kcfi_type diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs index 690bfb432f9b0..d79a9cf96ada3 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-gather.rs @@ -1,6 +1,10 @@ // //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -24,7 +28,8 @@ pub unsafe fn gather_f32x2( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -37,7 +42,8 @@ pub unsafe fn gather_f32x2_unsigned( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.gather.v2f32.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_gather(values, pointers, mask) } @@ -50,6 +56,7 @@ pub unsafe fn gather_pf32x2( ) -> Vec2<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) + // LLVM21: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) + // LLVM22: call <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]], <2 x ptr> {{.*}}) simd_gather(values, pointers, mask) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs index fda315dc66ca2..7df73cb9b4d73 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-load.rs @@ -1,4 +1,8 @@ //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -18,7 +22,8 @@ pub type Vec4 = Simd; pub unsafe fn load_f32x2(mask: Vec2, pointer: *const f32, values: Vec2) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } @@ -31,7 +36,8 @@ pub unsafe fn load_f32x2_unsigned( ) -> Vec2 { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM21: call <2 x float> @llvm.masked.load.v2f32.p0(ptr {{.*}}, i32 4, <2 x i1> [[B]], <2 x float> {{.*}}) + // LLVM22: call <2 x float> @llvm.masked.load.v2f32.p0(ptr align 4 {{.*}}, <2 x i1> [[B]], <2 x float> {{.*}}) simd_masked_load(mask, pointer, values) } @@ -44,6 +50,7 @@ pub unsafe fn load_pf32x4( ) -> Vec4<*const f32> { // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> - // CHECK: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) + // LLVM21: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) + // LLVM22: call <4 x ptr> @llvm.masked.load.v4p0.p0(ptr align {{.*}} {{.*}}, <4 x i1> [[B]], <4 x ptr> {{.*}}) simd_masked_load(mask, pointer, values) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs index 6ca7388d464b9..03119d89bacda 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-masked-store.rs @@ -1,4 +1,8 @@ //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -18,7 +22,8 @@ pub type Vec4 = Simd; pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) simd_masked_store(mask, pointer, values) } @@ -27,7 +32,8 @@ pub unsafe fn store_f32x2(mask: Vec2, pointer: *mut f32, values: Vec2) pub unsafe fn store_f32x2_unsigned(mask: Vec2, pointer: *mut f32, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr {{.*}}, i32 4, <2 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v2f32.p0(<2 x float> {{.*}}, ptr align 4 {{.*}}, <2 x i1> [[B]]) simd_masked_store(mask, pointer, values) } @@ -36,6 +42,7 @@ pub unsafe fn store_f32x2_unsigned(mask: Vec2, pointer: *mut f32, values: V pub unsafe fn store_pf32x4(mask: Vec4, pointer: *mut *const f32, values: Vec4<*const f32>) { // CHECK: [[A:%[0-9]+]] = lshr <4 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <4 x i32> [[A]] to <4 x i1> - // CHECK: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) + // LLVM21: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr {{.*}}, i32 {{.*}}, <4 x i1> [[B]]) + // LLVM22: call void @llvm.masked.store.v4p0.p0(<4 x ptr> {{.*}}, ptr align {{.*}} {{.*}}, <4 x i1> [[B]]) simd_masked_store(mask, pointer, values) } diff --git a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs index 743652966e164..533fa429ae700 100644 --- a/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs +++ b/tests/codegen-llvm/simd-intrinsic/simd-intrinsic-generic-scatter.rs @@ -1,6 +1,10 @@ // //@ compile-flags: -C no-prepopulate-passes +//@ revisions: LLVM21 LLVM22 +//@ [LLVM22] min-llvm-version: 22 +//@ [LLVM21] max-llvm-major-version: 21 +// ignore-tidy-linelength #![crate_type = "lib"] #![feature(repr_simd, core_intrinsics)] @@ -20,7 +24,8 @@ pub type Vec4 = Simd; pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } @@ -29,7 +34,8 @@ pub unsafe fn scatter_f32x2(pointers: Vec2<*mut f32>, mask: Vec2, values: V pub unsafe fn scatter_f32x2_unsigned(pointers: Vec2<*mut f32>, mask: Vec2, values: Vec2) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2f32.v2p0(<2 x float> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } @@ -42,6 +48,7 @@ pub unsafe fn scatter_pf32x2( ) { // CHECK: [[A:%[0-9]+]] = lshr <2 x i32> {{.*}}, {{|splat \(i32 31\)}} // CHECK: [[B:%[0-9]+]] = trunc <2 x i32> [[A]] to <2 x i1> - // CHECK: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM21: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> {{.*}}, i32 {{.*}}, <2 x i1> [[B]] + // LLVM22: call void @llvm.masked.scatter.v2p0.v2p0(<2 x ptr> {{.*}}, <2 x ptr> align {{.*}} {{.*}}, <2 x i1> [[B]] simd_scatter(values, pointers, mask) } diff --git a/tests/codegen-llvm/slice-last-elements-optimization.rs b/tests/codegen-llvm/slice-last-elements-optimization.rs index d982cda709d47..77fc1d21cd908 100644 --- a/tests/codegen-llvm/slice-last-elements-optimization.rs +++ b/tests/codegen-llvm/slice-last-elements-optimization.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=3 -//@ min-llvm-version: 20 #![crate_type = "lib"] // This test verifies that LLVM 20 properly optimizes the bounds check diff --git a/tests/codegen-llvm/swap-small-types.rs b/tests/codegen-llvm/swap-small-types.rs index 7aa613ae9c227..0799ff76331d3 100644 --- a/tests/codegen-llvm/swap-small-types.rs +++ b/tests/codegen-llvm/swap-small-types.rs @@ -1,6 +1,5 @@ //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled //@ only-x86_64 -//@ min-llvm-version: 20 //@ ignore-std-debug-assertions (`ptr::swap_nonoverlapping` has one which blocks some optimizations) #![crate_type = "lib"] diff --git a/tests/codegen-llvm/transmute-scalar.rs b/tests/codegen-llvm/transmute-scalar.rs index 21f7287047cf0..e1ce8e506066a 100644 --- a/tests/codegen-llvm/transmute-scalar.rs +++ b/tests/codegen-llvm/transmute-scalar.rs @@ -56,7 +56,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { } // CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) -// CHECK: %_0 = getelementptr i8, ptr null, [[USIZE]] %i +// CHECK: %_0 = inttoptr [[USIZE]] %i to ptr // CHECK-NEXT: ret ptr %_0 #[no_mangle] pub fn int_to_ptr(i: usize) -> *mut u16 { diff --git a/tests/codegen-llvm/try_question_mark_nop.rs b/tests/codegen-llvm/try_question_mark_nop.rs index 398c9a580bc30..a09fa0a49019d 100644 --- a/tests/codegen-llvm/try_question_mark_nop.rs +++ b/tests/codegen-llvm/try_question_mark_nop.rs @@ -1,9 +1,6 @@ //@ compile-flags: -Copt-level=3 -Z merge-functions=disabled //@ edition: 2021 //@ only-x86_64 -//@ revisions: NINETEEN TWENTY -//@[NINETEEN] exact-llvm-major-version: 19 -//@[TWENTY] min-llvm-version: 20 #![crate_type = "lib"] #![feature(try_blocks)] @@ -17,13 +14,9 @@ pub fn option_nop_match_32(x: Option) -> Option { // CHECK: start: // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1 - // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %0, i32 0 - // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 [[SELECT]], 0 - // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 %1, 1 - - // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef - // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 - // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1 + // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i32 %1, i32 undef + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0 + // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i32, i32 } [[REG2]], i32 [[SELECT]], 1 // CHECK-NEXT: ret { i32, i32 } [[REG3]] match x { @@ -36,8 +29,8 @@ pub fn option_nop_match_32(x: Option) -> Option { #[no_mangle] pub fn option_nop_traits_32(x: Option) -> Option { // CHECK: start: - // TWENTY-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 - // TWENTY-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef + // CHECK-NEXT: %[[IS_SOME:.+]] = trunc nuw i32 %0 to i1 + // CHECK-NEXT: select i1 %[[IS_SOME]], i32 %1, i32 undef // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: insertvalue { i32, i32 } // CHECK-NEXT: ret { i32, i32 } @@ -96,13 +89,9 @@ pub fn option_nop_match_64(x: Option) -> Option { // CHECK: start: // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i64 %0 to i1 - // NINETEEN-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %0, i64 0 - // NINETEEN-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 [[SELECT]], 0 - // NINETEEN-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 %1, 1 - - // TWENTY-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef - // TWENTY-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0 - // TWENTY-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1 + // CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i64, i64 } poison, i64 %0, 0 + // CHECK-NEXT: [[REG3:%.*]] = insertvalue { i64, i64 } [[REG2]], i64 [[SELECT]], 1 // CHECK-NEXT: ret { i64, i64 } [[REG3]] match x { @@ -115,8 +104,8 @@ pub fn option_nop_match_64(x: Option) -> Option { #[no_mangle] pub fn option_nop_traits_64(x: Option) -> Option { // CHECK: start: - // TWENTY-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 - // TWENTY-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef + // CHECK-NEXT: %[[TRUNC:[0-9]+]] = trunc nuw i64 %0 to i1 + // CHECK-NEXT: %[[SEL:\.[0-9]+]] = select i1 %[[TRUNC]], i64 %1, i64 undef // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: insertvalue { i64, i64 } // CHECK-NEXT: ret { i64, i64 } diff --git a/tests/codegen-llvm/union-aggregate.rs b/tests/codegen-llvm/union-aggregate.rs index aac66c5dcdd9f..7faa66804feaa 100644 --- a/tests/codegen-llvm/union-aggregate.rs +++ b/tests/codegen-llvm/union-aggregate.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Copt-level=0 -Cno-prepopulate-passes -//@ min-llvm-version: 19 //@ only-64bit #![crate_type = "lib"] diff --git a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs index 8d2745ba2f7ae..2ce1d1b2e00e6 100644 --- a/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs +++ b/tests/codegen-llvm/unwind-abis/c-unwind-abi-panic-abort.rs @@ -1,4 +1,9 @@ //@ compile-flags: -C panic=abort +//@ revisions: NONWASM WASM WASMEXN +//@ [NONWASM] ignore-wasm32 +//@ [WASM] only-wasm32 +//@ [WASMEXN] only-wasm32 +//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling // Test that `nounwind` attributes are also applied to extern `C-unwind` Rust functions // when the code is compiled with `panic=abort`. @@ -9,7 +14,9 @@ #[no_mangle] pub unsafe extern "C-unwind" fn rust_item_that_can_unwind() { // Handle both legacy and v0 symbol mangling. - // CHECK: call void @{{.*core9panicking19panic_cannot_unwind}} + // NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}} + // WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}} + // WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}} may_unwind(); } diff --git a/tests/codegen-llvm/unwind-and-panic-abort.rs b/tests/codegen-llvm/unwind-and-panic-abort.rs index 8efa140058ad1..c2838be00afa2 100644 --- a/tests/codegen-llvm/unwind-and-panic-abort.rs +++ b/tests/codegen-llvm/unwind-and-panic-abort.rs @@ -1,4 +1,9 @@ //@ compile-flags: -C panic=abort +//@ revisions: NONWASM WASM WASMEXN +//@ [NONWASM] ignore-wasm32 +//@ [WASM] only-wasm32 +//@ [WASMEXN] only-wasm32 +//@ [WASMEXN] compile-flags: -Ctarget-feature=+exception-handling #![crate_type = "lib"] @@ -9,7 +14,9 @@ extern "C-unwind" { // CHECK: Function Attrs:{{.*}}nounwind // CHECK-NEXT: define{{.*}}void @foo // Handle both legacy and v0 symbol mangling. -// CHECK: call void @{{.*core9panicking19panic_cannot_unwind}} +// NONWASM: call void @{{.*core9panicking19panic_cannot_unwind}} +// WASMEXN: call void @{{.*core9panicking19panic_cannot_unwind}} +// WASM-NOT: call void @{{.*core9panicking19panic_cannot_unwind}} #[no_mangle] pub unsafe extern "C" fn foo() { bar(); diff --git a/tests/codegen-llvm/vec_pop_push_noop.rs b/tests/codegen-llvm/vec_pop_push_noop.rs index 3e375219fe018..977c220b3baef 100644 --- a/tests/codegen-llvm/vec_pop_push_noop.rs +++ b/tests/codegen-llvm/vec_pop_push_noop.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -7,7 +10,7 @@ pub fn noop(v: &mut Vec) { // CHECK-NOT: grow_one // CHECK-NOT: call - // CHECK: tail call void @llvm.assume + // old: tail call void @llvm.assume // CHECK-NOT: grow_one // CHECK-NOT: call // CHECK: {{ret|[}]}} diff --git a/tests/codegen-llvm/vecdeque_pop_push.rs b/tests/codegen-llvm/vecdeque_pop_push.rs index 5afa1b2248b0e..6f9ad6674d6cd 100644 --- a/tests/codegen-llvm/vecdeque_pop_push.rs +++ b/tests/codegen-llvm/vecdeque_pop_push.rs @@ -1,4 +1,7 @@ //@ compile-flags: -Copt-level=3 +//@ revisions: new old +//@ [old] max-llvm-major-version: 21 +//@ [new] min-llvm-version: 22 #![crate_type = "lib"] @@ -8,7 +11,7 @@ use std::collections::VecDeque; // CHECK-LABEL: @noop_back( pub fn noop_back(v: &mut VecDeque) { // CHECK-NOT: grow - // CHECK: tail call void @llvm.assume + // old: tail call void @llvm.assume // CHECK-NOT: grow // CHECK: ret if let Some(x) = v.pop_back() { diff --git a/tests/codegen-llvm/wasm_exceptions.rs b/tests/codegen-llvm/wasm_exceptions.rs index 796b69b722b51..e718f599a3c2f 100644 --- a/tests/codegen-llvm/wasm_exceptions.rs +++ b/tests/codegen-llvm/wasm_exceptions.rs @@ -1,8 +1,9 @@ //@ only-wasm32 -//@ compile-flags: -C panic=unwind -Z emscripten-wasm-eh +//@ revisions: WASM WASMEXN +//@ [WASMEXN] compile-flags: -C panic=unwind -Z emscripten-wasm-eh #![crate_type = "lib"] -#![feature(core_intrinsics, wasm_exception_handling_intrinsics)] +#![feature(core_intrinsics, wasm_exception_handling_intrinsics, link_llvm_intrinsics)] extern "C-unwind" { fn may_panic(); @@ -22,7 +23,8 @@ impl Drop for LogOnDrop { } } -// CHECK-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 +// WASM-LABEL: @test_cleanup() {{.*}} +// WASMEXN-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] pub fn test_cleanup() { let _log_on_drop = LogOnDrop; @@ -30,12 +32,16 @@ pub fn test_cleanup() { may_panic(); } - // CHECK-NOT: call - // CHECK: invoke void @may_panic() - // CHECK: %cleanuppad = cleanuppad within none [] + // WASMEXN-NOT: call + // WASMEXN: invoke void @may_panic() + // WASMEXN: %cleanuppad = cleanuppad within none [] + // + // WASM: call void @may_panic() + // WASM-NOT: invoke void @may_panic() } -// CHECK-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 +// WASM-LABEL: @test_rtry() {{.*}} +// WASMEXN-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] pub fn test_rtry() { unsafe { @@ -51,23 +57,40 @@ pub fn test_rtry() { ); } - // CHECK-NOT: call - // CHECK: invoke void @may_panic() - // CHECK: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller - // CHECK: {{.*}} = catchpad within {{.*}} [ptr null] - // CHECK: catchret + // WASMEXN-NOT: call + // WASMEXN: invoke void @may_panic() + // WASMEXN: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller + // WASMEXN: {{.*}} = catchpad within {{.*}} [ptr null] + // WASMEXN: catchret + + // WASM: call void @may_panic() + // WASM-NOT: invoke void @may_panic() + // WASM-NOT: catchswitch + // WASM-NOT: catchpad + // WASM-NOT: catchret } // Make sure the intrinsic is not inferred as nounwind. This is a regression test for #132416. -// CHECK-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0 +// +// Note that this test uses the raw `wasm_throw` intrinsic because the one from +// libstd was built with `-Cpanic=abort` and it's technically not valid to use +// when this crate is compiled with `-Cpanic=unwind`. +// +// WASMEXN-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0 #[no_mangle] +#[cfg(wasmexn)] pub fn test_intrinsic() { let _log_on_drop = LogOnDrop; + + unsafe extern "C-unwind" { + #[link_name = "llvm.wasm.throw"] + fn wasm_throw(tag: i32, ptr: *mut u8) -> !; + } unsafe { - core::arch::wasm32::throw::<0>(core::ptr::null_mut()); + wasm_throw(0, core::ptr::null_mut()); } - // CHECK-NOT: call - // CHECK: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null) - // CHECK: %cleanuppad = cleanuppad within none [] + // WASMEXN-NOT: call + // WASMEXN: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null) + // WASMEXN: %cleanuppad = cleanuppad within none [] } diff --git a/tests/coverage/issue-83601.cov-map b/tests/coverage/issue-83601.cov-map index d1d751ff24b86..e42b5591c0fb3 100644 --- a/tests/coverage/issue-83601.cov-map +++ b/tests/coverage/issue-83601.cov-map @@ -1,30 +1,22 @@ Function name: issue_83601::main -Raw bytes (76): 0x[01, 01, 01, 05, 09, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 05, 00, 0d, 02, 00, 0e, 00, 14, 02, 01, 01, 00, 02] +Raw bytes (74): 0x[01, 01, 00, 0e, 01, 06, 01, 00, 0a, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-83601.rs -Number of expressions: 1 -- expression 0 operands: lhs = Counter(1), rhs = Counter(2) +Number of expressions: 0 Number of file 0 mappings: 14 - Code(Counter(0)) at (prev + 6, 1) to (start + 0, 10) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) - Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 13) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 0, 14) to (start + 0, 20) - = (c1 - c2) -- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2) - = (c1 - c2) -Highest counter ID seen: c1 +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 1) to (start + 0, 2) +Highest counter ID seen: c0 diff --git a/tests/coverage/issue-84561.cov-map b/tests/coverage/issue-84561.cov-map index 2b643ea599ed0..e5bb1afdcc263 100644 --- a/tests/coverage/issue-84561.cov-map +++ b/tests/coverage/issue-84561.cov-map @@ -73,20 +73,20 @@ Number of file 0 mappings: 4 Highest counter ID seen: c0 Function name: issue_84561::test3 -Raw bytes (409): 0x[01, 01, 0a, 0d, 11, 0d, 15, 0d, 19, 1d, 21, 29, 2d, 25, 29, 25, 29, 25, 29, 27, 31, 29, 2d, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 05, 01, 09, 00, 0c, 05, 00, 0f, 00, 15, 05, 01, 05, 00, 0f, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 01, 05, 00, 0d, 09, 00, 0e, 00, 14, 09, 02, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 05, 00, 0f, 09, 01, 09, 00, 0c, 09, 00, 0f, 00, 15, 09, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 0d, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 01, 05, 00, 0d, 0d, 00, 0e, 00, 14, 0d, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 0d, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 0d, 04, 09, 00, 10, 0d, 00, 13, 00, 2e, 0d, 02, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 05, 00, 0f, 0d, 04, 09, 00, 0c, 0d, 00, 0f, 00, 15, 0d, 01, 05, 00, 0f, 0d, 04, 08, 00, 0f, 11, 01, 09, 00, 13, 02, 05, 09, 00, 13, 0d, 05, 08, 00, 0f, 15, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 0d, 03, 05, 00, 0f, 0d, 01, 0c, 00, 13, 19, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 1d, 04, 05, 00, 0f, 1d, 02, 0c, 00, 13, 21, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 25, 01, 0c, 00, 13, 29, 01, 0d, 00, 17, 29, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 2d, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 31, 02, 05, 00, 0f, 31, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] +Raw bytes (409): 0x[01, 01, 0a, 01, 05, 01, 09, 01, 0d, 11, 15, 1d, 21, 19, 1d, 19, 1d, 19, 1d, 27, 25, 1d, 21, 4d, 01, 08, 01, 00, 0b, 01, 01, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 02, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 01, 01, 05, 00, 0f, 00, 00, 20, 00, 30, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 01, 05, 00, 0d, 01, 00, 0e, 00, 14, 01, 02, 05, 00, 0f, 00, 00, 20, 00, 24, 00, 00, 29, 00, 30, 00, 00, 33, 00, 41, 00, 00, 4b, 00, 5a, 01, 01, 05, 00, 0f, 00, 05, 09, 00, 0d, 00, 03, 09, 00, 10, 00, 02, 0d, 00, 1b, 00, 02, 0d, 00, 1c, 01, 04, 09, 00, 10, 01, 00, 13, 00, 2e, 01, 02, 05, 00, 0f, 01, 04, 05, 00, 0f, 01, 04, 05, 00, 0f, 01, 04, 09, 00, 0c, 01, 00, 0f, 00, 15, 01, 01, 05, 00, 0f, 01, 04, 08, 00, 0f, 05, 01, 09, 00, 13, 02, 05, 09, 00, 13, 01, 05, 08, 00, 0f, 09, 01, 09, 00, 13, 00, 03, 0d, 00, 1d, 06, 03, 09, 00, 13, 00, 03, 0d, 00, 1d, 01, 03, 05, 00, 0f, 01, 01, 0c, 00, 13, 0d, 01, 0d, 00, 13, 0a, 02, 0d, 00, 13, 11, 04, 05, 00, 0f, 11, 02, 0c, 00, 13, 15, 01, 0d, 00, 13, 0e, 02, 0d, 00, 13, 27, 03, 05, 00, 0f, 19, 01, 0c, 00, 13, 1d, 01, 0d, 00, 17, 1d, 04, 0d, 00, 13, 1e, 02, 0d, 00, 17, 1e, 01, 14, 00, 1b, 00, 01, 15, 00, 1b, 1e, 02, 15, 00, 1b, 21, 04, 0d, 00, 13, 22, 03, 09, 00, 19, 25, 02, 05, 00, 0f, 25, 03, 09, 00, 22, 00, 02, 05, 00, 0f, 00, 03, 09, 00, 2c, 00, 02, 01, 00, 02] Number of files: 1 - file 0 => $DIR/issue-84561.rs Number of expressions: 10 -- expression 0 operands: lhs = Counter(3), rhs = Counter(4) -- expression 1 operands: lhs = Counter(3), rhs = Counter(5) -- expression 2 operands: lhs = Counter(3), rhs = Counter(6) -- expression 3 operands: lhs = Counter(7), rhs = Counter(8) -- expression 4 operands: lhs = Counter(10), rhs = Counter(11) -- expression 5 operands: lhs = Counter(9), rhs = Counter(10) -- expression 6 operands: lhs = Counter(9), rhs = Counter(10) -- expression 7 operands: lhs = Counter(9), rhs = Counter(10) -- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(12) -- expression 9 operands: lhs = Counter(10), rhs = Counter(11) +- expression 0 operands: lhs = Counter(0), rhs = Counter(1) +- expression 1 operands: lhs = Counter(0), rhs = Counter(2) +- expression 2 operands: lhs = Counter(0), rhs = Counter(3) +- expression 3 operands: lhs = Counter(4), rhs = Counter(5) +- expression 4 operands: lhs = Counter(7), rhs = Counter(8) +- expression 5 operands: lhs = Counter(6), rhs = Counter(7) +- expression 6 operands: lhs = Counter(6), rhs = Counter(7) +- expression 7 operands: lhs = Counter(6), rhs = Counter(7) +- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(9) +- expression 9 operands: lhs = Counter(7), rhs = Counter(8) Number of file 0 mappings: 77 - Code(Counter(0)) at (prev + 8, 1) to (start + 0, 11) - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 16) @@ -94,85 +94,85 @@ Number of file 0 mappings: 77 - Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) - Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) - Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(1)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(1)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(2)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(2)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 12) -- Code(Counter(2)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(2)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 48) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 13) -- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 20) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 13) +- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 20) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 0, 32) to (start + 0, 36) - Code(Zero) at (prev + 0, 41) to (start + 0, 48) - Code(Zero) at (prev + 0, 51) to (start + 0, 65) - Code(Zero) at (prev + 0, 75) to (start + 0, 90) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) - Code(Zero) at (prev + 5, 9) to (start + 0, 13) - Code(Zero) at (prev + 3, 9) to (start + 0, 16) - Code(Zero) at (prev + 2, 13) to (start + 0, 27) - Code(Zero) at (prev + 2, 13) to (start + 0, 28) -- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 16) -- Code(Counter(3)) at (prev + 0, 19) to (start + 0, 46) -- Code(Counter(3)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 9) to (start + 0, 12) -- Code(Counter(3)) at (prev + 0, 15) to (start + 0, 21) -- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 4, 8) to (start + 0, 15) -- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 19) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 16) +- Code(Counter(0)) at (prev + 0, 19) to (start + 0, 46) +- Code(Counter(0)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 9) to (start + 0, 12) +- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 21) +- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 4, 8) to (start + 0, 15) +- Code(Counter(1)) at (prev + 1, 9) to (start + 0, 19) - Code(Expression(0, Sub)) at (prev + 5, 9) to (start + 0, 19) - = (c3 - c4) -- Code(Counter(3)) at (prev + 5, 8) to (start + 0, 15) -- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 19) + = (c0 - c1) +- Code(Counter(0)) at (prev + 5, 8) to (start + 0, 15) +- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 19) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) - Code(Expression(1, Sub)) at (prev + 3, 9) to (start + 0, 19) - = (c3 - c5) + = (c0 - c2) - Code(Zero) at (prev + 3, 13) to (start + 0, 29) -- Code(Counter(3)) at (prev + 3, 5) to (start + 0, 15) -- Code(Counter(3)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 19) +- Code(Counter(0)) at (prev + 3, 5) to (start + 0, 15) +- Code(Counter(0)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(3)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(2, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c3 - c6) -- Code(Counter(7)) at (prev + 4, 5) to (start + 0, 15) -- Code(Counter(7)) at (prev + 2, 12) to (start + 0, 19) -- Code(Counter(8)) at (prev + 1, 13) to (start + 0, 19) + = (c0 - c3) +- Code(Counter(4)) at (prev + 4, 5) to (start + 0, 15) +- Code(Counter(4)) at (prev + 2, 12) to (start + 0, 19) +- Code(Counter(5)) at (prev + 1, 13) to (start + 0, 19) - Code(Expression(3, Sub)) at (prev + 2, 13) to (start + 0, 19) - = (c7 - c8) + = (c4 - c5) - Code(Expression(9, Add)) at (prev + 3, 5) to (start + 0, 15) - = (c10 + c11) -- Code(Counter(9)) at (prev + 1, 12) to (start + 0, 19) -- Code(Counter(10)) at (prev + 1, 13) to (start + 0, 23) -- Code(Counter(10)) at (prev + 4, 13) to (start + 0, 19) + = (c7 + c8) +- Code(Counter(6)) at (prev + 1, 12) to (start + 0, 19) +- Code(Counter(7)) at (prev + 1, 13) to (start + 0, 23) +- Code(Counter(7)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(7, Sub)) at (prev + 2, 13) to (start + 0, 23) - = (c9 - c10) + = (c6 - c7) - Code(Expression(7, Sub)) at (prev + 1, 20) to (start + 0, 27) - = (c9 - c10) + = (c6 - c7) - Code(Zero) at (prev + 1, 21) to (start + 0, 27) - Code(Expression(7, Sub)) at (prev + 2, 21) to (start + 0, 27) - = (c9 - c10) -- Code(Counter(11)) at (prev + 4, 13) to (start + 0, 19) + = (c6 - c7) +- Code(Counter(8)) at (prev + 4, 13) to (start + 0, 19) - Code(Expression(8, Sub)) at (prev + 3, 9) to (start + 0, 25) - = ((c10 + c11) - c12) -- Code(Counter(12)) at (prev + 2, 5) to (start + 0, 15) -- Code(Counter(12)) at (prev + 3, 9) to (start + 0, 34) + = ((c7 + c8) - c9) +- Code(Counter(9)) at (prev + 2, 5) to (start + 0, 15) +- Code(Counter(9)) at (prev + 3, 9) to (start + 0, 34) - Code(Zero) at (prev + 2, 5) to (start + 0, 15) - Code(Zero) at (prev + 3, 9) to (start + 0, 44) - Code(Zero) at (prev + 2, 1) to (start + 0, 2) -Highest counter ID seen: c12 +Highest counter ID seen: c9 diff --git a/tests/crashes/105275.rs b/tests/crashes/105275.rs deleted file mode 100644 index a97f36d19872c..0000000000000 --- a/tests/crashes/105275.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #105275 -//@ compile-flags: -Copt-level=0 - -pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { - if n > 15 { - encode_num(n / 16, &mut writer)?; - } - Ok(()) -} - -pub trait ExampleWriter { - type Error; -} - -impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { - type Error = T::Error; -} - -struct Error; - -impl ExampleWriter for Error { - type Error = (); -} - -fn main() { - encode_num(69, &mut Error).unwrap(); -} diff --git a/tests/crashes/105937.rs b/tests/crashes/105937.rs deleted file mode 100644 index ffd1a493e46d5..0000000000000 --- a/tests/crashes/105937.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #105937 -//@ compile-flags: -Copt-level=0 - -pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { - if n > 15 { - encode_num(n / 16, &mut writer)?; - } - Ok(()) -} - -pub trait ExampleWriter { - type Error; -} - -impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { - type Error = T::Error; -} - -struct Error; - -impl ExampleWriter for Error { - type Error = (); -} - -fn main() { - encode_num(69, &mut Error).unwrap(); -} diff --git a/tests/crashes/117696-1.rs b/tests/crashes/117696-1.rs deleted file mode 100644 index dfca39177855d..0000000000000 --- a/tests/crashes/117696-1.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ known-bug: #117696 -fn main() { - let mut it = (Empty); - rec(&mut it); -} - -struct Empty; - -impl Iterator for Empty { - type Item = (); - fn next<'a>(&'a mut self) -> core::option::Option<()> { - None - } -} - -fn identity(x: T) -> T { - x -} - -fn rec(mut it: T) -where - T: Iterator, -{ - if () == () { - T::count(it); - } else { - rec(identity(&mut it)) - } -} diff --git a/tests/crashes/117696-2.rs b/tests/crashes/117696-2.rs deleted file mode 100644 index 9c2a68d3a915c..0000000000000 --- a/tests/crashes/117696-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #117696 -//@ compile-flags: -Copt-level=0 -fn main() { - rec(&mut None::<()>.into_iter()); -} - -fn rec(mut it: T) { - if true { - it.next(); - } else { - rec(&mut it); - } -} diff --git a/tests/crashes/117808.rs b/tests/crashes/117808.rs deleted file mode 100644 index 2c727986dd07f..0000000000000 --- a/tests/crashes/117808.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #117808 -//@ edition:2021 -//@ needs-rustc-debug-assertions - -use std::future::Future; - -fn hrc AsyncClosure<'a, (), R>>(f: F) -> F { - f -} - -fn main() { - hrc(|x| async {}); -} - -trait AsyncClosure<'a, I, R> -where - I: 'a, -{ -} - -impl<'a, I, R, Fut, F> AsyncClosure<'a, I, R> for F -where - I: 'a, - F: Fn(&'a I) -> Fut, - Fut: Future + Send + 'a, -{ -} diff --git a/tests/crashes/118244.rs b/tests/crashes/118244.rs index bfa1f5b7dd489..0330d0d838ab2 100644 --- a/tests/crashes/118244.rs +++ b/tests/crashes/118244.rs @@ -1,5 +1,6 @@ //@ known-bug: #118244 //@ compile-flags: -Cdebuginfo=2 +//@ ignore-backends: gcc #![allow(incomplete_features)] #![feature(generic_const_exprs)] diff --git a/tests/crashes/118590.rs b/tests/crashes/118590.rs deleted file mode 100644 index 829c16582dc92..0000000000000 --- a/tests/crashes/118590.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #118590 - -fn main() { - recurse(std::iter::empty::<()>()) -} - -fn recurse(nums: impl Iterator) { - if true { return } - - recurse(nums.skip(42).peekable()) -} diff --git a/tests/crashes/120016.rs b/tests/crashes/120016.rs index 7eda330e7adea..12f54dbc3d92c 100644 --- a/tests/crashes/120016.rs +++ b/tests/crashes/120016.rs @@ -1,19 +1,19 @@ //@ known-bug: #120016 -//@ compile-flags: -Zcrate-attr=feature(const_async_blocks) +//@ compile-flags: -Zvalidate-mir //@ edition: 2021 -#![feature(type_alias_impl_trait, const_async_blocks)] +#![feature(type_alias_impl_trait)] struct Bug { V1: [(); { - type F = impl std::future::Future; + type F = impl Sized; #[define_opaque(F)] fn concrete_use() -> F { - //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` - async {} + //~^ ERROR + 1i32 } - let f: F = async { 1 }; - //~^ ERROR `async` blocks are not allowed in constants + let f: F = 0u32; + 1 }], } diff --git a/tests/crashes/120175.rs b/tests/crashes/120175.rs index e441454bed294..e06da5a8e0ae0 100644 --- a/tests/crashes/120175.rs +++ b/tests/crashes/120175.rs @@ -1,5 +1,6 @@ //@ known-bug: #120175 //@ needs-rustc-debug-assertions +//@ ignore-apple (raw-dylib doesn't work on Apple targets yet) #![feature(extern_types)] #![feature(raw_dylib_elf)] diff --git a/tests/crashes/122630.rs b/tests/crashes/122630.rs deleted file mode 100644 index e66624431c510..0000000000000 --- a/tests/crashes/122630.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ known-bug: #122630 -//@ compile-flags: -Zvalidate-mir - -use std::ops::Coroutine; - -const FOO_SIZE: usize = 1024; -struct Foo([u8; FOO_SIZE]); - -impl Drop for Foo { - fn move_before_yield_with_noop() -> impl Coroutine {} -} - -fn overlap_move_points() -> impl Coroutine { - static || { - let first = Foo([0; FOO_SIZE]); - yield; - let second = first; - yield; - let second = first; - yield; - } -} diff --git a/tests/crashes/122823.rs b/tests/crashes/122823.rs deleted file mode 100644 index ec22b331ad929..0000000000000 --- a/tests/crashes/122823.rs +++ /dev/null @@ -1,69 +0,0 @@ -//@ known-bug: #122823 -//@ compile-flags: -Copt-level=0 -// ignore-tidy-linelength - -use std::vec::Vec; -use std::iter::Peekable; - -pub fn main() { - let packet = decode(vec![1,0,1,0]); -} - -pub fn decode(bitstream: Vec) -> Packet { - let mut bitstream_itr = bitstream.into_iter().peekable(); - return match decode_packet(&mut bitstream_itr) { - Some(p) => p, - None => panic!("expected outer packet"), - } -} - -pub fn decode_packets>(itr: &mut Peekable) -> Vec { - let mut res = Vec::new(); - loop { - match decode_packet(itr) { - Some(p) => { res.push(p); }, - None => break - } - } - - return res; -} - -pub fn decode_packet>(itr: &mut Peekable) -> Option { - // get version digits - let version = extend_number(0, itr, 3)?; - let type_id = extend_number(0, itr, 3)?; - return operator_packet(version, type_id, itr); -} - -pub fn operator_packet>(version: u64, type_id: u64, itr: &mut Peekable) -> Option { - let p = OperatorPacket { - version: version, - type_id: type_id, - packets: decode_packets(&mut itr.take(0).peekable()), - }; - - return Some(Packet::Operator(p)); -} - -pub fn extend_number>(num: u64, itr: &mut Peekable, take: u64) -> Option { - let mut value = num; - for _ in 0..take { - value *= 2; - value += itr.next()?; - } - - return Some(value); -} - -#[derive(Debug)] -pub enum Packet { - Operator(OperatorPacket), -} - -#[derive(Debug)] -pub struct OperatorPacket { - version: u64, - type_id: u64, - packets: Vec -} diff --git a/tests/crashes/122904-2.rs b/tests/crashes/122904-2.rs deleted file mode 100644 index db66b8625db0e..0000000000000 --- a/tests/crashes/122904-2.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #122904 -trait T {} - -type Alias<'a> = impl T; - -struct S; -impl<'a> T for &'a S {} - -#[define_opaque(Alias)] -fn with_positive(fun: impl Fn(Alias<'_>)) { - with_positive(|&n| ()); -} - -#[define_opaque(Alias)] -fn main(Alias<'_>) { - with_positive(|&a| ()); -} diff --git a/tests/crashes/125185.rs b/tests/crashes/125185.rs deleted file mode 100644 index e77666ca73d36..0000000000000 --- a/tests/crashes/125185.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ known-bug: rust-lang/rust#125185 -//@ compile-flags: -Zvalidate-mir - -#![feature(type_alias_impl_trait)] - -type Foo = impl Send; - -struct A; - -#[define_opaque(Foo)] -const fn foo() -> Foo { - value() -} - -const VALUE: Foo = foo(); - -#[define_opaque(Foo)] -fn test(foo: Foo, f: impl for<'b> FnMut()) { - match VALUE { - 0 | 0 => {} - - _ => (), - } -} - -fn main() {} diff --git a/tests/crashes/125323.rs b/tests/crashes/125323.rs deleted file mode 100644 index 180b7bbad097d..0000000000000 --- a/tests/crashes/125323.rs +++ /dev/null @@ -1,6 +0,0 @@ -//@ known-bug: rust-lang/rust#125323 -fn main() { - for _ in 0..0 { - [(); loop {}]; - } -} diff --git a/tests/crashes/125772.rs b/tests/crashes/125772.rs index 2965cfc9e7c3c..2b6cffd9463a9 100644 --- a/tests/crashes/125772.rs +++ b/tests/crashes/125772.rs @@ -1,5 +1,5 @@ //@ known-bug: rust-lang/rust#125772 -//@ only-x86_64 +//@ only-64bit #![feature(generic_const_exprs)] struct Outer(); diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs deleted file mode 100644 index b1bb74708c2d7..0000000000000 --- a/tests/crashes/129095.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#129095 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir - -#![feature(adt_const_params, unsized_const_params)] -#![allow(incomplete_features)] - -pub fn function_with_bytes() -> &'static [u8] { - BYTES -} - -pub fn main() { - assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]); -} diff --git a/tests/crashes/131292.rs b/tests/crashes/131292.rs index 01e0eca0bd6d6..05b93d06b0553 100644 --- a/tests/crashes/131292.rs +++ b/tests/crashes/131292.rs @@ -1,5 +1,5 @@ //@ known-bug: #131292 -//@ only-x86_64 +//@ needs-asm-support use std::arch::asm; unsafe fn f6() { diff --git a/tests/crashes/131342.rs b/tests/crashes/131342.rs deleted file mode 100644 index f4404092917a4..0000000000000 --- a/tests/crashes/131342.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #131342 - -fn main() { - let mut items = vec![1, 2, 3, 4, 5].into_iter(); - problem_thingy(&mut items); -} - -fn problem_thingy(items: &mut impl Iterator) { - let mut peeker = items.peekable(); - match peeker.peek() { - Some(_) => (), - None => return (), - } - problem_thingy(&mut peeker); -} diff --git a/tests/crashes/132142.rs b/tests/crashes/132142.rs deleted file mode 100644 index 813bf0bf0a8e5..0000000000000 --- a/tests/crashes/132142.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ known-bug: #132142 - -async extern "cmse-nonsecure-entry" fn fun(...) {} diff --git a/tests/crashes/134174.rs b/tests/crashes/134174.rs deleted file mode 100644 index 899cdc6faf358..0000000000000 --- a/tests/crashes/134174.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #134175 -//@compile-flags: -Zvalidate-mir -Zinline-mir=yes -use std::vec::IntoIter; - -pub(crate) trait Foo: Iterator::Key> { - type Key; -} - -impl Foo for IntoIter {} - -fn sum_foo>(f: F) -> i32 { - f.fold(0, |a, b| a + b) -} - -fn main() { - let x = sum_foo(vec![11, 10, 1].into_iter()); -} diff --git a/tests/crashes/134479.rs b/tests/crashes/134479.rs index 0e4ddb2bfd56d..02047050cec40 100644 --- a/tests/crashes/134479.rs +++ b/tests/crashes/134479.rs @@ -1,5 +1,6 @@ //@ known-bug: #134479 //@ compile-flags: -Csymbol-mangling-version=v0 -Cdebuginfo=1 +//@ ignore-backends: gcc #![feature(generic_const_exprs)] diff --git a/tests/crashes/134654.rs b/tests/crashes/134654.rs deleted file mode 100644 index f2323fe4ecdcd..0000000000000 --- a/tests/crashes/134654.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #134654 -//@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir -//@ only-x86_64 - -#![feature(adt_const_params, unsized_const_params)] -#![allow(incomplete_features)] - -fn function_with_bytes() -> &'static [u8] { - BYTES -} - -fn main() { - function_with_bytes::() == &[]; -} diff --git a/tests/crashes/135570.rs b/tests/crashes/135570.rs deleted file mode 100644 index 7919ceb26d50d..0000000000000 --- a/tests/crashes/135570.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ known-bug: #135570 -//@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN -//@ only-x86_64 - -#![feature(adt_const_params, unsized_const_params)] -#![allow(incomplete_features)] - -fn function_with_bytes( -) -> &'static [u8] { - BYTES -} - -fn main() { - function_with_bytes::() == &[]; -} diff --git a/tests/crashes/136381.rs b/tests/crashes/136381.rs deleted file mode 100644 index 13ccc14a2c5be..0000000000000 --- a/tests/crashes/136381.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #136381 -//@ compile-flags: -Zvalidate-mir -Zmir-enable-passes=+GVN -#![feature(trait_upcasting)] - -trait A {} -trait B: A { - fn c(&self); -} -impl B for i32 { - fn c(self) { - todo!(); - } -} - -fn main() { - let baz: &dyn B = &1; - let bar: &dyn A = baz; -} diff --git a/tests/crashes/137190-1.rs b/tests/crashes/137190-1.rs deleted file mode 100644 index bdfe883b71207..0000000000000 --- a/tests/crashes/137190-1.rs +++ /dev/null @@ -1,10 +0,0 @@ -//@ known-bug: #137190 -//@ compile-flags: -Zmir-opt-level=2 -Zvalidate-mir -trait A { - fn b(&self); -} -trait C: A {} -impl C for () {} -fn main() { - (&() as &dyn C as &dyn A).b(); -} diff --git a/tests/crashes/137468.rs b/tests/crashes/137468.rs deleted file mode 100644 index cceb0502bd21b..0000000000000 --- a/tests/crashes/137468.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ known-bug: #137468 -//@ compile-flags: -Copt-level=0 -Zmir-enable-passes=+GVN -Zvalidate-mir -trait Supertrait {} - -trait Identity { - type Selff; -} - -trait Trait

: Supertrait<()> + Supertrait<

::Selff> {} - -impl

Trait

for () {} - -fn main() { - let x: &dyn Trait<()> = &(); - let x: &dyn Supertrait<()> = x; -} diff --git a/tests/crashes/139462.rs b/tests/crashes/139462.rs index 05bb246d7be0e..d3be14b2be2a3 100644 --- a/tests/crashes/139462.rs +++ b/tests/crashes/139462.rs @@ -1,5 +1,6 @@ //@ known-bug: #139462 //@ compile-flags: -Cdebuginfo=2 +//@ ignore-backends: gcc #![feature(unsafe_binders)] use std::unsafe_binder::wrap_binder; fn main() { diff --git a/tests/crashes/139556.rs b/tests/crashes/139556.rs deleted file mode 100644 index 60dc8d7c3afcc..0000000000000 --- a/tests/crashes/139556.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #139556 - -trait T {} - -type Alias<'a> = impl T; - -struct S; -impl<'a> T for &'a S {} - -#[define_opaque(Alias)] -fn with_positive(fun: impl Fn(Alias<'_>)) { - with_positive(|&n| ()); -} diff --git a/tests/crashes/139659.rs b/tests/crashes/139659.rs deleted file mode 100644 index 7fc33f7e6a7cf..0000000000000 --- a/tests/crashes/139659.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ known-bug: #139659 -//@compile-flags: -Cdebuginfo=2 -Copt-level=0 --crate-type lib -trait Trait { - type Output; -} - -impl O> Trait for F { - type Output = O; -} - -struct Wrap

(P); -struct WrapOutput(O); - -impl Trait for Wrap

{ - type Output = WrapOutput; -} - -fn wrap(x: P) -> impl Trait { - Wrap(x) -} - -fn consume(_: P) -> P::Output { - unimplemented!() -} - -pub fn recurse() -> impl Sized { - consume(wrap(recurse)) -} -pub fn main() {} diff --git a/tests/crashes/139815.rs b/tests/crashes/139815.rs deleted file mode 100644 index 9094acdc94b21..0000000000000 --- a/tests/crashes/139815.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ known-bug: #139815 - -#![feature(generic_const_exprs)] -fn is_123( - x: [u32; { - N + 1; - 5 - }], -) -> bool { - match x { - [1, 2] => true, - _ => false, - } -} diff --git a/tests/crashes/140609.rs b/tests/crashes/140609.rs deleted file mode 100644 index ee8a4bb30489f..0000000000000 --- a/tests/crashes/140609.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #140609 -#![feature(with_negative_coherence)] -#![feature(generic_const_exprs)] -#![crate_type = "lib"] -trait Trait {} -struct A; - -trait C {} - -impl Trait for E where A<{ D <= 2 }>: FnOnce(&isize) {} -struct E; - -impl Trait for E where A<{ D <= 2 }>: C {} diff --git a/tests/crashes/146261.rs b/tests/crashes/146261.rs new file mode 100644 index 0000000000000..f901497a769c2 --- /dev/null +++ b/tests/crashes/146261.rs @@ -0,0 +1,13 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146261 + +enum U { + B(), +} + +fn main() { + A(U::C) +} diff --git a/tests/crashes/146706.rs b/tests/crashes/146706.rs new file mode 100644 index 0000000000000..358ce3e8600a8 --- /dev/null +++ b/tests/crashes/146706.rs @@ -0,0 +1,15 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146706 + +type Alias<'a, T> = Foo; + +enum Foo { + Bar { t: T }, +} + +fn main() { + Alias::Bar:: { t: 0 }; +} diff --git a/tests/crashes/147973.rs b/tests/crashes/147973.rs new file mode 100644 index 0000000000000..7271c54846f15 --- /dev/null +++ b/tests/crashes/147973.rs @@ -0,0 +1,14 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. +// This is one MCVE from the beta crater run regressions from issue 147973. + +//@ needs-rustc-debug-assertions +//@ known-bug: #147973 + +//@ aux-build: overlapping_spans_helper.rs +extern crate overlapping_spans_helper; + +fn main() { + let _name = Some(1); + overlapping_spans_helper::do_loop!(_name); +} diff --git a/tests/crashes/34127.rs b/tests/crashes/34127.rs index ea36b48ecba07..58725bff4c084 100644 --- a/tests/crashes/34127.rs +++ b/tests/crashes/34127.rs @@ -1,6 +1,7 @@ //@ compile-flags: -g -Copt-level=0 -Z verify-llvm-ir //@ known-bug: #34127 -//@ only-x86_64 +//@ only-64bit +//@ ignore-backends: gcc pub fn main() { let _a = [(); 1 << 63]; diff --git a/tests/crashes/92004.rs b/tests/crashes/92004.rs deleted file mode 100644 index bc2ca2a7ba389..0000000000000 --- a/tests/crashes/92004.rs +++ /dev/null @@ -1,70 +0,0 @@ -//@ known-bug: #102310 -//@ compile-flags: -Copt-level=0 -//@ edition:2021 -// ignore-tidy-linelength - -use std::vec::Vec; -use std::iter::Peekable; - -pub fn main() { - let packet = decode(vec![1,0,1,0]); -} - -pub fn decode(bitstream: Vec) -> Packet { - let mut bitstream_itr = bitstream.into_iter().peekable(); - return match decode_packet(&mut bitstream_itr) { - Some(p) => p, - None => panic!("expected outer packet"), - } -} - -pub fn decode_packets>(itr: &mut Peekable) -> Vec { - let mut res = Vec::new(); - loop { - match decode_packet(itr) { - Some(p) => { res.push(p); }, - None => break - } - } - - return res; -} - -pub fn decode_packet>(itr: &mut Peekable) -> Option { - // get version digits - let version = extend_number(0, itr, 3)?; - let type_id = extend_number(0, itr, 3)?; - return operator_packet(version, type_id, itr); -} - -pub fn operator_packet>(version: u64, type_id: u64, itr: &mut Peekable) -> Option { - let p = OperatorPacket { - version: version, - type_id: type_id, - packets: decode_packets(&mut itr.take(0).peekable()), - }; - - return Some(Packet::Operator(p)); -} - -pub fn extend_number>(num: u64, itr: &mut Peekable, take: u64) -> Option { - let mut value = num; - for _ in 0..take { - value *= 2; - value += itr.next()?; - } - - return Some(value); -} - -#[derive(Debug)] -pub enum Packet { - Operator(OperatorPacket), -} - -#[derive(Debug)] -pub struct OperatorPacket { - version: u64, - type_id: u64, - packets: Vec -} diff --git a/tests/crashes/92470.rs b/tests/crashes/92470.rs deleted file mode 100644 index a3c518f5ec62f..0000000000000 --- a/tests/crashes/92470.rs +++ /dev/null @@ -1,31 +0,0 @@ -//@ known-bug: #92470 -fn main() { - encode(&mut EncoderImpl); -} - -pub trait Encoder { - type W; - - fn writer(&self) -> Self::W; -} - -fn encode(mut encoder: E) { - encoder.writer(); - encode(&mut encoder); -} - -struct EncoderImpl; - -impl Encoder for EncoderImpl { - type W = (); - - fn writer(&self) {} -} - -impl<'a, T: Encoder> Encoder for &'a mut T { - type W = T::W; - - fn writer(&self) -> Self::W { - panic!() - } -} diff --git a/tests/crashes/95134.rs b/tests/crashes/95134.rs deleted file mode 100644 index bcd88b1076fd9..0000000000000 --- a/tests/crashes/95134.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ known-bug: #95134 -//@ compile-flags: -Copt-level=0 - -pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { - if n > 15 { - encode_num(n / 16, &mut writer)?; - } - Ok(()) -} - -pub trait ExampleWriter { - type Error; -} - -impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { - type Error = T::Error; -} - -struct EmptyWriter; - -impl ExampleWriter for EmptyWriter { - type Error = (); -} - -fn main() { - encode_num(69, &mut EmptyWriter).unwrap(); -} diff --git a/tests/crashes/auxiliary/overlapping_spans_helper.rs b/tests/crashes/auxiliary/overlapping_spans_helper.rs new file mode 100644 index 0000000000000..e449fcd36c376 --- /dev/null +++ b/tests/crashes/auxiliary/overlapping_spans_helper.rs @@ -0,0 +1,15 @@ +// Auxiliary lib for the issue 147973 regression test with ICEs due to overlapping spans. + +#[macro_export] +macro_rules! identity { + ($x:ident) => { + $x + }; +} + +#[macro_export] +macro_rules! do_loop { + ($x:ident) => { + for $crate::identity!($x) in $x {} + }; +} diff --git a/tests/debuginfo/associated-types.rs b/tests/debuginfo/associated-types.rs index 7c2a793c8cd39..e74a592662d2a 100644 --- a/tests/debuginfo/associated-types.rs +++ b/tests/debuginfo/associated-types.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/basic-stepping.rs b/tests/debuginfo/basic-stepping.rs index f6399814a43a8..aa9f29259d05a 100644 --- a/tests/debuginfo/basic-stepping.rs +++ b/tests/debuginfo/basic-stepping.rs @@ -6,6 +6,7 @@ //@ ignore-loongarch64: Doesn't work yet. //@ ignore-riscv64: Doesn't work yet. //@ compile-flags: -g +//@ ignore-backends: gcc // gdb-command: run // FIXME(#97083): Should we be able to break on initialization of zero-sized types? diff --git a/tests/debuginfo/basic-types-globals-metadata.rs b/tests/debuginfo/basic-types-globals-metadata.rs index fc8f6dc173fcc..cc32b338da728 100644 --- a/tests/debuginfo/basic-types-globals-metadata.rs +++ b/tests/debuginfo/basic-types-globals-metadata.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run // gdb-command:whatis basic_types_globals_metadata::B diff --git a/tests/debuginfo/basic-types-globals.rs b/tests/debuginfo/basic-types-globals.rs index 9d28820ce685c..d8997b3f75a9f 100644 --- a/tests/debuginfo/basic-types-globals.rs +++ b/tests/debuginfo/basic-types-globals.rs @@ -5,6 +5,39 @@ //@ [lto] compile-flags:-C lto //@ [lto] no-prefer-dynamic +//@ ignore-backends: gcc + +// lldb-command:run +// lldb-command:v B +// lldb-check: ::B::[...] = false +// lldb-command:v I +// lldb-check: ::I::[...] = -1 +// lldb-command:v --format=d C +// lldb-check: ::C::[...] = 97 +// lldb-command:v --format=d I8 +// lldb-check: ::I8::[...] = 68 +// lldb-command:v I16 +// lldb-check: ::I16::[...] = -16 +// lldb-command:v I32 +// lldb-check: ::I32::[...] = -32 +// lldb-command:v I64 +// lldb-check: ::I64::[...] = -64 +// lldb-command:v U +// lldb-check: ::U::[...] = 1 +// lldb-command:v --format=d U8 +// lldb-check: ::U8::[...] = 100 +// lldb-command:v U16 +// lldb-check: ::U16::[...] = 16 +// lldb-command:v U32 +// lldb-check: ::U32::[...] = 32 +// lldb-command:v U64 +// lldb-check: ::U64::[...] = 64 +// lldb-command:v F16 +// lldb-check: ::F16::[...] = 1.5 +// lldb-command:v F32 +// lldb-check: ::F32::[...] = 2.5 +// lldb-command:v F64 +// lldb-check: ::F64::[...] = 3.5 // gdb-command:run // gdb-command:print B diff --git a/tests/debuginfo/basic-types-metadata.rs b/tests/debuginfo/basic-types-metadata.rs index 941db81a4decc..495ef81a16c6b 100644 --- a/tests/debuginfo/basic-types-metadata.rs +++ b/tests/debuginfo/basic-types-metadata.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run // gdb-command:whatis unit diff --git a/tests/debuginfo/basic-types-mut-globals.rs b/tests/debuginfo/basic-types-mut-globals.rs index e979d82b55c62..6617f91c3df53 100644 --- a/tests/debuginfo/basic-types-mut-globals.rs +++ b/tests/debuginfo/basic-types-mut-globals.rs @@ -6,6 +6,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run diff --git a/tests/debuginfo/basic-types.rs b/tests/debuginfo/basic-types.rs index 7862f45b3c4e6..9b1452fab4135 100644 --- a/tests/debuginfo/basic-types.rs +++ b/tests/debuginfo/basic-types.rs @@ -6,6 +6,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-basic.rs b/tests/debuginfo/borrowed-basic.rs index 334eae38318e6..86c4df12866ef 100644 --- a/tests/debuginfo/borrowed-basic.rs +++ b/tests/debuginfo/borrowed-basic.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-c-style-enum.rs b/tests/debuginfo/borrowed-c-style-enum.rs index d382a389fe412..b331775743b4c 100644 --- a/tests/debuginfo/borrowed-c-style-enum.rs +++ b/tests/debuginfo/borrowed-c-style-enum.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-enum.rs b/tests/debuginfo/borrowed-enum.rs index 893dd777bcde6..48dce139a2f31 100644 --- a/tests/debuginfo/borrowed-enum.rs +++ b/tests/debuginfo/borrowed-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-struct.rs b/tests/debuginfo/borrowed-struct.rs index 5d64ba3cbefbd..876ec30b14019 100644 --- a/tests/debuginfo/borrowed-struct.rs +++ b/tests/debuginfo/borrowed-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-tuple.rs b/tests/debuginfo/borrowed-tuple.rs index fd4e22feb0691..42964c79485a3 100644 --- a/tests/debuginfo/borrowed-tuple.rs +++ b/tests/debuginfo/borrowed-tuple.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/borrowed-unique-basic.rs b/tests/debuginfo/borrowed-unique-basic.rs index 54d7f27bb0c80..c230ceae1c758 100644 --- a/tests/debuginfo/borrowed-unique-basic.rs +++ b/tests/debuginfo/borrowed-unique-basic.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/box.rs b/tests/debuginfo/box.rs index d4612f98a5f17..c5034410f49f4 100644 --- a/tests/debuginfo/box.rs +++ b/tests/debuginfo/box.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/boxed-struct.rs b/tests/debuginfo/boxed-struct.rs index ca072693cdcd0..fc676e8ce618a 100644 --- a/tests/debuginfo/boxed-struct.rs +++ b/tests/debuginfo/boxed-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/by-value-self-argument-in-trait-impl.rs b/tests/debuginfo/by-value-self-argument-in-trait-impl.rs index a49a375569b12..409cfc533c879 100644 --- a/tests/debuginfo/by-value-self-argument-in-trait-impl.rs +++ b/tests/debuginfo/by-value-self-argument-in-trait-impl.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/c-style-enum-in-composite.rs b/tests/debuginfo/c-style-enum-in-composite.rs index 47b4b980f9ccd..dd5e4f8b65d71 100644 --- a/tests/debuginfo/c-style-enum-in-composite.rs +++ b/tests/debuginfo/c-style-enum-in-composite.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/c-style-enum.rs b/tests/debuginfo/c-style-enum.rs index d5455be0cb56b..79438e3f2d439 100644 --- a/tests/debuginfo/c-style-enum.rs +++ b/tests/debuginfo/c-style-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/captured-fields-1.rs b/tests/debuginfo/captured-fields-1.rs index 69ca3ecd812dd..53f77d3146855 100644 --- a/tests/debuginfo/captured-fields-1.rs +++ b/tests/debuginfo/captured-fields-1.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ edition:2021 +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/captured-fields-2.rs b/tests/debuginfo/captured-fields-2.rs index 24bff1d3f35d7..cdebeaf3a9753 100644 --- a/tests/debuginfo/captured-fields-2.rs +++ b/tests/debuginfo/captured-fields-2.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ edition:2021 +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/closure-in-generic-function.rs b/tests/debuginfo/closure-in-generic-function.rs index 0bb72209cc822..88769399f0895 100644 --- a/tests/debuginfo/closure-in-generic-function.rs +++ b/tests/debuginfo/closure-in-generic-function.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs b/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs index 1aafcffa30472..bafa5408b1978 100644 --- a/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs +++ b/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs @@ -6,6 +6,7 @@ // without collapse_debuginfo attribute. //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/collapse-debuginfo-static-external.rs b/tests/debuginfo/collapse-debuginfo-static-external.rs index 2209bb9bd9481..6389bb734ddf3 100644 --- a/tests/debuginfo/collapse-debuginfo-static-external.rs +++ b/tests/debuginfo/collapse-debuginfo-static-external.rs @@ -3,11 +3,12 @@ // Test that static debug info is not collapsed with #[collapse_debuginfo(external)] //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:info line collapse_debuginfo_static_external::FOO -// gdb-check:[...]Line 15[...] +// gdb-check:[...]Line 16[...] #[collapse_debuginfo(external)] macro_rules! decl_foo { diff --git a/tests/debuginfo/collapse-debuginfo-static.rs b/tests/debuginfo/collapse-debuginfo-static.rs index e6469da4785e7..a5542a44091a2 100644 --- a/tests/debuginfo/collapse-debuginfo-static.rs +++ b/tests/debuginfo/collapse-debuginfo-static.rs @@ -3,11 +3,12 @@ // Test that static debug info is collapsed with #[collapse_debuginfo(yes)] //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:info line collapse_debuginfo_static::FOO -// gdb-check:[...]Line 19[...] +// gdb-check:[...]Line 20[...] #[collapse_debuginfo(yes)] macro_rules! decl_foo { diff --git a/tests/debuginfo/constant-ordering-prologue.rs b/tests/debuginfo/constant-ordering-prologue.rs index 3136aff238a2d..1d4674b1d32b0 100644 --- a/tests/debuginfo/constant-ordering-prologue.rs +++ b/tests/debuginfo/constant-ordering-prologue.rs @@ -1,6 +1,7 @@ //@ min-lldb-version: 310 //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/coroutine-locals.rs b/tests/debuginfo/coroutine-locals.rs index c2b8aef8a6738..d63ea4bde3675 100644 --- a/tests/debuginfo/coroutine-locals.rs +++ b/tests/debuginfo/coroutine-locals.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/coroutine-objects.rs b/tests/debuginfo/coroutine-objects.rs index 7ead154cbdb1f..f1165de4bfaaf 100644 --- a/tests/debuginfo/coroutine-objects.rs +++ b/tests/debuginfo/coroutine-objects.rs @@ -6,6 +6,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/cross-crate-spans.rs b/tests/debuginfo/cross-crate-spans.rs index 38176e46909c5..6ef17061070e8 100644 --- a/tests/debuginfo/cross-crate-spans.rs +++ b/tests/debuginfo/cross-crate-spans.rs @@ -3,6 +3,7 @@ extern crate cross_crate_spans; //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/cross-crate-type-uniquing.rs b/tests/debuginfo/cross-crate-type-uniquing.rs index 28ebc34388467..c29757ae7793f 100644 --- a/tests/debuginfo/cross-crate-type-uniquing.rs +++ b/tests/debuginfo/cross-crate-type-uniquing.rs @@ -3,6 +3,7 @@ extern crate cross_crate_debuginfo_type_uniquing; //@ no-prefer-dynamic //@ compile-flags:-g -C lto +//@ ignore-backends: gcc pub struct C; pub fn p() -> C { diff --git a/tests/debuginfo/destructured-fn-argument.rs b/tests/debuginfo/destructured-fn-argument.rs index fe8f91588e06a..27910ed46882e 100644 --- a/tests/debuginfo/destructured-fn-argument.rs +++ b/tests/debuginfo/destructured-fn-argument.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/destructured-for-loop-variable.rs b/tests/debuginfo/destructured-for-loop-variable.rs index 01c524083daee..12a9ff4172583 100644 --- a/tests/debuginfo/destructured-for-loop-variable.rs +++ b/tests/debuginfo/destructured-for-loop-variable.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/destructured-local.rs b/tests/debuginfo/destructured-local.rs index ff24c924aada3..ef595468b473f 100644 --- a/tests/debuginfo/destructured-local.rs +++ b/tests/debuginfo/destructured-local.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/dummy_span.rs b/tests/debuginfo/dummy_span.rs index d02eead470fa1..23822222006c2 100644 --- a/tests/debuginfo/dummy_span.rs +++ b/tests/debuginfo/dummy_span.rs @@ -1,6 +1,7 @@ //@ min-lldb-version: 310 //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/embedded-visualizer.rs b/tests/debuginfo/embedded-visualizer.rs index cbd8691394d54..3652036ae8b64 100644 --- a/tests/debuginfo/embedded-visualizer.rs +++ b/tests/debuginfo/embedded-visualizer.rs @@ -63,6 +63,7 @@ #![debugger_visualizer(gdb_script_file = "embedded-visualizer.py")] //@ aux-build: dependency-with-embedded-visualizers.rs +//@ ignore-backends: gcc extern crate dependency_with_embedded_visualizers; use dependency_with_embedded_visualizers::Person; diff --git a/tests/debuginfo/empty-string.rs b/tests/debuginfo/empty-string.rs index 6cf61e177714d..d9368001b6312 100644 --- a/tests/debuginfo/empty-string.rs +++ b/tests/debuginfo/empty-string.rs @@ -1,6 +1,7 @@ //@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/enum-thinlto.rs b/tests/debuginfo/enum-thinlto.rs index 6eb33b2ef46a7..789755438a6b9 100644 --- a/tests/debuginfo/enum-thinlto.rs +++ b/tests/debuginfo/enum-thinlto.rs @@ -1,6 +1,7 @@ //@ min-lldb-version: 1800 //@ compile-flags:-g -Z thinlto //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/evec-in-struct.rs b/tests/debuginfo/evec-in-struct.rs index f08c436bbe3ae..1c0c0a36bace8 100644 --- a/tests/debuginfo/evec-in-struct.rs +++ b/tests/debuginfo/evec-in-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/extern-c-fn.rs b/tests/debuginfo/extern-c-fn.rs index 7130658f2d82b..3a8a110afa2cb 100644 --- a/tests/debuginfo/extern-c-fn.rs +++ b/tests/debuginfo/extern-c-fn.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/function-arg-initialization.rs b/tests/debuginfo/function-arg-initialization.rs index 03fb1e2d062f5..1a681c7721163 100644 --- a/tests/debuginfo/function-arg-initialization.rs +++ b/tests/debuginfo/function-arg-initialization.rs @@ -9,6 +9,7 @@ //@ compile-flags:-g -Zmir-enable-passes=-SingleUseConsts // SingleUseConsts shouldn't need to be disabled, see #128945 //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/function-arguments.rs b/tests/debuginfo/function-arguments.rs index 64d026a705bfb..47c6ebe115547 100644 --- a/tests/debuginfo/function-arguments.rs +++ b/tests/debuginfo/function-arguments.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/function-call.rs b/tests/debuginfo/function-call.rs index 3d8d798928d7f..c0b23dc551ead 100644 --- a/tests/debuginfo/function-call.rs +++ b/tests/debuginfo/function-call.rs @@ -2,6 +2,7 @@ //@ min-gdb-version: 10.1 //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/function-names.rs b/tests/debuginfo/function-names.rs index b5aec5c595e73..75fc14129761b 100644 --- a/tests/debuginfo/function-names.rs +++ b/tests/debuginfo/function-names.rs @@ -3,6 +3,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/gdb-char.rs b/tests/debuginfo/gdb-char.rs index d296e675fa3e6..5f44fa5c4233d 100644 --- a/tests/debuginfo/gdb-char.rs +++ b/tests/debuginfo/gdb-char.rs @@ -4,6 +4,7 @@ //@ min-gdb-version: 11.2 //@ compile-flags: -g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/gdb-pretty-struct-and-enums.rs b/tests/debuginfo/gdb-pretty-struct-and-enums.rs index 08e01333a376e..ab6aea6b6316e 100644 --- a/tests/debuginfo/gdb-pretty-struct-and-enums.rs +++ b/tests/debuginfo/gdb-pretty-struct-and-enums.rs @@ -2,6 +2,7 @@ //@ ignore-android: FIXME(#10381) //@ compile-flags:-g +//@ ignore-backends: gcc // gdb-command: run diff --git a/tests/debuginfo/generic-enum-with-different-disr-sizes.rs b/tests/debuginfo/generic-enum-with-different-disr-sizes.rs index 5c5f05d9c4b1c..07a92619e211e 100644 --- a/tests/debuginfo/generic-enum-with-different-disr-sizes.rs +++ b/tests/debuginfo/generic-enum-with-different-disr-sizes.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/generic-function.rs b/tests/debuginfo/generic-function.rs index ab3cb6953ace4..9ca9eb32a2e10 100644 --- a/tests/debuginfo/generic-function.rs +++ b/tests/debuginfo/generic-function.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/generic-functions-nested.rs b/tests/debuginfo/generic-functions-nested.rs index 8ac2b8b9d7a1d..1a87827c7759d 100644 --- a/tests/debuginfo/generic-functions-nested.rs +++ b/tests/debuginfo/generic-functions-nested.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/generic-method-on-generic-struct.rs b/tests/debuginfo/generic-method-on-generic-struct.rs index 36a94f2999d7d..c549a14153659 100644 --- a/tests/debuginfo/generic-method-on-generic-struct.rs +++ b/tests/debuginfo/generic-method-on-generic-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/generic-static-method-on-struct-and-enum.rs b/tests/debuginfo/generic-static-method-on-struct-and-enum.rs index 09b515d69e495..be9f394f133d3 100644 --- a/tests/debuginfo/generic-static-method-on-struct-and-enum.rs +++ b/tests/debuginfo/generic-static-method-on-struct-and-enum.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run diff --git a/tests/debuginfo/generic-struct-style-enum.rs b/tests/debuginfo/generic-struct-style-enum.rs index 4f580f8c515d2..7b7a36effd575 100644 --- a/tests/debuginfo/generic-struct-style-enum.rs +++ b/tests/debuginfo/generic-struct-style-enum.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:set print union on // gdb-command:run diff --git a/tests/debuginfo/generic-struct.rs b/tests/debuginfo/generic-struct.rs index 0196ca435447b..daf6554fab0a4 100644 --- a/tests/debuginfo/generic-struct.rs +++ b/tests/debuginfo/generic-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/generic-tuple-style-enum.rs b/tests/debuginfo/generic-tuple-style-enum.rs index 719b5c6161f00..de8681bc53618 100644 --- a/tests/debuginfo/generic-tuple-style-enum.rs +++ b/tests/debuginfo/generic-tuple-style-enum.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/include_string.rs b/tests/debuginfo/include_string.rs index 4ec23b68262a2..565bd09f89e98 100644 --- a/tests/debuginfo/include_string.rs +++ b/tests/debuginfo/include_string.rs @@ -3,6 +3,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run // gdb-command:print string1.length // gdb-check:$1 = 48 diff --git a/tests/debuginfo/issue-57822.rs b/tests/debuginfo/issue-57822.rs index ba4e01196a4cb..59c0759737dd0 100644 --- a/tests/debuginfo/issue-57822.rs +++ b/tests/debuginfo/issue-57822.rs @@ -4,6 +4,7 @@ //@ min-lldb-version: 1800 //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-for-loop.rs b/tests/debuginfo/lexical-scope-in-for-loop.rs index f591f48ad59d9..c2e97ad469ef2 100644 --- a/tests/debuginfo/lexical-scope-in-for-loop.rs +++ b/tests/debuginfo/lexical-scope-in-for-loop.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-if-let.rs b/tests/debuginfo/lexical-scope-in-if-let.rs index b2c7790eab23a..3bc0c231b4d39 100644 --- a/tests/debuginfo/lexical-scope-in-if-let.rs +++ b/tests/debuginfo/lexical-scope-in-if-let.rs @@ -1,4 +1,5 @@ //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS ================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-if.rs b/tests/debuginfo/lexical-scope-in-if.rs index 2b3a4ee5fc4a4..622188269307a 100644 --- a/tests/debuginfo/lexical-scope-in-if.rs +++ b/tests/debuginfo/lexical-scope-in-if.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-match.rs b/tests/debuginfo/lexical-scope-in-match.rs index 0e369c6ca1645..329d959bc8488 100644 --- a/tests/debuginfo/lexical-scope-in-match.rs +++ b/tests/debuginfo/lexical-scope-in-match.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-stack-closure.rs b/tests/debuginfo/lexical-scope-in-stack-closure.rs index 483d5dda86ce5..b6abf507f26b5 100644 --- a/tests/debuginfo/lexical-scope-in-stack-closure.rs +++ b/tests/debuginfo/lexical-scope-in-stack-closure.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-unconditional-loop.rs b/tests/debuginfo/lexical-scope-in-unconditional-loop.rs index 129d0b8c83deb..270fbcf6ebf55 100644 --- a/tests/debuginfo/lexical-scope-in-unconditional-loop.rs +++ b/tests/debuginfo/lexical-scope-in-unconditional-loop.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-unique-closure.rs b/tests/debuginfo/lexical-scope-in-unique-closure.rs index 93bea18d7cd9b..b4909a97bea50 100644 --- a/tests/debuginfo/lexical-scope-in-unique-closure.rs +++ b/tests/debuginfo/lexical-scope-in-unique-closure.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-in-while.rs b/tests/debuginfo/lexical-scope-in-while.rs index 5fe76851bd7f0..e8e66d2835cd8 100644 --- a/tests/debuginfo/lexical-scope-in-while.rs +++ b/tests/debuginfo/lexical-scope-in-while.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scope-with-macro.rs b/tests/debuginfo/lexical-scope-with-macro.rs index efec9a3b1ce7d..8c302a94ea2aa 100644 --- a/tests/debuginfo/lexical-scope-with-macro.rs +++ b/tests/debuginfo/lexical-scope-with-macro.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/lexical-scopes-in-block-expression.rs b/tests/debuginfo/lexical-scopes-in-block-expression.rs index bec69ec87e849..9a7fba30397e1 100644 --- a/tests/debuginfo/lexical-scopes-in-block-expression.rs +++ b/tests/debuginfo/lexical-scopes-in-block-expression.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/limited-debuginfo.rs b/tests/debuginfo/limited-debuginfo.rs index c3b516460aa34..136953641a4da 100644 --- a/tests/debuginfo/limited-debuginfo.rs +++ b/tests/debuginfo/limited-debuginfo.rs @@ -2,6 +2,7 @@ //@ compile-flags:-C debuginfo=1 //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // Make sure functions have proper names // gdb-command:info functions diff --git a/tests/debuginfo/method-on-generic-struct.rs b/tests/debuginfo/method-on-generic-struct.rs index 5da952fa4e106..b9627f27b9123 100644 --- a/tests/debuginfo/method-on-generic-struct.rs +++ b/tests/debuginfo/method-on-generic-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/method-on-struct.rs b/tests/debuginfo/method-on-struct.rs index 83badd8dbf01f..4ccb55d3704b0 100644 --- a/tests/debuginfo/method-on-struct.rs +++ b/tests/debuginfo/method-on-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/method-on-trait.rs b/tests/debuginfo/method-on-trait.rs index c91b255bd6afe..baf1a8567bbf3 100644 --- a/tests/debuginfo/method-on-trait.rs +++ b/tests/debuginfo/method-on-trait.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/method-on-tuple-struct.rs b/tests/debuginfo/method-on-tuple-struct.rs index 7e6e724d42eb5..077c0bc13d90b 100644 --- a/tests/debuginfo/method-on-tuple-struct.rs +++ b/tests/debuginfo/method-on-tuple-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/multi-cgu.rs b/tests/debuginfo/multi-cgu.rs index ca4146da405e5..e3fa68d776598 100644 --- a/tests/debuginfo/multi-cgu.rs +++ b/tests/debuginfo/multi-cgu.rs @@ -3,6 +3,7 @@ //@ compile-flags:-g -Ccodegen-units=2 //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =============================================================== diff --git a/tests/debuginfo/multiple-functions-equal-var-names.rs b/tests/debuginfo/multiple-functions-equal-var-names.rs index 2bc40b87e6f5e..9df1fe1b9ca18 100644 --- a/tests/debuginfo/multiple-functions-equal-var-names.rs +++ b/tests/debuginfo/multiple-functions-equal-var-names.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/multiple-functions.rs b/tests/debuginfo/multiple-functions.rs index 5469408c78fb0..a5fe01f9dd2c1 100644 --- a/tests/debuginfo/multiple-functions.rs +++ b/tests/debuginfo/multiple-functions.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/name-shadowing-and-scope-nesting.rs b/tests/debuginfo/name-shadowing-and-scope-nesting.rs index e8d85473d8639..9a3393a71e833 100644 --- a/tests/debuginfo/name-shadowing-and-scope-nesting.rs +++ b/tests/debuginfo/name-shadowing-and-scope-nesting.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/no_mangle-info.rs b/tests/debuginfo/no_mangle-info.rs index 06c65a71b2e91..d1daef669cee3 100644 --- a/tests/debuginfo/no_mangle-info.rs +++ b/tests/debuginfo/no_mangle-info.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ min-gdb-version: 10.1 +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== // gdb-command:run diff --git a/tests/debuginfo/numeric-types.rs b/tests/debuginfo/numeric-types.rs index 9a0fd01d7e236..9f7ef5c537d22 100644 --- a/tests/debuginfo/numeric-types.rs +++ b/tests/debuginfo/numeric-types.rs @@ -9,6 +9,7 @@ // unblock the tree. //@ only-64bit //@ min-cdb-version: 10.0.26100.2161 +//@ ignore-backends: gcc // Tests the visualizations for `NonZero`, `Wrapping` and // `Atomic{Bool,I8,I16,I32,I64,Isize,U8,U16,U32,U64,Usize}` located in `libcore.natvis`. diff --git a/tests/debuginfo/opt/dead_refs.rs b/tests/debuginfo/opt/dead_refs.rs new file mode 100644 index 0000000000000..61e741573346e --- /dev/null +++ b/tests/debuginfo/opt/dead_refs.rs @@ -0,0 +1,50 @@ +//@ min-lldb-version: 1800 +//@ min-gdb-version: 13.0 +//@ compile-flags: -g -Copt-level=3 +//@ disable-gdb-pretty-printers + +// Checks that we still can access dead variables from debuginfos. + +// === GDB TESTS =================================================================================== + +// gdb-command:run +// gdb-command:print *ref_v0 +// gdb-check:$1 = 0 + +// gdb-command:print *ref_v1 +// gdb-check:$2 = 1 + +// gdb-command:print *ref_v2 +// gdb-check:$3 = 2 + +// === LLDB TESTS ================================================================================== + +// lldb-command:run +// lldb-command:v *ref_v0 +// lldb-check:[...] 0 + +// lldb-command:v *ref_v1 +// lldb-check:[...] 1 + +// lldb-command:v *ref_v2 +// lldb-check:[...] 2 + +#![allow(unused_variables)] + +use std::hint::black_box; + +pub struct Foo(i32, i64, i32); + +#[inline(never)] +#[no_mangle] +fn test_ref(ref_foo: &Foo) -> i32 { + let ref_v0 = &ref_foo.0; + let ref_v1 = &ref_foo.1; + let ref_v2 = &ref_foo.2; + ref_foo.0 // #break +} + +fn main() { + let foo = black_box(Foo(0, 1, 2)); + black_box(test_ref(&foo)); +} diff --git a/tests/debuginfo/packed-struct-with-destructor.rs b/tests/debuginfo/packed-struct-with-destructor.rs index 0c5725ca25cd6..2150ec53501c9 100644 --- a/tests/debuginfo/packed-struct-with-destructor.rs +++ b/tests/debuginfo/packed-struct-with-destructor.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/packed-struct.rs b/tests/debuginfo/packed-struct.rs index 3bc39adee831d..427289c847747 100644 --- a/tests/debuginfo/packed-struct.rs +++ b/tests/debuginfo/packed-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/pretty-huge-vec.rs b/tests/debuginfo/pretty-huge-vec.rs index 6938158e365e5..c73491bf28066 100644 --- a/tests/debuginfo/pretty-huge-vec.rs +++ b/tests/debuginfo/pretty-huge-vec.rs @@ -2,6 +2,7 @@ //@ ignore-android: FIXME(#10381) //@ ignore-aix: FIXME(#137965) //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/pretty-slices.rs b/tests/debuginfo/pretty-slices.rs index f1aad836434ed..fd347a4eb933d 100644 --- a/tests/debuginfo/pretty-slices.rs +++ b/tests/debuginfo/pretty-slices.rs @@ -1,6 +1,7 @@ //@ ignore-android: FIXME(#10381) //@ ignore-windows-gnu: #128981 //@ compile-flags:-g +//@ ignore-backends: gcc // gdb-command: run diff --git a/tests/debuginfo/pretty-std-collections.rs b/tests/debuginfo/pretty-std-collections.rs index 5e133ee718e2e..568ca0fd23039 100644 --- a/tests/debuginfo/pretty-std-collections.rs +++ b/tests/debuginfo/pretty-std-collections.rs @@ -1,6 +1,7 @@ //@ ignore-android: FIXME(#10381) //@ ignore-windows-gnu: #128981 //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/pretty-std.rs b/tests/debuginfo/pretty-std.rs index 53835d41be24e..2620557eaf991 100644 --- a/tests/debuginfo/pretty-std.rs +++ b/tests/debuginfo/pretty-std.rs @@ -4,6 +4,7 @@ //@ compile-flags:-g //@ min-lldb-version: 1800 //@ min-cdb-version: 10.0.18317.1001 +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/pretty-uninitialized-vec.rs b/tests/debuginfo/pretty-uninitialized-vec.rs index cea2f26ef58f2..e5a2df5c9345d 100644 --- a/tests/debuginfo/pretty-uninitialized-vec.rs +++ b/tests/debuginfo/pretty-uninitialized-vec.rs @@ -1,6 +1,7 @@ //@ ignore-windows-gnu: #128981 //@ ignore-android: FIXME(#10381) //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/rc_arc.rs b/tests/debuginfo/rc_arc.rs index f636c60702cde..c439ff7484fe3 100644 --- a/tests/debuginfo/rc_arc.rs +++ b/tests/debuginfo/rc_arc.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ min-cdb-version: 10.0.18317.1001 +//@ ignore-backends: gcc // === GDB TESTS ================================================================================== diff --git a/tests/debuginfo/recursive-struct.rs b/tests/debuginfo/recursive-struct.rs index 427a7100a4f78..723ab06a8b26b 100644 --- a/tests/debuginfo/recursive-struct.rs +++ b/tests/debuginfo/recursive-struct.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run diff --git a/tests/debuginfo/reference-debuginfo.rs b/tests/debuginfo/reference-debuginfo.rs index 242da1dd65410..75acbc131a8ce 100644 --- a/tests/debuginfo/reference-debuginfo.rs +++ b/tests/debuginfo/reference-debuginfo.rs @@ -4,6 +4,7 @@ // //@ compile-flags:-g -Zmir-enable-passes=+ReferencePropagation,-ConstDebugInfo //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/regression-bad-location-list-67992.rs b/tests/debuginfo/regression-bad-location-list-67992.rs index 0ec474b5b5af9..a5617a23c9311 100644 --- a/tests/debuginfo/regression-bad-location-list-67992.rs +++ b/tests/debuginfo/regression-bad-location-list-67992.rs @@ -1,4 +1,5 @@ //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/self-in-default-method.rs b/tests/debuginfo/self-in-default-method.rs index 4297129e0cf8c..6e08ef4cd83a1 100644 --- a/tests/debuginfo/self-in-default-method.rs +++ b/tests/debuginfo/self-in-default-method.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/self-in-generic-default-method.rs b/tests/debuginfo/self-in-generic-default-method.rs index e7ffa05f4188e..a06731a54bd22 100644 --- a/tests/debuginfo/self-in-generic-default-method.rs +++ b/tests/debuginfo/self-in-generic-default-method.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/shadowed-argument.rs b/tests/debuginfo/shadowed-argument.rs index 3a0f0ad17a819..7a7e54545b883 100644 --- a/tests/debuginfo/shadowed-argument.rs +++ b/tests/debuginfo/shadowed-argument.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/shadowed-variable.rs b/tests/debuginfo/shadowed-variable.rs index 6a658a7c49430..c55f22df0037c 100644 --- a/tests/debuginfo/shadowed-variable.rs +++ b/tests/debuginfo/shadowed-variable.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/simd.rs b/tests/debuginfo/simd.rs index 43cd7130b252d..888a78117b54f 100644 --- a/tests/debuginfo/simd.rs +++ b/tests/debuginfo/simd.rs @@ -8,6 +8,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run // gdb-command:print vi8x16 diff --git a/tests/debuginfo/simple-lexical-scope.rs b/tests/debuginfo/simple-lexical-scope.rs index 64afcf8d61dce..194da9169d9a5 100644 --- a/tests/debuginfo/simple-lexical-scope.rs +++ b/tests/debuginfo/simple-lexical-scope.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/simple-struct.rs b/tests/debuginfo/simple-struct.rs index da09a8a3ce027..665bb2fdb5799 100644 --- a/tests/debuginfo/simple-struct.rs +++ b/tests/debuginfo/simple-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags: -g -Zmir-enable-passes=-CheckAlignment //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/simple-tuple.rs b/tests/debuginfo/simple-tuple.rs index f086472d72569..c1509a8a9b4c6 100644 --- a/tests/debuginfo/simple-tuple.rs +++ b/tests/debuginfo/simple-tuple.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/skip_second_statement.rs b/tests/debuginfo/skip_second_statement.rs index ba182de038543..452b6db3882d9 100644 --- a/tests/debuginfo/skip_second_statement.rs +++ b/tests/debuginfo/skip_second_statement.rs @@ -4,6 +4,7 @@ // Performed step-over and step-into debug stepping through call statements. //@ compile-flags:-g -C collapse-macro-debuginfo=yes +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/skip_second_statement_collapse.rs b/tests/debuginfo/skip_second_statement_collapse.rs index db90cee8bfba8..52a85c5107e48 100644 --- a/tests/debuginfo/skip_second_statement_collapse.rs +++ b/tests/debuginfo/skip_second_statement_collapse.rs @@ -4,6 +4,7 @@ // Performed step-over and step-into debug stepping through call statements. //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/static-method-on-struct-and-enum.rs b/tests/debuginfo/static-method-on-struct-and-enum.rs index 2a3502712de1c..87b959f9df056 100644 --- a/tests/debuginfo/static-method-on-struct-and-enum.rs +++ b/tests/debuginfo/static-method-on-struct-and-enum.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/step-into-match.rs b/tests/debuginfo/step-into-match.rs index d4b7ea201195e..a05ed8653be2b 100644 --- a/tests/debuginfo/step-into-match.rs +++ b/tests/debuginfo/step-into-match.rs @@ -4,6 +4,7 @@ // On Arm64 Windows, stepping at the end of a function on goes to the callsite, not the instruction // after it. //@ ignore-aarch64-pc-windows-msvc: Stepping out of functions behaves differently. +//@ ignore-backends: gcc // === GDB TESTS ============================================================== diff --git a/tests/debuginfo/struct-in-enum.rs b/tests/debuginfo/struct-in-enum.rs index c5a7fb95e1e52..bd61e7cb14377 100644 --- a/tests/debuginfo/struct-in-enum.rs +++ b/tests/debuginfo/struct-in-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/struct-in-struct.rs b/tests/debuginfo/struct-in-struct.rs index c818df31b4b11..4f770e7e56c89 100644 --- a/tests/debuginfo/struct-in-struct.rs +++ b/tests/debuginfo/struct-in-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/struct-style-enum.rs b/tests/debuginfo/struct-style-enum.rs index 1f28fe4fea159..48ef97896ac15 100644 --- a/tests/debuginfo/struct-style-enum.rs +++ b/tests/debuginfo/struct-style-enum.rs @@ -1,6 +1,7 @@ //@ min-lldb-version: 1800 //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/struct-with-destructor.rs b/tests/debuginfo/struct-with-destructor.rs index 4d2ce8ff79db7..2cdac43ba500a 100644 --- a/tests/debuginfo/struct-with-destructor.rs +++ b/tests/debuginfo/struct-with-destructor.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/tuple-in-struct.rs b/tests/debuginfo/tuple-in-struct.rs index bef96fad50c6e..3223532b16a42 100644 --- a/tests/debuginfo/tuple-in-struct.rs +++ b/tests/debuginfo/tuple-in-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // gdb-command:run diff --git a/tests/debuginfo/tuple-in-tuple.rs b/tests/debuginfo/tuple-in-tuple.rs index 7bf97764c5c74..e906cbed67db7 100644 --- a/tests/debuginfo/tuple-in-tuple.rs +++ b/tests/debuginfo/tuple-in-tuple.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/tuple-struct.rs b/tests/debuginfo/tuple-struct.rs index a1bdaf1f3bb3a..44fc862c43c93 100644 --- a/tests/debuginfo/tuple-struct.rs +++ b/tests/debuginfo/tuple-struct.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/tuple-style-enum.rs b/tests/debuginfo/tuple-style-enum.rs index 6113ccc10a1bb..a452c57b30423 100644 --- a/tests/debuginfo/tuple-style-enum.rs +++ b/tests/debuginfo/tuple-style-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/type-names.rs b/tests/debuginfo/type-names.rs index ecf7c597c0c05..341112b0b88e2 100644 --- a/tests/debuginfo/type-names.rs +++ b/tests/debuginfo/type-names.rs @@ -7,6 +7,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS ================================================================================== diff --git a/tests/debuginfo/union-smoke.rs b/tests/debuginfo/union-smoke.rs index bd253794bd852..beaf4c8fa8fe3 100644 --- a/tests/debuginfo/union-smoke.rs +++ b/tests/debuginfo/union-smoke.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/unique-enum.rs b/tests/debuginfo/unique-enum.rs index e5a9c55013560..a9b928456e936 100644 --- a/tests/debuginfo/unique-enum.rs +++ b/tests/debuginfo/unique-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/unit-type.rs b/tests/debuginfo/unit-type.rs index 0ffa2fe490a5e..ce2a39521d905 100644 --- a/tests/debuginfo/unit-type.rs +++ b/tests/debuginfo/unit-type.rs @@ -2,6 +2,7 @@ // FIXME(jieyouxu): triple check if this works in CI //@ min-cdb-version: 10.0.26100.2161 +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs index e34eaaaacb979..eb0fb8193bf75 100644 --- a/tests/debuginfo/unsized.rs +++ b/tests/debuginfo/unsized.rs @@ -1,6 +1,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers //@ ignore-gdb-version: 13.1 - 99.0 +//@ ignore-backends: gcc // ^ https://sourceware.org/bugzilla/show_bug.cgi?id=30330 // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/var-captured-in-nested-closure.rs b/tests/debuginfo/var-captured-in-nested-closure.rs index 1795a352802fd..0343aea309d52 100644 --- a/tests/debuginfo/var-captured-in-nested-closure.rs +++ b/tests/debuginfo/var-captured-in-nested-closure.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/var-captured-in-sendable-closure.rs b/tests/debuginfo/var-captured-in-sendable-closure.rs index 2b0d4bb430a10..ad6aa5fb9c747 100644 --- a/tests/debuginfo/var-captured-in-sendable-closure.rs +++ b/tests/debuginfo/var-captured-in-sendable-closure.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/var-captured-in-stack-closure.rs b/tests/debuginfo/var-captured-in-stack-closure.rs index 7fda71c2297bf..cc7e2eff81b47 100644 --- a/tests/debuginfo/var-captured-in-stack-closure.rs +++ b/tests/debuginfo/var-captured-in-stack-closure.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/vec-slices.rs b/tests/debuginfo/vec-slices.rs index 2a4e413612fcc..7ed6b0cb66401 100644 --- a/tests/debuginfo/vec-slices.rs +++ b/tests/debuginfo/vec-slices.rs @@ -3,6 +3,7 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/vec.rs b/tests/debuginfo/vec.rs index fd75e7005af54..c0e9f802f1e3b 100644 --- a/tests/debuginfo/vec.rs +++ b/tests/debuginfo/vec.rs @@ -1,5 +1,6 @@ //@ compile-flags:-g //@ disable-gdb-pretty-printers +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/debuginfo/zst-interferes-with-prologue.rs b/tests/debuginfo/zst-interferes-with-prologue.rs index 09041a3bb72c7..4d87df1abe7a7 100644 --- a/tests/debuginfo/zst-interferes-with-prologue.rs +++ b/tests/debuginfo/zst-interferes-with-prologue.rs @@ -1,6 +1,7 @@ //@ min-lldb-version: 310 //@ compile-flags:-g +//@ ignore-backends: gcc // === GDB TESTS =================================================================================== diff --git a/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs b/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs index 65d363b35a673..0367af8d53b8d 100644 --- a/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs +++ b/tests/incremental/add_private_fn_at_krate_root_cc/struct_point.rs @@ -6,6 +6,7 @@ //@ compile-flags: -Z query-dep-graph //@ aux-build:point.rs //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/incremental/async-lifetimes.rs b/tests/incremental/async-lifetimes.rs index 8d55e7293df8b..f12f995193878 100644 --- a/tests/incremental/async-lifetimes.rs +++ b/tests/incremental/async-lifetimes.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 //@ edition:2021 +//@ ignore-backends: gcc // See https://github.com/rust-lang/rust/issues/98890 diff --git a/tests/incremental/callee_caller_cross_crate/b.rs b/tests/incremental/callee_caller_cross_crate/b.rs index b9012ecf7f77d..78f3d8b3958f7 100644 --- a/tests/incremental/callee_caller_cross_crate/b.rs +++ b/tests/incremental/callee_caller_cross_crate/b.rs @@ -1,6 +1,7 @@ //@ aux-build:a.rs //@ revisions:rpass1 rpass2 //@ compile-flags:-Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/change_add_field/struct_point.rs b/tests/incremental/change_add_field/struct_point.rs index 8ff992771fdc6..fb363c9ce496f 100644 --- a/tests/incremental/change_add_field/struct_point.rs +++ b/tests/incremental/change_add_field/struct_point.rs @@ -6,6 +6,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs index abca8de47198c..4fd0c345aad21 100644 --- a/tests/incremental/change_crate_dep_kind.rs +++ b/tests/incremental/change_crate_dep_kind.rs @@ -6,6 +6,7 @@ //@ compile-flags: -Z query-dep-graph -Cpanic=unwind //@ needs-unwind //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![feature(panic_unwind)] diff --git a/tests/incremental/change_crate_order/main.rs b/tests/incremental/change_crate_order/main.rs index 23f1782578e9d..38a2541a76b52 100644 --- a/tests/incremental/change_crate_order/main.rs +++ b/tests/incremental/change_crate_order/main.rs @@ -1,6 +1,7 @@ //@ aux-build:a.rs //@ aux-build:b.rs //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/change_implementation_cross_crate/main.rs b/tests/incremental/change_implementation_cross_crate/main.rs index 9919b0d01cb69..5c3b0815115c9 100644 --- a/tests/incremental/change_implementation_cross_crate/main.rs +++ b/tests/incremental/change_implementation_cross_crate/main.rs @@ -4,6 +4,7 @@ //@ revisions: rpass1 rpass2 //@ aux-build: a.rs //@ compile-flags: -Zquery-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "bin"] diff --git a/tests/incremental/change_name_of_static_in_fn.rs b/tests/incremental/change_name_of_static_in_fn.rs index 8081945018668..c6160efed7b94 100644 --- a/tests/incremental/change_name_of_static_in_fn.rs +++ b/tests/incremental/change_name_of_static_in_fn.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 rpass3 +//@ ignore-backends: gcc // See issue #57692. diff --git a/tests/incremental/change_private_fn/struct_point.rs b/tests/incremental/change_private_fn/struct_point.rs index a4c0a8db4098e..cce26fa7a3e6e 100644 --- a/tests/incremental/change_private_fn/struct_point.rs +++ b/tests/incremental/change_private_fn/struct_point.rs @@ -4,6 +4,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/incremental/change_private_fn_cc/struct_point.rs b/tests/incremental/change_private_fn_cc/struct_point.rs index 6262e32a807d8..87392ca857ed7 100644 --- a/tests/incremental/change_private_fn_cc/struct_point.rs +++ b/tests/incremental/change_private_fn_cc/struct_point.rs @@ -5,6 +5,7 @@ //@ compile-flags: -Z query-dep-graph //@ aux-build:point.rs //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/tests/incremental/change_private_impl_method/struct_point.rs b/tests/incremental/change_private_impl_method/struct_point.rs index 953d581015108..dc0ba82c0a311 100644 --- a/tests/incremental/change_private_impl_method/struct_point.rs +++ b/tests/incremental/change_private_impl_method/struct_point.rs @@ -4,6 +4,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] diff --git a/tests/incremental/change_private_impl_method_cc/struct_point.rs b/tests/incremental/change_private_impl_method_cc/struct_point.rs index 42cc41da4c8bc..eb51af7209495 100644 --- a/tests/incremental/change_private_impl_method_cc/struct_point.rs +++ b/tests/incremental/change_private_impl_method_cc/struct_point.rs @@ -5,6 +5,7 @@ //@ compile-flags: -Z query-dep-graph //@ aux-build:point.rs //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/tests/incremental/change_pub_inherent_method_body/struct_point.rs b/tests/incremental/change_pub_inherent_method_body/struct_point.rs index e112b25df5c53..b8e06d070a3c7 100644 --- a/tests/incremental/change_pub_inherent_method_body/struct_point.rs +++ b/tests/incremental/change_pub_inherent_method_body/struct_point.rs @@ -3,6 +3,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs index d67011f1e88cb..3672ec268010e 100644 --- a/tests/incremental/change_pub_inherent_method_sig/struct_point.rs +++ b/tests/incremental/change_pub_inherent_method_sig/struct_point.rs @@ -3,6 +3,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/tests/incremental/change_symbol_export_status.rs b/tests/incremental/change_symbol_export_status.rs index 5fc6afa741195..37f8b9b52e5f9 100644 --- a/tests/incremental/change_symbol_export_status.rs +++ b/tests/incremental/change_symbol_export_status.rs @@ -2,6 +2,7 @@ //@ compile-flags: -Zquery-dep-graph //@ [rpass1]compile-flags: -Zincremental-ignore-spans //@ [rpass2]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![rustc_partition_reused(module = "change_symbol_export_status-mod1", cfg = "rpass2")] diff --git a/tests/incremental/commandline-args.rs b/tests/incremental/commandline-args.rs index f7aabe1e6d009..eb7c8b6daf05d 100644 --- a/tests/incremental/commandline-args.rs +++ b/tests/incremental/commandline-args.rs @@ -18,6 +18,7 @@ //@[rpass2] compile-flags: -C debuginfo=2 //@[rpass3] compile-flags: -C debuginfo=2 --diagnostic-width=80 //@[rpass4] compile-flags: -C debuginfo=2 --diagnostic-width=80 --remap-path-prefix=/home/bors/r=src +//@ ignore-backends: gcc pub fn main() { // empty diff --git a/tests/incremental/const-generics/change-const-param-gat.rs b/tests/incremental/const-generics/change-const-param-gat.rs index 9fdac01429355..0aa628f4bd6b8 100644 --- a/tests/incremental/const-generics/change-const-param-gat.rs +++ b/tests/incremental/const-generics/change-const-param-gat.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 rpass3 //@ compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![feature(generic_associated_types)] // This test unsures that with_opt_const_param returns the diff --git a/tests/incremental/const-generics/change-const-param-type.rs b/tests/incremental/const-generics/change-const-param-type.rs index 989ad56990db6..2dc1194f5128c 100644 --- a/tests/incremental/const-generics/change-const-param-type.rs +++ b/tests/incremental/const-generics/change-const-param-type.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 rpass3 //@ compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc enum Foo { Variant, diff --git a/tests/incremental/crate_hash_reorder.rs b/tests/incremental/crate_hash_reorder.rs index bd26d604a8255..07b38014ff855 100644 --- a/tests/incremental/crate_hash_reorder.rs +++ b/tests/incremental/crate_hash_reorder.rs @@ -2,6 +2,7 @@ //@ revisions:rpass1 rpass2 rpass3 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/decl_macro.rs b/tests/incremental/decl_macro.rs index 74810ae422749..3ddf86a068f4d 100644 --- a/tests/incremental/decl_macro.rs +++ b/tests/incremental/decl_macro.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc // issue#112680 diff --git a/tests/incremental/dirty_clean.rs b/tests/incremental/dirty_clean.rs index 24aedb011c6b9..1188b46fa0ad4 100644 --- a/tests/incremental/dirty_clean.rs +++ b/tests/incremental/dirty_clean.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 cfail2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/env/env_macro.rs b/tests/incremental/env/env_macro.rs index 0c026328874dd..8d6bd2416b1fe 100644 --- a/tests/incremental/env/env_macro.rs +++ b/tests/incremental/env/env_macro.rs @@ -10,6 +10,7 @@ //@ [rpass3]rustc-env:EXAMPLE_ENV=two //@ [rpass3]exec-env:EXAMPLE_ENV=two //@ [cfail4]unset-rustc-env:EXAMPLE_ENV +//@ ignore-backends: gcc fn main() { assert_eq!(env!("EXAMPLE_ENV"), std::env::var("EXAMPLE_ENV").unwrap()); diff --git a/tests/incremental/env/option_env_macro.rs b/tests/incremental/env/option_env_macro.rs index 44c3bfd69e050..3b9110a5f4e08 100644 --- a/tests/incremental/env/option_env_macro.rs +++ b/tests/incremental/env/option_env_macro.rs @@ -12,6 +12,7 @@ //@ [rpass3]exec-env:EXAMPLE_ENV=two //@ [rpass4]unset-rustc-env:EXAMPLE_ENV //@ [rpass4]unset-exec-env:EXAMPLE_ENV +//@ ignore-backends: gcc fn main() { assert_eq!(option_env!("EXAMPLE_ENV"), std::env::var("EXAMPLE_ENV").ok().as_deref()); diff --git a/tests/incremental/extern_static/issue-49153.rs b/tests/incremental/extern_static/issue-49153.rs index 72340173b5ca1..386c175be5239 100644 --- a/tests/incremental/extern_static/issue-49153.rs +++ b/tests/incremental/extern_static/issue-49153.rs @@ -1,6 +1,7 @@ // https://github.com/rust-lang/rust/issues/49153 //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc extern "C" { pub static __ImageBase: u8; diff --git a/tests/incremental/hash-module-order.rs b/tests/incremental/hash-module-order.rs index c29e1e5b64c91..5261965e8f3f4 100644 --- a/tests/incremental/hash-module-order.rs +++ b/tests/incremental/hash-module-order.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 //@ compile-flags: -Z incremental-ignore-spans -Z query-dep-graph +//@ ignore-backends: gcc // Tests that module hashing depends on the order of the items // (since the order is exposed through `Mod.item_ids`). diff --git a/tests/incremental/hashes/call_expressions.rs b/tests/incremental/hashes/call_expressions.rs index 71423ef6aff66..d58bf0416c6f2 100644 --- a/tests/incremental/hashes/call_expressions.rs +++ b/tests/incremental/hashes/call_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] diff --git a/tests/incremental/hashes/closure_expressions.rs b/tests/incremental/hashes/closure_expressions.rs index e548e0b6ddc3f..3cda661834f52 100644 --- a/tests/incremental/hashes/closure_expressions.rs +++ b/tests/incremental/hashes/closure_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/consts.rs b/tests/incremental/hashes/consts.rs index bd5cc89caa865..b60dce16c37e7 100644 --- a/tests/incremental/hashes/consts.rs +++ b/tests/incremental/hashes/consts.rs @@ -8,6 +8,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -O +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs index d839dabf293af..dee485681e447 100644 --- a/tests/incremental/hashes/enum_constructors.rs +++ b/tests/incremental/hashes/enum_constructors.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/enum_defs.rs b/tests/incremental/hashes/enum_defs.rs index bc1a2a31e97a9..1f12c020116eb 100644 --- a/tests/incremental/hashes/enum_defs.rs +++ b/tests/incremental/hashes/enum_defs.rs @@ -16,6 +16,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/exported_vs_not.rs b/tests/incremental/hashes/exported_vs_not.rs index 1bd7756c1c6e5..9ac86f39bd1a9 100644 --- a/tests/incremental/hashes/exported_vs_not.rs +++ b/tests/incremental/hashes/exported_vs_not.rs @@ -4,6 +4,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/extern_mods.rs b/tests/incremental/hashes/extern_mods.rs index c26fc90dd01e3..0bda42fac8b85 100644 --- a/tests/incremental/hashes/extern_mods.rs +++ b/tests/incremental/hashes/extern_mods.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/for_loops.rs b/tests/incremental/hashes/for_loops.rs index b827ad9cc6f89..24717e0faaf54 100644 --- a/tests/incremental/hashes/for_loops.rs +++ b/tests/incremental/hashes/for_loops.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs index 016a1813babd7..e58ee1a6d4e4b 100644 --- a/tests/incremental/hashes/function_interfaces.rs +++ b/tests/incremental/hashes/function_interfaces.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(linkage)] diff --git a/tests/incremental/hashes/if_expressions.rs b/tests/incremental/hashes/if_expressions.rs index a21625c4f4ed8..6a241692977f4 100644 --- a/tests/incremental/hashes/if_expressions.rs +++ b/tests/incremental/hashes/if_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/indexing_expressions.rs b/tests/incremental/hashes/indexing_expressions.rs index 1b90483c50c3b..bfc64c904039a 100644 --- a/tests/incremental/hashes/indexing_expressions.rs +++ b/tests/incremental/hashes/indexing_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs index 044c3d2b86c13..66d6c2b7246ca 100644 --- a/tests/incremental/hashes/inherent_impls.rs +++ b/tests/incremental/hashes/inherent_impls.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] diff --git a/tests/incremental/hashes/inline_asm.rs b/tests/incremental/hashes/inline_asm.rs index 105ca76113565..3453259e5b2f4 100644 --- a/tests/incremental/hashes/inline_asm.rs +++ b/tests/incremental/hashes/inline_asm.rs @@ -12,6 +12,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs index 86578855699b2..b2e89380acb33 100644 --- a/tests/incremental/hashes/let_expressions.rs +++ b/tests/incremental/hashes/let_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/loop_expressions.rs b/tests/incremental/hashes/loop_expressions.rs index 631699d3d6874..a8b89217b949d 100644 --- a/tests/incremental/hashes/loop_expressions.rs +++ b/tests/incremental/hashes/loop_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/match_expressions.rs b/tests/incremental/hashes/match_expressions.rs index 9ed5b55fb2505..0c7f847932b8e 100644 --- a/tests/incremental/hashes/match_expressions.rs +++ b/tests/incremental/hashes/match_expressions.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/panic_exprs.rs b/tests/incremental/hashes/panic_exprs.rs index 509e111edc7ac..e3d6f8a211ecf 100644 --- a/tests/incremental/hashes/panic_exprs.rs +++ b/tests/incremental/hashes/panic_exprs.rs @@ -11,6 +11,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -C debug-assertions -O +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/statics.rs b/tests/incremental/hashes/statics.rs index 9ea21d84ba154..cd394ed866e9f 100644 --- a/tests/incremental/hashes/statics.rs +++ b/tests/incremental/hashes/statics.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/struct_constructors.rs b/tests/incremental/hashes/struct_constructors.rs index 31c549c6e7a90..da7abe049d982 100644 --- a/tests/incremental/hashes/struct_constructors.rs +++ b/tests/incremental/hashes/struct_constructors.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/struct_defs.rs b/tests/incremental/hashes/struct_defs.rs index 06ea087339790..c7582deb76aed 100644 --- a/tests/incremental/hashes/struct_defs.rs +++ b/tests/incremental/hashes/struct_defs.rs @@ -16,6 +16,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/trait_defs.rs b/tests/incremental/hashes/trait_defs.rs index 50b56441cca50..13334a08cae8b 100644 --- a/tests/incremental/hashes/trait_defs.rs +++ b/tests/incremental/hashes/trait_defs.rs @@ -16,6 +16,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/trait_impls.rs b/tests/incremental/hashes/trait_impls.rs index a89b5b3e78298..03ca672af1316 100644 --- a/tests/incremental/hashes/trait_impls.rs +++ b/tests/incremental/hashes/trait_impls.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/type_defs.rs b/tests/incremental/hashes/type_defs.rs index 137bffd9aeb62..b0cb2a6aa47d9 100644 --- a/tests/incremental/hashes/type_defs.rs +++ b/tests/incremental/hashes/type_defs.rs @@ -13,6 +13,7 @@ //@ build-pass (FIXME(62277): could be check-pass?) //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -O +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/unary_and_binary_exprs.rs b/tests/incremental/hashes/unary_and_binary_exprs.rs index d0b502845071c..fec167c2604cc 100644 --- a/tests/incremental/hashes/unary_and_binary_exprs.rs +++ b/tests/incremental/hashes/unary_and_binary_exprs.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/while_let_loops.rs b/tests/incremental/hashes/while_let_loops.rs index 7a7bcb7d039d9..1071ee86b1fb8 100644 --- a/tests/incremental/hashes/while_let_loops.rs +++ b/tests/incremental/hashes/while_let_loops.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hashes/while_loops.rs b/tests/incremental/hashes/while_loops.rs index dc343c3cbfaef..57287cbcdcee5 100644 --- a/tests/incremental/hashes/while_loops.rs +++ b/tests/incremental/hashes/while_loops.rs @@ -11,6 +11,7 @@ //@ [cfail1]compile-flags: -Zincremental-ignore-spans //@ [cfail2]compile-flags: -Zincremental-ignore-spans //@ [cfail3]compile-flags: -Zincremental-ignore-spans +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hello_world.rs b/tests/incremental/hello_world.rs index ab1f9dbf1840c..d6d9b6b598c22 100644 --- a/tests/incremental/hello_world.rs +++ b/tests/incremental/hello_world.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/hygiene/load_cached_hygiene.rs b/tests/incremental/hygiene/load_cached_hygiene.rs index 101d280cd492e..84f91e7ecdec5 100644 --- a/tests/incremental/hygiene/load_cached_hygiene.rs +++ b/tests/incremental/hygiene/load_cached_hygiene.rs @@ -1,6 +1,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph //@ aux-build:cached_hygiene.rs +//@ ignore-backends: gcc // This tests the following scenario // 1. A foreign crate is compiled with incremental compilation. diff --git a/tests/incremental/ich_method_call_trait_scope.rs b/tests/incremental/ich_method_call_trait_scope.rs index a4c6558602f7b..28234ca60d8e9 100644 --- a/tests/incremental/ich_method_call_trait_scope.rs +++ b/tests/incremental/ich_method_call_trait_scope.rs @@ -3,6 +3,7 @@ //@ revisions: rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/ich_nested_items.rs b/tests/incremental/ich_nested_items.rs index c2a041ba268c4..fa3ebcfa8e039 100644 --- a/tests/incremental/ich_nested_items.rs +++ b/tests/incremental/ich_nested_items.rs @@ -4,6 +4,7 @@ //@ revisions: cfail1 cfail2 //@ build-pass (FIXME(62277): could be check-pass?) //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(rustc_attrs)] diff --git a/tests/incremental/ich_resolve_results.rs b/tests/incremental/ich_resolve_results.rs index c5b2b66fef9f8..41c98bd389121 100644 --- a/tests/incremental/ich_resolve_results.rs +++ b/tests/incremental/ich_resolve_results.rs @@ -3,6 +3,7 @@ //@ revisions: rpass1 rpass2 rpass3 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/incremental_proc_macro.rs b/tests/incremental/incremental_proc_macro.rs index fc32aad5645ce..19ae746fc2729 100644 --- a/tests/incremental/incremental_proc_macro.rs +++ b/tests/incremental/incremental_proc_macro.rs @@ -1,6 +1,7 @@ //@ proc-macro: incremental_proc_macro_aux.rs //@ revisions: cfail1 cfail2 //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc // This test makes sure that we still find the proc-macro registrar function // when we compile proc-macros incrementally (see #47292). diff --git a/tests/incremental/inlined_hir_34991/main.rs b/tests/incremental/inlined_hir_34991/main.rs index 7754add917d22..1d4740bd16080 100644 --- a/tests/incremental/inlined_hir_34991/main.rs +++ b/tests/incremental/inlined_hir_34991/main.rs @@ -5,6 +5,7 @@ // libstd), and we can't hash a HIR node from std. //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/issue-100521-change-struct-name-assocty.rs b/tests/incremental/issue-100521-change-struct-name-assocty.rs index 0c1938beef27b..80f96ca7144d4 100644 --- a/tests/incremental/issue-100521-change-struct-name-assocty.rs +++ b/tests/incremental/issue-100521-change-struct-name-assocty.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc pub fn foo() { bar(); diff --git a/tests/incremental/issue-108481-feed-eval-always.rs b/tests/incremental/issue-108481-feed-eval-always.rs index ef2e2fb59c2d1..e2229eeed0f1f 100644 --- a/tests/incremental/issue-108481-feed-eval-always.rs +++ b/tests/incremental/issue-108481-feed-eval-always.rs @@ -1,4 +1,5 @@ //@ revisions: cpass1 cpass2 +//@ ignore-backends: gcc #![crate_type = "rlib"] diff --git a/tests/incremental/issue-110457-same-span-closures/main.rs b/tests/incremental/issue-110457-same-span-closures/main.rs index 6a5e4b315ce3e..b89ba9fb651af 100644 --- a/tests/incremental/issue-110457-same-span-closures/main.rs +++ b/tests/incremental/issue-110457-same-span-closures/main.rs @@ -1,5 +1,6 @@ //@ proc-macro: egui_inspect_derive.rs //@ revisions: cpass1 cpass2 +//@ ignore-backends: gcc extern crate egui_inspect_derive; diff --git a/tests/incremental/issue-35593.rs b/tests/incremental/issue-35593.rs index 5e5235dc2c4c1..522c88b9894ad 100644 --- a/tests/incremental/issue-35593.rs +++ b/tests/incremental/issue-35593.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![rustc_partition_reused(module="issue_35593", cfg="rpass2")] diff --git a/tests/incremental/issue-38222.rs b/tests/incremental/issue-38222.rs index e45a16f99b336..0aecd1e1f98a9 100644 --- a/tests/incremental/issue-38222.rs +++ b/tests/incremental/issue-38222.rs @@ -12,6 +12,7 @@ //@[rpass1] compile-flags: -C debuginfo=1 //@[rpass2] compile-flags: -C debuginfo=1 +//@ ignore-backends: gcc pub fn main() { mod1::some_fn(); diff --git a/tests/incremental/issue-39569.rs b/tests/incremental/issue-39569.rs index 6fd0776bd733e..dd8d972a21bd9 100644 --- a/tests/incremental/issue-39569.rs +++ b/tests/incremental/issue-39569.rs @@ -5,6 +5,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc use std::sync::Arc; diff --git a/tests/incremental/issue-39828/issue-39828.rs b/tests/incremental/issue-39828/issue-39828.rs index 703d8e8dd228f..a6e62c038b84d 100644 --- a/tests/incremental/issue-39828/issue-39828.rs +++ b/tests/incremental/issue-39828/issue-39828.rs @@ -7,6 +7,7 @@ //@ revisions:rpass1 rpass2 //@ aux-build:generic.rs +//@ ignore-backends: gcc extern crate generic; fn main() { } diff --git a/tests/incremental/issue-42602.rs b/tests/incremental/issue-42602.rs index d02c7f74665da..e75dd9696b793 100644 --- a/tests/incremental/issue-42602.rs +++ b/tests/incremental/issue-42602.rs @@ -9,6 +9,7 @@ //@ revisions:cfail1 cfail2 cfail3 //@ compile-flags:-Zquery-dep-graph //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/issue-49595/issue-49595.rs b/tests/incremental/issue-49595/issue-49595.rs index 7fe843135dfe6..890b1f963a2fe 100644 --- a/tests/incremental/issue-49595/issue-49595.rs +++ b/tests/incremental/issue-49595/issue-49595.rs @@ -1,6 +1,7 @@ //@ revisions:cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph --test //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "rlib"] diff --git a/tests/incremental/issue-59523-on-implemented-is-not-unused.rs b/tests/incremental/issue-59523-on-implemented-is-not-unused.rs index 973757223230f..8260bd350e721 100644 --- a/tests/incremental/issue-59523-on-implemented-is-not-unused.rs +++ b/tests/incremental/issue-59523-on-implemented-is-not-unused.rs @@ -4,6 +4,7 @@ //@ revisions: cfail1 cfail2 //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![deny(unused_attributes)] diff --git a/tests/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs b/tests/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs index fcd58f7a8d657..5954aaa18ff93 100644 --- a/tests/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs +++ b/tests/incremental/issue-59524-layout-scalar-valid-range-is-not-unused.rs @@ -5,6 +5,7 @@ //@ revisions: cfail1 cfail2 //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![deny(unused_attributes)] diff --git a/tests/incremental/issue-60629.rs b/tests/incremental/issue-60629.rs index 117e222fc3934..f21e5da92213a 100644 --- a/tests/incremental/issue-60629.rs +++ b/tests/incremental/issue-60629.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc struct A; diff --git a/tests/incremental/issue-61530.rs b/tests/incremental/issue-61530.rs index 673556a9d02f6..a06fa724615bb 100644 --- a/tests/incremental/issue-61530.rs +++ b/tests/incremental/issue-61530.rs @@ -1,6 +1,7 @@ #![feature(repr_simd, core_intrinsics)] //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc use std::intrinsics::simd::simd_shuffle; diff --git a/tests/incremental/issue-62649-path-collisions-happen.rs b/tests/incremental/issue-62649-path-collisions-happen.rs index 3b04f0ac9d71a..e604583b7aa77 100644 --- a/tests/incremental/issue-62649-path-collisions-happen.rs +++ b/tests/incremental/issue-62649-path-collisions-happen.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc #[cfg(rpass1)] pub trait Something { diff --git a/tests/incremental/issue-69596.rs b/tests/incremental/issue-69596.rs index 00d0d2b64a4f0..576cc0b828974 100644 --- a/tests/incremental/issue-69596.rs +++ b/tests/incremental/issue-69596.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc #![allow(unused_imports)] diff --git a/tests/incremental/issue-72386.rs b/tests/incremental/issue-72386.rs index b3cd2a6420817..de88dae5505fa 100644 --- a/tests/incremental/issue-72386.rs +++ b/tests/incremental/issue-72386.rs @@ -1,6 +1,7 @@ //@ revisions: rpass1 cfail1 rpass3 //@ needs-asm-support //@ only-x86_64 +//@ ignore-backends: gcc // Regression test for issue #72386 // Checks that we don't ICE when switching to an invalid register // and back again diff --git a/tests/incremental/issue-79661-missing-def-path-hash.rs b/tests/incremental/issue-79661-missing-def-path-hash.rs index c063c6a33a28f..f26f680c67e80 100644 --- a/tests/incremental/issue-79661-missing-def-path-hash.rs +++ b/tests/incremental/issue-79661-missing-def-path-hash.rs @@ -1,5 +1,6 @@ //@ aux-build:issue-79661.rs //@ revisions: rpass1 rpass2 rpass3 +//@ ignore-backends: gcc // Regression test for issue #79661 // We were failing to copy over a DefPathHash->DefId mapping diff --git a/tests/incremental/issue-79890-imported-crates-changed.rs b/tests/incremental/issue-79890-imported-crates-changed.rs index 8c70d224f9e58..f29ebd650c6ea 100644 --- a/tests/incremental/issue-79890-imported-crates-changed.rs +++ b/tests/incremental/issue-79890-imported-crates-changed.rs @@ -2,6 +2,7 @@ //@ revisions:rpass1 rpass2 rpass3 //@ compile-flags:--extern issue_79890 --test //@ edition:2018 +//@ ignore-backends: gcc // Tests that we don't ICE when the set of imported crates changes #[cfg(rpass2)] use issue_79890::MyTrait; diff --git a/tests/incremental/issue-80336-invalid-span.rs b/tests/incremental/issue-80336-invalid-span.rs index 251a59c3b57da..fe8a2688c496c 100644 --- a/tests/incremental/issue-80336-invalid-span.rs +++ b/tests/incremental/issue-80336-invalid-span.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ only-x86_64 +//@ ignore-backends: gcc pub fn main() { let _ = is_x86_feature_detected!("avx2"); diff --git a/tests/incremental/issue-80691-bad-eval-cache.rs b/tests/incremental/issue-80691-bad-eval-cache.rs index 4f897bd64a0d4..2d3dbf6fed661 100644 --- a/tests/incremental/issue-80691-bad-eval-cache.rs +++ b/tests/incremental/issue-80691-bad-eval-cache.rs @@ -2,6 +2,7 @@ //@ failure-status: 101 //@ error-pattern: not implemented //@ needs-unwind -Cpanic=abort causes abort instead of exit(101) +//@ ignore-backends: gcc pub trait Interner { type InternedVariableKinds; diff --git a/tests/incremental/issue-82920-predicate-order-miscompile.rs b/tests/incremental/issue-82920-predicate-order-miscompile.rs index e1c8b1253f62e..17a0601e9f4d8 100644 --- a/tests/incremental/issue-82920-predicate-order-miscompile.rs +++ b/tests/incremental/issue-82920-predicate-order-miscompile.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc trait MyTrait: One + Two {} impl One for T { diff --git a/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs b/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs index 6db5107cbe431..1814eb13ecc7a 100644 --- a/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs +++ b/tests/incremental/issue-85197-invalid-span/invalid_span_main.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 //@ aux-build:invalid-span-helper-lib.rs +//@ ignore-backends: gcc // This issue has several different parts. The high level idea is: // 1. We create an 'invalid' span with the help of the `respan` proc-macro, diff --git a/tests/incremental/issue-85360-eval-obligation-ice.rs b/tests/incremental/issue-85360-eval-obligation-ice.rs index 2148e45bb3876..2b25d2a39484f 100644 --- a/tests/incremental/issue-85360-eval-obligation-ice.rs +++ b/tests/incremental/issue-85360-eval-obligation-ice.rs @@ -3,6 +3,7 @@ //@[cfail2] compile-flags: --crate-type=lib -Zassert-incr-state=loaded //@ edition: 2021 //@ build-pass +//@ ignore-backends: gcc #![allow(dead_code)] diff --git a/tests/incremental/issue-92163-missing-sourcefile/issue_92163_main.rs b/tests/incremental/issue-92163-missing-sourcefile/issue_92163_main.rs index c5e73f056d70b..991ac4cf257d6 100644 --- a/tests/incremental/issue-92163-missing-sourcefile/issue_92163_main.rs +++ b/tests/incremental/issue-92163-missing-sourcefile/issue_92163_main.rs @@ -1,6 +1,7 @@ //@ aux-build:first_crate.rs //@ aux-build:second_crate.rs //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc // Regression test for issue #92163 // Under certain circumstances, we may end up trying to diff --git a/tests/incremental/issue-92987-provisional-dep-node.rs b/tests/incremental/issue-92987-provisional-dep-node.rs index 4daeb69189d57..4979f0956db0c 100644 --- a/tests/incremental/issue-92987-provisional-dep-node.rs +++ b/tests/incremental/issue-92987-provisional-dep-node.rs @@ -1,4 +1,5 @@ //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc // Regression test for issue #92987 // Tests that we properly manage `DepNode`s during trait evaluation diff --git a/tests/incremental/issue-96319-coinductive-cycle.rs b/tests/incremental/issue-96319-coinductive-cycle.rs index cf98b325271d4..f5524377256b9 100644 --- a/tests/incremental/issue-96319-coinductive-cycle.rs +++ b/tests/incremental/issue-96319-coinductive-cycle.rs @@ -1,5 +1,6 @@ //@ edition:2018 //@ revisions: rpass1 rpass2 +//@ ignore-backends: gcc pub struct Stmt { pub stmt_type: StmtKind, diff --git a/tests/incremental/krate-inherent.rs b/tests/incremental/krate-inherent.rs index 0322d112560cd..60ff636b6bea5 100644 --- a/tests/incremental/krate-inherent.rs +++ b/tests/incremental/krate-inherent.rs @@ -1,6 +1,7 @@ //@ revisions: cfail1 cfail2 //@ compile-flags: -Z query-dep-graph //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/krate-inlined.rs b/tests/incremental/krate-inlined.rs index 3d96b0570f155..563b14bc02638 100644 --- a/tests/incremental/krate-inlined.rs +++ b/tests/incremental/krate-inlined.rs @@ -4,6 +4,7 @@ //@ revisions: rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/krate_reassign_34991/main.rs b/tests/incremental/krate_reassign_34991/main.rs index 50f418a3fddb7..2aa77377f5dae 100644 --- a/tests/incremental/krate_reassign_34991/main.rs +++ b/tests/incremental/krate_reassign_34991/main.rs @@ -1,5 +1,6 @@ //@ aux-build:a.rs //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/link_order/main.rs b/tests/incremental/link_order/main.rs index 20931e25dd4bf..6046c018ef53b 100644 --- a/tests/incremental/link_order/main.rs +++ b/tests/incremental/link_order/main.rs @@ -1,6 +1,7 @@ //@ aux-build:my_lib.rs //@ revisions:cfail1 cfail2 //@ compile-flags:-Z query-dep-graph +//@ ignore-backends: gcc // Tests that re-ordering the `-l` arguments used // when compiling an external dependency does not lead to diff --git a/tests/incremental/lto.rs b/tests/incremental/lto.rs index 044267a9cfdf6..ddeddf95f8aee 100644 --- a/tests/incremental/lto.rs +++ b/tests/incremental/lto.rs @@ -1,6 +1,7 @@ //@ no-prefer-dynamic //@ revisions:rpass1 rpass2 //@ compile-flags: -C lto +//@ ignore-backends: gcc mod x { pub struct X { diff --git a/tests/incremental/macro_export.rs b/tests/incremental/macro_export.rs index 23e8f01cf330e..4cc243ec9f0c4 100644 --- a/tests/incremental/macro_export.rs +++ b/tests/incremental/macro_export.rs @@ -1,5 +1,6 @@ //@ revisions: cfail1 cfail2 cfail3 //@ build-pass (FIXME(62277): could be check-pass?) +//@ ignore-backends: gcc // This test case makes sure that we can compile with incremental compilation // enabled when there are macros exported from this crate. (See #37756) diff --git a/tests/incremental/mir-opt.rs b/tests/incremental/mir-opt.rs index 04b82d9ea7fd4..2735efd3ea593 100644 --- a/tests/incremental/mir-opt.rs +++ b/tests/incremental/mir-opt.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph -Z mir-opt-level=3 +//@ ignore-backends: gcc fn main() { if std::env::var("a").is_ok() { diff --git a/tests/incremental/remapped_paths_cc/main.rs b/tests/incremental/remapped_paths_cc/main.rs index 35e03d754469a..eee541148f0b3 100644 --- a/tests/incremental/remapped_paths_cc/main.rs +++ b/tests/incremental/remapped_paths_cc/main.rs @@ -1,6 +1,7 @@ //@ revisions:rpass1 rpass2 rpass3 //@ compile-flags: -Z query-dep-graph -g //@ aux-build:extern_crate.rs +//@ ignore-backends: gcc // This test case makes sure that we detect if paths emitted into debuginfo // are changed, even when the change happens in an external crate. diff --git a/tests/incremental/remove-private-item-cross-crate/main.rs b/tests/incremental/remove-private-item-cross-crate/main.rs index 209b061dfb66c..762d0aac26deb 100644 --- a/tests/incremental/remove-private-item-cross-crate/main.rs +++ b/tests/incremental/remove-private-item-cross-crate/main.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ aux-build:a.rs //@ compile-flags: -Zquery-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "bin"] diff --git a/tests/incremental/remove_crate/main.rs b/tests/incremental/remove_crate/main.rs index e3f15bd9c8cd6..ee6883b6db27e 100644 --- a/tests/incremental/remove_crate/main.rs +++ b/tests/incremental/remove_crate/main.rs @@ -2,6 +2,7 @@ //@ revisions:rpass1 rpass2 //@ aux-build:extern_crate.rs +//@ ignore-backends: gcc #[cfg(rpass1)] extern crate extern_crate; diff --git a/tests/incremental/reorder_vtable.rs b/tests/incremental/reorder_vtable.rs index 89ff14e8feee7..aba2749e2f653 100644 --- a/tests/incremental/reorder_vtable.rs +++ b/tests/incremental/reorder_vtable.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc // This test case makes sure re-order the methods in a vtable will // trigger recompilation of codegen units that instantiate it. diff --git a/tests/incremental/rlib_cross_crate/b.rs b/tests/incremental/rlib_cross_crate/b.rs index 672d2ba40684b..3373f8098c4f4 100644 --- a/tests/incremental/rlib_cross_crate/b.rs +++ b/tests/incremental/rlib_cross_crate/b.rs @@ -7,6 +7,7 @@ //@ revisions:rpass1 rpass2 rpass3 //@ no-prefer-dynamic //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/rustc-rust-log.rs b/tests/incremental/rustc-rust-log.rs index 602d376bae5f0..f3adbdcfa59ca 100644 --- a/tests/incremental/rustc-rust-log.rs +++ b/tests/incremental/rustc-rust-log.rs @@ -6,6 +6,7 @@ //@ dont-check-compiler-stderr //@ aux-build: rustc-rust-log-aux.rs //@ rustc-env:RUSTC_LOG=debug +//@ ignore-backends: gcc #[cfg(rpass1)] fn main() {} diff --git a/tests/incremental/slice-pattern-const-ice-83085.rs b/tests/incremental/slice-pattern-const-ice-83085.rs index 4d318fd7ec18a..e1a4407595f93 100644 --- a/tests/incremental/slice-pattern-const-ice-83085.rs +++ b/tests/incremental/slice-pattern-const-ice-83085.rs @@ -3,6 +3,7 @@ // this used to fail to build straight away without needing any kind of // stage1/2 builds but tidy demands it //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc fn main() { const BOO: &[u8; 0] = &[]; diff --git a/tests/incremental/source_loc_macros.rs b/tests/incremental/source_loc_macros.rs index dbe0a4ba90464..ba67fa2fadada 100644 --- a/tests/incremental/source_loc_macros.rs +++ b/tests/incremental/source_loc_macros.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/span_hash_stable/main.rs b/tests/incremental/span_hash_stable/main.rs index 0dba650163d36..c524ee3ec56df 100644 --- a/tests/incremental/span_hash_stable/main.rs +++ b/tests/incremental/span_hash_stable/main.rs @@ -5,6 +5,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -g -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/spans_in_type_debuginfo.rs b/tests/incremental/spans_in_type_debuginfo.rs index e8ae592c0c749..e56b782e92f16 100644 --- a/tests/incremental/spans_in_type_debuginfo.rs +++ b/tests/incremental/spans_in_type_debuginfo.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph -g +//@ ignore-backends: gcc #![rustc_partition_reused(module="spans_in_type_debuginfo-structs", cfg="rpass2")] #![rustc_partition_reused(module="spans_in_type_debuginfo-enums", cfg="rpass2")] diff --git a/tests/incremental/spans_significant_w_debuginfo.rs b/tests/incremental/spans_significant_w_debuginfo.rs index 48be9cd3bc967..06baecd75e5b4 100644 --- a/tests/incremental/spans_significant_w_debuginfo.rs +++ b/tests/incremental/spans_significant_w_debuginfo.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -g -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![rustc_partition_codegened(module = "spans_significant_w_debuginfo", cfg = "rpass2")] diff --git a/tests/incremental/spans_significant_w_panic.rs b/tests/incremental/spans_significant_w_panic.rs index f9016725258be..34363c359dca1 100644 --- a/tests/incremental/spans_significant_w_panic.rs +++ b/tests/incremental/spans_significant_w_panic.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -C overflow-checks=on -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass2")] diff --git a/tests/incremental/spike.rs b/tests/incremental/spike.rs index 5e6cd2fe3b39b..da1d20fe11656 100644 --- a/tests/incremental/spike.rs +++ b/tests/incremental/spike.rs @@ -4,6 +4,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/split_debuginfo_cached.rs b/tests/incremental/split_debuginfo_cached.rs index 4dea77308a71e..0feb1cb6174ed 100644 --- a/tests/incremental/split_debuginfo_cached.rs +++ b/tests/incremental/split_debuginfo_cached.rs @@ -8,6 +8,7 @@ //@ [rpass1]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split //@ [rpass2]compile-flags: -g -Zquery-dep-graph -Csplit-debuginfo=packed -Zsplit-dwarf-kind=split +//@ ignore-backends: gcc #![feature(rustc_attrs)] // For `rpass2`, nothing has changed so everything should re-used. diff --git a/tests/incremental/static_cycle/b.rs b/tests/incremental/static_cycle/b.rs index 7054b2ea4e360..c8243cb5328c5 100644 --- a/tests/incremental/static_cycle/b.rs +++ b/tests/incremental/static_cycle/b.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #![cfg_attr(rpass2, warn(dead_code))] diff --git a/tests/incremental/static_refering_to_other_static/issue-49081.rs b/tests/incremental/static_refering_to_other_static/issue-49081.rs index b6c1c1a9c8bd3..83111412fee85 100644 --- a/tests/incremental/static_refering_to_other_static/issue-49081.rs +++ b/tests/incremental/static_refering_to_other_static/issue-49081.rs @@ -1,6 +1,7 @@ // https://github.com/rust-lang/rust/issues/49081 //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc pub static A: i32 = 42; pub static B: &i32 = &A; diff --git a/tests/incremental/static_refering_to_other_static2/issue.rs b/tests/incremental/static_refering_to_other_static2/issue.rs index 8b6dc6d3e4b0b..7682352f33638 100644 --- a/tests/incremental/static_refering_to_other_static2/issue.rs +++ b/tests/incremental/static_refering_to_other_static2/issue.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #[cfg(rpass1)] pub static A: i32 = 42; diff --git a/tests/incremental/static_refering_to_other_static3/issue.rs b/tests/incremental/static_refering_to_other_static3/issue.rs index 39e46745f8a2b..b7ad0eacfd01c 100644 --- a/tests/incremental/static_refering_to_other_static3/issue.rs +++ b/tests/incremental/static_refering_to_other_static3/issue.rs @@ -1,4 +1,5 @@ //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #[cfg(rpass1)] pub static A: u8 = 42; diff --git a/tests/incremental/static_stable_hash/issue-49301.rs b/tests/incremental/static_stable_hash/issue-49301.rs index 68dc6d214c4e3..7d6b292d80d25 100644 --- a/tests/incremental/static_stable_hash/issue-49301.rs +++ b/tests/incremental/static_stable_hash/issue-49301.rs @@ -1,6 +1,7 @@ // https://github.com/rust-lang/rust/issues/49081 //@ revisions:rpass1 rpass2 +//@ ignore-backends: gcc #[cfg(rpass1)] pub static A: &str = "hello"; diff --git a/tests/incremental/struct_add_field.rs b/tests/incremental/struct_add_field.rs index ad1b6fcfe2828..2c26b388122a7 100644 --- a/tests/incremental/struct_add_field.rs +++ b/tests/incremental/struct_add_field.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/struct_change_field_type.rs b/tests/incremental/struct_change_field_type.rs index aed6c8884ac47..0291b34e3622a 100644 --- a/tests/incremental/struct_change_field_type.rs +++ b/tests/incremental/struct_change_field_type.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/struct_change_field_type_cross_crate/b.rs b/tests/incremental/struct_change_field_type_cross_crate/b.rs index 00bc3db0de86b..5307d0af9d0a4 100644 --- a/tests/incremental/struct_change_field_type_cross_crate/b.rs +++ b/tests/incremental/struct_change_field_type_cross_crate/b.rs @@ -1,6 +1,7 @@ //@ aux-build:a.rs //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/struct_change_nothing.rs b/tests/incremental/struct_change_nothing.rs index 3fc9a1c4de7fb..fd8c4882e1b2d 100644 --- a/tests/incremental/struct_change_nothing.rs +++ b/tests/incremental/struct_change_nothing.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/struct_remove_field.rs b/tests/incremental/struct_remove_field.rs index 488d7996b339b..23ba27344f9c1 100644 --- a/tests/incremental/struct_remove_field.rs +++ b/tests/incremental/struct_remove_field.rs @@ -3,6 +3,7 @@ //@ revisions:rpass1 rpass2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/thinlto/cgu_invalidated_via_import.rs b/tests/incremental/thinlto/cgu_invalidated_via_import.rs index 04a5a06384a3b..09380625ff617 100644 --- a/tests/incremental/thinlto/cgu_invalidated_via_import.rs +++ b/tests/incremental/thinlto/cgu_invalidated_via_import.rs @@ -5,6 +5,7 @@ //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -O //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/tests/incremental/thinlto/cgu_invalidated_when_export_added.rs b/tests/incremental/thinlto/cgu_invalidated_when_export_added.rs index a9b05467bf689..b6c9ceec2719d 100644 --- a/tests/incremental/thinlto/cgu_invalidated_when_export_added.rs +++ b/tests/incremental/thinlto/cgu_invalidated_when_export_added.rs @@ -1,5 +1,6 @@ //@ revisions: cfail1 cfail2 //@ build-pass +//@ ignore-backends: gcc // rust-lang/rust#69798: // diff --git a/tests/incremental/thinlto/cgu_invalidated_when_export_removed.rs b/tests/incremental/thinlto/cgu_invalidated_when_export_removed.rs index 3a78a290c7b22..488e8f68c510a 100644 --- a/tests/incremental/thinlto/cgu_invalidated_when_export_removed.rs +++ b/tests/incremental/thinlto/cgu_invalidated_when_export_removed.rs @@ -1,5 +1,6 @@ //@ revisions: cfail1 cfail2 //@ build-pass +//@ ignore-backends: gcc // rust-lang/rust#69798: // diff --git a/tests/incremental/thinlto/cgu_invalidated_when_import_added.rs b/tests/incremental/thinlto/cgu_invalidated_when_import_added.rs index 4198c6c273ba3..e17bf5eb8e806 100644 --- a/tests/incremental/thinlto/cgu_invalidated_when_import_added.rs +++ b/tests/incremental/thinlto/cgu_invalidated_when_import_added.rs @@ -1,6 +1,7 @@ //@ revisions: cfail1 cfail2 //@ compile-flags: -O -Zhuman-readable-cgu-names -Cllvm-args=-import-instr-limit=10 //@ build-pass +//@ ignore-backends: gcc // rust-lang/rust#59535: // diff --git a/tests/incremental/thinlto/cgu_invalidated_when_import_removed.rs b/tests/incremental/thinlto/cgu_invalidated_when_import_removed.rs index 4880d376fcc07..b2b86bdb80c2c 100644 --- a/tests/incremental/thinlto/cgu_invalidated_when_import_removed.rs +++ b/tests/incremental/thinlto/cgu_invalidated_when_import_removed.rs @@ -1,6 +1,7 @@ //@ revisions: cfail1 cfail2 //@ compile-flags: -O -Zhuman-readable-cgu-names -Cllvm-args=-import-instr-limit=10 //@ build-pass +//@ ignore-backends: gcc // rust-lang/rust#59535: // diff --git a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs index d124a3498c4a6..6c87130b73850 100644 --- a/tests/incremental/thinlto/cgu_keeps_identical_fn.rs +++ b/tests/incremental/thinlto/cgu_keeps_identical_fn.rs @@ -6,6 +6,7 @@ //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -O //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "rlib"] diff --git a/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs b/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs index e05508fa8e305..15d2f315d16e2 100644 --- a/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs +++ b/tests/incremental/thinlto/independent_cgus_dont_affect_each_other.rs @@ -4,6 +4,7 @@ //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Z query-dep-graph -O //@ build-pass +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type="rlib"] diff --git a/tests/incremental/type_alias_cross_crate/b.rs b/tests/incremental/type_alias_cross_crate/b.rs index 7187336ba5ee5..7fa7073e3da9e 100644 --- a/tests/incremental/type_alias_cross_crate/b.rs +++ b/tests/incremental/type_alias_cross_crate/b.rs @@ -1,6 +1,7 @@ //@ aux-build:a.rs //@ revisions:rpass1 rpass2 rpass3 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![feature(rustc_attrs)] diff --git a/tests/incremental/unchecked_dirty_clean.rs b/tests/incremental/unchecked_dirty_clean.rs index aab3333dff34b..e500bdf8fad3b 100644 --- a/tests/incremental/unchecked_dirty_clean.rs +++ b/tests/incremental/unchecked_dirty_clean.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 cfail2 //@ compile-flags: -Z query-dep-graph +//@ ignore-backends: gcc #![allow(warnings)] #![feature(rustc_attrs)] diff --git a/tests/incremental/unrecoverable_query.rs b/tests/incremental/unrecoverable_query.rs index 798a418f79902..367339cdcc021 100644 --- a/tests/incremental/unrecoverable_query.rs +++ b/tests/incremental/unrecoverable_query.rs @@ -7,6 +7,7 @@ //@ revisions:cfail1 cfail2 //@ compile-flags: --crate-type=lib //@ build-pass +//@ ignore-backends: gcc #![allow(dead_code)] diff --git a/tests/incremental/user-written-closure-synthetic-closure-conflict.rs b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs index 618604d06b173..31b94536c4ab1 100644 --- a/tests/incremental/user-written-closure-synthetic-closure-conflict.rs +++ b/tests/incremental/user-written-closure-synthetic-closure-conflict.rs @@ -1,5 +1,6 @@ //@ revisions: rpass1 rpass2 //@ edition: 2024 +//@ ignore-backends: gcc #![allow(unused)] diff --git a/tests/incremental/warnings-reemitted.rs b/tests/incremental/warnings-reemitted.rs index c38c43d46df6e..5eefd8608c2f9 100644 --- a/tests/incremental/warnings-reemitted.rs +++ b/tests/incremental/warnings-reemitted.rs @@ -1,6 +1,7 @@ //@ revisions: cfail1 cfail2 cfail3 //@ compile-flags: -Coverflow-checks=on //@ build-pass +//@ ignore-backends: gcc #![warn(arithmetic_overflow)] diff --git a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir index a18d7e7478fce..a1fe278c65207 100644 --- a/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/address_of.address_of_reborrow.SimplifyCfg-initial.after.mir @@ -1,30 +1,30 @@ // MIR for `address_of_reborrow` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] +| 0: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10] | 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send -| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] -| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 2: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] +| 3: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10] | 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] | 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10] | 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send | 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send | 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] | 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32] -| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] +| 10: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10] | 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send -| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] -| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 12: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] +| 13: user_ty: Canonical { value: Ty(*const ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10] | 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] | 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10] | 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send | 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send | 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] | 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32] -| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] +| 20: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10] | 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send -| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] -| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 22: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] +| 23: user_ty: Canonical { value: Ty(*mut ^c_0), max_universe: U0, variables: [Ty { ui: U0, sub_root: 0 }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10] | 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] | 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10] | 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir index 347e4119cd0e0..541b9b9895b3c 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-abort.mir @@ -1,7 +1,7 @@ // MIR for `a::{closure#0}` 0 coroutine_drop_async fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { - debug _task_context => _19; + debug _task_context => _2; debug x => ((*(_1.0: &mut {async fn body of a()})).0: T); let mut _0: std::task::Poll<()>; let _3: T; @@ -10,25 +10,24 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _6: std::pin::Pin<&mut T>; let mut _7: &mut T; let mut _8: *mut T; - let mut _9: (); - let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; - let mut _12: &mut impl std::future::Future; - let mut _13: std::pin::Pin<&mut impl std::future::Future>; - let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; - let mut _16: &mut impl std::future::Future; - let mut _17: std::pin::Pin<&mut impl std::future::Future>; - let mut _18: isize; - let mut _19: &mut std::task::Context<'_>; - let mut _20: u32; + let mut _9: std::task::Poll<()>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut impl std::future::Future>; + let mut _13: isize; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: (); + let mut _19: u32; scope 1 { debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); } bb0: { - _20 = discriminant((*(_1.0: &mut {async fn body of a()}))); - switchInt(move _20) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14]; + _19 = discriminant((*(_1.0: &mut {async fn body of a()}))); + switchInt(move _19) -> [0: bb9, 3: bb12, 4: bb13, otherwise: bb14]; } bb1: { @@ -49,9 +48,9 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb4: { - StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); - _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb7, unwind unreachable]; + StorageLive(_16); + _15 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb7, unwind unreachable]; } bb5: { @@ -59,13 +58,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb6: { - StorageDead(_17); - _18 = discriminant(_10); - switchInt(move _18) -> [0: bb1, 1: bb3, otherwise: bb5]; + StorageDead(_16); + _17 = discriminant(_9); + switchInt(move _17) -> [0: bb1, 1: bb3, otherwise: bb5]; } bb7: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb6, unwind unreachable]; + _9 = as Future>::poll(move _16, move _14) -> [return: bb6, unwind unreachable]; } bb8: { diff --git a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir index b1cf5373f9191..f2e1fb0997568 100644 --- a/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir +++ b/tests/mir-opt/async_drop_live_dead.a-{closure#0}.coroutine_drop_async.0.panic-unwind.mir @@ -1,7 +1,7 @@ // MIR for `a::{closure#0}` 0 coroutine_drop_async fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { - debug _task_context => _19; + debug _task_context => _2; debug x => ((*(_1.0: &mut {async fn body of a()})).0: T); let mut _0: std::task::Poll<()>; let _3: T; @@ -10,25 +10,24 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) let mut _6: std::pin::Pin<&mut T>; let mut _7: &mut T; let mut _8: *mut T; - let mut _9: (); - let mut _10: std::task::Poll<()>; - let mut _11: &mut std::task::Context<'_>; - let mut _12: &mut impl std::future::Future; - let mut _13: std::pin::Pin<&mut impl std::future::Future>; - let mut _14: isize; - let mut _15: &mut std::task::Context<'_>; - let mut _16: &mut impl std::future::Future; - let mut _17: std::pin::Pin<&mut impl std::future::Future>; - let mut _18: isize; - let mut _19: &mut std::task::Context<'_>; - let mut _20: u32; + let mut _9: std::task::Poll<()>; + let mut _10: &mut std::task::Context<'_>; + let mut _11: &mut impl std::future::Future; + let mut _12: std::pin::Pin<&mut impl std::future::Future>; + let mut _13: isize; + let mut _14: &mut std::task::Context<'_>; + let mut _15: &mut impl std::future::Future; + let mut _16: std::pin::Pin<&mut impl std::future::Future>; + let mut _17: isize; + let mut _18: (); + let mut _19: u32; scope 1 { debug x => (((*(_1.0: &mut {async fn body of a()})) as variant#4).0: T); } bb0: { - _20 = discriminant((*(_1.0: &mut {async fn body of a()}))); - switchInt(move _20) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; + _19 = discriminant((*(_1.0: &mut {async fn body of a()}))); + switchInt(move _19) -> [0: bb12, 2: bb18, 3: bb16, 4: bb17, otherwise: bb19]; } bb1: { @@ -63,9 +62,9 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb7: { - StorageLive(_17); - _16 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); - _17 = Pin::<&mut impl Future>::new_unchecked(move _16) -> [return: bb10, unwind: bb15]; + StorageLive(_16); + _15 = &mut (((*(_1.0: &mut {async fn body of a()})) as variant#4).1: impl std::future::Future); + _16 = Pin::<&mut impl Future>::new_unchecked(move _15) -> [return: bb10, unwind: bb15]; } bb8: { @@ -73,13 +72,13 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) } bb9: { - StorageDead(_17); - _18 = discriminant(_10); - switchInt(move _18) -> [0: bb1, 1: bb6, otherwise: bb8]; + StorageDead(_16); + _17 = discriminant(_9); + switchInt(move _17) -> [0: bb1, 1: bb6, otherwise: bb8]; } bb10: { - _10 = as Future>::poll(move _17, move _15) -> [return: bb9, unwind: bb3]; + _9 = as Future>::poll(move _16, move _14) -> [return: bb9, unwind: bb3]; } bb11: { diff --git a/tests/mir-opt/box_expr.rs b/tests/mir-opt/box_expr.rs index 009a5ae54e089..6299c98718094 100644 --- a/tests/mir-opt/box_expr.rs +++ b/tests/mir-opt/box_expr.rs @@ -6,7 +6,10 @@ // EMIT_MIR box_expr.main.ElaborateDrops.diff fn main() { // CHECK-LABEL: fn main( - // CHECK: [[box:_.*]] = ShallowInitBox( + // CHECK: [[ptr:_.*]] = move {{_.*}} as *const S (Transmute); + // CHECK: [[nonnull:_.*]] = NonNull:: { pointer: move [[ptr]] }; + // CHECK: [[unique:_.*]] = Unique:: { pointer: move [[nonnull]], _marker: const PhantomData:: }; + // CHECK: [[box:_.*]] = Box::(move [[unique]], const std::alloc::Global); // CHECK: [[ptr:_.*]] = copy (([[box]].0: std::ptr::Unique).0: std::ptr::NonNull) as *const S (Transmute); // CHECK: (*[[ptr]]) = S::new() -> [return: [[ret:bb.*]], unwind: [[unwind:bb.*]]]; // CHECK: [[ret]]: { diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir index 7480324b17791..2e2876cb3fcf2 100644 --- a/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.a-{closure#0}.coroutine_resume.0.mir @@ -10,19 +10,17 @@ } */ fn a::{closure#0}(_1: Pin<&mut {async fn body of a()}>, _2: &mut Context<'_>) -> Poll<()> { - debug _task_context => _4; + debug _task_context => _2; let mut _0: std::task::Poll<()>; let mut _3: (); - let mut _4: &mut std::task::Context<'_>; - let mut _5: u32; + let mut _4: u32; bb0: { - _5 = discriminant((*(_1.0: &mut {async fn body of a()}))); - switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5]; + _4 = discriminant((*(_1.0: &mut {async fn body of a()}))); + switchInt(move _4) -> [0: bb1, 1: bb4, otherwise: bb5]; } bb1: { - _4 = move _2; _3 = const (); goto -> bb3; } diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir index 9bff257e06392..20fc4112ef288 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir @@ -1,7 +1,7 @@ // MIR for `b::{closure#0}` 0 coroutine_resume /* coroutine_layout = CoroutineLayout { field_tys: { - _0: CoroutineSavedTy { + _s0: CoroutineSavedTy { ty: Coroutine( DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), [ @@ -18,7 +18,7 @@ }, ignore_for_traits: false, }, - _1: CoroutineSavedTy { + _s1: CoroutineSavedTy { ty: Coroutine( DefId(0:5 ~ async_await[ccf8]::a::{closure#0}), [ @@ -40,17 +40,17 @@ Unresumed(0): [], Returned (1): [], Panicked (2): [], - Suspend0 (3): [_0], - Suspend1 (4): [_1], + Suspend0 (3): [_s0], + Suspend1 (4): [_s1], }, storage_conflicts: BitMatrix(2x2) { - (_0, _0), - (_1, _1), + (_s0, _s0), + (_s1, _s1), }, } */ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> Poll<()> { - debug _task_context => _38; + debug _task_context => _2; let mut _0: std::task::Poll<()>; let _3: (); let mut _4: {async fn body of a()}; @@ -85,8 +85,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> let mut _35: &mut std::task::Context<'_>; let mut _36: (); let mut _37: (); - let mut _38: &mut std::task::Context<'_>; - let mut _39: u32; + let mut _38: u32; scope 1 { debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()}); let _17: (); @@ -103,12 +102,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> } bb0: { - _39 = discriminant((*(_1.0: &mut {async fn body of b()}))); - switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; + _38 = discriminant((*(_1.0: &mut {async fn body of b()}))); + switchInt(move _38) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb8]; } bb1: { - _38 = move _2; StorageLive(_3); StorageLive(_4); StorageLive(_5); @@ -143,7 +141,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageLive(_13); StorageLive(_14); StorageLive(_15); - _15 = copy _38; + _15 = copy _2; _14 = move _15; goto -> bb6; } @@ -198,7 +196,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb11: { StorageDead(_20); - _38 = move _19; + _2 = move _19; StorageDead(_19); _7 = const (); goto -> bb4; @@ -245,7 +243,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> StorageLive(_29); StorageLive(_30); StorageLive(_31); - _31 = copy _38; + _31 = copy _2; _30 = move _31; goto -> bb18; } @@ -295,7 +293,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) -> bb22: { StorageDead(_36); - _38 = move _35; + _2 = move _35; StorageDead(_35); _7 = const (); goto -> bb16; diff --git a/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir new file mode 100644 index 0000000000000..cd776ad7170a3 --- /dev/null +++ b/tests/mir-opt/building/coroutine.main-{closure#0}.StateTransform.after.mir @@ -0,0 +1,207 @@ +// MIR for `main::{closure#0}` after StateTransform +/* coroutine_layout = CoroutineLayout { + field_tys: { + _s0: CoroutineSavedTy { + ty: std::string::String, + source_info: SourceInfo { + span: $DIR/coroutine.rs:18:6: 18:9 (#0), + scope: scope[0], + }, + ignore_for_traits: false, + }, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + Suspend1 (4): [_s0], + }, + storage_conflicts: BitMatrix(1x1) { + (_s0, _s0), + }, +} */ + +fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { + debug arg => (((*(_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18})) as variant#4).0: std::string::String); + let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; + let _3: std::string::String; + let mut _4: (&str, std::string::String, &std::panic::Location<'_>); + let mut _5: std::string::String; + let mut _6: &std::string::String; + let mut _7: &std::panic::Location<'_>; + let _8: std::string::String; + let mut _9: (&str, std::string::String, &std::panic::Location<'_>); + let mut _10: &str; + let _11: &str; + let mut _12: std::string::String; + let mut _13: &std::string::String; + let mut _14: &std::panic::Location<'_>; + let _15: &std::panic::Location<'_>; + let mut _16: (); + let mut _17: u32; + let mut _18: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _19: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _20: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _21: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _22: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _23: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _24: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + let mut _25: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}; + + bb0: { + _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20]; + } + + bb1: { + _19 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + (((*_19) as variant#4).0: std::string::String) = move _2; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); + _20 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + _6 = &(((*_20) as variant#4).0: std::string::String); + _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_6); + StorageLive(_7); + _7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable]; + } + + bb3: { + _4 = (const "first", move _5, move _7); + StorageDead(_7); + goto -> bb4; + } + + bb4: { + StorageDead(_5); + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); + StorageDead(_3); + StorageDead(_4); + _21 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + discriminant((*_21)) = 3; + return; + } + + bb5: { + goto -> bb6; + } + + bb6: { + StorageDead(_4); + drop(_3) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_3); + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + _11 = const "second"; + _10 = &(*_11); + StorageLive(_12); + StorageLive(_13); + _22 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + _13 = &(((*_22) as variant#4).0: std::string::String); + _12 = ::clone(move _13) -> [return: bb8, unwind unreachable]; + } + + bb8: { + StorageDead(_13); + StorageLive(_14); + StorageLive(_15); + _15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable]; + } + + bb9: { + _14 = &(*_15); + _9 = (move _10, move _12, move _14); + StorageDead(_14); + goto -> bb10; + } + + bb10: { + StorageDead(_12); + StorageDead(_10); + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); + StorageDead(_8); + StorageDead(_9); + StorageDead(_11); + StorageDead(_15); + _23 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + discriminant((*_23)) = 4; + return; + } + + bb11: { + goto -> bb12; + } + + bb12: { + StorageDead(_9); + drop(_8) -> [return: bb13, unwind unreachable]; + } + + bb13: { + StorageDead(_15); + StorageDead(_11); + StorageDead(_8); + _16 = const (); + _24 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + drop((((*_24) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable]; + } + + bb14: { + goto -> bb16; + } + + bb15: { + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); + _25 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:18:5: 18:18}); + discriminant((*_25)) = 1; + return; + } + + bb16: { + goto -> bb15; + } + + bb17: { + StorageLive(_3); + StorageLive(_4); + _3 = move _2; + goto -> bb5; + } + + bb18: { + StorageLive(_8); + StorageLive(_9); + StorageLive(_11); + StorageLive(_15); + _8 = move _2; + goto -> bb11; + } + + bb19: { + assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable]; + } + + bb20: { + unreachable; + } +} + +ALLOC0 (size: 6, align: 1) { + 73 65 63 6f 6e 64 │ second +} + +ALLOC1 (size: 5, align: 1) { + 66 69 72 73 74 │ first +} diff --git a/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir new file mode 100644 index 0000000000000..981bc21dc878a --- /dev/null +++ b/tests/mir-opt/building/coroutine.main-{closure#1}.StateTransform.after.mir @@ -0,0 +1,207 @@ +// MIR for `main::{closure#1}` after StateTransform +/* coroutine_layout = CoroutineLayout { + field_tys: { + _s0: CoroutineSavedTy { + ty: std::string::String, + source_info: SourceInfo { + span: $DIR/coroutine.rs:25:6: 25:9 (#0), + scope: scope[0], + }, + ignore_for_traits: false, + }, + }, + variant_fields: { + Unresumed(0): [], + Returned (1): [], + Panicked (2): [], + Suspend0 (3): [_s0], + Suspend1 (4): [_s0], + }, + storage_conflicts: BitMatrix(1x1) { + (_s0, _s0), + }, +} */ + +fn main::{closure#1}(_1: Pin<&mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}>, _2: String) -> CoroutineState<(&str, String, &Location<'_>), ()> { + debug arg => (((*(_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18})) as variant#4).0: std::string::String); + let mut _0: std::ops::CoroutineState<(&str, std::string::String, &std::panic::Location<'_>), ()>; + let _3: std::string::String; + let mut _4: (&str, std::string::String, &std::panic::Location<'_>); + let mut _5: std::string::String; + let mut _6: &std::string::String; + let mut _7: &std::panic::Location<'_>; + let _8: std::string::String; + let mut _9: (&str, std::string::String, &std::panic::Location<'_>); + let mut _10: &str; + let _11: &str; + let mut _12: std::string::String; + let mut _13: &std::string::String; + let mut _14: &std::panic::Location<'_>; + let _15: &std::panic::Location<'_>; + let mut _16: (); + let mut _17: u32; + let mut _18: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _19: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _20: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _21: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _22: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _23: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _24: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + let mut _25: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}; + + bb0: { + _18 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + _17 = discriminant((*_18)); + switchInt(move _17) -> [0: bb1, 1: bb19, 3: bb17, 4: bb18, otherwise: bb20]; + } + + bb1: { + _19 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + (((*_19) as variant#4).0: std::string::String) = move _2; + StorageLive(_3); + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); + _20 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + _6 = &(((*_20) as variant#4).0: std::string::String); + _5 = ::clone(move _6) -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_6); + StorageLive(_7); + _7 = Location::<'_>::caller() -> [return: bb3, unwind unreachable]; + } + + bb3: { + _4 = (const "first", move _5, move _7); + StorageDead(_7); + goto -> bb4; + } + + bb4: { + StorageDead(_5); + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _4); + StorageDead(_3); + StorageDead(_4); + _21 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + discriminant((*_21)) = 3; + return; + } + + bb5: { + goto -> bb6; + } + + bb6: { + StorageDead(_4); + drop(_3) -> [return: bb7, unwind unreachable]; + } + + bb7: { + StorageDead(_3); + StorageLive(_8); + StorageLive(_9); + StorageLive(_10); + StorageLive(_11); + _11 = const "second"; + _10 = &(*_11); + StorageLive(_12); + StorageLive(_13); + _22 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + _13 = &(((*_22) as variant#4).0: std::string::String); + _12 = ::clone(move _13) -> [return: bb8, unwind unreachable]; + } + + bb8: { + StorageDead(_13); + StorageLive(_14); + StorageLive(_15); + _15 = Location::<'_>::caller() -> [return: bb9, unwind unreachable]; + } + + bb9: { + _14 = &(*_15); + _9 = (move _10, move _12, move _14); + StorageDead(_14); + goto -> bb10; + } + + bb10: { + StorageDead(_12); + StorageDead(_10); + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Yielded(move _9); + StorageDead(_8); + StorageDead(_9); + StorageDead(_11); + StorageDead(_15); + _23 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + discriminant((*_23)) = 4; + return; + } + + bb11: { + goto -> bb12; + } + + bb12: { + StorageDead(_9); + drop(_8) -> [return: bb13, unwind unreachable]; + } + + bb13: { + StorageDead(_15); + StorageDead(_11); + StorageDead(_8); + _16 = const (); + _24 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + drop((((*_24) as variant#4).0: std::string::String)) -> [return: bb14, unwind unreachable]; + } + + bb14: { + goto -> bb16; + } + + bb15: { + _0 = CoroutineState::<(&str, String, &Location<'_>), ()>::Complete(move _16); + _25 = copy (_1.0: &mut {coroutine@$DIR/coroutine.rs:25:5: 25:18}); + discriminant((*_25)) = 1; + return; + } + + bb16: { + goto -> bb15; + } + + bb17: { + StorageLive(_3); + StorageLive(_4); + _3 = move _2; + goto -> bb5; + } + + bb18: { + StorageLive(_8); + StorageLive(_9); + StorageLive(_11); + StorageLive(_15); + _8 = move _2; + goto -> bb11; + } + + bb19: { + assert(const false, "coroutine resumed after completion") -> [success: bb19, unwind unreachable]; + } + + bb20: { + unreachable; + } +} + +ALLOC0 (size: 6, align: 1) { + 73 65 63 6f 6e 64 │ second +} + +ALLOC1 (size: 5, align: 1) { + 66 69 72 73 74 │ first +} diff --git a/tests/mir-opt/building/coroutine.rs b/tests/mir-opt/building/coroutine.rs new file mode 100644 index 0000000000000..6d50c4d90b1a4 --- /dev/null +++ b/tests/mir-opt/building/coroutine.rs @@ -0,0 +1,29 @@ +// skip-filecheck +//@ edition:2024 +//@ compile-flags: -Zmir-opt-level=0 -C panic=abort + +#![feature(stmt_expr_attributes)] +#![feature(closure_track_caller)] +#![feature(coroutine_trait)] +#![feature(coroutines)] + +use std::ops::{Coroutine, CoroutineState}; +use std::panic::Location; +use std::pin::Pin; + +// EMIT_MIR coroutine.main-{closure#0}.StateTransform.after.mir +// EMIT_MIR coroutine.main-{closure#1}.StateTransform.after.mir +fn main() { + let simple = #[coroutine] + |arg: String| { + yield ("first", arg.clone(), Location::caller()); + yield ("second", arg.clone(), Location::caller()); + }; + + let track_caller = #[track_caller] + #[coroutine] + |arg: String| { + yield ("first", arg.clone(), Location::caller()); + yield ("second", arg.clone(), Location::caller()); + }; +} diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir index 30d11e31e4d4e..f9f24c8eabe4d 100644 --- a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir +++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir @@ -3,12 +3,16 @@ fn arrays() -> usize { let mut _0: usize; let mut _1: [i32; C]; - let mut _2: usize; + let mut _2: *const [i32; C]; + let mut _3: *const [i32]; + let mut _4: usize; bb0: { _1 = [const 5_i32; C]; - _2 = Len(_1); - _0 = copy _2; + _2 = &raw const _1; + _3 = copy _2 as *const [i32] (PointerCoercion(Unsize, AsCast)); + _4 = PtrMetadata(copy _3); + _0 = copy _4; return; } } diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs index 4bd6f93e11340..e9cdded4a0e68 100644 --- a/tests/mir-opt/building/custom/arrays.rs +++ b/tests/mir-opt/building/custom/arrays.rs @@ -10,7 +10,9 @@ fn arrays() -> usize { mir! { { let x = [5_i32; C]; - let c = Len(x); + let y = &raw const x; + let z = CastUnsize::<_, *const [i32]>(y); + let c = PtrMetadata(z); RET = c; Return() } diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs index 88ec228986ab7..6fad373203a69 100644 --- a/tests/mir-opt/building/custom/enums.rs +++ b/tests/mir-opt/building/custom/enums.rs @@ -88,7 +88,6 @@ fn switch_option_repr(option: Bool) -> bool { fn set_discr(option: &mut Option<()>) { mir! { { - Deinit(*option); SetDiscriminant(*option, 0); Return() } diff --git a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir index 8cc66e7e50d6a..d9b46dff43aa4 100644 --- a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir +++ b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir @@ -4,7 +4,6 @@ fn set_discr(_1: &mut Option<()>) -> () { let mut _0: (); bb0: { - Deinit((*_1)); discriminant((*_1)) = 0; return; } diff --git a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir b/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir deleted file mode 100644 index b28e96f10eae7..0000000000000 --- a/tests/mir-opt/building/custom/projections.copy_for_deref.built.after.mir +++ /dev/null @@ -1,12 +0,0 @@ -// MIR for `copy_for_deref` after built - -fn copy_for_deref(_1: (&i32, i32)) -> i32 { - let mut _0: i32; - let mut _2: &i32; - - bb0: { - _2 = deref_copy (_1.0: &i32); - _0 = copy (*_2); - return; - } -} diff --git a/tests/mir-opt/building/custom/projections.rs b/tests/mir-opt/building/custom/projections.rs index 0250b9b84b621..e59eebd9952d7 100644 --- a/tests/mir-opt/building/custom/projections.rs +++ b/tests/mir-opt/building/custom/projections.rs @@ -79,19 +79,6 @@ fn simple_index(a: [i32; 10], b: &[i32]) -> i32 { } } -// EMIT_MIR projections.copy_for_deref.built.after.mir -#[custom_mir(dialect = "runtime", phase = "initial")] -fn copy_for_deref(x: (&i32, i32)) -> i32 { - mir! { - let temp: &i32; - { - temp = CopyForDeref(x.0); - RET = *temp; - Return() - } - } -} - fn main() { assert_eq!(unions(U { a: 5 }), 5); assert_eq!(tuples((5, 6)), (5, 6)); @@ -103,7 +90,4 @@ fn main() { assert_eq!(o, Some(10)); assert_eq!(simple_index([0; 10], &[0; 10]), 0); - - let one = 1; - assert_eq!(copy_for_deref((&one, one)), 1); } diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir new file mode 100644 index 0000000000000..8d16f074b1e34 --- /dev/null +++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-abort.mir @@ -0,0 +1,155 @@ +// MIR for `const_array_len` after built + +fn const_array_len(_1: [T; 5]) -> () { + debug x => _1; + let mut _0: (); + let _6: (); + let mut _7: T; + let _8: (); + let mut _9: T; + let _10: (); + let mut _11: [T; 2]; + let _12: (); + let mut _13: T; + scope 1 { + debug a => _2; + debug b => _3; + debug rest => _4; + debug e => _5; + let _2: T; + let _3: T; + let _4: [T; 2]; + let _5: T; + } + + bb0: { + PlaceMention(_1); + falseEdge -> [real: bb2, imaginary: bb1]; + } + + bb1: { + goto -> bb7; + } + + bb2: { + StorageLive(_2); + _2 = move _1[0 of 5]; + StorageLive(_3); + _3 = move _1[1 of 5]; + StorageLive(_4); + _4 = move _1[2..4]; + StorageLive(_5); + _5 = move _1[4 of 5]; + StorageLive(_6); + StorageLive(_7); + _7 = move _2; + _6 = opaque::(move _7) -> [return: bb3, unwind: bb17]; + } + + bb3: { + StorageDead(_7); + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = move _3; + _8 = opaque::(move _9) -> [return: bb4, unwind: bb16]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + StorageLive(_11); + _11 = move _4; + _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15]; + } + + bb5: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = move _5; + _12 = opaque::(move _13) -> [return: bb6, unwind: bb14]; + } + + bb6: { + StorageDead(_13); + StorageDead(_12); + _0 = const (); + drop(_5) -> [return: bb8, unwind: bb19]; + } + + bb7: { + _0 = const (); + goto -> bb12; + } + + bb8: { + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb20]; + } + + bb9: { + StorageDead(_4); + drop(_3) -> [return: bb10, unwind: bb21]; + } + + bb10: { + StorageDead(_3); + drop(_2) -> [return: bb11, unwind: bb22]; + } + + bb11: { + StorageDead(_2); + goto -> bb12; + } + + bb12: { + drop(_1) -> [return: bb13, unwind: bb23]; + } + + bb13: { + return; + } + + bb14 (cleanup): { + drop(_13) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_11) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_9) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + drop(_7) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb18 (cleanup): { + drop(_5) -> [return: bb19, unwind terminate(cleanup)]; + } + + bb19 (cleanup): { + drop(_4) -> [return: bb20, unwind terminate(cleanup)]; + } + + bb20 (cleanup): { + drop(_3) -> [return: bb21, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_2) -> [return: bb22, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_1) -> [return: bb23, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir new file mode 100644 index 0000000000000..8d16f074b1e34 --- /dev/null +++ b/tests/mir-opt/building/match/array_len.const_array_len.built.after.panic-unwind.mir @@ -0,0 +1,155 @@ +// MIR for `const_array_len` after built + +fn const_array_len(_1: [T; 5]) -> () { + debug x => _1; + let mut _0: (); + let _6: (); + let mut _7: T; + let _8: (); + let mut _9: T; + let _10: (); + let mut _11: [T; 2]; + let _12: (); + let mut _13: T; + scope 1 { + debug a => _2; + debug b => _3; + debug rest => _4; + debug e => _5; + let _2: T; + let _3: T; + let _4: [T; 2]; + let _5: T; + } + + bb0: { + PlaceMention(_1); + falseEdge -> [real: bb2, imaginary: bb1]; + } + + bb1: { + goto -> bb7; + } + + bb2: { + StorageLive(_2); + _2 = move _1[0 of 5]; + StorageLive(_3); + _3 = move _1[1 of 5]; + StorageLive(_4); + _4 = move _1[2..4]; + StorageLive(_5); + _5 = move _1[4 of 5]; + StorageLive(_6); + StorageLive(_7); + _7 = move _2; + _6 = opaque::(move _7) -> [return: bb3, unwind: bb17]; + } + + bb3: { + StorageDead(_7); + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = move _3; + _8 = opaque::(move _9) -> [return: bb4, unwind: bb16]; + } + + bb4: { + StorageDead(_9); + StorageDead(_8); + StorageLive(_10); + StorageLive(_11); + _11 = move _4; + _10 = opaque::<[T; 2]>(move _11) -> [return: bb5, unwind: bb15]; + } + + bb5: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = move _5; + _12 = opaque::(move _13) -> [return: bb6, unwind: bb14]; + } + + bb6: { + StorageDead(_13); + StorageDead(_12); + _0 = const (); + drop(_5) -> [return: bb8, unwind: bb19]; + } + + bb7: { + _0 = const (); + goto -> bb12; + } + + bb8: { + StorageDead(_5); + drop(_4) -> [return: bb9, unwind: bb20]; + } + + bb9: { + StorageDead(_4); + drop(_3) -> [return: bb10, unwind: bb21]; + } + + bb10: { + StorageDead(_3); + drop(_2) -> [return: bb11, unwind: bb22]; + } + + bb11: { + StorageDead(_2); + goto -> bb12; + } + + bb12: { + drop(_1) -> [return: bb13, unwind: bb23]; + } + + bb13: { + return; + } + + bb14 (cleanup): { + drop(_13) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb15 (cleanup): { + drop(_11) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { + drop(_9) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb17 (cleanup): { + drop(_7) -> [return: bb18, unwind terminate(cleanup)]; + } + + bb18 (cleanup): { + drop(_5) -> [return: bb19, unwind terminate(cleanup)]; + } + + bb19 (cleanup): { + drop(_4) -> [return: bb20, unwind terminate(cleanup)]; + } + + bb20 (cleanup): { + drop(_3) -> [return: bb21, unwind terminate(cleanup)]; + } + + bb21 (cleanup): { + drop(_2) -> [return: bb22, unwind terminate(cleanup)]; + } + + bb22 (cleanup): { + drop(_1) -> [return: bb23, unwind terminate(cleanup)]; + } + + bb23 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/building/match/array_len.rs b/tests/mir-opt/building/match/array_len.rs new file mode 100644 index 0000000000000..0d889ada9b602 --- /dev/null +++ b/tests/mir-opt/building/match/array_len.rs @@ -0,0 +1,31 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Zmir-opt-level=0 + +fn opaque(x: T) {} + +// EMIT_MIR array_len.const_array_len.built.after.mir +fn const_array_len(x: [T; 5]) { + // CHECK-LABEL: fn const_array_len( + // CHECK-NOT: Len + // CHECK-NOT: PtrMetadata + // CHECK: = const 5_usize; + if let [a, b, rest @ .., e] = x { + opaque(a); + opaque(b); + opaque(rest); + opaque(e); + } +} + +// EMIT_MIR array_len.slice_len.built.after.mir +fn slice_len(x: &[T]) { + // CHECK-LABEL: fn slice_len( + // CHECK-NOT: Len + // CHECK: = PtrMetadata(copy _1); + if let [a, b, rest @ .., e] = x { + opaque(a); + opaque(b); + opaque(rest); + opaque(e); + } +} diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir new file mode 100644 index 0000000000000..d73f5a1b6f716 --- /dev/null +++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-abort.mir @@ -0,0 +1,115 @@ +// MIR for `slice_len` after built + +fn slice_len(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let mut _2: usize; + let mut _3: usize; + let mut _4: usize; + let mut _5: bool; + let _10: (); + let mut _11: &T; + let _12: (); + let mut _13: &T; + let _14: (); + let mut _15: &[T]; + let _16: (); + let mut _17: &T; + scope 1 { + debug a => _6; + debug b => _7; + debug rest => _8; + debug e => _9; + let _6: &T; + let _7: &T; + let _8: &[T]; + let _9: &T; + } + + bb0: { + PlaceMention(_1); + _3 = PtrMetadata(copy _1); + _2 = move _3; + _4 = const 3_usize; + _5 = Ge(move _2, move _4); + switchInt(move _5) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + goto -> bb9; + } + + bb2: { + falseEdge -> [real: bb4, imaginary: bb1]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + StorageLive(_6); + _6 = &(*_1)[0 of 3]; + StorageLive(_7); + _7 = &(*_1)[1 of 3]; + StorageLive(_8); + _8 = &(*_1)[2:-1]; + StorageLive(_9); + _9 = &(*_1)[-1 of 3]; + StorageLive(_10); + StorageLive(_11); + _11 = copy _6; + _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11]; + } + + bb5: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = copy _7; + _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11]; + } + + bb6: { + StorageDead(_13); + StorageDead(_12); + StorageLive(_14); + StorageLive(_15); + _15 = copy _8; + _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11]; + } + + bb7: { + StorageDead(_15); + StorageDead(_14); + StorageLive(_16); + StorageLive(_17); + _17 = copy _9; + _16 = opaque::<&T>(move _17) -> [return: bb8, unwind: bb11]; + } + + bb8: { + StorageDead(_17); + StorageDead(_16); + _0 = const (); + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + goto -> bb10; + } + + bb9: { + _0 = const (); + goto -> bb10; + } + + bb10: { + return; + } + + bb11 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir new file mode 100644 index 0000000000000..d73f5a1b6f716 --- /dev/null +++ b/tests/mir-opt/building/match/array_len.slice_len.built.after.panic-unwind.mir @@ -0,0 +1,115 @@ +// MIR for `slice_len` after built + +fn slice_len(_1: &[T]) -> () { + debug x => _1; + let mut _0: (); + let mut _2: usize; + let mut _3: usize; + let mut _4: usize; + let mut _5: bool; + let _10: (); + let mut _11: &T; + let _12: (); + let mut _13: &T; + let _14: (); + let mut _15: &[T]; + let _16: (); + let mut _17: &T; + scope 1 { + debug a => _6; + debug b => _7; + debug rest => _8; + debug e => _9; + let _6: &T; + let _7: &T; + let _8: &[T]; + let _9: &T; + } + + bb0: { + PlaceMention(_1); + _3 = PtrMetadata(copy _1); + _2 = move _3; + _4 = const 3_usize; + _5 = Ge(move _2, move _4); + switchInt(move _5) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + goto -> bb9; + } + + bb2: { + falseEdge -> [real: bb4, imaginary: bb1]; + } + + bb3: { + goto -> bb1; + } + + bb4: { + StorageLive(_6); + _6 = &(*_1)[0 of 3]; + StorageLive(_7); + _7 = &(*_1)[1 of 3]; + StorageLive(_8); + _8 = &(*_1)[2:-1]; + StorageLive(_9); + _9 = &(*_1)[-1 of 3]; + StorageLive(_10); + StorageLive(_11); + _11 = copy _6; + _10 = opaque::<&T>(move _11) -> [return: bb5, unwind: bb11]; + } + + bb5: { + StorageDead(_11); + StorageDead(_10); + StorageLive(_12); + StorageLive(_13); + _13 = copy _7; + _12 = opaque::<&T>(move _13) -> [return: bb6, unwind: bb11]; + } + + bb6: { + StorageDead(_13); + StorageDead(_12); + StorageLive(_14); + StorageLive(_15); + _15 = copy _8; + _14 = opaque::<&[T]>(move _15) -> [return: bb7, unwind: bb11]; + } + + bb7: { + StorageDead(_15); + StorageDead(_14); + StorageLive(_16); + StorageLive(_17); + _17 = copy _9; + _16 = opaque::<&T>(move _17) -> [return: bb8, unwind: bb11]; + } + + bb8: { + StorageDead(_17); + StorageDead(_16); + _0 = const (); + StorageDead(_9); + StorageDead(_8); + StorageDead(_7); + StorageDead(_6); + goto -> bb10; + } + + bb9: { + _0 = const (); + goto -> bb10; + } + + bb10: { + return; + } + + bb11 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff index f43c0cca9ad28..16bae67cc9892 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff @@ -11,7 +11,10 @@ let mut _6: *mut u8; let mut _7: std::boxed::Box; let mut _8: *const i32; - let mut _9: *const i32; + let mut _9: std::ptr::NonNull; + let mut _10: std::ptr::Unique; + let mut _11: *const i32; + let mut _12: *const i32; scope 1 { debug x => _1; } @@ -31,13 +34,21 @@ bb1: { StorageLive(_7); - _7 = ShallowInitBox(move _6, i32); - _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - (*_8) = const 42_i32; +- _8 = move _6 as *const i32 (Transmute); +- _9 = NonNull:: { pointer: move _8 }; +- _10 = Unique:: { pointer: move _9, _marker: const PhantomData:: }; ++ _8 = copy _6 as *const i32 (PtrToPtr); ++ _9 = NonNull:: { pointer: copy _8 }; ++ _10 = Unique:: { pointer: copy _9, _marker: const PhantomData:: }; + _7 = Box::(move _10, const std::alloc::Global); +- _11 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- (*_11) = const 42_i32; ++ _11 = copy _8; ++ (*_8) = const 42_i32; _3 = move _7; StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); + _12 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); + _2 = copy (*_12); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); + _1 = copy _2; diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff index 2c903b6d85349..3fbf7a57a76f8 100644 --- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff @@ -11,7 +11,10 @@ let mut _6: *mut u8; let mut _7: std::boxed::Box; let mut _8: *const i32; - let mut _9: *const i32; + let mut _9: std::ptr::NonNull; + let mut _10: std::ptr::Unique; + let mut _11: *const i32; + let mut _12: *const i32; scope 1 { debug x => _1; } @@ -31,13 +34,21 @@ bb1: { StorageLive(_7); - _7 = ShallowInitBox(move _6, i32); - _8 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - (*_8) = const 42_i32; +- _8 = move _6 as *const i32 (Transmute); +- _9 = NonNull:: { pointer: move _8 }; +- _10 = Unique:: { pointer: move _9, _marker: const PhantomData:: }; ++ _8 = copy _6 as *const i32 (PtrToPtr); ++ _9 = NonNull:: { pointer: copy _8 }; ++ _10 = Unique:: { pointer: copy _9, _marker: const PhantomData:: }; + _7 = Box::(move _10, const std::alloc::Global); +- _11 = copy ((_7.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); +- (*_11) = const 42_i32; ++ _11 = copy _8; ++ (*_8) = const 42_i32; _3 = move _7; StorageDead(_7); - _9 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); - _2 = copy (*_9); + _12 = copy ((_3.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); + _2 = copy (*_12); - _1 = Add(move _2, const 0_i32); - StorageDead(_2); + _1 = copy _2; diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff index 24b10217865bb..5df2232053fef 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-abort.diff @@ -3,23 +3,17 @@ fn hello() -> () { let mut _0: (); - let mut _1: bool; - let mut _2: !; + let mut _1: !; bb0: { - StorageLive(_1); -- _1 = const ::NEEDS; -- switchInt(move _1) -> [0: bb2, otherwise: bb1]; -+ _1 = const false; -+ switchInt(const false) -> [0: bb2, otherwise: bb1]; + goto -> bb2; } bb1: { - _2 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; + _1 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable; } bb2: { - StorageDead(_1); return; } } diff --git a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff index a73485e7944df..788a4424943e9 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff +++ b/tests/mir-opt/const_prop/control_flow_simplification.hello.GVN.panic-unwind.diff @@ -3,23 +3,17 @@ fn hello() -> () { let mut _0: (); - let mut _1: bool; - let mut _2: !; + let mut _1: !; bb0: { - StorageLive(_1); -- _1 = const ::NEEDS; -- switchInt(move _1) -> [0: bb2, otherwise: bb1]; -+ _1 = const false; -+ switchInt(const false) -> [0: bb2, otherwise: bb1]; + goto -> bb2; } bb1: { - _2 = begin_panic::<&str>(const "explicit panic") -> unwind continue; + _1 = begin_panic::<&str>(const "explicit panic") -> unwind continue; } bb2: { - StorageDead(_1); return; } } diff --git a/tests/mir-opt/const_prop/control_flow_simplification.rs b/tests/mir-opt/const_prop/control_flow_simplification.rs index 64605ca11c2cc..8ec630d6f48d0 100644 --- a/tests/mir-opt/const_prop/control_flow_simplification.rs +++ b/tests/mir-opt/const_prop/control_flow_simplification.rs @@ -1,4 +1,3 @@ -// skip-filecheck // EMIT_MIR_FOR_EACH_PANIC_STRATEGY //@ test-mir-pass: GVN //@ compile-flags: -Zmir-opt-level=1 @@ -12,6 +11,9 @@ impl NeedsDrop for This {} // EMIT_MIR control_flow_simplification.hello.GVN.diff // EMIT_MIR control_flow_simplification.hello.PreCodegen.before.mir fn hello() { + // CHECK-LABEL: fn hello( + // CHECK: bb0: + // CHECK-NEXT: return; if ::NEEDS { panic!() } diff --git a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff index 5e843da867923..a4900a1ac72ea 100644 --- a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff +++ b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff @@ -28,21 +28,27 @@ bb0: { StorageLive(_1); StorageLive(_2); - _2 = InvalidChar { int: const 1114113_u32 }; - _1 = copy (_2.1: char); +- _2 = InvalidChar { int: const 1114113_u32 }; +- _1 = copy (_2.1: char); ++ _2 = const InvalidChar {{ int: 1114113_u32, chr: {transmute(0x00110001): char} }}; ++ _1 = const {transmute(0x00110001): char}; StorageDead(_2); StorageLive(_3); StorageLive(_4); StorageLive(_5); - _5 = InvalidTag { int: const 4_u32 }; - _4 = copy (_5.1: E); - _3 = [move _4]; +- _5 = InvalidTag { int: const 4_u32 }; +- _4 = copy (_5.1: E); +- _3 = [move _4]; ++ _5 = const InvalidTag {{ int: 4_u32, e: Scalar(0x00000004): E }}; ++ _4 = const Scalar(0x00000004): E; ++ _3 = [const Scalar(0x00000004): E]; StorageDead(_4); StorageDead(_5); nop; nop; StorageLive(_8); - _8 = NoVariants { int: const 0_u32 }; +- _8 = NoVariants { int: const 0_u32 }; ++ _8 = const NoVariants {{ int: 0_u32, empty: ZeroSized: Empty }}; nop; nop; nop; @@ -55,5 +61,17 @@ StorageDead(_1); return; } ++ } ++ ++ ALLOC0 (size: 4, align: 4) { ++ 00 00 00 00 │ .... ++ } ++ ++ ALLOC1 (size: 4, align: 4) { ++ 04 00 00 00 │ .... ++ } ++ ++ ALLOC2 (size: 4, align: 4) { ++ 01 00 11 00 │ .... } diff --git a/tests/mir-opt/const_prop/transmute.rs b/tests/mir-opt/const_prop/transmute.rs index 33cbefbf053f5..ece6331ade279 100644 --- a/tests/mir-opt/const_prop/transmute.rs +++ b/tests/mir-opt/const_prop/transmute.rs @@ -43,8 +43,8 @@ pub unsafe fn invalid_bool() -> bool { // EMIT_MIR transmute.undef_union_as_integer.GVN.diff pub unsafe fn undef_union_as_integer() -> u32 { // CHECK-LABEL: fn undef_union_as_integer( - // CHECK: _1 = Union32 { - // CHECK: _0 = move _1 as u32 (Transmute); + // CHECK: _1 = const Union32 + // CHECK: _0 = const {{.*}}: u32; union Union32 { value: u32, unit: (), diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff index 2ac9769a0e773..be0450114b1c8 100644 --- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff @@ -12,11 +12,16 @@ - _2 = (); - _1 = Union32 { value: move _2 }; + _2 = const (); -+ _1 = Union32 { value: const () }; ++ _1 = const Union32 {{ value: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: u32, unit: () }}; StorageDead(_2); - _0 = move _1 as u32 (Transmute); +- _0 = move _1 as u32 (Transmute); ++ _0 = const Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: u32; StorageDead(_1); return; } ++ } ++ ++ ALLOC0 (size: 4, align: 4) { ++ __ __ __ __ │ ░░░░ } diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff index 2ac9769a0e773..be0450114b1c8 100644 --- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff +++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff @@ -12,11 +12,16 @@ - _2 = (); - _1 = Union32 { value: move _2 }; + _2 = const (); -+ _1 = Union32 { value: const () }; ++ _1 = const Union32 {{ value: Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: u32, unit: () }}; StorageDead(_2); - _0 = move _1 as u32 (Transmute); +- _0 = move _1 as u32 (Transmute); ++ _0 = const Indirect { alloc_id: ALLOC0, offset: Size(0 bytes) }: u32; StorageDead(_1); return; } ++ } ++ ++ ALLOC0 (size: 4, align: 4) { ++ __ __ __ __ │ ░░░░ } diff --git a/tests/mir-opt/const_prop/trivial_const.rs b/tests/mir-opt/const_prop/trivial_const.rs new file mode 100644 index 0000000000000..e9134c1ebdeff --- /dev/null +++ b/tests/mir-opt/const_prop/trivial_const.rs @@ -0,0 +1,15 @@ +//@ test-mir-pass: SimplifyConstCondition-after-inst-simplify +//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg -Zub_checks=false -Zinline-mir + +#![crate_type = "lib"] + +// EMIT_MIR trivial_const.unwrap_unchecked.SimplifyConstCondition-after-inst-simplify.diff +pub fn unwrap_unchecked(v: &Option) -> i32 { + // CHECK-LABEL: fn unwrap_unchecked( + // CHECK: bb0: { + // CHECK: switchInt({{.*}}) -> [0: [[AssumeFalseBB:bb.*]], 1: + // CHECK: [[AssumeFalseBB]]: { + // CHECK-NEXT: unreachable; + let v = unsafe { v.unwrap_unchecked() }; + v +} diff --git a/tests/mir-opt/const_prop/trivial_const.unwrap_unchecked.SimplifyConstCondition-after-inst-simplify.diff b/tests/mir-opt/const_prop/trivial_const.unwrap_unchecked.SimplifyConstCondition-after-inst-simplify.diff new file mode 100644 index 0000000000000..d14c42a330eb7 --- /dev/null +++ b/tests/mir-opt/const_prop/trivial_const.unwrap_unchecked.SimplifyConstCondition-after-inst-simplify.diff @@ -0,0 +1,58 @@ +- // MIR for `unwrap_unchecked` before SimplifyConstCondition-after-inst-simplify ++ // MIR for `unwrap_unchecked` after SimplifyConstCondition-after-inst-simplify + + fn unwrap_unchecked(_1: &Option) -> i32 { + debug v => _1; + let mut _0: i32; + let _2: i32; + let mut _3: std::option::Option; + scope 1 { + debug v => _2; + } + scope 2 (inlined #[track_caller] Option::::unwrap_unchecked) { + let mut _4: isize; + scope 3 { + } + scope 4 (inlined #[track_caller] unreachable_unchecked) { + let _5: (); + scope 5 (inlined core::ub_checks::check_language_ub) { + let mut _6: bool; + scope 6 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = copy (*_1); + StorageLive(_4); + StorageLive(_5); + _4 = discriminant(_3); + switchInt(move _4) -> [0: bb2, 1: bb3, otherwise: bb1]; + } + + bb1: { + unreachable; + } + + bb2: { +- StorageLive(_6); +- _6 = const false; +- assume(copy _6); +- _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable]; ++ unreachable; + } + + bb3: { + _2 = move ((_3 as Some).0: i32); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + _0 = copy _2; + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/const_prop/union.main.GVN.diff b/tests/mir-opt/const_prop/union.main.GVN.diff new file mode 100644 index 0000000000000..16a0432ab9013 --- /dev/null +++ b/tests/mir-opt/const_prop/union.main.GVN.diff @@ -0,0 +1,42 @@ +- // MIR for `main` before GVN ++ // MIR for `main` after GVN + + fn main() -> () { + let mut _0: (); + let _1: main::Un; + let mut _2: u32; + let _3: (); + let mut _4: u32; + scope 1 { + debug un => _1; + scope 3 (inlined std::mem::drop::) { + } + } + scope 2 (inlined val) { + } + + bb0: { + StorageLive(_1); +- StorageLive(_2); ++ nop; + _2 = const 1_u32; +- _1 = Un { us: move _2 }; +- StorageDead(_2); ++ _1 = const Un {{ us: 1_u32 }}; ++ nop; + StorageLive(_3); + StorageLive(_4); +- _4 = copy (_1.0: u32); ++ _4 = const 1_u32; + StorageDead(_4); + StorageDead(_3); + _0 = const (); + StorageDead(_1); + return; + } ++ } ++ ++ ALLOC0 (size: 4, align: 4) { ++ 01 00 00 00 │ .... + } + diff --git a/tests/mir-opt/const_prop/union.rs b/tests/mir-opt/const_prop/union.rs new file mode 100644 index 0000000000000..9f197a1a58338 --- /dev/null +++ b/tests/mir-opt/const_prop/union.rs @@ -0,0 +1,22 @@ +//! Tests that we can propagate into places that are projections into unions +//@ test-mir-pass: GVN +//@ compile-flags: -Zinline-mir + +fn val() -> u32 { + 1 +} + +// EMIT_MIR union.main.GVN.diff +fn main() { + // CHECK-LABEL: fn main( + // CHECK: debug un => [[un:_.*]]; + // CHECK: bb0: { + // CHECK: [[un]] = const Un {{{{ us: 1_u32 }}}}; + union Un { + us: u32, + } + + let un = Un { us: val() }; + + drop(unsafe { un.us }); +} diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir index 7e033916fd348..33fbca7f77ed1 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-abort.mir @@ -7,15 +7,14 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 let _4: (); let mut _5: (); let mut _6: (); - let mut _7: (); - let mut _8: u32; + let mut _7: u32; scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); } bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb5, 3: bb8, otherwise: bb9]; + _7 = discriminant((*_1)); + switchInt(move _7) -> [0: bb5, 3: bb8, otherwise: bb9]; } bb1: { diff --git a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir index 613ef2909b5e4..69e7219af9ff8 100644 --- a/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir +++ b/tests/mir-opt/coroutine_drop_cleanup.main-{closure#0}.coroutine_drop.0.panic-unwind.mir @@ -7,15 +7,14 @@ fn main::{closure#0}(_1: *mut {coroutine@$DIR/coroutine_drop_cleanup.rs:12:5: 12 let _4: (); let mut _5: (); let mut _6: (); - let mut _7: (); - let mut _8: u32; + let mut _7: u32; scope 1 { debug _s => (((*_1) as variant#3).0: std::string::String); } bb0: { - _8 = discriminant((*_1)); - switchInt(move _8) -> [0: bb7, 3: bb10, otherwise: bb11]; + _7 = discriminant((*_1)); + switchInt(move _7) -> [0: bb7, 3: bb10, otherwise: bb11]; } bb1: { diff --git a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir index f8b3f68d21e63..9905cc3e00f99 100644 --- a/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir +++ b/tests/mir-opt/coroutine_tiny.main-{closure#0}.coroutine_resume.0.mir @@ -1,7 +1,7 @@ // MIR for `main::{closure#0}` 0 coroutine_resume /* coroutine_layout = CoroutineLayout { field_tys: { - _0: CoroutineSavedTy { + _s0: CoroutineSavedTy { ty: HasDrop, source_info: SourceInfo { span: $DIR/coroutine_tiny.rs:22:13: 22:15 (#0), @@ -14,15 +14,15 @@ Unresumed(0): [], Returned (1): [], Panicked (2): [], - Suspend0 (3): [_0], + Suspend0 (3): [_s0], }, storage_conflicts: BitMatrix(1x1) { - (_0, _0), + (_s0, _s0), }, } */ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}>, _2: u8) -> CoroutineState<(), ()> { - debug _x => _10; + debug _x => _2; let mut _0: std::ops::CoroutineState<(), ()>; let _3: HasDrop; let mut _4: !; @@ -31,19 +31,17 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13} let mut _7: (); let _8: (); let mut _9: (); - let _10: u8; - let mut _11: u32; + let mut _10: u32; scope 1 { debug _d => (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop); } bb0: { - _11 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))); - switchInt(move _11) -> [0: bb1, 3: bb5, otherwise: bb6]; + _10 = discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13}))); + switchInt(move _10) -> [0: bb1, 3: bb5, otherwise: bb6]; } bb1: { - _10 = move _2; nop; (((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:21:5: 21:13})) as variant#3).0: HasDrop) = HasDrop; StorageLive(_4); diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff new file mode 100644 index 0000000000000..fd9ef54fe775f --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = PtrMetadata(copy _2); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = PtrMetadata(copy _10); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff new file mode 100644 index 0000000000000..1fec08c256201 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.32bit.panic-unwind.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = PtrMetadata(copy _2); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = PtrMetadata(copy _10); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff new file mode 100644 index 0000000000000..fd9ef54fe775f --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-abort.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = PtrMetadata(copy _2); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind unreachable]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind unreachable]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = PtrMetadata(copy _10); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind unreachable]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind unreachable]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff new file mode 100644 index 0000000000000..1fec08c256201 --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.main.DataflowConstProp.64bit.panic-unwind.diff @@ -0,0 +1,77 @@ +- // MIR for `main` before DataflowConstProp ++ // MIR for `main` after DataflowConstProp + + fn main() -> () { + let mut _0: (); + let _1: u32; + let mut _2: &[u32]; + let mut _3: &[u32; 3]; + let _4: &[u32; 3]; + let _5: [u32; 3]; + let _6: usize; + let mut _7: usize; + let mut _8: bool; + let mut _10: &[u32]; + let _11: usize; + let mut _12: usize; + let mut _13: bool; + let mut _14: &[u32; 3]; + scope 1 { + debug local => _1; + let _9: u32; + scope 2 { + debug constant => _9; + } + } + + bb0: { + StorageLive(_1); + StorageLive(_2); + StorageLive(_3); + StorageLive(_4); + _14 = const main::promoted[0]; + _4 = copy _14; + _3 = copy _4; + _2 = move _3 as &[u32] (PointerCoercion(Unsize, AsCast)); + StorageDead(_3); + StorageLive(_6); + _6 = const 1_usize; +- _7 = PtrMetadata(copy _2); +- _8 = Lt(copy _6, copy _7); +- assert(move _8, "index out of bounds: the length is {} but the index is {}", move _7, copy _6) -> [success: bb1, unwind continue]; ++ _7 = const 3_usize; ++ _8 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb1, unwind continue]; + } + + bb1: { +- _1 = copy (*_2)[_6]; ++ _1 = copy (*_2)[1 of 2]; + StorageDead(_6); + StorageDead(_4); + StorageDead(_2); + StorageLive(_9); + StorageLive(_10); + _10 = const main::SLICE; + StorageLive(_11); + _11 = const 1_usize; +- _12 = PtrMetadata(copy _10); +- _13 = Lt(copy _11, copy _12); +- assert(move _13, "index out of bounds: the length is {} but the index is {}", move _12, copy _11) -> [success: bb2, unwind continue]; ++ _12 = const 3_usize; ++ _13 = const true; ++ assert(const true, "index out of bounds: the length is {} but the index is {}", const 3_usize, const 1_usize) -> [success: bb2, unwind continue]; + } + + bb2: { +- _9 = copy (*_10)[_11]; ++ _9 = copy (*_10)[1 of 2]; + StorageDead(_11); + StorageDead(_10); + _0 = const (); + StorageDead(_9); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/slice_len.rs b/tests/mir-opt/dataflow-const-prop/slice_len.rs new file mode 100644 index 0000000000000..e0e68f9fde54a --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/slice_len.rs @@ -0,0 +1,34 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: DataflowConstProp +//@ compile-flags: -Zmir-enable-passes=+InstSimplify-after-simplifycfg +// EMIT_MIR_FOR_EACH_BIT_WIDTH + +// EMIT_MIR slice_len.main.DataflowConstProp.diff + +// CHECK-LABEL: fn main( +fn main() { + // CHECK: debug local => [[local:_.*]]; + // CHECK: debug constant => [[constant:_.*]]; + + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK: [[local]] = copy (*{{_.*}})[1 of 2]; + let local = (&[1u32, 2, 3] as &[u32])[1]; + + // CHECK-NOT: {{_.*}} = Len( + // CHECK-NOT: {{_.*}} = Lt( + // CHECK-NOT: assert(move _ + const SLICE: &[u32] = &[1, 2, 3]; + // CHECK: {{_.*}} = const 3_usize; + // CHECK: {{_.*}} = const true; + // CHECK: assert(const true, + + // CHECK-NOT: [[constant]] = {{copy|move}} (*{{_.*}})[_ + // CHECK: [[constant]] = copy (*{{_.*}})[1 of 2]; + let constant = SLICE[1]; +} diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff index 3ea49265cee33..132dfd3d8178a 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.32bit.diff @@ -112,16 +112,16 @@ StorageDead(_10); StorageLive(_14); _14 = const {ALLOC0: &&SmallStruct}; - _31 = deref_copy (*_14); + _31 = copy (*_14); StorageLive(_11); - _32 = deref_copy (*_14); + _32 = copy (*_14); - _11 = copy ((*_32).0: f32); + _11 = const 9f32; StorageLive(_12); - _33 = deref_copy (*_14); + _33 = copy (*_14); _12 = copy ((*_33).1: std::option::Option); StorageLive(_13); - _34 = deref_copy (*_14); + _34 = copy (*_14); _13 = copy ((*_34).2: &[f32]); StorageDead(_14); StorageLive(_15); @@ -149,16 +149,16 @@ StorageDead(_22); StorageLive(_26); _26 = const {ALLOC1: &&BigStruct}; - _35 = deref_copy (*_26); + _35 = copy (*_26); StorageLive(_23); - _36 = deref_copy (*_26); + _36 = copy (*_26); - _23 = copy ((*_36).0: f32); + _23 = const 82f32; StorageLive(_24); - _37 = deref_copy (*_26); + _37 = copy (*_26); _24 = copy ((*_37).1: std::option::Option); StorageLive(_25); - _38 = deref_copy (*_26); + _38 = copy (*_26); _25 = copy ((*_38).2: &[f32]); StorageDead(_26); StorageLive(_27); diff --git a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff index 78a0944975c86..0f3e6f0cb17f7 100644 --- a/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff +++ b/tests/mir-opt/dataflow-const-prop/struct.main.DataflowConstProp.64bit.diff @@ -112,16 +112,16 @@ StorageDead(_10); StorageLive(_14); _14 = const {ALLOC0: &&SmallStruct}; - _31 = deref_copy (*_14); + _31 = copy (*_14); StorageLive(_11); - _32 = deref_copy (*_14); + _32 = copy (*_14); - _11 = copy ((*_32).0: f32); + _11 = const 9f32; StorageLive(_12); - _33 = deref_copy (*_14); + _33 = copy (*_14); _12 = copy ((*_33).1: std::option::Option); StorageLive(_13); - _34 = deref_copy (*_14); + _34 = copy (*_14); _13 = copy ((*_34).2: &[f32]); StorageDead(_14); StorageLive(_15); @@ -149,16 +149,16 @@ StorageDead(_22); StorageLive(_26); _26 = const {ALLOC1: &&BigStruct}; - _35 = deref_copy (*_26); + _35 = copy (*_26); StorageLive(_23); - _36 = deref_copy (*_26); + _36 = copy (*_26); - _23 = copy ((*_36).0: f32); + _23 = const 82f32; StorageLive(_24); - _37 = deref_copy (*_26); + _37 = copy (*_26); _24 = copy ((*_37).1: std::option::Option); StorageLive(_25); - _38 = deref_copy (*_26); + _38 = copy (*_26); _25 = copy ((*_38).2: &[f32]); StorageDead(_26); StorageLive(_27); diff --git a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff index ff18df1efcfc9..d584de6861c0c 100644 --- a/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff +++ b/tests/mir-opt/dead-store-elimination/cycle.cycle.DeadStoreElimination-initial.diff @@ -19,10 +19,6 @@ - _3 = copy _2; - _2 = copy _1; - _1 = copy _5; -+ nop; -+ nop; -+ nop; -+ nop; _4 = cond() -> [return: bb1, unwind continue]; } diff --git a/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff new file mode 100644 index 0000000000000..2a793e24990ae --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/ref.dead_first.DeadStoreElimination-initial.diff @@ -0,0 +1,30 @@ +- // MIR for `dead_first` before DeadStoreElimination-initial ++ // MIR for `dead_first` after DeadStoreElimination-initial + + fn dead_first(_1: &Foo) -> &i32 { + debug v => _1; + let mut _0: &i32; + let mut _2: &i32; + let mut _3: &i32; + let _4: &i32; + scope 1 { + debug a => _2; + } + + bb0: { + StorageLive(_2); +- _2 = &((*_1).2: i32); ++ // DBG: _2 = &((*_1).2: i32); + StorageLive(_3); + StorageLive(_4); + _4 = &((*_1).0: i32); + _3 = &(*_4); + _2 = move _3; + StorageDead(_3); + StorageDead(_4); + _0 = &(*_2); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/dead-store-elimination/ref.rs b/tests/mir-opt/dead-store-elimination/ref.rs new file mode 100644 index 0000000000000..2d3200edab9f6 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/ref.rs @@ -0,0 +1,31 @@ +//@ test-mir-pass: DeadStoreElimination-initial + +pub struct Foo { + a: i32, + b: i64, + c: i32, +} + +// EMIT_MIR ref.tuple.DeadStoreElimination-initial.diff +pub fn tuple(v: (i32, &Foo)) -> i32 { + // CHECK-LABEL: fn tuple + // CHECK: debug _dead => [[dead:_[0-9]+]]; + // CHECK: bb0: + // CHECK: DBG: [[dead]] = &((*_3).2: i32) + let _dead = &v.1.c; + v.1.a +} + +// EMIT_MIR ref.dead_first.DeadStoreElimination-initial.diff +pub fn dead_first(v: &Foo) -> &i32 { + // CHECK-LABEL: fn dead_first + // CHECK: debug a => [[var_a:_[0-9]+]]; + // CHECK: bb0: + // CHECK: DBG: [[var_a]] = &((*_1).2: i32) + // CHECK: [[tmp_4:_[0-9]+]] = &((*_1).0: i32) + // CHECK: [[tmp_3:_[0-9]+]] = &(*[[tmp_4]]) + // CHECK: [[var_a]] = move [[tmp_3]] + let mut a = &v.c; + a = &v.a; + a +} diff --git a/tests/mir-opt/dead-store-elimination/ref.tuple.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/ref.tuple.DeadStoreElimination-initial.diff new file mode 100644 index 0000000000000..3e677d13b89c1 --- /dev/null +++ b/tests/mir-opt/dead-store-elimination/ref.tuple.DeadStoreElimination-initial.diff @@ -0,0 +1,25 @@ +- // MIR for `tuple` before DeadStoreElimination-initial ++ // MIR for `tuple` after DeadStoreElimination-initial + + fn tuple(_1: (i32, &Foo)) -> i32 { + debug v => _1; + let mut _0: i32; + let _2: &i32; + let mut _3: &Foo; + let mut _4: &Foo; + scope 1 { + debug _dead => _2; + } + + bb0: { +- StorageLive(_2); +- _3 = copy (_1.1: &Foo); +- _2 = &((*_3).2: i32); ++ // DBG: _2 = &((*_3).2: i32); + _4 = copy (_1.1: &Foo); + _0 = copy ((*_4).0: i32); +- StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff new file mode 100644 index 0000000000000..fe00da67e8bb0 --- /dev/null +++ b/tests/mir-opt/debuginfo/dest_prop.remap_debuginfo_locals.DestinationPropagation.diff @@ -0,0 +1,36 @@ +- // MIR for `remap_debuginfo_locals` before DestinationPropagation ++ // MIR for `remap_debuginfo_locals` after DestinationPropagation + + fn remap_debuginfo_locals(_1: bool, _2: &bool) -> &bool { +- debug c => _3; ++ debug c => _2; + let mut _0: &bool; + let mut _3: &bool; + let mut _4: bool; + + bb0: { +- // DBG: _3 = &_1; +- StorageLive(_4); +- _4 = copy _1; +- _3 = copy _2; +- switchInt(copy _4) -> [1: bb1, otherwise: bb2]; ++ // DBG: _2 = &_1; ++ nop; ++ nop; ++ nop; ++ switchInt(copy _1) -> [1: bb1, otherwise: bb2]; + } + + bb1: { + goto -> bb2; + } + + bb2: { +- StorageDead(_4); +- _0 = copy _3; ++ nop; ++ _0 = copy _2; + return; + } + } + diff --git a/tests/mir-opt/debuginfo/dest_prop.rs b/tests/mir-opt/debuginfo/dest_prop.rs new file mode 100644 index 0000000000000..a734cacb4d29a --- /dev/null +++ b/tests/mir-opt/debuginfo/dest_prop.rs @@ -0,0 +1,39 @@ +//@ test-mir-pass: DestinationPropagation +//@ compile-flags: -g -Zmir-enable-passes=+DeadStoreElimination-initial + +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// EMIT_MIR dest_prop.remap_debuginfo_locals.DestinationPropagation.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn remap_debuginfo_locals(a: bool, b: &bool) -> &bool { + // CHECK-LABEL: fn remap_debuginfo_locals( + // CHECK: debug c => [[c:_.*]]; + // CHECK: bb0: + // CHECK-NEXT: DBG: [[c]] = &_1; + mir! { + let _3: &bool; + let _4: bool; + debug c => _3; + { + _3 = &a; + StorageLive(_4); + _4 = a; + _3 = b; + match _4 { + true => bb1, + _ => bb2, + } + } + bb1 = { + Goto(bb2) + } + bb2 = { + StorageDead(_4); + RET = _3; + Return() + } + } +} diff --git a/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff new file mode 100644 index 0000000000000..2d93b1d842fa1 --- /dev/null +++ b/tests/mir-opt/debuginfo/ref_prop.remap_debuginfo_locals.ReferencePropagation.diff @@ -0,0 +1,33 @@ +- // MIR for `remap_debuginfo_locals` before ReferencePropagation ++ // MIR for `remap_debuginfo_locals` after ReferencePropagation + + fn remap_debuginfo_locals() -> () { + let mut _0: (); + let _1: &usize; + let mut _2: *const usize; + let _3: &usize; + let _4: usize; + let mut _5: &usize; + scope 1 (inlined foo) { +- debug a => _1; ++ debug a => _5; + } + + bb0: { +- StorageLive(_1); +- StorageLive(_2); +- StorageLive(_3); + _5 = const remap_debuginfo_locals::promoted[0]; +- _3 = &(*_5); +- _2 = &raw const (*_3); +- // DBG: _1 = &(*_2); +- _1 = &(*_2); +- StorageDead(_2); +- StorageDead(_3); +- StorageDead(_1); ++ // DBG: _5 = &(*_5); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/ref_prop.rs b/tests/mir-opt/debuginfo/ref_prop.rs new file mode 100644 index 0000000000000..60d68ba178a7b --- /dev/null +++ b/tests/mir-opt/debuginfo/ref_prop.rs @@ -0,0 +1,30 @@ +//@ test-mir-pass: ReferencePropagation +//@ compile-flags: -g -Zub_checks=false -Zinline-mir -Zmir-enable-passes=+DeadStoreElimination-initial + +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// EMIT_MIR ref_prop.remap_debuginfo_locals.ReferencePropagation.diff +pub fn remap_debuginfo_locals() { + // CHECK-LABEL: fn remap_debuginfo_locals() + // CHECK: debug a => [[a:_.*]]; + // CHECK: bb0: + // CHECK-NEXT: [[a]] = const + // CHECK-NEXT: DBG: [[a]] = &(*[[a]]); + foo(&0); +} + +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +#[inline] +fn foo(x: *const usize) -> &'static usize { + mir! { + debug a => RET; + { + RET = &*x; + RET = &*x; + Return() + } + } +} diff --git a/tests/mir-opt/debuginfo/simplifycfg.drop_debuginfo.SimplifyCfg-final.diff b/tests/mir-opt/debuginfo/simplifycfg.drop_debuginfo.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..d4a73351ee4a5 --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.drop_debuginfo.SimplifyCfg-final.diff @@ -0,0 +1,26 @@ +- // MIR for `drop_debuginfo` before SimplifyCfg-final ++ // MIR for `drop_debuginfo` after SimplifyCfg-final + + fn drop_debuginfo(_1: &Foo, _2: bool) -> i32 { + debug foo_a => _3; + debug foo_b => _4; + let mut _0: i32; + let mut _3: &i32; + let mut _4: &i64; + + bb0: { +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; +- } +- +- bb1: { +- // DBG: _3 = &((*_1).0: i32); +- goto -> bb2; +- } +- +- bb2: { + // DBG: _4 = &((*_1).1: i64); + _0 = copy ((*_1).2: i32); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_1.SimplifyCfg-final.diff b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_1.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..1c12358ad8934 --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_1.SimplifyCfg-final.diff @@ -0,0 +1,30 @@ +- // MIR for `preserve_debuginfo_1` before SimplifyCfg-final ++ // MIR for `preserve_debuginfo_1` after SimplifyCfg-final + + fn preserve_debuginfo_1(_1: &Foo, _2: &mut bool) -> i32 { + debug foo_a => _3; + debug foo_b => _4; + debug foo_c => _5; + let mut _0: i32; + let mut _3: &i32; + let mut _4: &i64; + let mut _5: &i32; + + bb0: { +- goto -> bb1; +- } +- +- bb1: { + (*_2) = const true; + // DBG: _3 = &((*_1).0: i32); +- goto -> bb2; +- } +- +- bb2: { + // DBG: _4 = &((*_1).1: i64); + _0 = copy ((*_1).2: i32); + // DBG: _5 = &((*_1).2: i32); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_2.SimplifyCfg-final.diff b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_2.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..de8e5612c8788 --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_2.SimplifyCfg-final.diff @@ -0,0 +1,29 @@ +- // MIR for `preserve_debuginfo_2` before SimplifyCfg-final ++ // MIR for `preserve_debuginfo_2` after SimplifyCfg-final + + fn preserve_debuginfo_2(_1: &Foo) -> i32 { + debug foo_a => _2; + debug foo_b => _3; + debug foo_c => _4; + let mut _0: i32; + let mut _2: &i32; + let mut _3: &i64; + let mut _4: &i32; + + bb0: { +- goto -> bb1; +- } +- +- bb1: { + // DBG: _2 = &((*_1).0: i32); +- goto -> bb2; +- } +- +- bb2: { + // DBG: _3 = &((*_1).1: i64); + _0 = copy ((*_1).2: i32); + // DBG: _4 = &((*_1).2: i32); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_3.SimplifyCfg-final.diff b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_3.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..11372a262a76e --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_3.SimplifyCfg-final.diff @@ -0,0 +1,37 @@ +- // MIR for `preserve_debuginfo_3` before SimplifyCfg-final ++ // MIR for `preserve_debuginfo_3` after SimplifyCfg-final + + fn preserve_debuginfo_3(_1: &Foo, _2: bool) -> i32 { + debug foo_a => _3; + debug foo_b => _4; + debug foo_c => _5; + let mut _0: i32; + let mut _3: &i32; + let mut _4: &i64; + let mut _5: &i32; + + bb0: { +- switchInt(copy _2) -> [1: bb1, otherwise: bb2]; ++ switchInt(copy _2) -> [1: bb2, otherwise: bb1]; + } + + bb1: { +- // DBG: _3 = &((*_1).0: i32); +- goto -> bb3; +- } +- +- bb2: { + // DBG: _4 = &((*_1).1: i64); + _0 = copy ((*_1).2: i32); + return; + } + +- bb3: { ++ bb2: { ++ // DBG: _3 = &((*_1).0: i32); + // DBG: _5 = &((*_1).2: i32); + _0 = copy ((*_1).0: i32); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_identical_succs.SimplifyCfg-final.diff b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_identical_succs.SimplifyCfg-final.diff new file mode 100644 index 0000000000000..0c6a75237d8b2 --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.preserve_debuginfo_identical_succs.SimplifyCfg-final.diff @@ -0,0 +1,29 @@ +- // MIR for `preserve_debuginfo_identical_succs` before SimplifyCfg-final ++ // MIR for `preserve_debuginfo_identical_succs` after SimplifyCfg-final + + fn preserve_debuginfo_identical_succs(_1: &Foo, _2: bool) -> i32 { + debug foo_a => _3; + debug foo_b => _4; + debug foo_c => _5; + let mut _0: i32; + let mut _3: &i32; + let mut _4: &i64; + let mut _5: &i32; + + bb0: { +- switchInt(copy _2) -> [1: bb1, otherwise: bb1]; +- } +- +- bb1: { + // DBG: _3 = &((*_1).0: i32); +- goto -> bb2; +- } +- +- bb2: { + // DBG: _4 = &((*_1).1: i64); + _0 = copy ((*_1).2: i32); + // DBG: _5 = &((*_1).2: i32); + return; + } + } + diff --git a/tests/mir-opt/debuginfo/simplifycfg.rs b/tests/mir-opt/debuginfo/simplifycfg.rs new file mode 100644 index 0000000000000..2bd510fd3b9db --- /dev/null +++ b/tests/mir-opt/debuginfo/simplifycfg.rs @@ -0,0 +1,207 @@ +//@ test-mir-pass: SimplifyCfg-final +//@ compile-flags: -Zmir-enable-passes=+DeadStoreElimination-initial + +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +pub struct Foo { + a: i32, + b: i64, + c: i32, +} + +// EMIT_MIR simplifycfg.drop_debuginfo.SimplifyCfg-final.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn drop_debuginfo(foo: &Foo, c: bool) -> i32 { + // CHECK-LABEL: fn drop_debuginfo + // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; + // CHECK: bb0: { + // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) + // CHECK-NEXT: _0 = copy ((*_1).2: i32); + // CHECK-NEXT: return; + mir! { + let _foo_a: &i32; + let _foo_b: &i64; + debug foo_a => _foo_a; + debug foo_b => _foo_b; + { + match c { + true => tmp, + _ => ret, + } + } + tmp = { + // Because we don't know if `c` is always true, we must drop this debuginfo. + _foo_a = &(*foo).a; + Goto(ret) + } + ret = { + _foo_b = &(*foo).b; + RET = (*foo).c; + Return() + } + } +} + +// EMIT_MIR simplifycfg.preserve_debuginfo_1.SimplifyCfg-final.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn preserve_debuginfo_1(foo: &Foo, v: &mut bool) -> i32 { + // CHECK-LABEL: fn preserve_debuginfo_1 + // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; + // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; + // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; + // CHECK: bb0: { + // CHECK-NEXT: (*_2) = const true; + // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) + // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) + // CHECK-NEXT: _0 = copy ((*_1).2: i32); + // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) + // CHECK-NEXT: return; + mir! { + let _foo_a: &i32; + let _foo_b: &i64; + let _foo_c: &i32; + debug foo_a => _foo_a; + debug foo_b => _foo_b; + debug foo_c => _foo_c; + { + Goto(tmp) + } + tmp = { + *v = true; + _foo_a = &(*foo).a; + Goto(ret) + } + ret = { + _foo_b = &(*foo).b; + RET = (*foo).c; + _foo_c = &(*foo).c; + Return() + } + } +} + +// EMIT_MIR simplifycfg.preserve_debuginfo_2.SimplifyCfg-final.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn preserve_debuginfo_2(foo: &Foo) -> i32 { + // CHECK-LABEL: fn preserve_debuginfo_2 + // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; + // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; + // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; + // CHECK: bb0: { + // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) + // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) + // CHECK-NEXT: _0 = copy ((*_1).2: i32); + // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) + // CHECK-NEXT: return; + mir! { + let _foo_a: &i32; + let _foo_b: &i64; + let _foo_c: &i32; + debug foo_a => _foo_a; + debug foo_b => _foo_b; + debug foo_c => _foo_c; + { + Goto(tmp) + } + tmp = { + _foo_a = &(*foo).a; + Goto(ret) + } + ret = { + _foo_b = &(*foo).b; + RET = (*foo).c; + _foo_c = &(*foo).c; + Return() + } + } +} + +// EMIT_MIR simplifycfg.preserve_debuginfo_3.SimplifyCfg-final.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn preserve_debuginfo_3(foo: &Foo, c: bool) -> i32 { + // CHECK-LABEL: fn preserve_debuginfo_3 + // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; + // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; + // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; + // CHECK: bb0: { + // CHECK-NEXT: switchInt(copy _2) -> [1: bb2, otherwise: bb1]; + // CHECK: bb1: { + // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) + // CHECK-NEXT: _0 = copy ((*_1).2: i32); + // CHECK-NEXT: return; + // CHECK: bb2: { + // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) + // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) + // CHECK-NEXT: _0 = copy ((*_1).0: i32); + // CHECK-NEXT: return; + mir! { + let _foo_a: &i32; + let _foo_b: &i64; + let _foo_c: &i32; + debug foo_a => _foo_a; + debug foo_b => _foo_b; + debug foo_c => _foo_c; + { + match c { + true => tmp, + _ => ret, + } + } + tmp = { + _foo_a = &(*foo).a; + Goto(ret_1) + } + ret = { + _foo_b = &(*foo).b; + RET = (*foo).c; + Return() + } + ret_1 = { + _foo_c = &(*foo).c; + RET = (*foo).a; + Return() + } + } +} + +// EMIT_MIR simplifycfg.preserve_debuginfo_identical_succs.SimplifyCfg-final.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub fn preserve_debuginfo_identical_succs(foo: &Foo, c: bool) -> i32 { + // CHECK-LABEL: fn preserve_debuginfo_identical_succs + // CHECK: debug foo_a => [[foo_a:_[0-9]+]]; + // CHECK: debug foo_b => [[foo_b:_[0-9]+]]; + // CHECK: debug foo_c => [[foo_c:_[0-9]+]]; + // CHECK: bb0: { + // CHECK-NEXT: DBG: [[foo_a]] = &((*_1).0: i32) + // CHECK-NEXT: DBG: [[foo_b]] = &((*_1).1: i64) + // CHECK-NEXT: _0 = copy ((*_1).2: i32); + // CHECK-NEXT: DBG: [[foo_c]] = &((*_1).2: i32) + // CHECK-NEXT: return; + mir! { + let _foo_a: &i32; + let _foo_b: &i64; + let _foo_c: &i32; + debug foo_a => _foo_a; + debug foo_b => _foo_b; + debug foo_c => _foo_c; + { + match c { + true => tmp, + _ => tmp, + } + } + tmp = { + _foo_a = &(*foo).a; + Goto(ret) + } + ret = { + _foo_b = &(*foo).b; + RET = (*foo).c; + _foo_c = &(*foo).c; + Return() + } + } +} diff --git a/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..e80660f176b7b --- /dev/null +++ b/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-abort.diff @@ -0,0 +1,19 @@ +- // MIR for `rewrap` before DestinationPropagation ++ // MIR for `rewrap` after DestinationPropagation + + fn rewrap() -> (u8,) { + let mut _0: (u8,); + let mut _1: (u8,); + let mut _2: (u8,); + + bb0: { +- (_1.0: u8) = const 0_u8; +- _0 = copy _1; ++ (_0.0: u8) = const 0_u8; ++ nop; + _2 = (copy (_0.0: u8),); + _0 = copy _2; + return; + } + } + diff --git a/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-unwind.diff new file mode 100644 index 0000000000000..e80660f176b7b --- /dev/null +++ b/tests/mir-opt/dest-prop/aggregate.rewrap.DestinationPropagation.panic-unwind.diff @@ -0,0 +1,19 @@ +- // MIR for `rewrap` before DestinationPropagation ++ // MIR for `rewrap` after DestinationPropagation + + fn rewrap() -> (u8,) { + let mut _0: (u8,); + let mut _1: (u8,); + let mut _2: (u8,); + + bb0: { +- (_1.0: u8) = const 0_u8; +- _0 = copy _1; ++ (_0.0: u8) = const 0_u8; ++ nop; + _2 = (copy (_0.0: u8),); + _0 = copy _2; + return; + } + } + diff --git a/tests/mir-opt/dest-prop/aggregate.rs b/tests/mir-opt/dest-prop/aggregate.rs new file mode 100644 index 0000000000000..636852159eb4c --- /dev/null +++ b/tests/mir-opt/dest-prop/aggregate.rs @@ -0,0 +1,51 @@ +//@ test-mir-pass: DestinationPropagation +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +#![feature(custom_mir, core_intrinsics)] +#![allow(internal_features)] + +use std::intrinsics::mir::*; +use std::mem::MaybeUninit; + +fn dump_var(_: T) {} + +// EMIT_MIR aggregate.rewrap.DestinationPropagation.diff +#[custom_mir(dialect = "runtime")] +fn rewrap() -> (u8,) { + // CHECK-LABEL: fn rewrap( + // CHECK: (_0.0: u8) = const 0_u8; + // CHECK: _2 = (copy (_0.0: u8),); + // CHECK: _0 = copy _2; + mir! { + let _1: (u8,); + let _2: (u8,); + { + _1.0 = 0; + RET = _1; + _2 = (RET.0, ); + RET = _2; + Return() + } + } +} + +// EMIT_MIR aggregate.swap.DestinationPropagation.diff +#[custom_mir(dialect = "runtime")] +fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) { + // CHECK-LABEL: fn swap( + // CHECK: _0 = const + // CHECK: _2 = copy _0; + // CHECK: _0 = (copy (_2.1: {{.*}}), copy (_2.0: {{.*}})); + mir! { + let _1: (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>); + let _2: (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>); + let _3: (); + { + _1 = const { (MaybeUninit::new([0; 10]), MaybeUninit::new([1; 10])) }; + _2 = _1; + _1 = (_2.1, _2.0); + RET = _1; + Return() + } + } +} diff --git a/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..3aaad3aaf6920 --- /dev/null +++ b/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-abort.diff @@ -0,0 +1,22 @@ +- // MIR for `swap` before DestinationPropagation ++ // MIR for `swap` after DestinationPropagation + + fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) { + let mut _0: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _1: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _2: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _3: (); + + bb0: { +- _1 = const swap::{constant#6}; +- _2 = copy _1; +- _1 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>)); +- _0 = copy _1; ++ _0 = const swap::{constant#6}; ++ _2 = copy _0; ++ _0 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>)); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-unwind.diff new file mode 100644 index 0000000000000..3aaad3aaf6920 --- /dev/null +++ b/tests/mir-opt/dest-prop/aggregate.swap.DestinationPropagation.panic-unwind.diff @@ -0,0 +1,22 @@ +- // MIR for `swap` before DestinationPropagation ++ // MIR for `swap` after DestinationPropagation + + fn swap() -> (MaybeUninit<[u8; 10]>, MaybeUninit<[u8; 10]>) { + let mut _0: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _1: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _2: (std::mem::MaybeUninit<[u8; 10]>, std::mem::MaybeUninit<[u8; 10]>); + let mut _3: (); + + bb0: { +- _1 = const swap::{constant#6}; +- _2 = copy _1; +- _1 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>)); +- _0 = copy _1; ++ _0 = const swap::{constant#6}; ++ _2 = copy _0; ++ _0 = (copy (_2.1: std::mem::MaybeUninit<[u8; 10]>), copy (_2.0: std::mem::MaybeUninit<[u8; 10]>)); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff new file mode 100644 index 0000000000000..e9fbcf20a7228 --- /dev/null +++ b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-abort.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before DestinationPropagation ++ // MIR for `nrvo` after DestinationPropagation + + fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; + let mut _0: [u8; 1024]; + let mut _2: [u8; 1024]; + let _3: (); + let mut _4: for<'a> fn(&'a mut [u8; 1024]); + let mut _5: &mut [u8; 1024]; + let mut _6: &mut [u8; 1024]; + scope 1 { + debug buf => _2; + } + + bb0: { + StorageLive(_2); + _2 = [const 0_u8; 1024]; + StorageLive(_3); +- StorageLive(_4); +- _4 = copy _1; ++ nop; ++ nop; + StorageLive(_5); + StorageLive(_6); + _6 = &mut _2; + _5 = &mut (*_6); +- _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; ++ _3 = move _1(move _5) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_5); +- StorageDead(_4); ++ nop; + StorageDead(_6); + StorageDead(_3); + _0 = copy _2; + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff new file mode 100644 index 0000000000000..95d5fe1b9304b --- /dev/null +++ b/tests/mir-opt/dest-prop/nrvo_borrowed.nrvo.DestinationPropagation.panic-unwind.diff @@ -0,0 +1,43 @@ +- // MIR for `nrvo` before DestinationPropagation ++ // MIR for `nrvo` after DestinationPropagation + + fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { + debug init => _1; + let mut _0: [u8; 1024]; + let mut _2: [u8; 1024]; + let _3: (); + let mut _4: for<'a> fn(&'a mut [u8; 1024]); + let mut _5: &mut [u8; 1024]; + let mut _6: &mut [u8; 1024]; + scope 1 { + debug buf => _2; + } + + bb0: { + StorageLive(_2); + _2 = [const 0_u8; 1024]; + StorageLive(_3); +- StorageLive(_4); +- _4 = copy _1; ++ nop; ++ nop; + StorageLive(_5); + StorageLive(_6); + _6 = &mut _2; + _5 = &mut (*_6); +- _3 = move _4(move _5) -> [return: bb1, unwind continue]; ++ _3 = move _1(move _5) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_5); +- StorageDead(_4); ++ nop; + StorageDead(_6); + StorageDead(_3); + _0 = copy _2; + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/dest-prop/nrvo_borrowed.rs b/tests/mir-opt/dest-prop/nrvo_borrowed.rs new file mode 100644 index 0000000000000..6f3076d4c13e9 --- /dev/null +++ b/tests/mir-opt/dest-prop/nrvo_borrowed.rs @@ -0,0 +1,16 @@ +// skip-filecheck +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: DestinationPropagation + +// EMIT_MIR nrvo_borrowed.nrvo.DestinationPropagation.diff +fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { + let mut buf = [0; 1024]; + init(&mut buf); + buf +} + +fn main() { + let _ = nrvo(|buf| { + buf[4] = 4; + }); +} diff --git a/tests/mir-opt/nrvo_miscompile_111005.rs b/tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs similarity index 75% rename from tests/mir-opt/nrvo_miscompile_111005.rs rename to tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs index 131f7b8f6f991..17e6450278ac6 100644 --- a/tests/mir-opt/nrvo_miscompile_111005.rs +++ b/tests/mir-opt/dest-prop/nrvo_miscompile_111005.rs @@ -1,18 +1,17 @@ // This is a miscompilation, #111005 to track -//@ test-mir-pass: RenameReturnPlace +//@ test-mir-pass: DestinationPropagation #![feature(custom_mir, core_intrinsics)] extern crate core; use core::intrinsics::mir::*; -// EMIT_MIR nrvo_miscompile_111005.wrong.RenameReturnPlace.diff +// EMIT_MIR nrvo_miscompile_111005.wrong.DestinationPropagation.diff #[custom_mir(dialect = "runtime", phase = "initial")] pub fn wrong(arg: char) -> char { // CHECK-LABEL: fn wrong( // CHECK: _0 = copy _1; - // FIXME: This is wrong: - // CHECK-NEXT: _0 = const 'b'; + // CHECK-NEXT: _1 = const 'b'; // CHECK-NEXT: return; mir! { { diff --git a/tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff b/tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff new file mode 100644 index 0000000000000..60cf9236f6c2a --- /dev/null +++ b/tests/mir-opt/dest-prop/nrvo_miscompile_111005.wrong.DestinationPropagation.diff @@ -0,0 +1,18 @@ +- // MIR for `wrong` before DestinationPropagation ++ // MIR for `wrong` after DestinationPropagation + + fn wrong(_1: char) -> char { + let mut _0: char; + let mut _2: char; + + bb0: { +- _2 = copy _1; +- _0 = copy _2; +- _2 = const 'b'; ++ nop; ++ _0 = copy _1; ++ _1 = const 'b'; + return; + } + } + diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff deleted file mode 100644 index ef418798faaf7..0000000000000 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff +++ /dev/null @@ -1,27 +0,0 @@ -- // MIR for `main` before DestinationPropagation -+ // MIR for `main` after DestinationPropagation - - fn main() -> () { - let mut _0: (); - let _1: main::Un; - let mut _2: u32; - scope 1 { - debug un => _1; - scope 3 (inlined std::mem::drop::) { - debug _x => _2; - } - } - scope 2 (inlined val) { - } - - bb0: { - StorageLive(_1); - _1 = Un { us: const 1_u32 }; - StorageLive(_2); - _2 = copy (_1.0: u32); - StorageDead(_2); - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff deleted file mode 100644 index ef418798faaf7..0000000000000 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff +++ /dev/null @@ -1,27 +0,0 @@ -- // MIR for `main` before DestinationPropagation -+ // MIR for `main` after DestinationPropagation - - fn main() -> () { - let mut _0: (); - let _1: main::Un; - let mut _2: u32; - scope 1 { - debug un => _1; - scope 3 (inlined std::mem::drop::) { - debug _x => _2; - } - } - scope 2 (inlined val) { - } - - bb0: { - StorageLive(_1); - _1 = Un { us: const 1_u32 }; - StorageLive(_2); - _2 = copy (_1.0: u32); - StorageDead(_2); - StorageDead(_1); - return; - } - } - diff --git a/tests/mir-opt/dest-prop/union.rs b/tests/mir-opt/dest-prop/union.rs deleted file mode 100644 index 85eded0998031..0000000000000 --- a/tests/mir-opt/dest-prop/union.rs +++ /dev/null @@ -1,19 +0,0 @@ -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//! Tests that we can propagate into places that are projections into unions -//@ compile-flags: -Zunsound-mir-opts -C debuginfo=full -fn val() -> u32 { - 1 -} - -// EMIT_MIR union.main.DestinationPropagation.diff -fn main() { - // CHECK-LABEL: fn main( - // CHECK: {{_.*}} = Un { us: const 1_u32 }; - union Un { - us: u32, - } - - let un = Un { us: val() }; - - drop(unsafe { un.us }); -} diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.rs b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.rs index 4368933dc627f..5534a45f19d64 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.rs +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.rs @@ -1,10 +1,14 @@ -// skip-filecheck -//@ compile-flags: -Zmir-enable-passes=+Inline,+GVN --crate-type lib +//@ test-mir-pass: GVN +//@ compile-flags: -Zinline-mir --crate-type lib // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR_FOR_EACH_PANIC_STRATEGY // EMIT_MIR dont_reset_cast_kind_without_updating_operand.test.GVN.diff fn test() { + // CHECK-LABEL: fn test( + // CHECK: debug slf => [[SLF:_.*]]; + // CHECK: debug _x => [[X:_.*]]; + // CHECK: [[X]] = copy [[SLF]] as *mut () (PtrToPtr); let vp_ctx: &Box<()> = &Box::new(()); let slf: *const () = &raw const **vp_ctx; let bytes = std::ptr::slice_from_raw_parts(slf, 1); diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff index f203b80e4776c..f47e544385497 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-abort.diff @@ -6,24 +6,26 @@ let _1: &std::boxed::Box<()>; let _2: &std::boxed::Box<()>; let _3: std::boxed::Box<()>; - let mut _6: *const (); - let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _23: usize; + let mut _4: (); + let mut _7: *const (); + let mut _9: *const [()]; + let mut _10: std::boxed::Box<()>; + let mut _11: *const (); + let mut _27: usize; scope 1 { debug vp_ctx => _1; - let _4: *const (); + let _5: *const (); scope 2 { - debug slf => _10; - let _5: *const [()]; + debug slf => _5; + let _6: *const [()]; scope 3 { - debug bytes => _5; - let _7: *mut (); + debug bytes => _6; + let _8: *mut (); scope 4 { - debug _x => _7; + debug _x => _8; } scope 18 (inlined foo) { + let mut _28: *const [()]; } } scope 16 (inlined slice_from_raw_parts::<()>) { @@ -33,21 +35,24 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _11: usize; let mut _12: usize; - let mut _13: *mut u8; + let mut _13: usize; + let mut _14: *mut u8; + let mut _15: *const (); + let mut _16: std::ptr::NonNull<()>; + let mut _17: std::ptr::Unique<()>; scope 6 (inlined alloc::alloc::exchange_malloc) { - let _14: std::alloc::Layout; - let mut _15: std::result::Result, std::alloc::AllocError>; - let mut _16: isize; - let mut _18: !; + let _18: std::alloc::Layout; + let mut _19: std::result::Result, std::alloc::AllocError>; + let mut _20: isize; + let mut _22: !; scope 7 { - let _17: std::ptr::NonNull<[u8]>; + let _21: std::ptr::NonNull<[u8]>; scope 8 { scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { scope 13 (inlined NonNull::<[u8]>::cast::) { - let mut _22: *mut [u8]; + let mut _26: *mut [u8]; scope 14 (inlined NonNull::<[u8]>::as_ptr) { } } @@ -60,31 +65,39 @@ } } scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) { - let mut _19: bool; - let _20: (); - let mut _21: std::ptr::Alignment; + let mut _23: bool; + let _24: (); + let mut _25: std::ptr::Alignment; } } } bb0: { StorageLive(_1); - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); - StorageLive(_11); + StorageLive(_4); +- _4 = (); ++ _4 = const (); StorageLive(_12); StorageLive(_13); -- _11 = SizeOf(()); -- _12 = AlignOf(()); -+ _11 = const 0_usize; -+ _12 = const 1_usize; StorageLive(_14); + StorageLive(_15); StorageLive(_16); StorageLive(_17); - StorageLive(_19); - _19 = const false; -- switchInt(move _19) -> [0: bb6, otherwise: bb5]; -+ switchInt(const false) -> [0: bb6, otherwise: bb5]; +- _12 = SizeOf(()); +- _13 = AlignOf(()); ++ _12 = const 0_usize; ++ _13 = const 1_usize; + StorageLive(_18); + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + StorageLive(_24); + StorageLive(_23); + _23 = UbChecks(); + switchInt(move _23) -> [0: bb6, otherwise: bb5]; } bb1: { @@ -98,77 +111,98 @@ } bb3: { -- _18 = handle_alloc_error(move _14) -> unwind unreachable; -+ _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; +- _22 = handle_alloc_error(move _18) -> unwind unreachable; ++ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; } bb4: { - _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); - StorageLive(_22); - _22 = copy _17 as *mut [u8] (Transmute); - _13 = copy _22 as *mut u8 (PtrToPtr); + _21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>); +- StorageLive(_26); ++ nop; + _26 = copy _21 as *mut [u8] (Transmute); + _14 = copy _26 as *mut u8 (PtrToPtr); +- StorageDead(_26); ++ nop; + StorageDead(_19); + StorageDead(_24); StorageDead(_22); - StorageDead(_15); + StorageDead(_21); + StorageDead(_20); + StorageDead(_18); +- _15 = copy _14 as *const () (PtrToPtr); ++ _15 = copy _26 as *const () (PtrToPtr); + _16 = NonNull::<()> { pointer: copy _15 }; + _17 = Unique::<()> { pointer: copy _16, _marker: const PhantomData::<()> }; + _3 = Box::<()>(move _17, const std::alloc::Global); +- (*_15) = move _4; ++ (*_15) = const (); StorageDead(_17); StorageDead(_16); + StorageDead(_15); StorageDead(_14); - _3 = ShallowInitBox(copy _13, ()); StorageDead(_13); StorageDead(_12); - StorageDead(_11); + StorageDead(_4); _2 = &_3; - _1 = copy _2; - StorageDead(_2); - StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _1 = &(*_2); +- StorageDead(_2); - StorageLive(_5); +- _10 = copy (*_1); ++ nop; ++ nop; ++ _10 = copy (*_2); + _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _5 = &raw const (*_11); +- StorageLive(_6); + nop; - StorageLive(_6); -- _6 = copy _4; -+ _6 = copy _10; - StorageLive(_23); - _23 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _23); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_23); - StorageDead(_6); StorageLive(_7); + _7 = copy _5; + StorageLive(_27); + _27 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _27); ++ _6 = *const [()] from (copy _5, const 1_usize); + StorageDead(_27); + StorageDead(_7); StorageLive(_8); - _8 = copy _5; -- _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); + StorageLive(_9); + _9 = copy _6; + StorageLive(_28); +- _28 = copy _9; +- _8 = copy _9 as *mut () (PtrToPtr); ++ _28 = copy _6; ++ _8 = copy _5 as *mut () (PtrToPtr); + StorageDead(_28); + StorageDead(_9); + _0 = const (); StorageDead(_8); - StorageDead(_7); +- StorageDead(_6); - StorageDead(_5); + nop; - StorageDead(_4); ++ nop; drop(_3) -> [return: bb1, unwind unreachable]; } bb5: { -- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb6, unwind unreachable]; -+ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; +- _24 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable]; ++ _24 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_19); - StorageLive(_21); -- _21 = copy _12 as std::ptr::Alignment (Transmute); -- _14 = Layout { size: copy _11, align: move _21 }; -+ _21 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); -+ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; - StorageDead(_21); - StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb7, unwind unreachable]; -+ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; + StorageDead(_23); + StorageLive(_25); +- _25 = copy _13 as std::ptr::Alignment (Transmute); +- _18 = Layout { size: copy _12, align: move _25 }; ++ _25 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); ++ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; + StorageDead(_25); + StorageLive(_19); +- _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _18, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; + _20 = discriminant(_19); + switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2]; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff index b2085afb71379..82a14a8b6ec99 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.32bit.panic-unwind.diff @@ -6,24 +6,26 @@ let _1: &std::boxed::Box<()>; let _2: &std::boxed::Box<()>; let _3: std::boxed::Box<()>; - let mut _6: *const (); - let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _11: usize; + let mut _4: (); + let mut _7: *const (); + let mut _9: *const [()]; + let mut _10: std::boxed::Box<()>; + let mut _11: *const (); + let mut _12: usize; scope 1 { debug vp_ctx => _1; - let _4: *const (); + let _5: *const (); scope 2 { - debug slf => _10; - let _5: *const [()]; + debug slf => _5; + let _6: *const [()]; scope 3 { - debug bytes => _5; - let _7: *mut (); + debug bytes => _6; + let _8: *mut (); scope 4 { - debug _x => _7; + debug _x => _8; } scope 7 (inlined foo) { + let mut _13: *const [()]; } } scope 5 (inlined slice_from_raw_parts::<()>) { @@ -35,41 +37,54 @@ bb0: { StorageLive(_1); - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); - _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; + StorageLive(_4); +- _4 = (); +- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue]; ++ _4 = const (); ++ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } bb1: { + StorageDead(_4); _2 = &_3; - _1 = copy _2; - StorageDead(_2); - StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _1 = &(*_2); +- StorageDead(_2); - StorageLive(_5); +- _10 = copy (*_1); ++ nop; ++ nop; ++ _10 = copy (*_2); + _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _5 = &raw const (*_11); +- StorageLive(_6); + nop; - StorageLive(_6); -- _6 = copy _4; -+ _6 = copy _10; - StorageLive(_11); - _11 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _11); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_11); - StorageDead(_6); StorageLive(_7); + _7 = copy _5; + StorageLive(_12); + _12 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _12); ++ _6 = *const [()] from (copy _5, const 1_usize); + StorageDead(_12); + StorageDead(_7); StorageLive(_8); - _8 = copy _5; -- _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); + StorageLive(_9); + _9 = copy _6; + StorageLive(_13); +- _13 = copy _9; +- _8 = copy _9 as *mut () (PtrToPtr); ++ _13 = copy _6; ++ _8 = copy _5 as *mut () (PtrToPtr); + StorageDead(_13); + StorageDead(_9); + _0 = const (); StorageDead(_8); - StorageDead(_7); +- StorageDead(_6); - StorageDead(_5); + nop; - StorageDead(_4); ++ nop; drop(_3) -> [return: bb2, unwind: bb3]; } diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff index f072eb6ef8bf6..fe88ff7a53e7d 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-abort.diff @@ -6,24 +6,26 @@ let _1: &std::boxed::Box<()>; let _2: &std::boxed::Box<()>; let _3: std::boxed::Box<()>; - let mut _6: *const (); - let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _23: usize; + let mut _4: (); + let mut _7: *const (); + let mut _9: *const [()]; + let mut _10: std::boxed::Box<()>; + let mut _11: *const (); + let mut _27: usize; scope 1 { debug vp_ctx => _1; - let _4: *const (); + let _5: *const (); scope 2 { - debug slf => _10; - let _5: *const [()]; + debug slf => _5; + let _6: *const [()]; scope 3 { - debug bytes => _5; - let _7: *mut (); + debug bytes => _6; + let _8: *mut (); scope 4 { - debug _x => _7; + debug _x => _8; } scope 18 (inlined foo) { + let mut _28: *const [()]; } } scope 16 (inlined slice_from_raw_parts::<()>) { @@ -33,21 +35,24 @@ } } scope 5 (inlined Box::<()>::new) { - let mut _11: usize; let mut _12: usize; - let mut _13: *mut u8; + let mut _13: usize; + let mut _14: *mut u8; + let mut _15: *const (); + let mut _16: std::ptr::NonNull<()>; + let mut _17: std::ptr::Unique<()>; scope 6 (inlined alloc::alloc::exchange_malloc) { - let _14: std::alloc::Layout; - let mut _15: std::result::Result, std::alloc::AllocError>; - let mut _16: isize; - let mut _18: !; + let _18: std::alloc::Layout; + let mut _19: std::result::Result, std::alloc::AllocError>; + let mut _20: isize; + let mut _22: !; scope 7 { - let _17: std::ptr::NonNull<[u8]>; + let _21: std::ptr::NonNull<[u8]>; scope 8 { scope 11 (inlined NonNull::<[u8]>::as_mut_ptr) { scope 12 (inlined NonNull::<[u8]>::as_non_null_ptr) { scope 13 (inlined NonNull::<[u8]>::cast::) { - let mut _22: *mut [u8]; + let mut _26: *mut [u8]; scope 14 (inlined NonNull::<[u8]>::as_ptr) { } } @@ -60,31 +65,39 @@ } } scope 9 (inlined #[track_caller] Layout::from_size_align_unchecked) { - let mut _19: bool; - let _20: (); - let mut _21: std::ptr::Alignment; + let mut _23: bool; + let _24: (); + let mut _25: std::ptr::Alignment; } } } bb0: { StorageLive(_1); - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); - StorageLive(_11); + StorageLive(_4); +- _4 = (); ++ _4 = const (); StorageLive(_12); StorageLive(_13); -- _11 = SizeOf(()); -- _12 = AlignOf(()); -+ _11 = const 0_usize; -+ _12 = const 1_usize; StorageLive(_14); + StorageLive(_15); StorageLive(_16); StorageLive(_17); - StorageLive(_19); - _19 = const false; -- switchInt(move _19) -> [0: bb6, otherwise: bb5]; -+ switchInt(const false) -> [0: bb6, otherwise: bb5]; +- _12 = SizeOf(()); +- _13 = AlignOf(()); ++ _12 = const 0_usize; ++ _13 = const 1_usize; + StorageLive(_18); + StorageLive(_20); + StorageLive(_21); + StorageLive(_22); + StorageLive(_24); + StorageLive(_23); + _23 = UbChecks(); + switchInt(move _23) -> [0: bb6, otherwise: bb5]; } bb1: { @@ -98,77 +111,98 @@ } bb3: { -- _18 = handle_alloc_error(move _14) -> unwind unreachable; -+ _18 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; +- _22 = handle_alloc_error(move _18) -> unwind unreachable; ++ _22 = handle_alloc_error(const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}) -> unwind unreachable; } bb4: { - _17 = copy ((_15 as Ok).0: std::ptr::NonNull<[u8]>); - StorageLive(_22); - _22 = copy _17 as *mut [u8] (Transmute); - _13 = copy _22 as *mut u8 (PtrToPtr); + _21 = copy ((_19 as Ok).0: std::ptr::NonNull<[u8]>); +- StorageLive(_26); ++ nop; + _26 = copy _21 as *mut [u8] (Transmute); + _14 = copy _26 as *mut u8 (PtrToPtr); +- StorageDead(_26); ++ nop; + StorageDead(_19); + StorageDead(_24); StorageDead(_22); - StorageDead(_15); + StorageDead(_21); + StorageDead(_20); + StorageDead(_18); +- _15 = copy _14 as *const () (PtrToPtr); ++ _15 = copy _26 as *const () (PtrToPtr); + _16 = NonNull::<()> { pointer: copy _15 }; + _17 = Unique::<()> { pointer: copy _16, _marker: const PhantomData::<()> }; + _3 = Box::<()>(move _17, const std::alloc::Global); +- (*_15) = move _4; ++ (*_15) = const (); StorageDead(_17); StorageDead(_16); + StorageDead(_15); StorageDead(_14); - _3 = ShallowInitBox(copy _13, ()); StorageDead(_13); StorageDead(_12); - StorageDead(_11); + StorageDead(_4); _2 = &_3; - _1 = copy _2; - StorageDead(_2); - StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _1 = &(*_2); +- StorageDead(_2); - StorageLive(_5); +- _10 = copy (*_1); ++ nop; ++ nop; ++ _10 = copy (*_2); + _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _5 = &raw const (*_11); +- StorageLive(_6); + nop; - StorageLive(_6); -- _6 = copy _4; -+ _6 = copy _10; - StorageLive(_23); - _23 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _23); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_23); - StorageDead(_6); StorageLive(_7); + _7 = copy _5; + StorageLive(_27); + _27 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _27); ++ _6 = *const [()] from (copy _5, const 1_usize); + StorageDead(_27); + StorageDead(_7); StorageLive(_8); - _8 = copy _5; -- _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); + StorageLive(_9); + _9 = copy _6; + StorageLive(_28); +- _28 = copy _9; +- _8 = copy _9 as *mut () (PtrToPtr); ++ _28 = copy _6; ++ _8 = copy _5 as *mut () (PtrToPtr); + StorageDead(_28); + StorageDead(_9); + _0 = const (); StorageDead(_8); - StorageDead(_7); +- StorageDead(_6); - StorageDead(_5); + nop; - StorageDead(_4); ++ nop; drop(_3) -> [return: bb1, unwind unreachable]; } bb5: { -- _20 = Layout::from_size_align_unchecked::precondition_check(copy _11, copy _12) -> [return: bb6, unwind unreachable]; -+ _20 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; +- _24 = Layout::from_size_align_unchecked::precondition_check(copy _12, copy _13) -> [return: bb6, unwind unreachable]; ++ _24 = Layout::from_size_align_unchecked::precondition_check(const 0_usize, const 1_usize) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_19); - StorageLive(_21); -- _21 = copy _12 as std::ptr::Alignment (Transmute); -- _14 = Layout { size: copy _11, align: move _21 }; -+ _21 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); -+ _14 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; - StorageDead(_21); - StorageLive(_15); -- _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _14, const false) -> [return: bb7, unwind unreachable]; -+ _15 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; + StorageDead(_23); + StorageLive(_25); +- _25 = copy _13 as std::ptr::Alignment (Transmute); +- _18 = Layout { size: copy _12, align: move _25 }; ++ _25 = const std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0); ++ _18 = const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}; + StorageDead(_25); + StorageLive(_19); +- _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], copy _18, const false) -> [return: bb7, unwind unreachable]; ++ _19 = std::alloc::Global::alloc_impl(const alloc::alloc::exchange_malloc::promoted[0], const Layout {{ size: 0_usize, align: std::ptr::Alignment(std::ptr::alignment::AlignmentEnum::_Align1Shl0) }}, const false) -> [return: bb7, unwind unreachable]; } bb7: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb4, 1: bb3, otherwise: bb2]; + _20 = discriminant(_19); + switchInt(move _20) -> [0: bb4, 1: bb3, otherwise: bb2]; } + } + diff --git a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff index b2085afb71379..82a14a8b6ec99 100644 --- a/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/dont_reset_cast_kind_without_updating_operand.test.GVN.64bit.panic-unwind.diff @@ -6,24 +6,26 @@ let _1: &std::boxed::Box<()>; let _2: &std::boxed::Box<()>; let _3: std::boxed::Box<()>; - let mut _6: *const (); - let mut _8: *const [()]; - let mut _9: std::boxed::Box<()>; - let mut _10: *const (); - let mut _11: usize; + let mut _4: (); + let mut _7: *const (); + let mut _9: *const [()]; + let mut _10: std::boxed::Box<()>; + let mut _11: *const (); + let mut _12: usize; scope 1 { debug vp_ctx => _1; - let _4: *const (); + let _5: *const (); scope 2 { - debug slf => _10; - let _5: *const [()]; + debug slf => _5; + let _6: *const [()]; scope 3 { - debug bytes => _5; - let _7: *mut (); + debug bytes => _6; + let _8: *mut (); scope 4 { - debug _x => _7; + debug _x => _8; } scope 7 (inlined foo) { + let mut _13: *const [()]; } } scope 5 (inlined slice_from_raw_parts::<()>) { @@ -35,41 +37,54 @@ bb0: { StorageLive(_1); - StorageLive(_2); +- StorageLive(_2); ++ nop; StorageLive(_3); - _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; + StorageLive(_4); +- _4 = (); +- _3 = Box::<()>::new(move _4) -> [return: bb1, unwind continue]; ++ _4 = const (); ++ _3 = Box::<()>::new(const ()) -> [return: bb1, unwind continue]; } bb1: { + StorageDead(_4); _2 = &_3; - _1 = copy _2; - StorageDead(_2); - StorageLive(_4); -- _9 = deref_copy _3; -+ _9 = copy _3; - _10 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); - _4 = copy _10; + _1 = &(*_2); +- StorageDead(_2); - StorageLive(_5); +- _10 = copy (*_1); ++ nop; ++ nop; ++ _10 = copy (*_2); + _11 = copy ((_10.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *const () (Transmute); + _5 = &raw const (*_11); +- StorageLive(_6); + nop; - StorageLive(_6); -- _6 = copy _4; -+ _6 = copy _10; - StorageLive(_11); - _11 = const 1_usize; -- _5 = *const [()] from (copy _6, copy _11); -+ _5 = *const [()] from (copy _10, const 1_usize); - StorageDead(_11); - StorageDead(_6); StorageLive(_7); + _7 = copy _5; + StorageLive(_12); + _12 = const 1_usize; +- _6 = *const [()] from (copy _7, copy _12); ++ _6 = *const [()] from (copy _5, const 1_usize); + StorageDead(_12); + StorageDead(_7); StorageLive(_8); - _8 = copy _5; -- _7 = copy _8 as *mut () (PtrToPtr); -+ _7 = copy ((_9.0: std::ptr::Unique<()>).0: std::ptr::NonNull<()>) as *mut () (Transmute); + StorageLive(_9); + _9 = copy _6; + StorageLive(_13); +- _13 = copy _9; +- _8 = copy _9 as *mut () (PtrToPtr); ++ _13 = copy _6; ++ _8 = copy _5 as *mut () (PtrToPtr); + StorageDead(_13); + StorageDead(_9); + _0 = const (); StorageDead(_8); - StorageDead(_7); +- StorageDead(_6); - StorageDead(_5); + nop; - StorageDead(_4); ++ nop; drop(_3) -> [return: bb2, unwind: bb3]; } diff --git a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index fec318c1ab492..c8b516c14987b 100644 --- a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -76,7 +76,7 @@ _4 = (move _5, move _6); StorageDead(_6); StorageDead(_5); - _34 = deref_copy (_4.0: &ViewportPercentageLength); + _34 = copy (_4.0: &ViewportPercentageLength); _11 = discriminant((*_34)); switchInt(move _11) -> [0: bb2, 1: bb3, 2: bb4, 3: bb5, otherwise: bb12]; } @@ -92,35 +92,35 @@ } bb2: { - _35 = deref_copy (_4.1: &ViewportPercentageLength); + _35 = copy (_4.1: &ViewportPercentageLength); _7 = discriminant((*_35)); switchInt(move _7) -> [0: bb9, otherwise: bb1]; } bb3: { - _36 = deref_copy (_4.1: &ViewportPercentageLength); + _36 = copy (_4.1: &ViewportPercentageLength); _8 = discriminant((*_36)); switchInt(move _8) -> [1: bb8, otherwise: bb1]; } bb4: { - _37 = deref_copy (_4.1: &ViewportPercentageLength); + _37 = copy (_4.1: &ViewportPercentageLength); _9 = discriminant((*_37)); switchInt(move _9) -> [2: bb7, otherwise: bb1]; } bb5: { - _38 = deref_copy (_4.1: &ViewportPercentageLength); + _38 = copy (_4.1: &ViewportPercentageLength); _10 = discriminant((*_38)); switchInt(move _10) -> [3: bb6, otherwise: bb1]; } bb6: { StorageLive(_27); - _39 = deref_copy (_4.0: &ViewportPercentageLength); + _39 = copy (_4.0: &ViewportPercentageLength); _27 = copy (((*_39) as Vmax).0: f32); StorageLive(_28); - _40 = deref_copy (_4.1: &ViewportPercentageLength); + _40 = copy (_4.1: &ViewportPercentageLength); _28 = copy (((*_40) as Vmax).0: f32); StorageLive(_29); StorageLive(_30); @@ -139,10 +139,10 @@ bb7: { StorageLive(_22); - _41 = deref_copy (_4.0: &ViewportPercentageLength); + _41 = copy (_4.0: &ViewportPercentageLength); _22 = copy (((*_41) as Vmin).0: f32); StorageLive(_23); - _42 = deref_copy (_4.1: &ViewportPercentageLength); + _42 = copy (_4.1: &ViewportPercentageLength); _23 = copy (((*_42) as Vmin).0: f32); StorageLive(_24); StorageLive(_25); @@ -161,10 +161,10 @@ bb8: { StorageLive(_17); - _43 = deref_copy (_4.0: &ViewportPercentageLength); + _43 = copy (_4.0: &ViewportPercentageLength); _17 = copy (((*_43) as Vh).0: f32); StorageLive(_18); - _44 = deref_copy (_4.1: &ViewportPercentageLength); + _44 = copy (_4.1: &ViewportPercentageLength); _18 = copy (((*_44) as Vh).0: f32); StorageLive(_19); StorageLive(_20); @@ -183,10 +183,10 @@ bb9: { StorageLive(_12); - _45 = deref_copy (_4.0: &ViewportPercentageLength); + _45 = copy (_4.0: &ViewportPercentageLength); _12 = copy (((*_45) as Vw).0: f32); StorageLive(_13); - _46 = deref_copy (_4.1: &ViewportPercentageLength); + _46 = copy (_4.1: &ViewportPercentageLength); _13 = copy (((*_46) as Vw).0: f32); StorageLive(_14); StorageLive(_15); diff --git a/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff index 6a4c947b8826e..ab81f0a67e4eb 100644 --- a/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +++ b/tests/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -16,7 +16,7 @@ } bb1: { - _4 = deref_copy (((*_1) as Some).0: &E<'_>); + _4 = copy (((*_1) as Some).0: &E<'_>); _2 = discriminant((*_4)); switchInt(move _2) -> [1: bb2, 0: bb3, otherwise: bb5]; } diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff index 267a4c1cf6beb..cf850351c1d62 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.32bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff index 8e5c403cd7e6b..dc5ea1add0005 100644 --- a/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.cand.EnumSizeOpt.64bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff index 96c5aadd85fd4..3cd2e74a0db6f 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.32bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff index d20e2e08eaafd..10b0ec5a63fa4 100644 --- a/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff +++ b/tests/mir-opt/enum_opt.unin.EnumSizeOpt.64bit.diff @@ -44,7 +44,6 @@ + _9 = copy _8 as *mut u8 (PtrToPtr); + _10 = &raw const _2; + _11 = copy _10 as *const u8 (PtrToPtr); -+ Deinit(_8); + copy_nonoverlapping(dst = copy _9, src = copy _11, count = copy _7); + StorageDead(_4); + nop; @@ -59,7 +58,6 @@ + _17 = copy _16 as *mut u8 (PtrToPtr); + _18 = &raw const _1; + _19 = copy _18 as *const u8 (PtrToPtr); -+ Deinit(_16); + copy_nonoverlapping(dst = copy _17, src = copy _19, count = copy _15); + StorageDead(_12); + nop; diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff index 0d0477fe7729f..59b65a52f4ee6 100644 --- a/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.array_len.GVN.panic-abort.diff @@ -12,8 +12,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); _3 = &(*_1); _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit)); @@ -23,8 +22,7 @@ - _0 = PtrMetadata(move _4); + _0 = const 42_usize; StorageDead(_4); -- StorageDead(_2); -+ nop; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff index 0d0477fe7729f..59b65a52f4ee6 100644 --- a/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.array_len.GVN.panic-unwind.diff @@ -12,8 +12,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); _3 = &(*_1); _2 = move _3 as &[i32] (PointerCoercion(Unsize, Implicit)); @@ -23,8 +22,7 @@ - _0 = PtrMetadata(move _4); + _0 = const 42_usize; StorageDead(_4); -- StorageDead(_2); -+ nop; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/gvn.dereference_indexing.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereference_indexing.GVN.panic-abort.diff index 9bdcc2f108a6a..1a07638cbafea 100644 --- a/tests/mir-opt/gvn.dereference_indexing.GVN.panic-abort.diff +++ b/tests/mir-opt/gvn.dereference_indexing.GVN.panic-abort.diff @@ -43,7 +43,8 @@ + nop; StorageLive(_8); StorageLive(_9); - _9 = copy (*_3); +- _9 = copy (*_3); ++ _9 = copy _1[_4]; _8 = opaque::(move _9) -> [return: bb2, unwind unreachable]; } diff --git a/tests/mir-opt/gvn.dereference_indexing.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereference_indexing.GVN.panic-unwind.diff index f38bc51adc480..6e67b66e783c4 100644 --- a/tests/mir-opt/gvn.dereference_indexing.GVN.panic-unwind.diff +++ b/tests/mir-opt/gvn.dereference_indexing.GVN.panic-unwind.diff @@ -43,7 +43,8 @@ + nop; StorageLive(_8); StorageLive(_9); - _9 = copy (*_3); +- _9 = copy (*_3); ++ _9 = copy _1[_4]; _8 = opaque::(move _9) -> [return: bb2, unwind continue]; } diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 98f94fbf0b146..3c3241fefe22e 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -1065,8 +1065,8 @@ fn dereference_indexing(array: [u8; 2], index: usize) { &array[i] }; - // CHECK-NOT: [{{.*}}] - // CHECK: [[tmp:_.*]] = copy (*[[a]]); + // CHECK-NOT: StorageDead([[i]]); + // CHECK: [[tmp:_.*]] = copy _1[[[i]]]; // CHECK: opaque::(move [[tmp]]) opaque(*a); } diff --git a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff index 452d8a9332036..eed8cb7d62e70 100644 --- a/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff +++ b/tests/mir-opt/gvn_copy_aggregate.all_copy_2.GVN.diff @@ -25,15 +25,14 @@ bb0: { - StorageLive(_2); -- _8 = deref_copy (*_1); + nop; -+ _8 = copy (*_1); + _8 = copy (*_1); _2 = copy ((*_8).0: i32); - StorageLive(_3); -- _9 = deref_copy (*_1); +- _9 = copy (*_1); - _3 = copy ((*_9).1: u64); - StorageLive(_4); -- _10 = deref_copy (*_1); +- _10 = copy (*_1); - _4 = copy ((*_10).2: [i8; 3]); + nop; + _9 = copy _8; diff --git a/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff new file mode 100644 index 0000000000000..92e5ccabedf9e --- /dev/null +++ b/tests/mir-opt/gvn_loop.loop_deref_mut.GVN.diff @@ -0,0 +1,115 @@ +- // MIR for `loop_deref_mut` before GVN ++ // MIR for `loop_deref_mut` after GVN + + fn loop_deref_mut(_1: &mut Value) -> Value { + debug val => _1; + let mut _0: Value; + let _2: &Value; + let _3: &Value; + let mut _4: &Value; + let mut _6: !; + let mut _8: isize; + let mut _9: !; + let mut _10: (); + let mut _12: i32; + let _13: (); + let mut _14: bool; + let mut _15: !; + let mut _16: Value; + scope 1 { + debug val_alias => _2; + let mut _5: bool; + scope 2 { + debug stop => _5; + let _7: i32; + scope 3 { + debug v => _7; + let _11: Value; + scope 4 { + debug v => _11; + } + } + } + } + + bb0: { + StorageLive(_2); +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = &(*_1); + _3 = get::(move _4) -> [return: bb1, unwind unreachable]; + } + + bb1: { + _2 = &(*_3); + StorageDead(_4); +- StorageDead(_3); ++ nop; + StorageLive(_5); + _5 = const false; +- _8 = discriminant((*_2)); ++ _8 = discriminant((*_3)); + switchInt(move _8) -> [0: bb3, otherwise: bb2]; + } + + bb2: { + unreachable; + } + + bb3: { +- StorageLive(_7); +- _7 = copy (((*_2) as V0).0: i32); ++ nop; ++ _7 = copy (((*_3) as V0).0: i32); + StorageLive(_9); + goto -> bb4; + } + + bb4: { + StorageLive(_11); + StorageLive(_12); + _12 = copy _7; +- _11 = Value::V0(move _12); ++ _11 = Value::V0(copy _7); + StorageDead(_12); + StorageLive(_13); + StorageLive(_14); + _14 = copy _5; + switchInt(move _14) -> [0: bb6, otherwise: bb5]; + } + + bb5: { + _0 = move _11; + StorageDead(_14); + StorageDead(_13); + StorageDead(_11); + StorageDead(_9); +- StorageDead(_7); ++ nop; + StorageDead(_5); + StorageDead(_2); + return; + } + + bb6: { + _13 = const (); + StorageDead(_14); + StorageDead(_13); + _5 = const true; + StorageLive(_16); +- _16 = Value::V1; +- (*_1) = move _16; ++ _16 = const Value::V1; ++ (*_1) = const Value::V1; + StorageDead(_16); + _10 = const (); + StorageDead(_11); + goto -> bb4; + } ++ } ++ ++ ALLOC0 (size: 8, align: 4) { ++ 01 00 00 00 __ __ __ __ │ ....░░░░ + } + diff --git a/tests/mir-opt/gvn_loop.rs b/tests/mir-opt/gvn_loop.rs new file mode 100644 index 0000000000000..6e9df55a968dc --- /dev/null +++ b/tests/mir-opt/gvn_loop.rs @@ -0,0 +1,39 @@ +//@ test-mir-pass: GVN + +#![crate_type = "lib"] +#![feature(core_intrinsics, rustc_attrs)] + +pub enum Value { + V0(i32), + V1, +} + +// Check that we do not use the dereferenced value of `val_alias` when returning. + +// EMIT_MIR gvn_loop.loop_deref_mut.GVN.diff +fn loop_deref_mut(val: &mut Value) -> Value { + // CHECK-LABEL: fn loop_deref_mut( + // CHECK: [[VAL_REF:_.*]] = get::( + // CHECK: [[V:_.*]] = copy (((*[[VAL_REF]]) as V0).0: i32); + // CEHCK-NOT: copy (*[[VAL_REF]]); + // CHECK: [[RET:_*]] = Value::V0(copy [[V]]); + // CEHCK-NOT: copy (*[[VAL_REF]]); + // CHECK: _0 = move [[RET]] + let val_alias: &Value = get(val); + let mut stop = false; + let Value::V0(v) = *val_alias else { unsafe { core::intrinsics::unreachable() } }; + loop { + let v = Value::V0(v); + if stop { + return v; + } + stop = true; + *val = Value::V1; + } +} + +#[inline(never)] +#[rustc_nounwind] +fn get(v: &T) -> &T { + v +} diff --git a/tests/mir-opt/gvn_repeat.index_place.GVN.diff b/tests/mir-opt/gvn_repeat.index_place.GVN.diff new file mode 100644 index 0000000000000..1eb7e9015cc3f --- /dev/null +++ b/tests/mir-opt/gvn_repeat.index_place.GVN.diff @@ -0,0 +1,15 @@ +- // MIR for `index_place` before GVN ++ // MIR for `index_place` after GVN + + fn index_place(_1: usize, _2: usize, _3: [i32; 5]) -> i32 { + let mut _0: i32; + let mut _4: &i32; + + bb0: { + _4 = &_3[_1]; + _1 = copy _2; + _0 = copy (*_4); + return; + } + } + diff --git a/tests/mir-opt/gvn_repeat.repeat_local.GVN.diff b/tests/mir-opt/gvn_repeat.repeat_local.GVN.diff index fd04782528117..eb3f885b8665b 100644 --- a/tests/mir-opt/gvn_repeat.repeat_local.GVN.diff +++ b/tests/mir-opt/gvn_repeat.repeat_local.GVN.diff @@ -10,8 +10,7 @@ _4 = [copy _3; 5]; _5 = &_4[_1]; _1 = copy _2; -- _0 = copy (*_5); -+ _0 = copy _3; + _0 = copy (*_5); return; } } diff --git a/tests/mir-opt/gvn_repeat.rs b/tests/mir-opt/gvn_repeat.rs index bbbb2a7ccbaf5..49364c6bfd232 100644 --- a/tests/mir-opt/gvn_repeat.rs +++ b/tests/mir-opt/gvn_repeat.rs @@ -6,6 +6,23 @@ use std::intrinsics::mir::*; +// EMIT_MIR gvn_repeat.index_place.GVN.diff +#[custom_mir(dialect = "runtime")] +pub fn index_place(mut idx1: usize, idx2: usize, array: [i32; 5]) -> i32 { + // CHECK-LABEL: fn index_place( + // CHECK: let mut [[ELEM:.*]]: &i32; + // CHECK: _0 = copy (*[[ELEM]]) + mir! { + let elem; + { + elem = &array[idx1]; + idx1 = idx2; + RET = *elem; + Return() + } + } +} + // EMIT_MIR gvn_repeat.repeat_place.GVN.diff #[custom_mir(dialect = "runtime")] pub fn repeat_place(mut idx1: usize, idx2: usize, val: &i32) -> i32 { @@ -29,7 +46,8 @@ pub fn repeat_place(mut idx1: usize, idx2: usize, val: &i32) -> i32 { #[custom_mir(dialect = "runtime")] pub fn repeat_local(mut idx1: usize, idx2: usize, val: i32) -> i32 { // CHECK-LABEL: fn repeat_local( - // CHECK: _0 = copy _3 + // CHECK: let mut [[ELEM:.*]]: &i32; + // CHECK: _0 = copy (*[[ELEM]]); mir! { let array; let elem; @@ -44,6 +62,7 @@ pub fn repeat_local(mut idx1: usize, idx2: usize, val: i32) -> i32 { } fn main() { + assert_eq!(index_place(0, 5, [0; 5]), 0); assert_eq!(repeat_place(0, 5, &0), 0); assert_eq!(repeat_local(0, 5, 0), 0); } diff --git a/tests/mir-opt/inline/asm_unwind.rs b/tests/mir-opt/inline/asm_unwind.rs index 8a102b2f56138..df4dc8f0c3335 100644 --- a/tests/mir-opt/inline/asm_unwind.rs +++ b/tests/mir-opt/inline/asm_unwind.rs @@ -4,6 +4,7 @@ //@ needs-asm-support //@ needs-unwind //@ compile-flags: -Zinline-mir-hint-threshold=1000 -C debuginfo=full +//@ ignore-backends: gcc #![feature(asm_unwind)] struct D; diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff index 0615f8132af00..86e8749fb0b51 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff @@ -9,8 +9,8 @@ let mut _4: I; + scope 1 (inlined > as FnMut>::call_mut) { + let mut _5: &mut dyn std::ops::FnMut; -+ let mut _6: std::boxed::Box>; -+ let mut _7: *const dyn std::ops::FnMut; ++ let mut _6: *const dyn std::ops::FnMut; ++ let mut _7: std::ptr::NonNull>; + } bb0: { @@ -22,9 +22,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); -+ _5 = &mut (*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique>).0: std::ptr::NonNull>); ++ _6 = copy _7 as *const dyn std::ops::FnMut (Transmute); ++ _5 = &mut (*_6); + _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable]; } diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff index 21b20329d4fa9..50136ae8766b2 100644 --- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff @@ -9,8 +9,8 @@ let mut _4: I; + scope 1 (inlined > as FnMut>::call_mut) { + let mut _5: &mut dyn std::ops::FnMut; -+ let mut _6: std::boxed::Box>; -+ let mut _7: *const dyn std::ops::FnMut; ++ let mut _6: *const dyn std::ops::FnMut; ++ let mut _7: std::ptr::NonNull>; + } bb0: { @@ -22,9 +22,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique>).0: std::ptr::NonNull>) as *const dyn std::ops::FnMut (Transmute); -+ _5 = &mut (*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique>).0: std::ptr::NonNull>); ++ _6 = copy _7 as *const dyn std::ops::FnMut (Transmute); ++ _5 = &mut (*_6); + _0 = as FnMut>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2]; } diff --git a/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-abort.diff new file mode 100644 index 0000000000000..8e03432c2af2d --- /dev/null +++ b/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `caller::{closure#0}` before ForceInline ++ // MIR for `caller::{closure#0}` after ForceInline + + fn caller::{closure#0}(_1: &{closure@$DIR/forced_closure_inherent.rs:14:6: 14:8}) -> () { + let mut _0: (); + let _2: (); ++ scope 1 (inlined Foo::callee_forced) { ++ } + + bb0: { + StorageLive(_2); +- _2 = Foo::callee_forced() -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + StorageDead(_2); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-unwind.diff new file mode 100644 index 0000000000000..0e41fd89dacf7 --- /dev/null +++ b/tests/mir-opt/inline/forced_closure_inherent.caller-{closure#0}.ForceInline.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `caller::{closure#0}` before ForceInline ++ // MIR for `caller::{closure#0}` after ForceInline + + fn caller::{closure#0}(_1: &{closure@$DIR/forced_closure_inherent.rs:14:6: 14:8}) -> () { + let mut _0: (); + let _2: (); ++ scope 1 (inlined Foo::callee_forced) { ++ } + + bb0: { + StorageLive(_2); +- _2 = Foo::callee_forced() -> [return: bb1, unwind continue]; +- } +- +- bb1: { + StorageDead(_2); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_closure_inherent.rs b/tests/mir-opt/inline/forced_closure_inherent.rs new file mode 100644 index 0000000000000..949c7d6ecbf28 --- /dev/null +++ b/tests/mir-opt/inline/forced_closure_inherent.rs @@ -0,0 +1,19 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 --crate-type=lib +#![feature(rustc_attrs)] + +struct Foo {} + +impl Foo { + #[rustc_force_inline] + pub fn callee_forced() {} +} + +// EMIT_MIR forced_closure_inherent.caller-{closure#0}.ForceInline.diff +pub fn caller() { + (|| { + Foo::callee_forced(); + // CHECK-LABEL: fn caller::{closure#0}( + // CHECK: (inlined Foo::callee_forced) + })(); +} diff --git a/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-abort.diff new file mode 100644 index 0000000000000..6ea1894af9895 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::bar) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::bar() -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-unwind.diff new file mode 100644 index 0000000000000..dd91c3387723f --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent.caller.ForceInline.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::bar) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::bar() -> [return: bb1, unwind continue]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent.rs b/tests/mir-opt/inline/forced_inherent.rs new file mode 100644 index 0000000000000..24bf8daa64450 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent.rs @@ -0,0 +1,17 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 --crate-type=lib +#![feature(rustc_attrs)] + +struct Foo; + +impl Foo { + #[rustc_force_inline] + fn bar() {} +} + +// EMIT_MIR forced_inherent.caller.ForceInline.diff +fn caller() { + Foo::bar(); + // CHECK-LABEL: fn caller( + // CHECK: (inlined Foo::bar) +} diff --git a/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-abort.diff new file mode 100644 index 0000000000000..6ea1894af9895 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::bar) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::bar() -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-unwind.diff new file mode 100644 index 0000000000000..dd91c3387723f --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_ambiguous.caller.ForceInline.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::bar) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::bar() -> [return: bb1, unwind continue]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_ambiguous.rs b/tests/mir-opt/inline/forced_inherent_ambiguous.rs new file mode 100644 index 0000000000000..e3c5d3e4f9e81 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_ambiguous.rs @@ -0,0 +1,25 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 --crate-type=lib +#![feature(rustc_attrs)] + +struct Foo; + +impl Foo { + #[rustc_force_inline] + fn bar() {} +} + +trait Tr { + fn bar(); +} + +impl Tr for Foo { + fn bar() {} +} + +// EMIT_MIR forced_inherent_ambiguous.caller.ForceInline.diff +fn caller() { + Foo::bar(); + // CHECK-LABEL: fn caller( + // CHECK: (inlined Foo::bar) +} diff --git a/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-abort.diff new file mode 100644 index 0000000000000..6495ddbafba41 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-abort.diff @@ -0,0 +1,12 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> {async fn body of caller()} { + let mut _0: {async fn body of caller()}; + + bb0: { + _0 = {coroutine@$DIR/forced_inherent_async.rs:14:19: 18:2 (#0)}; + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-unwind.diff new file mode 100644 index 0000000000000..6495ddbafba41 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_async.caller.ForceInline.panic-unwind.diff @@ -0,0 +1,12 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> {async fn body of caller()} { + let mut _0: {async fn body of caller()}; + + bb0: { + _0 = {coroutine@$DIR/forced_inherent_async.rs:14:19: 18:2 (#0)}; + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_async.rs b/tests/mir-opt/inline/forced_inherent_async.rs new file mode 100644 index 0000000000000..ce58a0ac48f47 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_async.rs @@ -0,0 +1,18 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 --crate-type=lib +//@ edition: 2021 +#![feature(rustc_attrs)] + +struct Foo {} + +impl Foo { + #[rustc_force_inline] + pub fn callee_forced() {} +} + +// EMIT_MIR forced_inherent_async.caller.ForceInline.diff +async fn caller() { + Foo::callee_forced(); + // CHECK-LABEL: fn caller( + // CHECK: (inlined Foo::callee_forced) +} diff --git a/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-abort.diff b/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-abort.diff new file mode 100644 index 0000000000000..edaf2820d85c3 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::callee_forced) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::callee_forced() -> [return: bb1, unwind unreachable]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-unwind.diff b/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-unwind.diff new file mode 100644 index 0000000000000..22f8b14a724b8 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_dead_code.caller.ForceInline.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `caller` before ForceInline ++ // MIR for `caller` after ForceInline + + fn caller() -> () { + let mut _0: (); + let _1: (); ++ scope 1 (inlined Foo::callee_forced) { ++ } + + bb0: { + StorageLive(_1); +- _1 = Foo::callee_forced() -> [return: bb1, unwind continue]; +- } +- +- bb1: { + StorageDead(_1); + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/inline/forced_inherent_dead_code.rs b/tests/mir-opt/inline/forced_inherent_dead_code.rs new file mode 100644 index 0000000000000..057a4cac52870 --- /dev/null +++ b/tests/mir-opt/inline/forced_inherent_dead_code.rs @@ -0,0 +1,21 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ compile-flags: -Copt-level=0 -Clink-dead-code +#![feature(rustc_attrs)] + +struct Foo {} + +impl Foo { + #[rustc_force_inline] + pub fn callee_forced() {} +} + +// EMIT_MIR forced_inherent_dead_code.caller.ForceInline.diff +pub fn caller() { + Foo::callee_forced(); + // CHECK-LABEL: fn caller( + // CHECK: (inlined Foo::callee_forced) +} + +fn main() { + caller(); +} diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff index ecea7a97513d5..97a8a99d9805e 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff @@ -9,8 +9,8 @@ let mut _4: (i32,); + scope 1 (inlined as Fn<(i32,)>>::call) { + let mut _5: &dyn std::ops::Fn(i32); -+ let mut _6: std::boxed::Box; -+ let mut _7: *const dyn std::ops::Fn(i32); ++ let mut _6: *const dyn std::ops::Fn(i32); ++ let mut _7: std::ptr::NonNull; + } bb0: { @@ -23,9 +23,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); -+ _5 = &(*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique).0: std::ptr::NonNull); ++ _6 = copy _7 as *const dyn std::ops::Fn(i32) (Transmute); ++ _5 = &(*_6); + _2 = >::call(move _5, move _4) -> [return: bb2, unwind unreachable]; } diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff index 3a4a528e879fb..3b18052616e2f 100644 --- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff @@ -9,8 +9,8 @@ let mut _4: (i32,); + scope 1 (inlined as Fn<(i32,)>>::call) { + let mut _5: &dyn std::ops::Fn(i32); -+ let mut _6: std::boxed::Box; -+ let mut _7: *const dyn std::ops::Fn(i32); ++ let mut _6: *const dyn std::ops::Fn(i32); ++ let mut _7: std::ptr::NonNull; + } bb0: { @@ -23,9 +23,9 @@ + StorageLive(_6); + StorageLive(_7); + StorageLive(_5); -+ _6 = copy (*_3); -+ _7 = copy ((_6.0: std::ptr::Unique).0: std::ptr::NonNull) as *const dyn std::ops::Fn(i32) (Transmute); -+ _5 = &(*_7); ++ _7 = copy (((*_3).0: std::ptr::Unique).0: std::ptr::NonNull); ++ _6 = copy _7 as *const dyn std::ops::Fn(i32) (Transmute); ++ _5 = &(*_6); + _2 = >::call(move _5, move _4) -> [return: bb4, unwind: bb2]; } diff --git a/tests/mir-opt/inline/inline_compatibility.rs b/tests/mir-opt/inline/inline_compatibility.rs index a31153dedc9fe..2b8280a3cfb00 100644 --- a/tests/mir-opt/inline/inline_compatibility.rs +++ b/tests/mir-opt/inline/inline_compatibility.rs @@ -1,6 +1,7 @@ // Checks that only functions with compatible attributes are inlined. //@ only-x86_64 //@ compile-flags: -Cpanic=abort +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(sanitize)] diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff index f6c111a2228a9..9509739413b76 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff @@ -84,7 +84,6 @@ _5 = copy _2; - _0 = drop_in_place::>(move _5) -> [return: bb2, unwind unreachable]; + StorageLive(_15); -+ StorageLive(_16); + _15 = discriminant((*_5)); + switchInt(move _15) -> [0: bb5, otherwise: bb6]; } @@ -110,7 +109,6 @@ + } + + bb5: { -+ StorageDead(_16); + StorageDead(_15); StorageDead(_5); return; diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff index 1832427642528..34f89da19f51f 100644 --- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff @@ -27,13 +27,11 @@ _5 = copy _2; - _0 = drop_in_place::>(move _5) -> [return: bb2, unwind continue]; + StorageLive(_6); -+ StorageLive(_7); + _6 = discriminant((*_5)); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb2: { -+ StorageDead(_7); + StorageDead(_6); StorageDead(_5); return; diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 103475b608cee..688e6967c2f85 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -8,8 +8,8 @@ fn b(_1: &mut Box) -> &mut T { let mut _4: &mut std::boxed::Box; scope 1 (inlined as AsMut>::as_mut) { debug self => _4; - let mut _5: std::boxed::Box; - let mut _6: *const T; + let mut _5: *const T; + let mut _6: std::ptr::NonNull; } bb0: { @@ -19,9 +19,9 @@ fn b(_1: &mut Box) -> &mut T { _4 = copy _1; StorageLive(_5); StorageLive(_6); - _5 = copy (*_4); - _6 = copy ((_5.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); - _3 = &mut (*_6); + _6 = copy (((*_4).0: std::ptr::Unique).0: std::ptr::NonNull); + _5 = copy _6 as *const T (Transmute); + _3 = &mut (*_5); StorageDead(_6); StorageDead(_5); _2 = copy _3; diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index babb26808cece..663741c62fb84 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -7,8 +7,8 @@ fn d(_1: &Box) -> &T { let mut _3: &std::boxed::Box; scope 1 (inlined as AsRef>::as_ref) { debug self => _3; - let mut _4: std::boxed::Box; - let mut _5: *const T; + let mut _4: *const T; + let mut _5: std::ptr::NonNull; } bb0: { @@ -17,9 +17,9 @@ fn d(_1: &Box) -> &T { _3 = copy _1; StorageLive(_4); StorageLive(_5); - _4 = copy (*_3); - _5 = copy ((_4.0: std::ptr::Unique).0: std::ptr::NonNull) as *const T (Transmute); - _2 = &(*_5); + _5 = copy (((*_3).0: std::ptr::Unique).0: std::ptr::NonNull); + _4 = copy _5 as *const T (Transmute); + _2 = &(*_4); StorageDead(_5); StorageDead(_4); _0 = copy _2; diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff index 22e6ea722ddaf..4ca8dbbc76f07 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff @@ -39,8 +39,8 @@ + let mut _28: &mut std::task::Context<'_>; + let mut _29: (); + let mut _30: (); -+ let mut _31: &mut std::task::Context<'_>; -+ let mut _32: u32; ++ let mut _31: u32; ++ let mut _32: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()}; @@ -48,7 +48,6 @@ + let mut _37: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()}; -+ let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()}; + scope 7 { + let mut _15: std::future::Ready<()>; + scope 8 { @@ -58,39 +57,37 @@ + scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 13 (inlined as Future>::poll) { -+ let mut _42: (); -+ let mut _43: std::option::Option<()>; -+ let mut _44: &mut std::option::Option<()>; -+ let mut _45: &mut std::future::Ready<()>; -+ let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>; ++ let mut _41: (); ++ let mut _42: std::option::Option<()>; ++ let mut _43: &mut std::option::Option<()>; ++ let mut _44: &mut std::future::Ready<()>; ++ let mut _45: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _47: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ let mut _46: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _47: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _48: &mut &mut std::future::Ready<()>; ++ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } -+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { -+ } -+ } -+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) { + } + } -+ scope 19 (inlined Option::<()>::take) { -+ let mut _48: std::option::Option<()>; -+ scope 20 (inlined std::mem::replace::>) { -+ scope 21 { ++ scope 17 (inlined Option::<()>::take) { ++ let mut _49: std::option::Option<()>; ++ scope 18 (inlined std::mem::replace::>) { ++ scope 19 { + } + } + } -+ scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _49: isize; -+ let mut _50: !; -+ scope 23 { ++ scope 20 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _50: isize; ++ let mut _51: !; ++ scope 21 { + } + } + } + } + scope 10 (inlined ready::<()>) { -+ let mut _41: std::option::Option<()>; ++ let mut _40: std::option::Option<()>; + } + scope 11 (inlined as IntoFuture>::into_future) { + } @@ -127,14 +124,11 @@ StorageLive(_8); _8 = move _4; StorageLive(_9); - _10 = deref_copy (_1.1: &mut std::task::Context<'_>); + _10 = copy (_1.1: &mut std::task::Context<'_>); _9 = &mut (*_10); - _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind unreachable]; -+ StorageLive(_11); -+ StorageLive(_15); + StorageLive(_16); + StorageLive(_25); -+ StorageLive(_27); + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); @@ -145,10 +139,9 @@ + StorageLive(_37); + StorageLive(_38); + StorageLive(_39); -+ StorageLive(_40); -+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _32 = discriminant((*_33)); -+ switchInt(move _32) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5]; ++ _32 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _31 = discriminant((*_32)); ++ switchInt(move _31) -> [0: bb3, 1: bb10, 3: bb9, otherwise: bb5]; } - bb3: { @@ -158,7 +151,6 @@ + } + + bb2: { -+ StorageDead(_40); + StorageDead(_39); + StorageDead(_38); + StorageDead(_37); @@ -169,11 +161,8 @@ + StorageDead(_32); + StorageDead(_31); + StorageDead(_30); -+ StorageDead(_27); + StorageDead(_25); + StorageDead(_16); -+ StorageDead(_15); -+ StorageDead(_11); StorageDead(_9); StorageDead(_8); StorageDead(_7); @@ -186,23 +175,22 @@ } + bb3: { -+ _31 = move _9; -+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>); ++ _33 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _34 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>); + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + _14 = (); -+ StorageLive(_41); -+ _41 = Option::<()>::Some(copy _14); -+ _13 = std::future::Ready::<()>(move _41); -+ StorageDead(_41); ++ StorageLive(_40); ++ _40 = Option::<()>::Some(copy _14); ++ _13 = std::future::Ready::<()>(move _40); ++ StorageDead(_40); + StorageDead(_14); + _12 = move _13; + StorageDead(_13); -+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; ++ _35 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12; + goto -> bb4; + } + @@ -214,39 +202,36 @@ + StorageLive(_19); + StorageLive(_20); + StorageLive(_21); -+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); ++ _36 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); + _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 }; + StorageDead(_20); + StorageLive(_22); + StorageLive(_23); + StorageLive(_24); -+ _24 = copy _31; ++ _24 = copy _9; + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); -+ StorageLive(_45); ++ StorageLive(_44); + StorageLive(_46); -+ StorageLive(_50); ++ StorageLive(_51); ++ StorageLive(_41); + StorageLive(_42); -+ StorageLive(_43); -+ StorageLive(_44); -+ _46 = &mut _19; + StorageLive(_47); -+ _47 = &mut (_19.0: &mut std::future::Ready<()>); -+ _45 = copy (_19.0: &mut std::future::Ready<()>); ++ _47 = &raw mut _19; ++ _46 = copy _47 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); + StorageDead(_47); -+ _44 = &mut ((*_45).0: std::option::Option<()>); -+ StorageLive(_48); -+ _48 = Option::<()>::None; -+ _43 = copy ((*_45).0: std::option::Option<()>); -+ ((*_45).0: std::option::Option<()>) = copy _48; -+ StorageDead(_48); -+ StorageDead(_44); ++ _44 = copy ((*_46).0: &mut std::future::Ready<()>); + StorageLive(_49); -+ _49 = discriminant(_43); -+ switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5]; ++ _49 = Option::<()>::None; ++ _42 = copy ((*_44).0: std::option::Option<()>); ++ ((*_44).0: std::option::Option<()>) = copy _49; ++ StorageDead(_49); ++ StorageLive(_50); ++ _50 = discriminant(_42); ++ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5]; } + + bb5: { @@ -266,8 +251,8 @@ + StorageDead(_12); + StorageDead(_28); + StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_38)) = 3; ++ _37 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_37)) = 3; + goto -> bb2; + } + @@ -281,14 +266,14 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable]; ++ _38 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb8, unwind unreachable]; + } + + bb8: { + _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_40)) = 1; ++ _39 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_39)) = 1; + goto -> bb2; + } + @@ -298,7 +283,7 @@ + StorageLive(_29); + _28 = move _9; + StorageDead(_29); -+ _31 = move _28; ++ _9 = move _28; + StorageDead(_28); + _16 = const (); + goto -> bb4; @@ -309,18 +294,18 @@ + } + + bb11: { -+ _50 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; ++ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable; + } + + bb12: { -+ _42 = move ((_43 as Some).0: ()); -+ StorageDead(_49); -+ StorageDead(_43); -+ _18 = Poll::<()>::Ready(move _42); -+ StorageDead(_42); ++ _41 = move ((_42 as Some).0: ()); + StorageDead(_50); ++ StorageDead(_42); ++ _18 = Poll::<()>::Ready(move _41); ++ StorageDead(_41); ++ StorageDead(_51); + StorageDead(_46); -+ StorageDead(_45); ++ StorageDead(_44); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff index 8b027e988b8e8..6ce8693007b92 100644 --- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff @@ -39,8 +39,8 @@ + let mut _28: &mut std::task::Context<'_>; + let mut _29: (); + let mut _30: (); -+ let mut _31: &mut std::task::Context<'_>; -+ let mut _32: u32; ++ let mut _31: u32; ++ let mut _32: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _33: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _34: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _35: &mut {async fn body of ActionPermit<'_, T>::perform()}; @@ -50,7 +50,6 @@ + let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()}; + let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()}; -+ let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()}; + scope 7 { + let mut _15: std::future::Ready<()>; + scope 8 { @@ -60,39 +59,37 @@ + scope 12 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { + } + scope 13 (inlined as Future>::poll) { -+ let mut _44: (); -+ let mut _45: std::option::Option<()>; -+ let mut _46: &mut std::option::Option<()>; -+ let mut _47: &mut std::future::Ready<()>; -+ let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>; ++ let mut _43: (); ++ let mut _44: std::option::Option<()>; ++ let mut _45: &mut std::option::Option<()>; ++ let mut _46: &mut std::future::Ready<()>; ++ let mut _47: &mut std::pin::Pin<&mut std::future::Ready<()>>; + scope 14 (inlined > as DerefMut>::deref_mut) { -+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) { -+ let mut _49: &mut &mut std::future::Ready<()>; -+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) { ++ let mut _48: *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>>; ++ let mut _49: *mut std::pin::Pin<&mut std::future::Ready<()>>; ++ scope 15 (inlined > as pin::helper::PinDerefMutHelper>::deref_mut) { ++ let mut _50: &mut &mut std::future::Ready<()>; ++ scope 16 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { + } -+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) { -+ } -+ } -+ scope 17 (inlined Pin::<&mut std::future::Ready<()>>::get_mut) { + } + } -+ scope 19 (inlined Option::<()>::take) { -+ let mut _50: std::option::Option<()>; -+ scope 20 (inlined std::mem::replace::>) { -+ scope 21 { ++ scope 17 (inlined Option::<()>::take) { ++ let mut _51: std::option::Option<()>; ++ scope 18 (inlined std::mem::replace::>) { ++ scope 19 { + } + } + } -+ scope 22 (inlined #[track_caller] Option::<()>::expect) { -+ let mut _51: isize; -+ let mut _52: !; -+ scope 23 { ++ scope 20 (inlined #[track_caller] Option::<()>::expect) { ++ let mut _52: isize; ++ let mut _53: !; ++ scope 21 { + } + } + } + } + scope 10 (inlined ready::<()>) { -+ let mut _43: std::option::Option<()>; ++ let mut _42: std::option::Option<()>; + } + scope 11 (inlined as IntoFuture>::into_future) { + } @@ -129,14 +126,11 @@ StorageLive(_8); _8 = move _4; StorageLive(_9); - _10 = deref_copy (_1.1: &mut std::task::Context<'_>); + _10 = copy (_1.1: &mut std::task::Context<'_>); _9 = &mut (*_10); - _7 = <{async fn body of ActionPermit<'_, T>::perform()} as Future>::poll(move _8, move _9) -> [return: bb3, unwind: bb5]; -+ StorageLive(_11); -+ StorageLive(_15); + StorageLive(_16); + StorageLive(_25); -+ StorageLive(_27); + StorageLive(_30); + StorageLive(_31); + StorageLive(_32); @@ -149,10 +143,9 @@ + StorageLive(_39); + StorageLive(_40); + StorageLive(_41); -+ StorageLive(_42); -+ _33 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _32 = discriminant((*_33)); -+ switchInt(move _32) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7]; ++ _32 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _31 = discriminant((*_32)); ++ switchInt(move _31) -> [0: bb5, 1: bb15, 2: bb14, 3: bb13, otherwise: bb7]; } - bb3: { @@ -170,7 +163,6 @@ + } + + bb4: { -+ StorageDead(_42); + StorageDead(_41); + StorageDead(_40); + StorageDead(_39); @@ -183,11 +175,8 @@ + StorageDead(_32); + StorageDead(_31); + StorageDead(_30); -+ StorageDead(_27); + StorageDead(_25); + StorageDead(_16); -+ StorageDead(_15); -+ StorageDead(_11); StorageDead(_9); StorageDead(_8); StorageDead(_7); @@ -203,23 +192,22 @@ - StorageDead(_2); - return; + bb5: { -+ _31 = move _9; -+ _34 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _35 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ (((*_34) as variant#3).0: ActionPermit<'_, T>) = move ((*_35).0: ActionPermit<'_, T>); ++ _33 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _34 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ (((*_33) as variant#3).0: ActionPermit<'_, T>) = move ((*_34).0: ActionPermit<'_, T>); + StorageLive(_12); + StorageLive(_13); + StorageLive(_14); + _14 = (); -+ StorageLive(_43); -+ _43 = Option::<()>::Some(copy _14); -+ _13 = std::future::Ready::<()>(move _43); -+ StorageDead(_43); ++ StorageLive(_42); ++ _42 = Option::<()>::Some(copy _14); ++ _13 = std::future::Ready::<()>(move _42); ++ StorageDead(_42); + StorageDead(_14); + _12 = move _13; + StorageDead(_13); -+ _36 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ (((*_36) as variant#3).1: std::future::Ready<()>) = move _12; ++ _35 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ (((*_35) as variant#3).1: std::future::Ready<()>) = move _12; + goto -> bb6; } @@ -231,39 +219,36 @@ + StorageLive(_19); + StorageLive(_20); + StorageLive(_21); -+ _37 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ _21 = &mut (((*_37) as variant#3).1: std::future::Ready<()>); ++ _36 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ _21 = &mut (((*_36) as variant#3).1: std::future::Ready<()>); + _20 = &mut (*_21); + _19 = Pin::<&mut std::future::Ready<()>> { pointer: copy _20 }; + StorageDead(_20); + StorageLive(_22); + StorageLive(_23); + StorageLive(_24); -+ _24 = copy _31; ++ _24 = copy _9; + _23 = move _24; + _22 = &mut (*_23); + StorageDead(_24); -+ StorageLive(_47); ++ StorageLive(_46); + StorageLive(_48); -+ StorageLive(_52); ++ StorageLive(_53); ++ StorageLive(_43); + StorageLive(_44); -+ StorageLive(_45); -+ StorageLive(_46); -+ _48 = &mut _19; + StorageLive(_49); -+ _49 = &mut (_19.0: &mut std::future::Ready<()>); -+ _47 = copy (_19.0: &mut std::future::Ready<()>); ++ _49 = &raw mut _19; ++ _48 = copy _49 as *mut std::pin::helper::PinHelper<&mut std::future::Ready<()>> (PtrToPtr); + StorageDead(_49); -+ _46 = &mut ((*_47).0: std::option::Option<()>); -+ StorageLive(_50); -+ _50 = Option::<()>::None; -+ _45 = copy ((*_47).0: std::option::Option<()>); -+ ((*_47).0: std::option::Option<()>) = copy _50; -+ StorageDead(_50); -+ StorageDead(_46); ++ _46 = copy ((*_48).0: &mut std::future::Ready<()>); + StorageLive(_51); -+ _51 = discriminant(_45); -+ switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7]; ++ _51 = Option::<()>::None; ++ _44 = copy ((*_46).0: std::option::Option<()>); ++ ((*_46).0: std::option::Option<()>) = copy _51; ++ StorageDead(_51); ++ StorageLive(_52); ++ _52 = discriminant(_44); ++ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7]; } - bb6 (cleanup): { @@ -285,8 +270,8 @@ + StorageDead(_12); + StorageDead(_28); + StorageDead(_29); -+ _38 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_38)) = 3; ++ _37 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_37)) = 3; + goto -> bb4; + } + @@ -300,14 +285,14 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _39 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_39) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12]; ++ _38 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ drop((((*_38) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb10, unwind: bb12]; + } + + bb10: { + _7 = Poll::<()>::Ready(move _30); -+ _40 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_40)) = 1; ++ _39 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_39)) = 1; + goto -> bb4; + } + @@ -319,13 +304,13 @@ + StorageDead(_18); + StorageDead(_17); + StorageDead(_12); -+ _41 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ drop((((*_41) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; ++ _40 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ drop((((*_40) as variant#3).0: ActionPermit<'_, T>)) -> [return: bb12, unwind terminate(cleanup)]; + } + + bb12 (cleanup): { -+ _42 = deref_copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); -+ discriminant((*_42)) = 2; ++ _41 = copy (_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()}); ++ discriminant((*_41)) = 2; + goto -> bb2; + } + @@ -335,7 +320,7 @@ + StorageLive(_29); + _28 = move _9; + StorageDead(_29); -+ _31 = move _28; ++ _9 = move _28; + StorageDead(_28); + _16 = const (); + goto -> bb6; @@ -350,18 +335,18 @@ + } + + bb16: { -+ _52 = option::expect_failed(const "`Ready` polled after completion") -> bb11; ++ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11; + } + + bb17: { -+ _44 = move ((_45 as Some).0: ()); -+ StorageDead(_51); -+ StorageDead(_45); -+ _18 = Poll::<()>::Ready(move _44); -+ StorageDead(_44); ++ _43 = move ((_44 as Some).0: ()); + StorageDead(_52); ++ StorageDead(_44); ++ _18 = Poll::<()>::Ready(move _43); ++ StorageDead(_43); ++ StorageDead(_53); + StorageDead(_48); -+ StorageDead(_47); ++ StorageDead(_46); + StorageDead(_22); + StorageDead(_19); + _25 = discriminant(_18); diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff new file mode 100644 index 0000000000000..feba0fe7c4a21 --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-abort.diff @@ -0,0 +1,71 @@ +- // MIR for `norm2` before InstSimplify-after-simplifycfg ++ // MIR for `norm2` after InstSimplify-after-simplifycfg + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: bool; + let _6: usize; + let mut _7: bool; + let mut _8: f32; + let mut _9: f32; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + scope 1 { + debug a => _2; + let _5: f32; + scope 2 { + debug b => _5; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; + _4 = Lt(copy _3, const 2_usize); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _3) -> [success: bb1, unwind unreachable]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_5); + StorageLive(_6); + _6 = const 1_usize; + _7 = Lt(copy _6, const 2_usize); + assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb2, unwind unreachable]; + } + + bb2: { + _5 = copy _1[_6]; + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = copy _2; + StorageLive(_10); + _10 = copy _2; + _8 = Mul(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + _12 = copy _5; + StorageLive(_13); + _13 = copy _5; + _11 = Mul(move _12, move _13); + StorageDead(_13); + StorageDead(_12); + _0 = Add(move _8, move _11); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff new file mode 100644 index 0000000000000..0ccf6a825c49a --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.norm2.InstSimplify-after-simplifycfg.panic-unwind.diff @@ -0,0 +1,71 @@ +- // MIR for `norm2` before InstSimplify-after-simplifycfg ++ // MIR for `norm2` after InstSimplify-after-simplifycfg + + fn norm2(_1: [f32; 2]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: bool; + let _6: usize; + let mut _7: bool; + let mut _8: f32; + let mut _9: f32; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + scope 1 { + debug a => _2; + let _5: f32; + scope 2 { + debug b => _5; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; + _4 = Lt(copy _3, const 2_usize); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _3) -> [success: bb1, unwind continue]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_5); + StorageLive(_6); + _6 = const 1_usize; + _7 = Lt(copy _6, const 2_usize); + assert(move _7, "index out of bounds: the length is {} but the index is {}", const 2_usize, copy _6) -> [success: bb2, unwind continue]; + } + + bb2: { + _5 = copy _1[_6]; + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = copy _2; + StorageLive(_10); + _10 = copy _2; + _8 = Mul(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + _12 = copy _5; + StorageLive(_13); + _13 = copy _5; + _11 = Mul(move _12, move _13); + StorageDead(_13); + StorageDead(_12); + _0 = Add(move _8, move _11); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff new file mode 100644 index 0000000000000..e9cb2c5817720 --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-abort.diff @@ -0,0 +1,71 @@ +- // MIR for `normN` before InstSimplify-after-simplifycfg ++ // MIR for `normN` after InstSimplify-after-simplifycfg + + fn normN(_1: [f32; N]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: bool; + let _6: usize; + let mut _7: bool; + let mut _8: f32; + let mut _9: f32; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + scope 1 { + debug a => _2; + let _5: f32; + scope 2 { + debug b => _5; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; + _4 = Lt(copy _3, const N); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const N, copy _3) -> [success: bb1, unwind unreachable]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_5); + StorageLive(_6); + _6 = const 1_usize; + _7 = Lt(copy _6, const N); + assert(move _7, "index out of bounds: the length is {} but the index is {}", const N, copy _6) -> [success: bb2, unwind unreachable]; + } + + bb2: { + _5 = copy _1[_6]; + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = copy _2; + StorageLive(_10); + _10 = copy _2; + _8 = Mul(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + _12 = copy _5; + StorageLive(_13); + _13 = copy _5; + _11 = Mul(move _12, move _13); + StorageDead(_13); + StorageDead(_12); + _0 = Add(move _8, move _11); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff new file mode 100644 index 0000000000000..0ddc70f2003e8 --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.normN.InstSimplify-after-simplifycfg.panic-unwind.diff @@ -0,0 +1,71 @@ +- // MIR for `normN` before InstSimplify-after-simplifycfg ++ // MIR for `normN` after InstSimplify-after-simplifycfg + + fn normN(_1: [f32; N]) -> f32 { + debug x => _1; + let mut _0: f32; + let _2: f32; + let _3: usize; + let mut _4: bool; + let _6: usize; + let mut _7: bool; + let mut _8: f32; + let mut _9: f32; + let mut _10: f32; + let mut _11: f32; + let mut _12: f32; + let mut _13: f32; + scope 1 { + debug a => _2; + let _5: f32; + scope 2 { + debug b => _5; + } + } + + bb0: { + StorageLive(_2); + StorageLive(_3); + _3 = const 0_usize; + _4 = Lt(copy _3, const N); + assert(move _4, "index out of bounds: the length is {} but the index is {}", const N, copy _3) -> [success: bb1, unwind continue]; + } + + bb1: { + _2 = copy _1[_3]; + StorageDead(_3); + StorageLive(_5); + StorageLive(_6); + _6 = const 1_usize; + _7 = Lt(copy _6, const N); + assert(move _7, "index out of bounds: the length is {} but the index is {}", const N, copy _6) -> [success: bb2, unwind continue]; + } + + bb2: { + _5 = copy _1[_6]; + StorageDead(_6); + StorageLive(_8); + StorageLive(_9); + _9 = copy _2; + StorageLive(_10); + _10 = copy _2; + _8 = Mul(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + StorageLive(_11); + StorageLive(_12); + _12 = copy _5; + StorageLive(_13); + _13 = copy _5; + _11 = Mul(move _12, move _13); + StorageDead(_13); + StorageDead(_12); + _0 = Add(move _8, move _11); + StorageDead(_11); + StorageDead(_8); + StorageDead(_5); + StorageDead(_2); + return; + } + } + diff --git a/tests/mir-opt/instsimplify/combine_array_len.rs b/tests/mir-opt/instsimplify/combine_array_len.rs new file mode 100644 index 0000000000000..1c4d42d3bbe82 --- /dev/null +++ b/tests/mir-opt/instsimplify/combine_array_len.rs @@ -0,0 +1,25 @@ +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY +//@ test-mir-pass: InstSimplify-after-simplifycfg + +// EMIT_MIR combine_array_len.norm2.InstSimplify-after-simplifycfg.diff +fn norm2(x: [f32; 2]) -> f32 { + // CHECK-LABEL: fn norm2( + // CHECK-NOT: PtrMetadata( + let a = x[0]; + let b = x[1]; + a * a + b * b +} + +// EMIT_MIR combine_array_len.normN.InstSimplify-after-simplifycfg.diff +fn normN(x: [f32; N]) -> f32 { + // CHECK-LABEL: fn normN( + // CHECK-NOT: PtrMetadata( + let a = x[0]; + let b = x[1]; + a * a + b * b +} + +fn main() { + assert_eq!(norm2([3.0, 4.0]), 5.0 * 5.0); + assert_eq!(normN([3.0, 4.0]), 5.0 * 5.0); +} diff --git a/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff b/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff index ac88fe67bb86f..3ea7387a48d3c 100644 --- a/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff +++ b/tests/mir-opt/issue_101973.inner.GVN.panic-abort.diff @@ -30,7 +30,6 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; - nop; - StorageLive(_14); - _14 = BitAnd(copy _5, const 255_u32); - _4 = BitOr(const 0_u32, move _14); diff --git a/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff b/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff index 96c3cae2d334a..832db856b2cf9 100644 --- a/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff +++ b/tests/mir-opt/issue_101973.inner.GVN.panic-unwind.diff @@ -30,7 +30,6 @@ StorageLive(_4); StorageLive(_5); _5 = copy _1; - nop; - StorageLive(_14); - _14 = BitAnd(copy _5, const 255_u32); - _4 = BitOr(const 0_u32, move _14); diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index 08dee3697e072..614d9ad440d20 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -7,18 +7,16 @@ let _2: &[T]; let _3: &[T; 3]; let _4: [T; 3]; - let mut _5: usize; - let mut _6: bool; - let mut _10: !; + let mut _8: !; scope 1 { debug v => _2; + let _5: &T; + let _6: &T; let _7: &T; - let _8: &T; - let _9: &T; scope 2 { - debug v1 => _7; - debug v2 => _8; - debug v3 => _9; + debug v1 => _5; + debug v2 => _6; + debug v3 => _7; } } @@ -27,25 +25,17 @@ _4 = [copy _1, copy _1, copy _1]; _3 = &_4; _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); - nop; - nop; goto -> bb2; } bb1: { - _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; + _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; } bb2: { - StorageLive(_7); - _7 = &(*_2)[0 of 3]; - StorageLive(_8); - _8 = &(*_2)[1 of 3]; - StorageLive(_9); - _9 = &(*_2)[2 of 3]; - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); + // DBG: _5 = &(*_2)[0 of 3]; + // DBG: _6 = &(*_2)[1 of 3]; + // DBG: _7 = &(*_2)[2 of 3]; StorageDead(_4); return; } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index aa44a2ad532be..57a88cf898412 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -7,18 +7,16 @@ let _2: &[T]; let _3: &[T; 3]; let _4: [T; 3]; - let mut _5: usize; - let mut _6: bool; - let mut _10: !; + let mut _8: !; scope 1 { debug v => _2; + let _5: &T; + let _6: &T; let _7: &T; - let _8: &T; - let _9: &T; scope 2 { - debug v1 => _7; - debug v2 => _8; - debug v3 => _9; + debug v1 => _5; + debug v2 => _6; + debug v3 => _7; } } @@ -27,25 +25,17 @@ _4 = [copy _1, copy _1, copy _1]; _3 = &_4; _2 = copy _3 as &[T] (PointerCoercion(Unsize, Implicit)); - nop; - nop; goto -> bb2; } bb1: { - _10 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue; + _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue; } bb2: { - StorageLive(_7); - _7 = &(*_2)[0 of 3]; - StorageLive(_8); - _8 = &(*_2)[1 of 3]; - StorageLive(_9); - _9 = &(*_2)[2 of 3]; - StorageDead(_9); - StorageDead(_8); - StorageDead(_7); + // DBG: _5 = &(*_2)[0 of 3]; + // DBG: _6 = &(*_2)[1 of 3]; + // DBG: _7 = &(*_2)[2 of 3]; StorageDead(_4); return; } diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff index 180a7db029794..714a12804e692 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-abort.diff @@ -18,8 +18,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = &_1; @@ -41,8 +40,7 @@ bb1: { StorageDead(_6); StorageDead(_5); -- StorageDead(_2); -+ nop; + StorageDead(_2); StorageDead(_7); return; } diff --git a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff index 180a7db029794..714a12804e692 100644 --- a/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_raw.GVN.panic-unwind.diff @@ -18,8 +18,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = &_1; @@ -41,8 +40,7 @@ bb1: { StorageDead(_6); StorageDead(_5); -- StorageDead(_2); -+ nop; + StorageDead(_2); StorageDead(_7); return; } diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff index 49964f8b49e26..b236b22f067d8 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-abort.diff @@ -17,8 +17,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = &mut _1; @@ -38,8 +37,7 @@ bb1: { StorageDead(_6); StorageDead(_5); -- StorageDead(_2); -+ nop; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff index 49964f8b49e26..b236b22f067d8 100644 --- a/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff +++ b/tests/mir-opt/lower_array_len.array_len_reborrow.GVN.panic-unwind.diff @@ -17,8 +17,7 @@ } bb0: { -- StorageLive(_2); -+ nop; + StorageLive(_2); StorageLive(_3); StorageLive(_4); _4 = &mut _1; @@ -38,8 +37,7 @@ bb1: { StorageDead(_6); StorageDead(_5); -- StorageDead(_2); -+ nop; + StorageDead(_2); return; } } diff --git a/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff b/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff deleted file mode 100644 index d248c76f261b6..0000000000000 --- a/tests/mir-opt/nrvo_miscompile_111005.wrong.RenameReturnPlace.diff +++ /dev/null @@ -1,17 +0,0 @@ -- // MIR for `wrong` before RenameReturnPlace -+ // MIR for `wrong` after RenameReturnPlace - - fn wrong(_1: char) -> char { - let mut _0: char; - let mut _2: char; - - bb0: { -- _2 = copy _1; -- _0 = copy _2; -- _2 = const 'b'; -+ _0 = copy _1; -+ _0 = const 'b'; - return; - } - } - diff --git a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff deleted file mode 100644 index 6dce3ec5303d7..0000000000000 --- a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-abort.diff +++ /dev/null @@ -1,42 +0,0 @@ -- // MIR for `nrvo` before RenameReturnPlace -+ // MIR for `nrvo` after RenameReturnPlace - - fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { - debug init => _1; - let mut _0: [u8; 1024]; - let mut _2: [u8; 1024]; - let _3: (); - let mut _4: for<'a> fn(&'a mut [u8; 1024]); - let mut _5: &mut [u8; 1024]; - let mut _6: &mut [u8; 1024]; - scope 1 { -- debug buf => _2; -+ debug buf => _0; - } - - bb0: { -- StorageLive(_2); -- _2 = [const 0_u8; 1024]; -+ _0 = [const 0_u8; 1024]; - StorageLive(_3); - StorageLive(_4); - _4 = copy _1; - StorageLive(_5); - StorageLive(_6); -- _6 = &mut _2; -+ _6 = &mut _0; - _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind unreachable]; - } - - bb1: { - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); -- _0 = copy _2; -- StorageDead(_2); - return; - } - } - diff --git a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff b/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff deleted file mode 100644 index 54cbe2871f15a..0000000000000 --- a/tests/mir-opt/nrvo_simple.nrvo.RenameReturnPlace.panic-unwind.diff +++ /dev/null @@ -1,42 +0,0 @@ -- // MIR for `nrvo` before RenameReturnPlace -+ // MIR for `nrvo` after RenameReturnPlace - - fn nrvo(_1: for<'a> fn(&'a mut [u8; 1024])) -> [u8; 1024] { - debug init => _1; - let mut _0: [u8; 1024]; - let mut _2: [u8; 1024]; - let _3: (); - let mut _4: for<'a> fn(&'a mut [u8; 1024]); - let mut _5: &mut [u8; 1024]; - let mut _6: &mut [u8; 1024]; - scope 1 { -- debug buf => _2; -+ debug buf => _0; - } - - bb0: { -- StorageLive(_2); -- _2 = [const 0_u8; 1024]; -+ _0 = [const 0_u8; 1024]; - StorageLive(_3); - StorageLive(_4); - _4 = copy _1; - StorageLive(_5); - StorageLive(_6); -- _6 = &mut _2; -+ _6 = &mut _0; - _5 = &mut (*_6); - _3 = move _4(move _5) -> [return: bb1, unwind continue]; - } - - bb1: { - StorageDead(_5); - StorageDead(_4); - StorageDead(_6); - StorageDead(_3); -- _0 = copy _2; -- StorageDead(_2); - return; - } - } - diff --git a/tests/mir-opt/nrvo_simple.rs b/tests/mir-opt/nrvo_simple.rs deleted file mode 100644 index df540472e1ccb..0000000000000 --- a/tests/mir-opt/nrvo_simple.rs +++ /dev/null @@ -1,16 +0,0 @@ -// skip-filecheck -// EMIT_MIR_FOR_EACH_PANIC_STRATEGY -//@ test-mir-pass: RenameReturnPlace - -// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff -fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { - let mut buf = [0; 1024]; - init(&mut buf); - buf -} - -fn main() { - let _ = nrvo(|buf| { - buf[4] = 4; - }); -} diff --git a/tests/mir-opt/pre-codegen/checked_ops.rs b/tests/mir-opt/pre-codegen/checked_ops.rs index 8fd340503f548..dfbc0f4a1108d 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.rs +++ b/tests/mir-opt/pre-codegen/checked_ops.rs @@ -44,8 +44,7 @@ pub fn saturating_sub_at_home(lhs: u32, rhs: u32) -> u32 { // CHECK-LABEL: fn saturating_sub_at_home // CHECK: [[DELTA:_[0-9]+]] = SubUnchecked(copy _1, copy _2) // CHECK: [[TEMP1:_.+]] = Option::::Some({{move|copy}} [[DELTA]]); - // CHECK: [[TEMP2:_.+]] = {{move|copy}} (([[TEMP1]] as Some).0: u32); - // CHECK: _0 = {{move|copy}} [[TEMP2]]; + // CHECK: _0 = {{move|copy}} (([[TEMP1]] as Some).0: u32); u32::checked_sub(lhs, rhs).unwrap_or(0) } diff --git a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir index 5b4fdeda85731..dc7567b57e70a 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir @@ -10,7 +10,6 @@ fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { let mut _4: u32; } scope 2 (inlined Option::::unwrap_or) { - let _6: u32; scope 3 { } } @@ -28,10 +27,7 @@ fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { _5 = Option::::Some(move _4); StorageDead(_4); StorageDead(_3); - StorageLive(_6); - _6 = move ((_5 as Some).0: u32); - _0 = move _6; - StorageDead(_6); + _0 = move ((_5 as Some).0: u32); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir index 5b4fdeda85731..dc7567b57e70a 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir @@ -10,7 +10,6 @@ fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { let mut _4: u32; } scope 2 (inlined Option::::unwrap_or) { - let _6: u32; scope 3 { } } @@ -28,10 +27,7 @@ fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { _5 = Option::::Some(move _4); StorageDead(_4); StorageDead(_3); - StorageLive(_6); - _6 = move ((_5 as Some).0: u32); - _0 = move _6; - StorageDead(_6); + _0 = move ((_5 as Some).0: u32); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir index 34747e5a92854..1e6e2ee1b8b73 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.clone_as_copy.PreCodegen.after.mir @@ -12,10 +12,8 @@ fn clone_as_copy(_1: &NestCopy) -> NestCopy { } bb0: { - StorageLive(_2); - _2 = &((*_1).1: AllCopy); + // DBG: _2 = &((*_1).1: AllCopy); _0 = copy (*_1); - StorageDead(_2); return; } } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir index e67f362ee04ae..76bb49bc9c1b3 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir @@ -5,58 +5,28 @@ fn enum_clone_as_copy(_1: &Enum1) -> Enum1 { let mut _0: Enum1; scope 1 (inlined ::clone) { debug self => _1; - let mut _2: isize; - let _3: &AllCopy; - let _4: &NestCopy; + let _2: &AllCopy; + let _3: &NestCopy; scope 2 { - debug __self_0 => _3; + debug __self_0 => _2; scope 6 (inlined ::clone) { - debug self => _3; + debug self => _2; } } scope 3 { - debug __self_0 => _4; + debug __self_0 => _3; scope 4 (inlined ::clone) { - debug self => _4; - let _5: &AllCopy; + debug self => _3; + let _4: &AllCopy; scope 5 (inlined ::clone) { - debug self => _5; + debug self => _4; } } } } bb0: { - StorageLive(_2); - StorageLive(_3); - StorageLive(_4); - _2 = discriminant((*_1)); - switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; - } - - bb1: { - _3 = &(((*_1) as A).0: AllCopy); _0 = copy (*_1); - goto -> bb3; - } - - bb2: { - _4 = &(((*_1) as B).0: NestCopy); - StorageLive(_5); - _5 = &((((*_1) as B).0: NestCopy).1: AllCopy); - StorageDead(_5); - _0 = copy (*_1); - goto -> bb3; - } - - bb3: { - StorageDead(_4); - StorageDead(_3); - StorageDead(_2); return; } - - bb4: { - unreachable; - } } diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs index f5ff1854d387d..00f24754d5913 100644 --- a/tests/mir-opt/pre-codegen/clone_as_copy.rs +++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs @@ -25,19 +25,19 @@ enum Enum1 { // EMIT_MIR clone_as_copy.clone_as_copy.PreCodegen.after.mir fn clone_as_copy(v: &NestCopy) -> NestCopy { // CHECK-LABEL: fn clone_as_copy( - // CHECK-NOT: = AllCopy { {{.*}} }; - // CHECK-NOT: = NestCopy { {{.*}} }; - // CHECK: _0 = copy (*_1); - // CHECK: return; + // CHECK: let [[DEAD_VAR:_.*]]: &AllCopy; + // CHECK: bb0: { + // CHECK-NEXT: DBG: [[DEAD_VAR]] = &((*_1).1: AllCopy) + // CHECK-NEXT: _0 = copy (*_1); + // CHECK-NEXT: return; v.clone() } -// FIXME: We can merge into exactly one assignment statement. // EMIT_MIR clone_as_copy.enum_clone_as_copy.PreCodegen.after.mir fn enum_clone_as_copy(v: &Enum1) -> Enum1 { // CHECK-LABEL: fn enum_clone_as_copy( - // CHECK-NOT: = Enum1:: - // CHECK: _0 = copy (*_1); - // CHECK: _0 = copy (*_1); + // CHECK: bb0: { + // CHECK-NEXT: _0 = copy (*_1); + // CHECK-NEXT: return; v.clone() } diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir new file mode 100644 index 0000000000000..66b51ad48e7a5 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.direct.PreCodegen.after.mir @@ -0,0 +1,46 @@ +// MIR for `direct` after PreCodegen + +fn direct(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 2 { + scope 3 (inlined ::eq) { + let _3: i8; + scope 4 { + scope 5 { + } + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + } + + bb1: { + _0 = const false; + goto -> bb3; + } + + bb2: { + StorageLive(_3); + _3 = discriminant(((_1 as Some).0: std::cmp::Ordering)); + _0 = Eq(copy _3, const 0_i8); + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_2); + return; + } + + bb4: { + unreachable; + } +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs new file mode 100644 index 0000000000000..3c1e96fa47484 --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.rs @@ -0,0 +1,30 @@ +//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 + +// Check that comparing `Option` to a constant inlined `Some(...)` +// does not produce unnecessarily complex MIR compared to using a local binding. +// +// Regression test for . +// Originally, inlined constants like `Some(Ordering::Equal)` would get promoted, +// leading to more MIR (and extra LLVM IR checks) than necessary. +// Both cases should now generate identical MIR. + +use std::cmp::Ordering; + +// EMIT_MIR const_promotion_option_ordering_eq.direct.PreCodegen.after.mir +pub fn direct(e: Option) -> bool { + // CHECK-LABEL: fn direct( + // CHECK-NOT: promoted[ + // CHECK: switchInt( + // CHECK: return + e == Some(Ordering::Equal) +} + +// EMIT_MIR const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir +pub fn with_let(e: Option) -> bool { + // CHECK-LABEL: fn with_let( + // CHECK-NOT: promoted[ + // CHECK: switchInt( + // CHECK: return + let eq = Ordering::Equal; + e == Some(eq) +} diff --git a/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir new file mode 100644 index 0000000000000..f089e9ad960bd --- /dev/null +++ b/tests/mir-opt/pre-codegen/const_promotion_option_ordering_eq.with_let.PreCodegen.after.mir @@ -0,0 +1,49 @@ +// MIR for `with_let` after PreCodegen + +fn with_let(_1: Option) -> bool { + debug e => _1; + let mut _0: bool; + scope 1 { + debug eq => const Equal; + scope 2 (inlined as PartialEq>::eq) { + let mut _2: isize; + scope 3 { + scope 4 (inlined ::eq) { + let _3: i8; + scope 5 { + scope 6 { + } + } + } + } + } + } + + bb0: { + StorageLive(_2); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + } + + bb1: { + _0 = const false; + goto -> bb3; + } + + bb2: { + StorageLive(_3); + _3 = discriminant(((_1 as Some).0: std::cmp::Ordering)); + _0 = Eq(copy _3, const 0_i8); + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_2); + return; + } + + bb4: { + unreachable; + } +} diff --git a/tests/mir-opt/pre-codegen/dead_on_invalid_place.invalid_place.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/dead_on_invalid_place.invalid_place.PreCodegen.after.mir new file mode 100644 index 0000000000000..4a2127178fb0b --- /dev/null +++ b/tests/mir-opt/pre-codegen/dead_on_invalid_place.invalid_place.PreCodegen.after.mir @@ -0,0 +1,13 @@ +// MIR for `invalid_place` after PreCodegen + +fn invalid_place(_1: bool) -> bool { + debug c1_ref => _2; + let mut _0: bool; + let mut _2: &bool; + + bb0: { + // DBG: _2 = &?; + _0 = copy _1; + return; + } +} diff --git a/tests/mir-opt/pre-codegen/dead_on_invalid_place.rs b/tests/mir-opt/pre-codegen/dead_on_invalid_place.rs new file mode 100644 index 0000000000000..5abe9fa43a5d2 --- /dev/null +++ b/tests/mir-opt/pre-codegen/dead_on_invalid_place.rs @@ -0,0 +1,27 @@ +#![feature(core_intrinsics, custom_mir)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// EMIT_MIR dead_on_invalid_place.invalid_place.PreCodegen.after.mir +#[custom_mir(dialect = "runtime")] +pub fn invalid_place(c: bool) -> bool { + // CHECK-LABEL: fn invalid_place + // CHECK: debug c1_ref => [[c1_ref:_[0-9]+]]; + // CHECK: bb0: { + // We cannot read the reference, since `c1` is dead. + // CHECK-NEXT: DBG: [[c1_ref]] = &? + // CHECK-NEXT: _0 = copy _1; + // CHECK-NEXT: return; + mir! { + let _c1_ref: &bool; + let c1: bool; + debug c1_ref => _c1_ref; + { + c1 = c; + _c1_ref = &c1; + RET = c; + Return() + } + } +} diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff index 993857f225a81..269af438e37ef 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-abort.diff @@ -16,17 +16,15 @@ bb0: { - StorageLive(_2); -- _6 = deref_copy (*_1); + nop; -+ _6 = copy (*_1); + _6 = copy (*_1); _2 = copy (*_6); _3 = unknown() -> [return: bb1, unwind unreachable]; } bb1: { StorageLive(_4); -- _7 = deref_copy (*_1); -+ _7 = copy (*_1); + _7 = copy (*_1); _4 = copy (*_7); StorageLive(_5); _5 = copy _2; diff --git a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff index d81bfa9310bc1..9ce17342a445c 100644 --- a/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff +++ b/tests/mir-opt/pre-codegen/deref_nested_borrows.src.GVN.panic-unwind.diff @@ -16,17 +16,15 @@ bb0: { - StorageLive(_2); -- _6 = deref_copy (*_1); + nop; -+ _6 = copy (*_1); + _6 = copy (*_1); _2 = copy (*_6); _3 = unknown() -> [return: bb1, unwind continue]; } bb1: { StorageLive(_4); -- _7 = deref_copy (*_1); -+ _7 = copy (*_1); + _7 = copy (*_1); _4 = copy (*_7); StorageLive(_5); _5 = copy _2; diff --git a/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir index 8746cb0899166..e235fa35c0238 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.demo_le.PreCodegen.after.mir @@ -5,8 +5,9 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { debug b => _2; let mut _0: bool; scope 1 (inlined ::le) { - let mut _11: std::option::Option; + let mut _6: std::option::Option; scope 2 (inlined Option::::is_some_and:: bool {std::cmp::Ordering::is_le}>) { + let mut _11: isize; let _12: std::cmp::Ordering; scope 3 { scope 4 (inlined bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) { @@ -19,7 +20,6 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { } } scope 7 (inlined ::partial_cmp) { - let mut _6: std::option::Option; let mut _7: i8; scope 8 { } @@ -38,9 +38,8 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { bb0: { StorageLive(_12); - StorageLive(_11); - StorageLive(_5); StorageLive(_6); + StorageLive(_5); StorageLive(_7); StorageLive(_3); _3 = copy ((*_1).0: char); @@ -63,30 +62,44 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool { _10 = Cmp(move _8, move _9); StorageDead(_9); StorageDead(_8); - _11 = Option::::Some(move _10); + _6 = Option::::Some(move _10); StorageDead(_10); StorageDead(_7); - StorageDead(_6); StorageDead(_5); - goto -> bb3; + StorageLive(_11); + goto -> bb4; } bb2: { - _11 = copy _6; StorageDead(_7); - StorageDead(_6); StorageDead(_5); - goto -> bb3; + StorageLive(_11); + _11 = discriminant(_6); + switchInt(move _11) -> [0: bb3, 1: bb4, otherwise: bb6]; } bb3: { - _12 = move ((_11 as Some).0: std::cmp::Ordering); + _0 = const false; + goto -> bb5; + } + + bb4: { + _12 = move ((_6 as Some).0: std::cmp::Ordering); StorageLive(_13); _13 = discriminant(_12); _0 = Le(move _13, const 0_i8); StorageDead(_13); + goto -> bb5; + } + + bb5: { StorageDead(_11); + StorageDead(_6); StorageDead(_12); return; } + + bb6: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/derived_ord.rs b/tests/mir-opt/pre-codegen/derived_ord.rs index 73ae923a6cb9c..823e0f6d09c2b 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.rs +++ b/tests/mir-opt/pre-codegen/derived_ord.rs @@ -25,7 +25,10 @@ pub fn demo_le(a: &MultiField, b: &MultiField) -> bool { // CHECK: Cmp(move [[A1]], move [[B1]]); // CHECK: [[D1:_[0-9]+]] = discriminant({{.+}}); - // CHECK: _0 = Le(move [[D1]], const 0_i8); + // CHECK: switchInt(move [[D1]]) -> [0: bb{{[0-9]+}}, 1: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}]; + + // CHECK: [[D2:_[0-9]+]] = discriminant({{.+}}); + // CHECK: _0 = Le(move [[D2]], const 0_i8); *a <= *b } diff --git a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir index de25eebee77ff..5993bd79d274c 100644 --- a/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/derived_ord.{impl#0}-partial_cmp.PreCodegen.after.mir @@ -4,10 +4,9 @@ fn ::partial_cmp(_1: &MultiField, _2: &M debug self => _1; debug other => _2; let mut _0: std::option::Option; - let mut _6: std::option::Option; - let mut _7: i8; + let mut _6: i8; scope 1 { - debug cmp => _6; + debug cmp => _0; } scope 2 (inlined std::cmp::impls::::partial_cmp) { let mut _3: char; @@ -15,9 +14,9 @@ fn ::partial_cmp(_1: &MultiField, _2: &M let mut _5: std::cmp::Ordering; } scope 3 (inlined std::cmp::impls::::partial_cmp) { + let mut _7: i16; let mut _8: i16; - let mut _9: i16; - let mut _10: std::cmp::Ordering; + let mut _9: std::cmp::Ordering; } bb0: { @@ -28,27 +27,26 @@ fn ::partial_cmp(_1: &MultiField, _2: &M _5 = Cmp(move _3, move _4); StorageDead(_4); StorageDead(_3); - _6 = Option::::Some(copy _5); - _7 = discriminant(_5); - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + _0 = Option::::Some(copy _5); + _6 = discriminant(_5); + switchInt(move _6) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_10); - StorageLive(_8); - _8 = copy ((*_1).1: i16); StorageLive(_9); - _9 = copy ((*_2).1: i16); - _10 = Cmp(move _8, move _9); - StorageDead(_9); + StorageLive(_7); + _7 = copy ((*_1).1: i16); + StorageLive(_8); + _8 = copy ((*_2).1: i16); + _9 = Cmp(move _7, move _8); StorageDead(_8); - _0 = Option::::Some(move _10); - StorageDead(_10); + StorageDead(_7); + _0 = Option::::Some(move _9); + StorageDead(_9); goto -> bb3; } bb2: { - _0 = copy _6; goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir index 75e8cb1d8618c..8f30ad30fccdf 100644 --- a/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.filter_mapped.PreCodegen.after.mir @@ -6,20 +6,20 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () let mut _0: (); let mut _3: std::iter::FilterMap, impl Fn(T) -> Option>; let mut _4: std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _5: &mut std::iter::FilterMap, impl Fn(T) -> Option>; - let mut _8: std::option::Option; - let mut _9: isize; - let _11: (); + let mut _7: std::option::Option; + let mut _8: isize; + let _10: (); + let mut _11: &mut std::iter::FilterMap, impl Fn(T) -> Option>; scope 1 { debug iter => _4; - let _10: U; + let _9: U; scope 2 { - debug x => _10; + debug x => _9; } scope 4 (inlined , impl Fn(T) -> Option> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: &mut impl Fn(T) -> Option; + debug self => _11; + let mut _5: &mut impl Iterator; + let mut _6: &mut impl Fn(T) -> Option; } } scope 3 (inlined , impl Fn(T) -> Option> as IntoIterator>::into_iter) { @@ -37,24 +37,24 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb2: { - StorageLive(_8); - _5 = &mut _4; - StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); StorageLive(_7); - _7 = &mut (_4.1: impl Fn(T) -> Option); - _8 = as Iterator>::find_map:: Option>(move _6, move _7) -> [return: bb3, unwind: bb9]; + // DBG: _11 = &_4; + StorageLive(_5); + _5 = &mut (_4.0: impl Iterator); + StorageLive(_6); + _6 = &mut (_4.1: impl Fn(T) -> Option); + _7 = as Iterator>::find_map:: Option>(move _5, move _6) -> [return: bb3, unwind: bb9]; } bb3: { - StorageDead(_7); StorageDead(_6); - _9 = discriminant(_8); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8]; + StorageDead(_5); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8]; } bb4: { - StorageDead(_8); + StorageDead(_7); drop(_4) -> [return: bb5, unwind continue]; } @@ -64,12 +64,12 @@ fn filter_mapped(_1: impl Iterator, _2: impl Fn(T) -> Option) -> () } bb6: { - _10 = move ((_8 as Some).0: U); - _11 = opaque::(move _10) -> [return: bb7, unwind: bb9]; + _9 = move ((_7 as Some).0: U); + _10 = opaque::(move _9) -> [return: bb7, unwind: bb9]; } bb7: { - StorageDead(_8); + StorageDead(_7); goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir index 154cbd3791cbd..beb7b936ccf74 100644 --- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir @@ -5,32 +5,31 @@ fn int_range(_1: usize, _2: usize) -> () { debug end => _2; let mut _0: (); let mut _3: std::ops::Range; - let mut _4: std::ops::Range; - let mut _5: &mut std::ops::Range; - let mut _13: std::option::Option; - let _15: (); + let mut _9: std::option::Option; + let _11: (); + let mut _12: &mut std::ops::Range; scope 1 { - debug iter => _4; - let _14: usize; + debug iter => _3; + let _10: usize; scope 2 { - debug i => _14; + debug i => _10; } scope 4 (inlined iter::range::>::next) { - debug self => _5; + debug self => _12; scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _5; - let mut _6: &usize; - let mut _7: &usize; - let mut _10: bool; - let _11: usize; - let mut _12: usize; + debug self => _12; + let mut _6: bool; + let _7: usize; + let mut _8: usize; + let mut _13: &usize; + let mut _14: &usize; scope 6 { - debug old => _11; + debug old => _7; scope 8 (inlined ::forward_unchecked) { - debug start => _11; + debug start => _7; debug n => const 1_usize; scope 9 (inlined #[track_caller] core::num::::unchecked_add) { - debug self => _11; + debug self => _7; debug rhs => const 1_usize; scope 10 (inlined core::ub_checks::check_language_ub) { scope 11 (inlined core::ub_checks::check_language_ub::runtime) { @@ -40,10 +39,10 @@ fn int_range(_1: usize, _2: usize) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - debug self => _6; - debug other => _7; - let mut _8: usize; - let mut _9: usize; + debug self => _13; + debug other => _14; + let mut _4: usize; + let mut _5: usize; } } } @@ -54,54 +53,45 @@ fn int_range(_1: usize, _2: usize) -> () { bb0: { _3 = std::ops::Range:: { start: copy _1, end: copy _2 }; - StorageLive(_4); - _4 = copy _3; goto -> bb1; } bb1: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_10); - StorageLive(_6); - _6 = &(_4.0: usize); - StorageLive(_7); - _7 = &(_4.1: usize); - StorageLive(_8); - _8 = copy (_4.0: usize); StorageLive(_9); - _9 = copy (_4.1: usize); - _10 = Lt(move _8, move _9); - StorageDead(_9); - StorageDead(_8); - switchInt(move _10) -> [0: bb2, otherwise: bb3]; + // DBG: _12 = &_3; + StorageLive(_6); + // DBG: _13 = &(_3.0: usize); + // DBG: _14 = &(_3.1: usize); + StorageLive(_4); + _4 = copy (_3.0: usize); + StorageLive(_5); + _5 = copy (_3.1: usize); + _6 = Lt(move _4, move _5); + StorageDead(_5); + StorageDead(_4); + switchInt(move _6) -> [0: bb2, otherwise: bb3]; } bb2: { - StorageDead(_7); StorageDead(_6); - StorageDead(_10); - StorageDead(_13); - StorageDead(_4); + StorageDead(_9); return; } bb3: { - StorageDead(_7); + _7 = copy (_3.0: usize); + StorageLive(_8); + _8 = AddUnchecked(copy _7, const 1_usize); + (_3.0: usize) = move _8; + StorageDead(_8); + _9 = Option::::Some(copy _7); StorageDead(_6); - _11 = copy (_4.0: usize); - StorageLive(_12); - _12 = AddUnchecked(copy _11, const 1_usize); - (_4.0: usize) = move _12; - StorageDead(_12); - _13 = Option::::Some(copy _11); - StorageDead(_10); - _14 = copy ((_13 as Some).0: usize); - _15 = opaque::(move _14) -> [return: bb4, unwind continue]; + _10 = copy ((_9 as Some).0: usize); + _11 = opaque::(move _10) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_13); + StorageDead(_9); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir index d22ea54004c91..406c96fc32f48 100644 --- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir @@ -6,32 +6,32 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { let mut _0: (); let mut _3: std::iter::Map, impl Fn(T) -> U>; let mut _4: std::iter::Map, impl Fn(T) -> U>; - let mut _5: &mut std::iter::Map, impl Fn(T) -> U>; - let mut _13: std::option::Option; - let _15: (); + let mut _12: std::option::Option; + let _14: (); + let mut _15: &mut std::iter::Map, impl Fn(T) -> U>; scope 1 { debug iter => _4; - let _14: U; + let _13: U; scope 2 { - debug x => _14; + debug x => _13; } scope 4 (inlined , impl Fn(T) -> U> as Iterator>::next) { - debug self => _5; - let mut _6: &mut impl Iterator; - let mut _7: std::option::Option; - let mut _8: &mut impl Fn(T) -> U; + debug self => _15; + let mut _5: &mut impl Iterator; + let mut _6: std::option::Option; + let mut _7: &mut impl Fn(T) -> U; scope 5 (inlined Option::::map:: U>) { - debug self => _7; - debug f => _8; - let mut _9: isize; - let _10: T; - let mut _11: (T,); - let mut _12: U; + debug self => _6; + debug f => _7; + let mut _8: isize; + let _9: T; + let mut _10: (T,); + let mut _11: U; scope 6 { - debug x => _10; + debug x => _9; scope 7 (inlined ops::function::impls:: for &mut impl Fn(T) -> U>::call_once) { - debug self => _8; - debug args => _11; + debug self => _7; + debug args => _10; } } } @@ -52,30 +52,30 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb2: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_8); + StorageLive(_12); + // DBG: _15 = &_4; StorageLive(_7); StorageLive(_6); - _6 = &mut (_4.0: impl Iterator); - _7 = as Iterator>::next(move _6) -> [return: bb3, unwind: bb10]; + StorageLive(_5); + _5 = &mut (_4.0: impl Iterator); + _6 = as Iterator>::next(move _5) -> [return: bb3, unwind: bb10]; } bb3: { - StorageDead(_6); - _8 = &mut (_4.1: impl Fn(T) -> U); + StorageDead(_5); + _7 = &mut (_4.1: impl Fn(T) -> U); + StorageLive(_8); StorageLive(_9); - StorageLive(_10); - _9 = discriminant(_7); - switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb9]; + _8 = discriminant(_6); + switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb9]; } bb4: { - StorageDead(_10); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - StorageDead(_13); + StorageDead(_6); + StorageDead(_7); + StorageDead(_12); drop(_4) -> [return: bb5, unwind continue]; } @@ -85,27 +85,27 @@ fn mapped(_1: impl Iterator, _2: impl Fn(T) -> U) -> () { } bb6: { - _10 = move ((_7 as Some).0: T); - StorageLive(_12); + _9 = move ((_6 as Some).0: T); StorageLive(_11); - _11 = (copy _10,); - _12 = U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10]; + StorageLive(_10); + _10 = (copy _9,); + _11 = U as FnMut<(T,)>>::call_mut(move _7, move _10) -> [return: bb7, unwind: bb10]; } bb7: { - StorageDead(_11); - _13 = Option::::Some(move _12); - StorageDead(_12); StorageDead(_10); + _12 = Option::::Some(move _11); + StorageDead(_11); StorageDead(_9); - StorageDead(_7); StorageDead(_8); - _14 = move ((_13 as Some).0: U); - _15 = opaque::(move _14) -> [return: bb8, unwind: bb10]; + StorageDead(_6); + StorageDead(_7); + _13 = move ((_12 as Some).0: U); + _14 = opaque::(move _13) -> [return: bb8, unwind: bb10]; } bb8: { - StorageDead(_13); + StorageDead(_12); goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/loops.rs b/tests/mir-opt/pre-codegen/loops.rs index d0b8cc8db7a90..952dd8cac60fd 100644 --- a/tests/mir-opt/pre-codegen/loops.rs +++ b/tests/mir-opt/pre-codegen/loops.rs @@ -1,5 +1,6 @@ // skip-filecheck //@ compile-flags: -O -Zmir-opt-level=2 -g +//@ ignore-std-debug-assertions (debug assertions result in different inlines) //@ needs-unwind #![crate_type = "lib"] diff --git a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir index e537dd6a28ef8..66eb1bcfaa665 100644 --- a/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.vec_move.PreCodegen.after.mir @@ -3,72 +3,320 @@ fn vec_move(_1: Vec) -> () { debug v => _1; let mut _0: (); - let mut _2: std::vec::IntoIter; - let mut _3: std::vec::IntoIter; - let mut _4: &mut std::vec::IntoIter; - let mut _5: std::option::Option; - let mut _6: isize; - let _8: (); + let mut _22: std::vec::IntoIter; + let mut _23: std::vec::IntoIter; + let mut _24: &mut std::vec::IntoIter; + let mut _25: std::option::Option; + let mut _26: isize; + let _28: (); scope 1 { - debug iter => _3; - let _7: impl Sized; + debug iter => _23; + let _27: impl Sized; scope 2 { - debug x => _7; + debug x => _27; + } + } + scope 3 (inlined as IntoIterator>::into_iter) { + debug self => _1; + let _2: std::mem::ManuallyDrop>; + let mut _3: *const std::alloc::Global; + let mut _8: usize; + let mut _10: *mut impl Sized; + let mut _11: *const impl Sized; + let mut _12: usize; + let _29: &std::vec::Vec; + let mut _30: &std::mem::ManuallyDrop>; + let mut _31: &alloc::raw_vec::RawVec; + let mut _32: &std::mem::ManuallyDrop>; + let _33: &std::vec::Vec; + let mut _34: &std::mem::ManuallyDrop>; + let _35: &std::vec::Vec; + let mut _36: &std::mem::ManuallyDrop>; + let mut _37: &alloc::raw_vec::RawVec; + let mut _38: &std::mem::ManuallyDrop>; + scope 4 { + debug me => _2; + scope 5 { + debug alloc => const ManuallyDrop:: {{ value: std::alloc::Global }}; + let _6: std::ptr::NonNull; + scope 6 { + debug buf => _6; + let _7: *mut impl Sized; + scope 7 { + debug begin => _7; + scope 8 { + debug end => _11; + let _20: usize; + scope 9 { + debug cap => _20; + } + scope 39 (inlined > as Deref>::deref) { + debug self => _38; + } + scope 40 (inlined alloc::raw_vec::RawVec::::capacity) { + debug self => _37; + let mut _19: usize; + let mut _39: &alloc::raw_vec::RawVecInner; + scope 41 (inlined std::mem::size_of::) { + } + scope 42 (inlined alloc::raw_vec::RawVecInner::capacity) { + debug self => _39; + debug elem_size => _19; + let mut _21: core::num::niche_types::UsizeNoHighBit; + scope 43 (inlined core::num::niche_types::UsizeNoHighBit::as_inner) { + debug self => _21; + } + } + } + } + scope 25 (inlined > as Deref>::deref) { + debug self => _34; + } + scope 26 (inlined Vec::::len) { + debug self => _33; + let mut _13: bool; + scope 27 { + } + } + scope 28 (inlined std::ptr::mut_ptr::::wrapping_byte_add) { + debug self => _7; + debug count => _12; + let mut _14: *mut u8; + let mut _18: *mut u8; + scope 29 (inlined std::ptr::mut_ptr::::cast::) { + debug self => _7; + } + scope 30 (inlined std::ptr::mut_ptr::::wrapping_add) { + debug self => _14; + debug count => _12; + let mut _15: isize; + scope 31 (inlined std::ptr::mut_ptr::::wrapping_offset) { + debug self => _14; + debug count => _15; + let mut _16: *const u8; + let mut _17: *const u8; + } + } + scope 32 (inlined std::ptr::mut_ptr::::with_metadata_of::) { + debug self => _18; + debug meta => _5; + scope 33 (inlined std::ptr::metadata::) { + debug ptr => _5; + } + scope 34 (inlined std::ptr::from_raw_parts_mut::) { + } + } + } + scope 35 (inlined > as Deref>::deref) { + debug self => _36; + } + scope 36 (inlined Vec::::len) { + debug self => _35; + let mut _9: bool; + scope 37 { + } + } + scope 38 (inlined #[track_caller] std::ptr::mut_ptr::::add) { + debug self => _7; + debug count => _8; + } + } + scope 24 (inlined NonNull::::as_ptr) { + debug self => _6; + } + } + scope 17 (inlined > as Deref>::deref) { + debug self => _32; + } + scope 18 (inlined alloc::raw_vec::RawVec::::non_null) { + debug self => _31; + scope 19 (inlined alloc::raw_vec::RawVecInner::non_null::) { + let mut _4: std::ptr::NonNull; + scope 20 (inlined Unique::::cast::) { + scope 21 (inlined NonNull::::cast::) { + let mut _5: *const impl Sized; + scope 22 (inlined NonNull::::as_ptr) { + } + } + } + scope 23 (inlined Unique::::as_non_null_ptr) { + } + } + } + } + scope 11 (inlined > as Deref>::deref) { + debug self => _30; + } + scope 12 (inlined Vec::::allocator) { + debug self => _29; + scope 13 (inlined alloc::raw_vec::RawVec::::allocator) { + scope 14 (inlined alloc::raw_vec::RawVecInner::allocator) { + } + } + } + scope 15 (inlined #[track_caller] std::ptr::read::) { + debug src => _3; + } + scope 16 (inlined ManuallyDrop::::new) { + debug value => const std::alloc::Global; + } + } + scope 10 (inlined ManuallyDrop::>::new) { + debug value => _1; } } bb0: { + StorageLive(_22); + StorageLive(_6); + StorageLive(_7); + StorageLive(_11); + StorageLive(_20); + StorageLive(_5); + StorageLive(_4); + StorageLive(_17); StorageLive(_2); - _2 = as IntoIterator>::into_iter(move _1) -> [return: bb1, unwind continue]; + _2 = ManuallyDrop::> { value: copy _1 }; + StorageLive(_3); + // DBG: _30 = &_2; + // DBG: _29 = &(_2.0: std::vec::Vec); + _3 = &raw const ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).2: std::alloc::Global); + StorageDead(_3); + // DBG: _32 = &_2; + // DBG: _31 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); + _4 = copy (((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique).0: std::ptr::NonNull); + _5 = copy _4 as *const impl Sized (Transmute); + _6 = NonNull:: { pointer: copy _5 }; + _7 = copy _4 as *mut impl Sized (Transmute); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_3); - _3 = move _2; - goto -> bb2; + StorageLive(_10); + StorageLive(_8); + // DBG: _36 = &_2; + // DBG: _35 = &(_2.0: std::vec::Vec); + _8 = copy ((_2.0: std::vec::Vec).1: usize); + StorageLive(_9); + _9 = Le(copy _8, const ::MAX_SLICE_LEN); + assume(move _9); + StorageDead(_9); + _10 = Offset(copy _7, copy _8); + _11 = copy _10 as *const impl Sized (PtrToPtr); + StorageDead(_8); + StorageDead(_10); + goto -> bb4; } bb2: { - StorageLive(_5); - _4 = &mut _3; - _5 = as Iterator>::next(move _4) -> [return: bb3, unwind: bb9]; + StorageLive(_12); + // DBG: _34 = &_2; + // DBG: _33 = &(_2.0: std::vec::Vec); + _12 = copy ((_2.0: std::vec::Vec).1: usize); + StorageLive(_13); + _13 = Le(copy _12, const ::MAX_SLICE_LEN); + assume(move _13); + StorageDead(_13); + StorageLive(_18); + StorageLive(_14); + _14 = copy _4 as *mut u8 (Transmute); + StorageLive(_15); + _15 = copy _12 as isize (IntToInt); + StorageLive(_16); + _16 = copy _4 as *const u8 (Transmute); + _17 = arith_offset::(move _16, move _15) -> [return: bb3, unwind unreachable]; } bb3: { - _6 = discriminant(_5); - switchInt(move _6) -> [0: bb4, 1: bb6, otherwise: bb8]; + StorageDead(_16); + _18 = copy _17 as *mut u8 (PtrToPtr); + StorageDead(_15); + StorageDead(_14); + StorageDead(_18); + StorageDead(_12); + _11 = copy _17 as *const impl Sized (PtrToPtr); + goto -> bb4; } bb4: { - StorageDead(_5); - drop(_3) -> [return: bb5, unwind continue]; + // DBG: _38 = &_2; + // DBG: _37 = &((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec); + // DBG: _39 = &(((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner); + StorageLive(_19); + _19 = SizeOf(impl Sized); + switchInt(move _19) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_3); - StorageDead(_2); - return; + _20 = const usize::MAX; + goto -> bb7; } bb6: { - _7 = move ((_5 as Some).0: impl Sized); - _8 = opaque::(move _7) -> [return: bb7, unwind: bb9]; + StorageLive(_21); + _21 = copy ((((_2.0: std::vec::Vec).0: alloc::raw_vec::RawVec).0: alloc::raw_vec::RawVecInner).1: core::num::niche_types::UsizeNoHighBit); + _20 = copy _21 as usize (Transmute); + StorageDead(_21); + goto -> bb7; } bb7: { + StorageDead(_19); + _22 = std::vec::IntoIter:: { buf: copy _6, phantom: const ZeroSized: PhantomData, cap: move _20, alloc: const ManuallyDrop:: {{ value: std::alloc::Global }}, ptr: copy _6, end: copy _11 }; + StorageDead(_2); + StorageDead(_17); + StorageDead(_4); StorageDead(_5); - goto -> bb2; + StorageDead(_20); + StorageDead(_11); + StorageDead(_7); + StorageDead(_6); + StorageLive(_23); + _23 = move _22; + goto -> bb8; } bb8: { + StorageLive(_25); + _24 = &mut _23; + _25 = as Iterator>::next(move _24) -> [return: bb9, unwind: bb15]; + } + + bb9: { + _26 = discriminant(_25); + switchInt(move _26) -> [0: bb10, 1: bb12, otherwise: bb14]; + } + + bb10: { + StorageDead(_25); + drop(_23) -> [return: bb11, unwind continue]; + } + + bb11: { + StorageDead(_23); + StorageDead(_22); + return; + } + + bb12: { + _27 = move ((_25 as Some).0: impl Sized); + _28 = opaque::(move _27) -> [return: bb13, unwind: bb15]; + } + + bb13: { + StorageDead(_25); + goto -> bb8; + } + + bb14: { unreachable; } - bb9 (cleanup): { - drop(_3) -> [return: bb10, unwind terminate(cleanup)]; + bb15 (cleanup): { + drop(_23) -> [return: bb16, unwind terminate(cleanup)]; } - bb10 (cleanup): { + bb16 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir index dfe618612ab96..03a52b82b49b1 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -5,23 +5,21 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug end => _2; debug f => _3; let mut _0: (); - let mut _4: u32; - let mut _9: std::option::Option; - let mut _11: &impl Fn(u32); - let mut _12: (u32,); - let _13: (); + let mut _7: std::option::Option; + let mut _9: &impl Fn(u32); + let mut _10: (u32,); + let _11: (); scope 1 { - debug ((iter: std::ops::Range).0: u32) => _4; + debug ((iter: std::ops::Range).0: u32) => _1; debug ((iter: std::ops::Range).1: u32) => _2; - let _10: u32; + let _8: u32; scope 2 { - debug x => _10; + debug x => _8; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: u32; - let mut _8: u32; + let mut _5: bool; + let _6: u32; scope 6 { scope 8 (inlined ::forward_unchecked) { scope 9 (inlined #[track_caller] core::num::::unchecked_add) { @@ -33,7 +31,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - let mut _5: u32; + let mut _4: u32; } } } @@ -42,25 +40,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { - StorageLive(_4); - _4 = copy _1; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_7); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _2); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + StorageLive(_4); + _4 = copy _1; + _5 = Lt(move _4, copy _2); + StorageDead(_4); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_7); drop(_3) -> [return: bb3, unwind unreachable]; } @@ -69,25 +64,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_u32); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: u32); - StorageLive(_11); - _11 = &_3; - StorageLive(_12); - _12 = (copy _10,); - _13 = >::call(move _11, move _12) -> [return: bb5, unwind unreachable]; + _6 = copy _1; + _1 = AddUnchecked(copy _6, const 1_u32); + _7 = Option::::Some(copy _6); + StorageDead(_5); + _8 = copy ((_7 as Some).0: u32); + StorageLive(_9); + _9 = &_3; + StorageLive(_10); + _10 = (copy _8,); + _11 = >::call(move _9, move _10) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_12); - StorageDead(_11); + StorageDead(_10); StorageDead(_9); + StorageDead(_7); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index e0fcfcaffc59a..3b09f33e73338 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -5,23 +5,21 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { debug end => _2; debug f => _3; let mut _0: (); - let mut _4: u32; - let mut _9: std::option::Option; - let mut _11: &impl Fn(u32); - let mut _12: (u32,); - let _13: (); + let mut _7: std::option::Option; + let mut _9: &impl Fn(u32); + let mut _10: (u32,); + let _11: (); scope 1 { - debug ((iter: std::ops::Range).0: u32) => _4; + debug ((iter: std::ops::Range).0: u32) => _1; debug ((iter: std::ops::Range).1: u32) => _2; - let _10: u32; + let _8: u32; scope 2 { - debug x => _10; + debug x => _8; } scope 4 (inlined iter::range::>::next) { scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - let mut _6: bool; - let _7: u32; - let mut _8: u32; + let mut _5: bool; + let _6: u32; scope 6 { scope 8 (inlined ::forward_unchecked) { scope 9 (inlined #[track_caller] core::num::::unchecked_add) { @@ -33,7 +31,7 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } } scope 7 (inlined std::cmp::impls::::lt) { - let mut _5: u32; + let mut _4: u32; } } } @@ -42,25 +40,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb0: { - StorageLive(_4); - _4 = copy _1; goto -> bb1; } bb1: { - StorageLive(_9); - StorageLive(_6); + StorageLive(_7); StorageLive(_5); - _5 = copy _4; - _6 = Lt(move _5, copy _2); - StorageDead(_5); - switchInt(move _6) -> [0: bb2, otherwise: bb4]; + StorageLive(_4); + _4 = copy _1; + _5 = Lt(move _4, copy _2); + StorageDead(_4); + switchInt(move _5) -> [0: bb2, otherwise: bb4]; } bb2: { - StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_5); + StorageDead(_7); drop(_3) -> [return: bb3, unwind continue]; } @@ -69,25 +64,22 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb4: { - _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_u32); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); - StorageDead(_6); - _10 = copy ((_9 as Some).0: u32); - StorageLive(_11); - _11 = &_3; - StorageLive(_12); - _12 = (copy _10,); - _13 = >::call(move _11, move _12) -> [return: bb5, unwind: bb6]; + _6 = copy _1; + _1 = AddUnchecked(copy _6, const 1_u32); + _7 = Option::::Some(copy _6); + StorageDead(_5); + _8 = copy ((_7 as Some).0: u32); + StorageLive(_9); + _9 = &_3; + StorageLive(_10); + _10 = (copy _8,); + _11 = >::call(move _9, move _10) -> [return: bb5, unwind: bb6]; } bb5: { - StorageDead(_12); - StorageDead(_11); + StorageDead(_10); StorageDead(_9); + StorageDead(_7); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir index cbdd194afd3ab..2cab88182962f 100644 --- a/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir @@ -3,183 +3,134 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2: &&(usize, usize, usize, usize)) -> bool { let mut _0: bool; let mut _3: &(usize, usize, usize, usize); - let _4: &usize; - let _5: &usize; - let _6: &usize; - let _7: &usize; - let mut _8: &&usize; - let _9: &usize; - let mut _10: &&usize; - let mut _13: bool; - let mut _14: &&usize; + let mut _6: bool; + let mut _9: bool; + let mut _10: bool; + let _13: &usize; + let _14: &usize; let _15: &usize; - let mut _16: &&usize; - let mut _19: bool; + let _16: &usize; + let mut _17: &&usize; + let mut _18: &&usize; + let mut _19: &&usize; let mut _20: &&usize; - let _21: &usize; + let mut _21: &&usize; let mut _22: &&usize; - let mut _23: bool; + let mut _23: &&usize; let mut _24: &&usize; - let _25: &usize; - let mut _26: &&usize; scope 1 { - debug a => _4; - debug b => _5; - debug c => _6; - debug d => _7; + debug a => _13; + debug b => _14; + debug c => _15; + debug d => _16; scope 2 (inlined std::cmp::impls::::le) { - debug self => _8; - debug other => _10; + debug self => _17; + debug other => _18; scope 3 (inlined std::cmp::impls::::le) { - debug self => _4; - debug other => _6; - let mut _11: usize; - let mut _12: usize; + debug self => _13; + debug other => _15; + let mut _4: usize; + let mut _5: usize; } } scope 4 (inlined std::cmp::impls::::le) { - debug self => _14; - debug other => _16; + debug self => _19; + debug other => _20; scope 5 (inlined std::cmp::impls::::le) { - debug self => _7; - debug other => _5; - let mut _17: usize; - let mut _18: usize; + debug self => _16; + debug other => _14; + let mut _7: usize; + let mut _8: usize; } } scope 6 (inlined std::cmp::impls::::le) { - debug self => _20; + debug self => _21; debug other => _22; scope 7 (inlined std::cmp::impls::::le) { - debug self => _6; - debug other => _4; + debug self => _15; + debug other => _13; } } scope 8 (inlined std::cmp::impls::::le) { - debug self => _24; - debug other => _26; + debug self => _23; + debug other => _24; scope 9 (inlined std::cmp::impls::::le) { - debug self => _5; - debug other => _7; - let mut _27: usize; - let mut _28: usize; + debug self => _14; + debug other => _16; + let mut _11: usize; + let mut _12: usize; } } } bb0: { _3 = copy (*_2); - _4 = &((*_3).0: usize); - _5 = &((*_3).1: usize); - _6 = &((*_3).2: usize); - _7 = &((*_3).3: usize); - StorageLive(_13); - StorageLive(_8); - _8 = &_4; - StorageLive(_10); - StorageLive(_9); - _9 = copy _6; - _10 = &_9; - _11 = copy ((*_3).0: usize); - _12 = copy ((*_3).2: usize); - _13 = Le(copy _11, copy _12); - switchInt(move _13) -> [0: bb1, otherwise: bb2]; + // DBG: _13 = &((*_3).0: usize); + // DBG: _14 = &((*_3).1: usize); + // DBG: _15 = &((*_3).2: usize); + // DBG: _16 = &((*_3).3: usize); + StorageLive(_6); + // DBG: _17 = &_13; + // DBG: _18 = &?; + _4 = copy ((*_3).0: usize); + _5 = copy ((*_3).2: usize); + _6 = Le(copy _4, copy _5); + switchInt(move _6) -> [0: bb2, otherwise: bb1]; } bb1: { - StorageDead(_9); - StorageDead(_10); + StorageLive(_9); + // DBG: _19 = &_16; + // DBG: _20 = &?; + StorageLive(_7); + _7 = copy ((*_3).3: usize); + StorageLive(_8); + _8 = copy ((*_3).1: usize); + _9 = Le(move _7, move _8); StorageDead(_8); - goto -> bb4; + StorageDead(_7); + switchInt(move _9) -> [0: bb2, otherwise: bb6]; } bb2: { - StorageDead(_9); - StorageDead(_10); - StorageDead(_8); - StorageLive(_19); - StorageLive(_14); - _14 = &_7; - StorageLive(_16); - StorageLive(_15); - _15 = copy _5; - _16 = &_15; - StorageLive(_17); - _17 = copy ((*_3).3: usize); - StorageLive(_18); - _18 = copy ((*_3).1: usize); - _19 = Le(move _17, move _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb3, otherwise: bb8]; + StorageLive(_10); + // DBG: _21 = &_15; + // DBG: _22 = &?; + _10 = Le(copy _5, copy _4); + switchInt(move _10) -> [0: bb3, otherwise: bb4]; } bb3: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); - goto -> bb4; + _0 = const false; + goto -> bb5; } bb4: { - StorageLive(_23); - StorageLive(_20); - _20 = &_6; - StorageLive(_22); - StorageLive(_21); - _21 = copy _4; - _22 = &_21; - _23 = Le(copy _12, copy _11); - switchInt(move _23) -> [0: bb5, otherwise: bb6]; + // DBG: _23 = &_14; + // DBG: _24 = &?; + StorageLive(_11); + _11 = copy ((*_3).1: usize); + StorageLive(_12); + _12 = copy ((*_3).3: usize); + _0 = Le(move _11, move _12); + StorageDead(_12); + StorageDead(_11); + goto -> bb5; } bb5: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); - _0 = const false; + StorageDead(_10); goto -> bb7; } bb6: { - StorageDead(_21); - StorageDead(_22); - StorageDead(_20); - StorageLive(_24); - _24 = &_5; - StorageLive(_26); - StorageLive(_25); - _25 = copy _7; - _26 = &_25; - StorageLive(_27); - _27 = copy ((*_3).1: usize); - StorageLive(_28); - _28 = copy ((*_3).3: usize); - _0 = Le(move _27, move _28); - StorageDead(_28); - StorageDead(_27); - StorageDead(_25); - StorageDead(_26); - StorageDead(_24); + _0 = const true; goto -> bb7; } bb7: { - StorageDead(_23); - goto -> bb9; - } - - bb8: { - StorageDead(_15); - StorageDead(_16); - StorageDead(_14); - _0 = const true; - goto -> bb9; - } - - bb9: { - StorageDead(_19); - StorageDead(_13); + StorageDead(_9); + StorageDead(_6); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index 72b39a7f6a87b..104987b0fdda9 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,30 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _13: usize; - let mut _32: std::option::Option<(usize, &T)>; - let mut _35: &impl Fn(usize, &T); - let mut _36: (usize, &T); - let _37: (); + let mut _10: usize; + let mut _28: std::option::Option<(usize, &T)>; + let mut _31: &impl Fn(usize, &T); + let mut _32: (usize, &T); + let _33: (); scope 1 { - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _12; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; + debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).1: *const T) => _9; debug (((iter: Enumerate>).0: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - debug ((iter: Enumerate>).1: usize) => _13; - let _33: usize; - let _34: &T; + debug ((iter: Enumerate>).1: usize) => _10; + let _29: usize; + let _30: &T; scope 2 { - debug i => _33; - debug x => _34; + debug i => _29; + debug x => _30; } scope 18 (inlined > as Iterator>::next) { - let mut _27: std::option::Option<&T>; - let mut _30: (usize, bool); - let mut _31: (usize, &T); + let mut _23: std::option::Option<&T>; + let mut _26: (usize, bool); + let mut _27: (usize, &T); scope 19 { - let _29: usize; + let _25: usize; scope 24 { } } @@ -42,21 +40,21 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 25 (inlined as Try>::branch) { - let _28: &T; + let _24: &T; scope 26 { } } scope 28 (inlined as Iterator>::next) { - let _14: std::ptr::NonNull; - let _16: std::ptr::NonNull; - let mut _19: bool; - let mut _22: std::ptr::NonNull; - let mut _24: usize; - let _26: &T; + let mut _6: std::ptr::NonNull; + let _11: std::ptr::NonNull; + let _13: std::ptr::NonNull; + let mut _16: bool; + let mut _20: usize; + let _22: &T; scope 29 { - let _15: *const T; + let _12: *const T; scope 30 { - let _23: usize; + let _19: usize; scope 31 { scope 34 (inlined #[track_caller] core::num::::unchecked_sub) { scope 35 (inlined core::ub_checks::check_language_ub) { @@ -72,21 +70,21 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } } scope 38 (inlined as PartialEq>::eq) { - let mut _17: *mut T; - let mut _18: *mut T; + let mut _14: *mut T; + let mut _15: *mut T; scope 39 (inlined NonNull::::as_ptr) { } scope 40 (inlined NonNull::::as_ptr) { } } scope 41 (inlined NonNull::::add) { - let mut _20: *const T; - let mut _21: *const T; + let mut _17: *const T; + let mut _18: *const T; scope 42 (inlined NonNull::::as_ptr) { } } scope 43 (inlined NonNull::::as_ref::<'_>) { - let _25: *const T; + let _21: *const T; scope 44 (inlined NonNull::::as_ptr) { } scope 45 (inlined std::ptr::mut_ptr::::cast_const) { @@ -102,9 +100,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { - let _6: std::ptr::NonNull; scope 6 { let _9: *const T; scope 7 { @@ -145,7 +141,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -166,97 +161,86 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); - StorageLive(_11); - StorageLive(_12); - StorageLive(_13); - _11 = copy _6; - _12 = copy _10; - _13 = const 0_usize; + StorageLive(_10); + _10 = const 0_usize; goto -> bb4; } bb4: { - StorageLive(_32); - StorageLive(_29); - StorageLive(_30); - StorageLive(_27); - StorageLive(_14); - StorageLive(_15); - StorageLive(_23); - StorageLive(_24); - StorageLive(_16); + StorageLive(_28); + StorageLive(_25); StorageLive(_26); - _14 = copy _11; - _15 = copy _12; + StorageLive(_23); + StorageLive(_11); + StorageLive(_12); + StorageLive(_19); + StorageLive(_20); + StorageLive(_13); + StorageLive(_22); + _11 = copy _6; + _12 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_19); - _16 = copy _15 as std::ptr::NonNull (Transmute); - StorageLive(_17); - _17 = copy _14 as *mut T (Transmute); - StorageLive(_18); - _18 = copy _16 as *mut T (Transmute); - _19 = Eq(copy _17, copy _18); - StorageDead(_18); - StorageDead(_17); - switchInt(move _19) -> [0: bb6, otherwise: bb7]; + StorageLive(_16); + _13 = copy _12 as std::ptr::NonNull (Transmute); + StorageLive(_14); + _14 = copy _11 as *mut T (Transmute); + StorageLive(_15); + _15 = copy _13 as *mut T (Transmute); + _16 = Eq(copy _14, copy _15); + StorageDead(_15); + StorageDead(_14); + switchInt(move _16) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_19); - StorageLive(_22); - StorageLive(_21); - StorageLive(_20); - _20 = copy _14 as *const T (Transmute); - _21 = Offset(copy _20, const 1_usize); - StorageDead(_20); - _22 = NonNull:: { pointer: copy _21 }; - StorageDead(_21); - _11 = move _22; - StorageDead(_22); + StorageDead(_16); + StorageLive(_18); + StorageLive(_17); + _17 = copy _11 as *const T (Transmute); + _18 = Offset(copy _17, const 1_usize); + StorageDead(_17); + _6 = NonNull:: { pointer: copy _18 }; + StorageDead(_18); goto -> bb13; } bb7: { - StorageDead(_19); - StorageDead(_26); StorageDead(_16); - StorageDead(_24); - StorageDead(_23); - StorageDead(_15); - StorageDead(_14); + StorageDead(_22); + StorageDead(_13); + StorageDead(_20); + StorageDead(_19); + StorageDead(_12); + StorageDead(_11); goto -> bb10; } bb8: { - _23 = copy _15 as usize (Transmute); - switchInt(copy _23) -> [0: bb9, otherwise: bb12]; + _19 = copy _12 as usize (Transmute); + switchInt(copy _19) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); - StorageDead(_23); - StorageDead(_15); - StorageDead(_14); + StorageDead(_22); + StorageDead(_13); + StorageDead(_20); + StorageDead(_19); + StorageDead(_12); + StorageDead(_11); goto -> bb10; } bb10: { - StorageDead(_27); - StorageDead(_30); - StorageDead(_29); - StorageDead(_32); - StorageDead(_11); - StorageDead(_12); - StorageDead(_13); + StorageDead(_23); + StorageDead(_26); + StorageDead(_25); + StorageDead(_28); + StorageDead(_10); drop(_2) -> [return: bb11, unwind unreachable]; } @@ -265,51 +249,51 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb12: { - _24 = SubUnchecked(copy _23, const 1_usize); - _12 = copy _24 as *const T (Transmute); + _20 = SubUnchecked(copy _19, const 1_usize); + _9 = copy _20 as *const T (Transmute); goto -> bb13; } bb13: { - StorageLive(_25); - _25 = copy _14 as *const T (Transmute); - _26 = &(*_25); - StorageDead(_25); - _27 = Option::<&T>::Some(copy _26); - StorageDead(_26); - StorageDead(_16); - StorageDead(_24); + StorageLive(_21); + _21 = copy _11 as *const T (Transmute); + _22 = &(*_21); + StorageDead(_21); + _23 = Option::<&T>::Some(copy _22); + StorageDead(_22); + StorageDead(_13); + StorageDead(_20); + StorageDead(_19); + StorageDead(_12); + StorageDead(_11); + _24 = copy ((_23 as Some).0: &T); StorageDead(_23); - StorageDead(_15); - StorageDead(_14); - _28 = copy ((_27 as Some).0: &T); - StorageDead(_27); - _29 = copy _13; - _30 = AddWithOverflow(copy _13, const 1_usize); - assert(!move (_30.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _13, const 1_usize) -> [success: bb14, unwind unreachable]; + _25 = copy _10; + _26 = AddWithOverflow(copy _10, const 1_usize); + assert(!move (_26.1: bool), "attempt to compute `{} + {}`, which would overflow", copy _10, const 1_usize) -> [success: bb14, unwind unreachable]; } bb14: { - _13 = move (_30.0: usize); + _10 = move (_26.0: usize); + StorageLive(_27); + _27 = (copy _25, copy _24); + _28 = Option::<(usize, &T)>::Some(move _27); + StorageDead(_27); + StorageDead(_26); + StorageDead(_25); + _29 = copy (((_28 as Some).0: (usize, &T)).0: usize); + _30 = copy (((_28 as Some).0: (usize, &T)).1: &T); StorageLive(_31); - _31 = (copy _29, copy _28); - _32 = Option::<(usize, &T)>::Some(move _31); - StorageDead(_31); - StorageDead(_30); - StorageDead(_29); - _33 = copy (((_32 as Some).0: (usize, &T)).0: usize); - _34 = copy (((_32 as Some).0: (usize, &T)).1: &T); - StorageLive(_35); - _35 = &_2; - StorageLive(_36); - _36 = (copy _33, copy _34); - _37 = >::call(move _35, move _36) -> [return: bb15, unwind unreachable]; + _31 = &_2; + StorageLive(_32); + _32 = (copy _29, copy _30); + _33 = >::call(move _31, move _32) -> [return: bb15, unwind unreachable]; } bb15: { - StorageDead(_36); - StorageDead(_35); StorageDead(_32); + StorageDead(_31); + StorageDead(_28); goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 42aa152ec99d6..28b12cdf36755 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,22 +4,22 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Enumerate>; let mut _12: std::iter::Enumerate>; - let mut _13: std::iter::Enumerate>; - let mut _14: &mut std::iter::Enumerate>; - let mut _15: std::option::Option<(usize, &T)>; - let mut _16: isize; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _13: &mut std::iter::Enumerate>; + let mut _14: std::option::Option<(usize, &T)>; + let mut _15: isize; + let mut _18: &impl Fn(usize, &T); + let mut _19: (usize, &T); + let _20: (); scope 1 { - debug iter => _13; - let _17: usize; - let _18: &T; + debug iter => _12; + let _16: usize; + let _17: &T; scope 2 { - debug i => _17; - debug x => _18; + debug i => _16; + debug x => _17; } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +27,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,9 +61,10 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); + StorageLive(_9); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -72,7 +72,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,33 +92,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); + StorageDead(_9); StorageDead(_6); StorageDead(_3); - _12 = Enumerate::> { iter: copy _11, count: const 0_usize }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Enumerate::> { iter: copy _10, count: const 0_usize }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - _14 = &mut _13; - _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + _13 = &mut _12; + _14 = > as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_13); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -128,18 +124,18 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _17 = copy (((_15 as Some).0: (usize, &T)).0: usize); - _18 = copy (((_15 as Some).0: (usize, &T)).1: &T); + _16 = copy (((_14 as Some).0: (usize, &T)).0: usize); + _17 = copy (((_14 as Some).0: (usize, &T)).1: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = copy ((_15 as Some).0: (usize, &T)); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = copy ((_14 as Some).0: (usize, &T)); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); StorageDead(_19); + StorageDead(_18); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 0d65640ec9b14..4d0e3548e7d6b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,31 +4,29 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _22: std::option::Option<&T>; + let mut _24: &impl Fn(&T); + let mut _25: (&T,); + let _26: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _9; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + let _23: &T; scope 2 { - debug x => _27; + debug x => _23; } scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; + let mut _6: std::ptr::NonNull; + let _10: std::ptr::NonNull; + let _12: std::ptr::NonNull; + let mut _15: bool; + let mut _19: usize; + let _21: &T; scope 17 { - let _14: *const T; + let _11: *const T; scope 18 { - let _22: usize; + let _18: usize; scope 19 { scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { scope 23 (inlined core::ub_checks::check_language_ub) { @@ -44,21 +42,21 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 26 (inlined as PartialEq>::eq) { - let mut _16: *mut T; - let mut _17: *mut T; + let mut _13: *mut T; + let mut _14: *mut T; scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined NonNull::::as_ptr) { } } scope 29 (inlined NonNull::::add) { - let mut _19: *const T; - let mut _20: *const T; + let mut _16: *const T; + let mut _17: *const T; scope 30 (inlined NonNull::::as_ptr) { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; + let _20: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -73,9 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { - let _6: std::ptr::NonNull; scope 6 { let _9: *const T; scope 7 { @@ -112,7 +108,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -133,88 +128,77 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); - StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; goto -> bb4; } bb4: { - StorageLive(_26); - StorageLive(_13); - StorageLive(_14); StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); - _13 = copy _11; - _14 = copy _12; + StorageLive(_10); + StorageLive(_11); + StorageLive(_18); + StorageLive(_19); + StorageLive(_12); + StorageLive(_21); + _10 = copy _6; + _11 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); - StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(copy _16, copy _17); - StorageDead(_17); - StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + StorageLive(_15); + _12 = copy _11 as std::ptr::NonNull (Transmute); + StorageLive(_13); + _13 = copy _10 as *mut T (Transmute); + StorageLive(_14); + _14 = copy _12 as *mut T (Transmute); + _15 = Eq(copy _13, copy _14); + StorageDead(_14); + StorageDead(_13); + switchInt(move _15) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(copy _19, const 1_usize); - StorageDead(_19); - _21 = NonNull:: { pointer: copy _20 }; - StorageDead(_20); - _11 = move _21; - StorageDead(_21); + StorageDead(_15); + StorageLive(_17); + StorageLive(_16); + _16 = copy _10 as *const T (Transmute); + _17 = Offset(copy _16, const 1_usize); + StorageDead(_16); + _6 = NonNull:: { pointer: copy _17 }; + StorageDead(_17); goto -> bb13; } bb7: { - StorageDead(_18); - StorageDead(_25); StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); goto -> bb10; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _18 = copy _11 as usize (Transmute); + switchInt(copy _18) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); goto -> bb10; } bb10: { - StorageDead(_26); - StorageDead(_11); - StorageDead(_12); + StorageDead(_22); drop(_2) -> [return: bb11, unwind unreachable]; } @@ -223,35 +207,35 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); + _19 = SubUnchecked(copy _18, const 1_usize); + _9 = copy _19 as *const T (Transmute); goto -> bb13; } bb13: { + StorageLive(_20); + _20 = copy _10 as *const T (Transmute); + _21 = &(*_20); + StorageDead(_20); + _22 = Option::<&T>::Some(copy _21); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); + _23 = copy ((_22 as Some).0: &T); StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); - StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind unreachable]; + _24 = &_2; + StorageLive(_25); + _25 = (copy _23,); + _26 = >::call(move _24, move _25) -> [return: bb14, unwind unreachable]; } bb14: { - StorageDead(_29); - StorageDead(_28); - StorageDead(_26); + StorageDead(_25); + StorageDead(_24); + StorageDead(_22); goto -> bb4; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 02efb193474d6..2b5d8c27d7109 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,31 +4,29 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::ptr::NonNull; - let mut _12: *const T; - let mut _26: std::option::Option<&T>; - let mut _28: &impl Fn(&T); - let mut _29: (&T,); - let _30: (); + let mut _22: std::option::Option<&T>; + let mut _24: &impl Fn(&T); + let mut _25: (&T,); + let _26: (); scope 1 { - debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _11; - debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _12; + debug ((iter: std::slice::Iter<'_, T>).0: std::ptr::NonNull) => _6; + debug ((iter: std::slice::Iter<'_, T>).1: *const T) => _9; debug ((iter: std::slice::Iter<'_, T>).2: std::marker::PhantomData<&T>) => const ZeroSized: PhantomData<&T>; - let _27: &T; + let _23: &T; scope 2 { - debug x => _27; + debug x => _23; } scope 16 (inlined as Iterator>::next) { - let _13: std::ptr::NonNull; - let _15: std::ptr::NonNull; - let mut _18: bool; - let mut _21: std::ptr::NonNull; - let mut _23: usize; - let _25: &T; + let mut _6: std::ptr::NonNull; + let _10: std::ptr::NonNull; + let _12: std::ptr::NonNull; + let mut _15: bool; + let mut _19: usize; + let _21: &T; scope 17 { - let _14: *const T; + let _11: *const T; scope 18 { - let _22: usize; + let _18: usize; scope 19 { scope 22 (inlined #[track_caller] core::num::::unchecked_sub) { scope 23 (inlined core::ub_checks::check_language_ub) { @@ -44,21 +42,21 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } } scope 26 (inlined as PartialEq>::eq) { - let mut _16: *mut T; - let mut _17: *mut T; + let mut _13: *mut T; + let mut _14: *mut T; scope 27 (inlined NonNull::::as_ptr) { } scope 28 (inlined NonNull::::as_ptr) { } } scope 29 (inlined NonNull::::add) { - let mut _19: *const T; - let mut _20: *const T; + let mut _16: *const T; + let mut _17: *const T; scope 30 (inlined NonNull::::as_ptr) { } } scope 31 (inlined NonNull::::as_ref::<'_>) { - let _24: *const T; + let _20: *const T; scope 32 (inlined NonNull::::as_ptr) { } scope 33 (inlined std::ptr::mut_ptr::::cast_const) { @@ -73,9 +71,7 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { - let _6: std::ptr::NonNull; scope 6 { let _9: *const T; scope 7 { @@ -112,7 +108,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -133,88 +128,77 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - _10 = copy _9; - StorageDead(_9); StorageDead(_4); StorageDead(_3); - StorageLive(_11); - StorageLive(_12); - _11 = copy _6; - _12 = copy _10; goto -> bb4; } bb4: { - StorageLive(_26); - StorageLive(_13); - StorageLive(_14); StorageLive(_22); - StorageLive(_23); - StorageLive(_15); - StorageLive(_25); - _13 = copy _11; - _14 = copy _12; + StorageLive(_10); + StorageLive(_11); + StorageLive(_18); + StorageLive(_19); + StorageLive(_12); + StorageLive(_21); + _10 = copy _6; + _11 = copy _9; switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; } bb5: { - StorageLive(_18); - _15 = copy _14 as std::ptr::NonNull (Transmute); - StorageLive(_16); - _16 = copy _13 as *mut T (Transmute); - StorageLive(_17); - _17 = copy _15 as *mut T (Transmute); - _18 = Eq(copy _16, copy _17); - StorageDead(_17); - StorageDead(_16); - switchInt(move _18) -> [0: bb6, otherwise: bb7]; + StorageLive(_15); + _12 = copy _11 as std::ptr::NonNull (Transmute); + StorageLive(_13); + _13 = copy _10 as *mut T (Transmute); + StorageLive(_14); + _14 = copy _12 as *mut T (Transmute); + _15 = Eq(copy _13, copy _14); + StorageDead(_14); + StorageDead(_13); + switchInt(move _15) -> [0: bb6, otherwise: bb7]; } bb6: { - StorageDead(_18); - StorageLive(_21); - StorageLive(_20); - StorageLive(_19); - _19 = copy _13 as *const T (Transmute); - _20 = Offset(copy _19, const 1_usize); - StorageDead(_19); - _21 = NonNull:: { pointer: copy _20 }; - StorageDead(_20); - _11 = move _21; - StorageDead(_21); + StorageDead(_15); + StorageLive(_17); + StorageLive(_16); + _16 = copy _10 as *const T (Transmute); + _17 = Offset(copy _16, const 1_usize); + StorageDead(_16); + _6 = NonNull:: { pointer: copy _17 }; + StorageDead(_17); goto -> bb13; } bb7: { - StorageDead(_18); - StorageDead(_25); StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); goto -> bb10; } bb8: { - _22 = copy _14 as usize (Transmute); - switchInt(copy _22) -> [0: bb9, otherwise: bb12]; + _18 = copy _11 as usize (Transmute); + switchInt(copy _18) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); goto -> bb10; } bb10: { - StorageDead(_26); - StorageDead(_11); - StorageDead(_12); + StorageDead(_22); drop(_2) -> [return: bb11, unwind continue]; } @@ -223,35 +207,35 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb12: { - _23 = SubUnchecked(copy _22, const 1_usize); - _12 = copy _23 as *const T (Transmute); + _19 = SubUnchecked(copy _18, const 1_usize); + _9 = copy _19 as *const T (Transmute); goto -> bb13; } bb13: { + StorageLive(_20); + _20 = copy _10 as *const T (Transmute); + _21 = &(*_20); + StorageDead(_20); + _22 = Option::<&T>::Some(copy _21); + StorageDead(_21); + StorageDead(_12); + StorageDead(_19); + StorageDead(_18); + StorageDead(_11); + StorageDead(_10); + _23 = copy ((_22 as Some).0: &T); StorageLive(_24); - _24 = copy _13 as *const T (Transmute); - _25 = &(*_24); - StorageDead(_24); - _26 = Option::<&T>::Some(copy _25); - StorageDead(_25); - StorageDead(_15); - StorageDead(_23); - StorageDead(_22); - StorageDead(_14); - StorageDead(_13); - _27 = copy ((_26 as Some).0: &T); - StorageLive(_28); - _28 = &_2; - StorageLive(_29); - _29 = (copy _27,); - _30 = >::call(move _28, move _29) -> [return: bb14, unwind: bb15]; + _24 = &_2; + StorageLive(_25); + _25 = (copy _23,); + _26 = >::call(move _24, move _25) -> [return: bb14, unwind: bb15]; } bb14: { - StorageDead(_29); - StorageDead(_28); - StorageDead(_26); + StorageDead(_25); + StorageDead(_24); + StorageDead(_22); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index 41e273151eca4..145375990710b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -5,28 +5,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug f => _2; let mut _0: (); let mut _3: usize; - let mut _4: usize; - let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _8: std::option::Option; + let mut _10: bool; + let mut _12: &impl Fn(usize, &T); + let mut _13: (usize, &T); + let _14: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _10: usize; + let _9: usize; scope 2 { - debug i => _10; - let _12: &T; + debug i => _9; + let _11: &T; scope 3 { - debug x => _12; + debug x => _11; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { + let mut _4: usize; let mut _6: bool; let _7: usize; - let mut _8: usize; scope 7 { scope 9 (inlined ::forward_unchecked) { scope 10 (inlined #[track_caller] core::num::::unchecked_add) { @@ -48,13 +47,12 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = PtrMetadata(copy _1); - StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_9); + StorageLive(_8); StorageLive(_6); StorageLive(_5); _5 = copy _4; @@ -65,8 +63,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb2: { StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_8); drop(_2) -> [return: bb3, unwind unreachable]; } @@ -76,30 +73,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb4: { _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_usize); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); + _4 = AddUnchecked(copy _7, const 1_usize); + _8 = Option::::Some(copy _7); StorageDead(_6); - _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind unreachable]; + _9 = copy ((_8 as Some).0: usize); + _10 = Lt(copy _9, copy _3); + assert(move _10, "index out of bounds: the length is {} but the index is {}", copy _3, copy _9) -> [success: bb5, unwind unreachable]; } bb5: { - _12 = &(*_1)[_10]; + _11 = &(*_1)[_9]; + StorageLive(_12); + _12 = &_2; StorageLive(_13); - _13 = &_2; - StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb6, unwind unreachable]; + _13 = (copy _9, copy _11); + _14 = >::call(move _12, move _13) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_14); StorageDead(_13); - StorageDead(_9); + StorageDead(_12); + StorageDead(_8); goto -> bb1; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index ec781c1480c74..8e573ef488fce 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -5,28 +5,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug f => _2; let mut _0: (); let mut _3: usize; - let mut _4: usize; - let mut _9: std::option::Option; - let mut _11: bool; - let mut _13: &impl Fn(usize, &T); - let mut _14: (usize, &T); - let _15: (); + let mut _8: std::option::Option; + let mut _10: bool; + let mut _12: &impl Fn(usize, &T); + let mut _13: (usize, &T); + let _14: (); scope 1 { debug ((iter: std::ops::Range).0: usize) => _4; debug ((iter: std::ops::Range).1: usize) => _3; - let _10: usize; + let _9: usize; scope 2 { - debug i => _10; - let _12: &T; + debug i => _9; + let _11: &T; scope 3 { - debug x => _12; + debug x => _11; } } scope 5 (inlined iter::range::>::next) { scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { + let mut _4: usize; let mut _6: bool; let _7: usize; - let mut _8: usize; scope 7 { scope 9 (inlined ::forward_unchecked) { scope 10 (inlined #[track_caller] core::num::::unchecked_add) { @@ -48,13 +47,12 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb0: { _3 = PtrMetadata(copy _1); - StorageLive(_4); _4 = const 0_usize; goto -> bb1; } bb1: { - StorageLive(_9); + StorageLive(_8); StorageLive(_6); StorageLive(_5); _5 = copy _4; @@ -65,8 +63,7 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb2: { StorageDead(_6); - StorageDead(_9); - StorageDead(_4); + StorageDead(_8); drop(_2) -> [return: bb3, unwind continue]; } @@ -76,30 +73,27 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { bb4: { _7 = copy _4; - StorageLive(_8); - _8 = AddUnchecked(copy _7, const 1_usize); - _4 = move _8; - StorageDead(_8); - _9 = Option::::Some(copy _7); + _4 = AddUnchecked(copy _7, const 1_usize); + _8 = Option::::Some(copy _7); StorageDead(_6); - _10 = copy ((_9 as Some).0: usize); - _11 = Lt(copy _10, copy _3); - assert(move _11, "index out of bounds: the length is {} but the index is {}", copy _3, copy _10) -> [success: bb5, unwind: bb7]; + _9 = copy ((_8 as Some).0: usize); + _10 = Lt(copy _9, copy _3); + assert(move _10, "index out of bounds: the length is {} but the index is {}", copy _3, copy _9) -> [success: bb5, unwind: bb7]; } bb5: { - _12 = &(*_1)[_10]; + _11 = &(*_1)[_9]; + StorageLive(_12); + _12 = &_2; StorageLive(_13); - _13 = &_2; - StorageLive(_14); - _14 = (copy _10, copy _12); - _15 = >::call(move _13, move _14) -> [return: bb6, unwind: bb7]; + _13 = (copy _9, copy _11); + _14 = >::call(move _12, move _13) -> [return: bb6, unwind: bb7]; } bb6: { - StorageDead(_14); StorageDead(_13); - StorageDead(_9); + StorageDead(_12); + StorageDead(_8); goto -> bb1; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index ee638be7d7ac2..3009be3f9dc67 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,22 +4,90 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _33: std::option::Option<&T>; + let mut _35: &impl Fn(&T); + let mut _36: (&T,); + let _37: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _34: &T; scope 2 { - debug x => _17; + debug x => _34; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 19 (inlined as DoubleEndedIterator>::next_back) { + let mut _13: *const T; + let mut _18: bool; + let mut _19: *const T; + let _32: &T; + scope 20 { + let _14: std::ptr::NonNull; + let _20: usize; + scope 21 { + } + scope 22 { + scope 25 (inlined as PartialEq>::eq) { + let mut _15: std::ptr::NonNull; + let mut _16: *mut T; + let mut _17: *mut T; + scope 26 (inlined NonNull::::as_ptr) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + } + } + scope 23 (inlined std::ptr::const_ptr::::addr) { + scope 24 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _26: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _21: *mut *const T; + let mut _22: *mut std::ptr::NonNull; + let mut _23: std::ptr::NonNull; + let mut _27: *mut *const T; + let mut _28: *mut usize; + let mut _29: usize; + let mut _30: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _24: *const T; + let mut _25: *const T; + scope 40 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 41 (inlined NonNull::::as_ref::<'_>) { + let _31: *const T; + scope 42 (inlined NonNull::::as_ptr) { + } + scope 43 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +95,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,9 +129,10 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); + StorageLive(_9); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -72,7 +140,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,61 +160,149 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); + StorageDead(_9); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); + StorageLive(_33); + StorageLive(_20); + StorageLive(_19); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_32); + StorageLive(_18); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_13); + _13 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _14 = copy _13 as std::ptr::NonNull (Transmute); + StorageDead(_13); + StorageLive(_16); + StorageLive(_15); + _15 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _16 = copy _15 as *mut T (Transmute); + StorageDead(_15); + StorageLive(_17); + _17 = copy _14 as *mut T (Transmute); + _18 = Eq(copy _16, copy _17); + StorageDead(_17); + StorageDead(_16); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind unreachable]; + _19 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _20 = copy _19 as usize (Transmute); + _18 = Eq(copy _20, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _18) -> [0: bb8, otherwise: bb15]; } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + StorageLive(_26); + StorageLive(_28); + StorageLive(_22); + StorageLive(_23); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_19); + StorageLive(_21); + _21 = &raw mut ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _22 = copy _21 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_21); + _23 = copy (*_22); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; + } + + bb10: { + StorageLive(_25); + StorageLive(_24); + _24 = copy _23 as *const T (Transmute); + _25 = Offset(copy _24, const -1_isize); + StorageDead(_24); + _23 = NonNull:: { pointer: copy _25 }; + StorageDead(_25); + goto -> bb11; + } + + bb11: { + (*_22) = move _23; + _26 = copy (*_22); + goto -> bb13; + } + + bb12: { + StorageLive(_27); + _27 = &raw mut ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _28 = copy _27 as *mut usize (PtrToPtr); + StorageDead(_27); + StorageLive(_30); + StorageLive(_29); + _29 = copy (*_28); + _30 = SubUnchecked(move _29, const 1_usize); + StorageDead(_29); + (*_28) = move _30; + StorageDead(_30); + _26 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb13; + } + + bb13: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_28); + StorageLive(_31); + _31 = copy _26 as *const T (Transmute); + _32 = &(*_31); + StorageDead(_31); + StorageDead(_26); + _33 = Option::<&T>::Some(copy _32); StorageDead(_18); - StorageDead(_15); + StorageDead(_32); + StorageDead(_14); + StorageDead(_19); + StorageDead(_20); + _34 = copy ((_33 as Some).0: &T); + StorageLive(_35); + _35 = &_2; + StorageLive(_36); + _36 = (copy _34,); + _37 = >::call(move _35, move _36) -> [return: bb14, unwind unreachable]; + } + + bb14: { + StorageDead(_36); + StorageDead(_35); + StorageDead(_33); goto -> bb4; } - bb10: { - unreachable; + bb15: { + StorageDead(_18); + StorageDead(_32); + StorageDead(_14); + StorageDead(_19); + StorageDead(_20); + StorageDead(_33); + StorageDead(_12); + drop(_2) -> [return: bb16, unwind unreachable]; + } + + bb16: { + return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index aee29d4d4fef9..e40bff5ea3504 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,22 +4,90 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _11: std::slice::Iter<'_, T>; + let mut _10: std::slice::Iter<'_, T>; + let mut _11: std::iter::Rev>; let mut _12: std::iter::Rev>; - let mut _13: std::iter::Rev>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _33: std::option::Option<&T>; + let mut _35: &impl Fn(&T); + let mut _36: (&T,); + let _37: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _34: &T; scope 2 { - debug x => _17; + debug x => _34; } scope 18 (inlined > as Iterator>::next) { - let mut _14: &mut std::slice::Iter<'_, T>; + scope 19 (inlined as DoubleEndedIterator>::next_back) { + let mut _13: *const T; + let mut _18: bool; + let mut _19: *const T; + let _32: &T; + scope 20 { + let _14: std::ptr::NonNull; + let _20: usize; + scope 21 { + } + scope 22 { + scope 25 (inlined as PartialEq>::eq) { + let mut _15: std::ptr::NonNull; + let mut _16: *mut T; + let mut _17: *mut T; + scope 26 (inlined NonNull::::as_ptr) { + } + scope 27 (inlined NonNull::::as_ptr) { + } + } + } + scope 23 (inlined std::ptr::const_ptr::::addr) { + scope 24 (inlined std::ptr::const_ptr::::cast::<()>) { + } + } + } + scope 28 (inlined std::slice::Iter::<'_, T>::next_back_unchecked) { + let _26: std::ptr::NonNull; + scope 29 (inlined std::slice::Iter::<'_, T>::pre_dec_end) { + let mut _21: *mut *const T; + let mut _22: *mut std::ptr::NonNull; + let mut _23: std::ptr::NonNull; + let mut _27: *mut *const T; + let mut _28: *mut usize; + let mut _29: usize; + let mut _30: usize; + scope 30 { + scope 31 { + } + scope 32 { + scope 35 (inlined NonNull::::sub) { + scope 36 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 37 (inlined core::ub_checks::check_language_ub) { + scope 38 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 39 (inlined NonNull::::offset) { + let mut _24: *const T; + let mut _25: *const T; + scope 40 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 33 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 34 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 41 (inlined NonNull::::as_ref::<'_>) { + let _31: *const T; + scope 42 (inlined NonNull::::as_ptr) { + } + scope 43 (inlined std::ptr::mut_ptr::::cast_const) { + } + } + } + } } } scope 3 (inlined core::slice::::iter) { @@ -27,7 +95,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { let _3: usize; let mut _7: *mut T; let mut _8: *mut T; - let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { @@ -62,9 +129,10 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_11); + StorageLive(_10); StorageLive(_3); StorageLive(_6); + StorageLive(_9); StorageLive(_4); _3 = PtrMetadata(copy _1); _4 = &raw const (*_1); @@ -72,7 +140,6 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _5 = copy _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: copy _5 }; StorageDead(_5); - StorageLive(_9); switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } @@ -93,69 +160,157 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb3: { - StorageLive(_10); - _10 = copy _9; - _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _10, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_10); - StorageDead(_9); + _10 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: copy _9, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_4); + StorageDead(_9); StorageDead(_6); StorageDead(_3); - _12 = Rev::> { iter: copy _11 }; - StorageDead(_11); - StorageLive(_13); - _13 = copy _12; + _11 = Rev::> { iter: copy _10 }; + StorageDead(_10); + StorageLive(_12); + _12 = copy _11; goto -> bb4; } bb4: { - StorageLive(_15); + StorageLive(_33); + StorageLive(_20); + StorageLive(_19); StorageLive(_14); - _14 = &mut (_13.0: std::slice::Iter<'_, T>); - _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_32); + StorageLive(_18); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb6]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageLive(_13); + _13 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _14 = copy _13 as std::ptr::NonNull (Transmute); + StorageDead(_13); + StorageLive(_16); + StorageLive(_15); + _15 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + _16 = copy _15 as *mut T (Transmute); + StorageDead(_15); + StorageLive(_17); + _17 = copy _14 as *mut T (Transmute); + _18 = Eq(copy _16, copy _17); + StorageDead(_17); + StorageDead(_16); + goto -> bb7; } bb6: { - StorageDead(_15); - StorageDead(_13); - drop(_2) -> [return: bb7, unwind continue]; + _19 = copy ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _20 = copy _19 as usize (Transmute); + _18 = Eq(copy _20, const 0_usize); + goto -> bb7; } bb7: { - return; + switchInt(move _18) -> [0: bb8, otherwise: bb17]; } bb8: { - _17 = copy ((_15 as Some).0: &T); - StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (copy _17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + StorageLive(_26); + StorageLive(_28); + StorageLive(_22); + StorageLive(_23); + switchInt(const ::IS_ZST) -> [0: bb9, otherwise: bb12]; } bb9: { - StorageDead(_19); - StorageDead(_18); - StorageDead(_15); - goto -> bb4; + StorageLive(_21); + _21 = &raw mut ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _22 = copy _21 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_21); + _23 = copy (*_22); + switchInt(const ::IS_ZST) -> [0: bb10, otherwise: bb11]; } bb10: { - unreachable; + StorageLive(_25); + StorageLive(_24); + _24 = copy _23 as *const T (Transmute); + _25 = Offset(copy _24, const -1_isize); + StorageDead(_24); + _23 = NonNull:: { pointer: copy _25 }; + StorageDead(_25); + goto -> bb11; + } + + bb11: { + (*_22) = move _23; + _26 = copy (*_22); + goto -> bb13; } - bb11 (cleanup): { - drop(_2) -> [return: bb12, unwind terminate(cleanup)]; + bb12: { + StorageLive(_27); + _27 = &raw mut ((_12.0: std::slice::Iter<'_, T>).1: *const T); + _28 = copy _27 as *mut usize (PtrToPtr); + StorageDead(_27); + StorageLive(_30); + StorageLive(_29); + _29 = copy (*_28); + _30 = SubUnchecked(move _29, const 1_usize); + StorageDead(_29); + (*_28) = move _30; + StorageDead(_30); + _26 = copy ((_12.0: std::slice::Iter<'_, T>).0: std::ptr::NonNull); + goto -> bb13; } - bb12 (cleanup): { + bb13: { + StorageDead(_23); + StorageDead(_22); + StorageDead(_28); + StorageLive(_31); + _31 = copy _26 as *const T (Transmute); + _32 = &(*_31); + StorageDead(_31); + StorageDead(_26); + _33 = Option::<&T>::Some(copy _32); + StorageDead(_18); + StorageDead(_32); + StorageDead(_14); + StorageDead(_19); + StorageDead(_20); + _34 = copy ((_33 as Some).0: &T); + StorageLive(_35); + _35 = &_2; + StorageLive(_36); + _36 = (copy _34,); + _37 = >::call(move _35, move _36) -> [return: bb14, unwind: bb15]; + } + + bb14: { + StorageDead(_36); + StorageDead(_35); + StorageDead(_33); + goto -> bb4; + } + + bb15 (cleanup): { + drop(_2) -> [return: bb16, unwind terminate(cleanup)]; + } + + bb16 (cleanup): { resume; } + + bb17: { + StorageDead(_18); + StorageDead(_32); + StorageDead(_14); + StorageDead(_19); + StorageDead(_20); + StorageDead(_33); + StorageDead(_12); + drop(_2) -> [return: bb18, unwind continue]; + } + + bb18: { + return; + } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir index 78f96bf419559..62b738c36bf4b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-abort.mir @@ -3,12 +3,187 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *mut T; + let mut _7: bool; + let mut _8: *mut T; + let mut _21: &mut T; + scope 2 { + let _3: std::ptr::NonNull; + let _9: usize; + scope 3 { + } + scope 4 { + scope 7 (inlined as PartialEq>::eq) { + let mut _4: std::ptr::NonNull; + let mut _5: *mut T; + let mut _6: *mut T; + scope 8 (inlined NonNull::::as_ptr) { + } + scope 9 (inlined NonNull::::as_ptr) { + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + } + scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _15: std::ptr::NonNull; + scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _10: *mut *mut T; + let mut _11: *mut std::ptr::NonNull; + let mut _12: std::ptr::NonNull; + let mut _16: *mut *mut T; + let mut _17: *mut usize; + let mut _18: usize; + let mut _19: usize; + scope 12 { + scope 13 { + } + scope 14 { + scope 17 (inlined NonNull::::sub) { + scope 18 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 19 (inlined core::ub_checks::check_language_ub) { + scope 20 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 21 (inlined NonNull::::offset) { + let mut _13: *const T; + let mut _14: *const T; + scope 22 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 15 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 16 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _20: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind unreachable]; + StorageLive(_9); + StorageLive(_8); + StorageLive(_3); + StorageLive(_2); + StorageLive(_21); + StorageLive(_7); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + _2 = copy ((*_1).1: *mut T); + _3 = copy _2 as std::ptr::NonNull (Transmute); + StorageLive(_5); + StorageLive(_4); + _4 = copy ((*_1).0: std::ptr::NonNull); + _5 = copy _4 as *mut T (Transmute); + StorageDead(_4); + StorageLive(_6); + _6 = copy _3 as *mut T (Transmute); + _7 = Eq(copy _5, copy _6); + StorageDead(_6); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _8 = copy ((*_1).1: *mut T); + _9 = copy _8 as usize (Transmute); + _7 = Eq(copy _9, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _7) -> [0: bb4, otherwise: bb10]; + } + + bb4: { + StorageLive(_15); + StorageLive(_17); + StorageLive(_11); + StorageLive(_12); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; + } + + bb5: { + StorageLive(_10); + _10 = &raw mut ((*_1).1: *mut T); + _11 = copy _10 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_10); + _12 = copy (*_11); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_14); + StorageLive(_13); + _13 = copy _12 as *const T (Transmute); + _14 = Offset(copy _13, const -1_isize); + StorageDead(_13); + _12 = NonNull:: { pointer: copy _14 }; + StorageDead(_14); + goto -> bb7; + } + + bb7: { + (*_11) = move _12; + _15 = copy (*_11); + goto -> bb9; + } + + bb8: { + StorageLive(_16); + _16 = &raw mut ((*_1).1: *mut T); + _17 = copy _16 as *mut usize (PtrToPtr); + StorageDead(_16); + StorageLive(_19); + StorageLive(_18); + _18 = copy (*_17); + _19 = SubUnchecked(move _18, const 1_usize); + StorageDead(_18); + (*_17) = move _19; + StorageDead(_19); + _15 = copy ((*_1).0: std::ptr::NonNull); + goto -> bb9; + } + + bb9: { + StorageDead(_12); + StorageDead(_11); + StorageDead(_17); + StorageLive(_20); + _20 = copy _15 as *mut T (Transmute); + _21 = &mut (*_20); + StorageDead(_20); + StorageDead(_15); + _0 = Option::<&mut T>::Some(copy _21); + goto -> bb11; + } + + bb10: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb11; + } + + bb11: { + StorageDead(_7); + StorageDead(_21); + StorageDead(_2); + StorageDead(_3); + StorageDead(_8); + StorageDead(_9); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir index dfe5e206fadaf..62b738c36bf4b 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.panic-unwind.mir @@ -3,12 +3,187 @@ fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { debug it => _1; let mut _0: std::option::Option<&mut T>; + scope 1 (inlined as DoubleEndedIterator>::next_back) { + let mut _2: *mut T; + let mut _7: bool; + let mut _8: *mut T; + let mut _21: &mut T; + scope 2 { + let _3: std::ptr::NonNull; + let _9: usize; + scope 3 { + } + scope 4 { + scope 7 (inlined as PartialEq>::eq) { + let mut _4: std::ptr::NonNull; + let mut _5: *mut T; + let mut _6: *mut T; + scope 8 (inlined NonNull::::as_ptr) { + } + scope 9 (inlined NonNull::::as_ptr) { + } + } + } + scope 5 (inlined std::ptr::mut_ptr::::addr) { + scope 6 (inlined std::ptr::mut_ptr::::cast::<()>) { + } + } + } + scope 10 (inlined std::slice::IterMut::<'_, T>::next_back_unchecked) { + let mut _15: std::ptr::NonNull; + scope 11 (inlined std::slice::IterMut::<'_, T>::pre_dec_end) { + let mut _10: *mut *mut T; + let mut _11: *mut std::ptr::NonNull; + let mut _12: std::ptr::NonNull; + let mut _16: *mut *mut T; + let mut _17: *mut usize; + let mut _18: usize; + let mut _19: usize; + scope 12 { + scope 13 { + } + scope 14 { + scope 17 (inlined NonNull::::sub) { + scope 18 (inlined #[track_caller] core::num::::unchecked_neg) { + scope 19 (inlined core::ub_checks::check_language_ub) { + scope 20 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + scope 21 (inlined NonNull::::offset) { + let mut _13: *const T; + let mut _14: *const T; + scope 22 (inlined NonNull::::as_ptr) { + } + } + } + } + scope 15 (inlined std::ptr::mut_ptr::::cast::) { + } + scope 16 (inlined std::ptr::mut_ptr::::cast::>) { + } + } + } + scope 23 (inlined NonNull::::as_mut::<'_>) { + let mut _20: *mut T; + scope 24 (inlined NonNull::::as_ptr) { + } + } + } + } bb0: { - _0 = as DoubleEndedIterator>::next_back(move _1) -> [return: bb1, unwind continue]; + StorageLive(_9); + StorageLive(_8); + StorageLive(_3); + StorageLive(_2); + StorageLive(_21); + StorageLive(_7); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { + _2 = copy ((*_1).1: *mut T); + _3 = copy _2 as std::ptr::NonNull (Transmute); + StorageLive(_5); + StorageLive(_4); + _4 = copy ((*_1).0: std::ptr::NonNull); + _5 = copy _4 as *mut T (Transmute); + StorageDead(_4); + StorageLive(_6); + _6 = copy _3 as *mut T (Transmute); + _7 = Eq(copy _5, copy _6); + StorageDead(_6); + StorageDead(_5); + goto -> bb3; + } + + bb2: { + _8 = copy ((*_1).1: *mut T); + _9 = copy _8 as usize (Transmute); + _7 = Eq(copy _9, const 0_usize); + goto -> bb3; + } + + bb3: { + switchInt(move _7) -> [0: bb4, otherwise: bb10]; + } + + bb4: { + StorageLive(_15); + StorageLive(_17); + StorageLive(_11); + StorageLive(_12); + switchInt(const ::IS_ZST) -> [0: bb5, otherwise: bb8]; + } + + bb5: { + StorageLive(_10); + _10 = &raw mut ((*_1).1: *mut T); + _11 = copy _10 as *mut std::ptr::NonNull (PtrToPtr); + StorageDead(_10); + _12 = copy (*_11); + switchInt(const ::IS_ZST) -> [0: bb6, otherwise: bb7]; + } + + bb6: { + StorageLive(_14); + StorageLive(_13); + _13 = copy _12 as *const T (Transmute); + _14 = Offset(copy _13, const -1_isize); + StorageDead(_13); + _12 = NonNull:: { pointer: copy _14 }; + StorageDead(_14); + goto -> bb7; + } + + bb7: { + (*_11) = move _12; + _15 = copy (*_11); + goto -> bb9; + } + + bb8: { + StorageLive(_16); + _16 = &raw mut ((*_1).1: *mut T); + _17 = copy _16 as *mut usize (PtrToPtr); + StorageDead(_16); + StorageLive(_19); + StorageLive(_18); + _18 = copy (*_17); + _19 = SubUnchecked(move _18, const 1_usize); + StorageDead(_18); + (*_17) = move _19; + StorageDead(_19); + _15 = copy ((*_1).0: std::ptr::NonNull); + goto -> bb9; + } + + bb9: { + StorageDead(_12); + StorageDead(_11); + StorageDead(_17); + StorageLive(_20); + _20 = copy _15 as *mut T (Transmute); + _21 = &mut (*_20); + StorageDead(_20); + StorageDead(_15); + _0 = Option::<&mut T>::Some(copy _21); + goto -> bb11; + } + + bb10: { + _0 = const {transmute(0x0000000000000000): Option<&mut T>}; + goto -> bb11; + } + + bb11: { + StorageDead(_7); + StorageDead(_21); + StorageDead(_2); + StorageDead(_3); + StorageDead(_8); + StorageDead(_9); return; } } diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir index fe4e2deab8706..79aa9c5ae1e36 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-abort.mir @@ -9,7 +9,7 @@ fn outer(_1: u8) -> u8 { } bb0: { - _2 = &_1; // scope 0 at $DIR/spans.rs:11:11: 11:13 + // DBG: _2 = &_1; _0 = copy _1; // scope 1 at $DIR/spans.rs:15:5: 15:7 return; // scope 0 at $DIR/spans.rs:12:2: 12:2 } diff --git a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir index fe4e2deab8706..79aa9c5ae1e36 100644 --- a/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/spans.outer.PreCodegen.after.panic-unwind.mir @@ -9,7 +9,7 @@ fn outer(_1: u8) -> u8 { } bb0: { - _2 = &_1; // scope 0 at $DIR/spans.rs:11:11: 11:13 + // DBG: _2 = &_1; _0 = copy _1; // scope 1 at $DIR/spans.rs:15:5: 15:7 return; // scope 0 at $DIR/spans.rs:12:2: 12:2 } diff --git a/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir index c4d0e318b58dc..29bfe962974cf 100644 --- a/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir @@ -7,7 +7,6 @@ fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool { scope 1 (inlined std::cmp::impls::::ge) { scope 2 (inlined core::tuple::::ge) { let mut _7: std::ops::ControlFlow; - let _8: bool; scope 3 { } scope 4 (inlined std::cmp::impls::::__chaining_ge) { @@ -19,8 +18,8 @@ fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool { } } scope 6 (inlined std::cmp::impls::::ge) { + let mut _8: f32; let mut _9: f32; - let mut _10: f32; } } } @@ -44,10 +43,7 @@ fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool { StorageDead(_5); StorageDead(_4); StorageDead(_3); - StorageLive(_8); - _8 = copy ((_7 as Break).0: bool); - _0 = copy _8; - StorageDead(_8); + _0 = copy ((_7 as Break).0: bool); goto -> bb3; } @@ -55,13 +51,13 @@ fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool { StorageDead(_5); StorageDead(_4); StorageDead(_3); + StorageLive(_8); + _8 = copy ((*_1).1: f32); StorageLive(_9); - _9 = copy ((*_1).1: f32); - StorageLive(_10); - _10 = copy ((*_2).1: f32); - _0 = Ge(move _9, move _10); - StorageDead(_10); + _9 = copy ((*_2).1: f32); + _0 = Ge(move _8, move _9); StorageDead(_9); + StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir index 44df8b279935b..7678c92a1f0c6 100644 --- a/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir @@ -7,7 +7,6 @@ fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool { scope 1 (inlined std::cmp::impls::::le) { scope 2 (inlined core::tuple::::le) { let mut _7: std::ops::ControlFlow; - let _8: bool; scope 3 { } scope 4 (inlined std::cmp::impls::::__chaining_le) { @@ -19,8 +18,8 @@ fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool { } } scope 6 (inlined std::cmp::impls::::le) { + let mut _8: i16; let mut _9: i16; - let mut _10: i16; } } } @@ -44,10 +43,7 @@ fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool { StorageDead(_5); StorageDead(_4); StorageDead(_3); - StorageLive(_8); - _8 = copy ((_7 as Break).0: bool); - _0 = copy _8; - StorageDead(_8); + _0 = copy ((_7 as Break).0: bool); goto -> bb3; } @@ -55,13 +51,13 @@ fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool { StorageDead(_5); StorageDead(_4); StorageDead(_3); + StorageLive(_8); + _8 = copy ((*_1).1: i16); StorageLive(_9); - _9 = copy ((*_1).1: i16); - StorageLive(_10); - _10 = copy ((*_2).1: i16); - _0 = Le(move _9, move _10); - StorageDead(_10); + _9 = copy ((*_2).1: i16); + _0 = Le(move _8, move _9); StorageDead(_9); + StorageDead(_8); goto -> bb3; } diff --git a/tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs new file mode 100644 index 0000000000000..7b742b956ae5c --- /dev/null +++ b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.rs @@ -0,0 +1,15 @@ +//@ compile-flags: -O + +#![crate_type = "lib"] + +// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff +// EMIT_MIR two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir +pub fn two_unwrap_unchecked(v: &Option) -> i32 { + // CHECK-LABEL: fn two_unwrap_unchecked( + // CHECK: [[DEREF_V:_.*]] = copy (*_1); + // CHECK: [[V1V2:_.*]] = copy (([[DEREF_V]] as Some).0: i32); + // CHECK: _0 = Add(copy [[V1V2]], copy [[V1V2]]); + let v1 = unsafe { v.unwrap_unchecked() }; + let v2 = unsafe { v.unwrap_unchecked() }; + v1 + v2 +} diff --git a/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff new file mode 100644 index 0000000000000..5b063e6762e07 --- /dev/null +++ b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.GVN.diff @@ -0,0 +1,105 @@ +- // MIR for `two_unwrap_unchecked` before GVN ++ // MIR for `two_unwrap_unchecked` after GVN + + fn two_unwrap_unchecked(_1: &Option) -> i32 { + debug v => _1; + let mut _0: i32; + let _2: i32; + let mut _3: std::option::Option; + let mut _5: std::option::Option; + let mut _6: i32; + let mut _7: i32; + scope 1 { + debug v1 => _2; + let _4: i32; + scope 2 { + debug v2 => _4; + } + scope 8 (inlined #[track_caller] Option::::unwrap_unchecked) { + let mut _9: isize; + scope 9 { + } + scope 10 (inlined #[track_caller] unreachable_unchecked) { + scope 11 (inlined core::ub_checks::check_language_ub) { + scope 12 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + } + scope 3 (inlined #[track_caller] Option::::unwrap_unchecked) { + let mut _8: isize; + scope 4 { + } + scope 5 (inlined #[track_caller] unreachable_unchecked) { + scope 6 (inlined core::ub_checks::check_language_ub) { + scope 7 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + + bb0: { +- StorageLive(_2); +- StorageLive(_3); ++ nop; ++ nop; + _3 = copy (*_1); +- StorageLive(_8); ++ nop; + _8 = discriminant(_3); +- switchInt(move _8) -> [0: bb2, 1: bb3, otherwise: bb1]; ++ switchInt(copy _8) -> [0: bb2, 1: bb3, otherwise: bb1]; + } + + bb1: { + unreachable; + } + + bb2: { + unreachable; + } + + bb3: { +- _2 = move ((_3 as Some).0: i32); +- StorageDead(_8); +- StorageDead(_3); ++ _2 = copy ((_3 as Some).0: i32); ++ nop; ++ nop; + StorageLive(_4); + StorageLive(_5); +- _5 = copy (*_1); ++ _5 = copy _3; + StorageLive(_9); +- _9 = discriminant(_5); +- switchInt(move _9) -> [0: bb4, 1: bb5, otherwise: bb1]; ++ _9 = copy _8; ++ switchInt(copy _8) -> [0: bb4, 1: bb5, otherwise: bb1]; + } + + bb4: { + unreachable; + } + + bb5: { +- _4 = move ((_5 as Some).0: i32); ++ _4 = copy _2; + StorageDead(_9); + StorageDead(_5); + StorageLive(_6); + _6 = copy _2; + StorageLive(_7); +- _7 = copy _4; +- _0 = Add(move _6, move _7); ++ _7 = copy _2; ++ _0 = Add(copy _2, copy _2); + StorageDead(_7); + StorageDead(_6); + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir new file mode 100644 index 0000000000000..b2b7f88d8534b --- /dev/null +++ b/tests/mir-opt/pre-codegen/two_unwrap_unchecked.two_unwrap_unchecked.PreCodegen.after.mir @@ -0,0 +1,51 @@ +// MIR for `two_unwrap_unchecked` after PreCodegen + +fn two_unwrap_unchecked(_1: &Option) -> i32 { + debug v => _1; + let mut _0: i32; + let mut _2: std::option::Option; + let _4: i32; + scope 1 { + debug v1 => _4; + scope 2 { + debug v2 => _4; + } + scope 8 (inlined #[track_caller] Option::::unwrap_unchecked) { + scope 9 { + } + scope 10 (inlined #[track_caller] unreachable_unchecked) { + scope 11 (inlined core::ub_checks::check_language_ub) { + scope 12 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + } + scope 3 (inlined #[track_caller] Option::::unwrap_unchecked) { + let mut _3: isize; + scope 4 { + } + scope 5 (inlined #[track_caller] unreachable_unchecked) { + scope 6 (inlined core::ub_checks::check_language_ub) { + scope 7 (inlined core::ub_checks::check_language_ub::runtime) { + } + } + } + } + + bb0: { + _2 = copy (*_1); + _3 = discriminant(_2); + switchInt(copy _3) -> [0: bb2, 1: bb1, otherwise: bb2]; + } + + bb1: { + _4 = copy ((_2 as Some).0: i32); + _0 = Add(copy _4, copy _4); + return; + } + + bb2: { + unreachable; + } +} diff --git a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff index 3da795b61f948..375b6096d88d8 100644 --- a/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff +++ b/tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff @@ -17,14 +17,15 @@ let mut _15: std::ops::RangeFull; let mut _16: usize; let mut _17: usize; - let mut _18: bool; - let _23: &&mut u8; - let _24: &mut u8; - let mut _25: debuginfo::T; + let mut _18: usize; + let mut _19: bool; + let _24: &&mut u8; + let _25: &mut u8; + let mut _26: debuginfo::T; scope 1 { debug ref_mut_u8 => _1; let _3: &u8; - let mut _28: &debuginfo::T; + let mut _29: &debuginfo::T; scope 2 { debug field => _3; let _5: &u8; @@ -32,22 +33,22 @@ - debug reborrow => _5; + debug reborrow => _1; let _9: &i32; - let _22: &&&mut u8; - let mut _27: &std::option::Option; + let _23: &&&mut u8; + let mut _28: &std::option::Option; scope 4 { debug variant_field => _9; } scope 5 { - debug constant_index => _19; - debug subslice => _20; - debug constant_index_from_end => _21; - let _19: &i32; - let _20: &[i32]; - let _21: &i32; - let mut _26: &[i32; 10]; + debug constant_index => _20; + debug subslice => _21; + debug constant_index_from_end => _22; + let _20: &i32; + let _21: &[i32]; + let _22: &i32; + let mut _27: &[i32; 10]; } scope 6 { - debug multiple_borrow => _22; + debug multiple_borrow => _23; } } } @@ -59,8 +60,8 @@ _2 = const 5_u8; _1 = &mut _2; StorageLive(_3); - _28 = const debuginfo::promoted[2]; - _3 = &((*_28).0: u8); + _29 = const debuginfo::promoted[2]; + _3 = &((*_29).0: u8); - StorageLive(_5); - _5 = &(*_1); - StorageLive(_6); @@ -76,8 +77,8 @@ bb2: { StorageLive(_9); - _27 = const debuginfo::promoted[1]; - _9 = &(((*_27) as Some).0: i32); + _28 = const debuginfo::promoted[1]; + _9 = &(((*_28) as Some).0: i32); - _6 = const (); StorageDead(_9); goto -> bb4; @@ -92,11 +93,11 @@ StorageDead(_7); - StorageDead(_6); - StorageLive(_10); -- StorageLive(_11); + StorageLive(_11); - StorageLive(_12); StorageLive(_13); - _26 = const debuginfo::promoted[0]; - _13 = &(*_26); + _27 = const debuginfo::promoted[0]; + _13 = &(*_27); StorageLive(_15); _15 = RangeFull; - _12 = <[i32; 10] as Index>::index(move _13, move _15) -> [return: bb5, unwind continue]; @@ -106,28 +107,28 @@ bb5: { StorageDead(_15); StorageDead(_13); -- _11 = &(*_12); -- _16 = Len((*_11)); -+ _16 = Len((*_12)); - _17 = const 3_usize; - _18 = Ge(move _16, move _17); - switchInt(move _18) -> [0: bb7, otherwise: bb6]; + _11 = &(*_12); + _17 = PtrMetadata(copy _11); + _16 = move _17; + _18 = const 3_usize; + _19 = Ge(move _16, move _18); + switchInt(move _19) -> [0: bb7, otherwise: bb6]; } bb6: { - StorageLive(_19); -- _19 = &(*_11)[1 of 3]; -+ _19 = &(*_12)[1 of 3]; StorageLive(_20); -- _20 = &(*_11)[2:-1]; -+ _20 = &(*_12)[2:-1]; +- _20 = &(*_11)[1 of 3]; ++ _20 = &(*_12)[1 of 3]; StorageLive(_21); -- _21 = &(*_11)[-1 of 3]; +- _21 = &(*_11)[2:-1]; ++ _21 = &(*_12)[2:-1]; + StorageLive(_22); +- _22 = &(*_11)[-1 of 3]; - _10 = const (); -+ _21 = &(*_12)[-1 of 3]; ++ _22 = &(*_12)[-1 of 3]; + StorageDead(_22); StorageDead(_21); StorageDead(_20); - StorageDead(_19); goto -> bb8; } @@ -138,21 +139,21 @@ bb8: { - StorageDead(_12); -- StorageDead(_11); + StorageDead(_11); - StorageDead(_10); - StorageLive(_22); StorageLive(_23); StorageLive(_24); StorageLive(_25); - _25 = T(const 6_u8); - _24 = &mut (_25.0: u8); + StorageLive(_26); + _26 = T(const 6_u8); + _25 = &mut (_26.0: u8); + _24 = &_25; _23 = &_24; - _22 = &_23; _0 = const (); + StorageDead(_26); StorageDead(_25); StorageDead(_24); StorageDead(_23); - StorageDead(_22); - StorageDead(_5); StorageDead(_3); StorageDead(_2); diff --git a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir index da005d552e2bf..4861abead2f32 100644 --- a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir +++ b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-abort.mir @@ -8,7 +8,7 @@ fn box_to_raw_mut(_1: &mut Box) -> *mut i32 { bb0: { Retag([fn entry] _1); - _2 = deref_copy (*_1); + _2 = copy (*_1); _3 = copy ((_2.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); _0 = &raw mut (*_3); Retag([raw] _0); diff --git a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir index da005d552e2bf..4861abead2f32 100644 --- a/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir +++ b/tests/mir-opt/retag.box_to_raw_mut.SimplifyCfg-pre-optimizations.after.panic-unwind.mir @@ -8,7 +8,7 @@ fn box_to_raw_mut(_1: &mut Box) -> *mut i32 { bb0: { Retag([fn entry] _1); - _2 = deref_copy (*_1); + _2 = copy (*_1); _3 = copy ((_2.0: std::ptr::Unique).0: std::ptr::NonNull) as *const i32 (Transmute); _0 = &raw mut (*_3); Retag([raw] _0); diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff deleted file mode 100644 index c3076fb67c231..0000000000000 --- a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-abort.diff +++ /dev/null @@ -1,21 +0,0 @@ -- // MIR for `main` before SimplifyConstCondition-after-const-prop -+ // MIR for `main` after SimplifyConstCondition-after-const-prop - - fn main() -> () { - let mut _0: (); - let _1: (); - - bb0: { -- switchInt(const false) -> [0: bb2, otherwise: bb1]; -+ goto -> bb2; - } - - bb1: { - _1 = noop() -> [return: bb2, unwind unreachable]; - } - - bb2: { - return; - } - } - diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff deleted file mode 100644 index 6c346e20e5893..0000000000000 --- a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-const-prop.panic-unwind.diff +++ /dev/null @@ -1,21 +0,0 @@ -- // MIR for `main` before SimplifyConstCondition-after-const-prop -+ // MIR for `main` after SimplifyConstCondition-after-const-prop - - fn main() -> () { - let mut _0: (); - let _1: (); - - bb0: { -- switchInt(const false) -> [0: bb2, otherwise: bb1]; -+ goto -> bb2; - } - - bb1: { - _1 = noop() -> [return: bb2, unwind continue]; - } - - bb2: { - return; - } - } - diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-abort.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-abort.diff new file mode 100644 index 0000000000000..c67fd69235b47 --- /dev/null +++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-abort.diff @@ -0,0 +1,25 @@ +- // MIR for `main` before SimplifyConstCondition-after-inst-simplify ++ // MIR for `main` after SimplifyConstCondition-after-inst-simplify + + fn main() -> () { + let mut _0: (); + let mut _1: bool; + let _2: (); + + bb0: { + StorageLive(_1); + _1 = const false; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ goto -> bb2; + } + + bb1: { + _2 = noop() -> [return: bb2, unwind unreachable]; + } + + bb2: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-unwind.diff b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-unwind.diff new file mode 100644 index 0000000000000..07f179dfdd454 --- /dev/null +++ b/tests/mir-opt/simplify_if.main.SimplifyConstCondition-after-inst-simplify.panic-unwind.diff @@ -0,0 +1,25 @@ +- // MIR for `main` before SimplifyConstCondition-after-inst-simplify ++ // MIR for `main` after SimplifyConstCondition-after-inst-simplify + + fn main() -> () { + let mut _0: (); + let mut _1: bool; + let _2: (); + + bb0: { + StorageLive(_1); + _1 = const false; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ goto -> bb2; + } + + bb1: { + _2 = noop() -> [return: bb2, unwind continue]; + } + + bb2: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/simplify_if.rs b/tests/mir-opt/simplify_if.rs index f600c05958198..6aca233655544 100644 --- a/tests/mir-opt/simplify_if.rs +++ b/tests/mir-opt/simplify_if.rs @@ -2,7 +2,7 @@ #[inline(never)] fn noop() {} -// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff +// EMIT_MIR simplify_if.main.SimplifyConstCondition-after-inst-simplify.diff fn main() { // CHECK-LABEL: fn main( diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 0d5fcf9ef1432..056dc4c42c11f 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -117,8 +117,8 @@ StorageLive(_15); StorageLive(_16); StorageLive(_17); -- _26 = deref_copy (_12.0: &std::boxed::Box); -+ _26 = deref_copy _34; +- _26 = copy (_12.0: &std::boxed::Box); ++ _26 = copy _34; _17 = &(*_26); _16 = core::fmt::rt::Argument::<'_>::new_display::>(move _17) -> [return: bb3, unwind unreachable]; } @@ -127,8 +127,8 @@ StorageDead(_17); StorageLive(_18); StorageLive(_19); -- _27 = deref_copy (_12.1: &u32); -+ _27 = deref_copy _35; +- _27 = copy (_12.1: &u32); ++ _27 = copy _35; _19 = &(*_27); _18 = core::fmt::rt::Argument::<'_>::new_display::(move _19) -> [return: bb4, unwind unreachable]; } diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml b/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml new file mode 100644 index 0000000000000..3c61c12a84ede --- /dev/null +++ b/tests/run-make-cargo/panic-immediate-abort-codegen/Cargo.toml @@ -0,0 +1,12 @@ +cargo-features = ["profile-rustflags"] + +[package] +name = "panic_scenarios" +version = "0.1.0" +edition = "2024" + +[lib] +path = "lib.rs" + +[profile.release] +rustflags = ["-Zmerge-functions=disabled", "-Zcodegen-source-order", "--emit=llvm-ir"] diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs b/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs new file mode 100644 index 0000000000000..1e20da93ba805 --- /dev/null +++ b/tests/run-make-cargo/panic-immediate-abort-codegen/lib.rs @@ -0,0 +1,65 @@ +#![no_std] + +#[unsafe(no_mangle)] +pub fn panic_noarg() { + // CHECK-LABEL: @panic_noarg( + // CHECK-NEXT: start: + // CHECK-NEXT: tail call void @llvm.trap() + panic!(); +} + +#[unsafe(no_mangle)] +pub fn panic_str() { + // CHECK-LABEL: @panic_str( + // CHECK-NEXT: start: + // CHECK-NEXT: tail call void @llvm.trap() + panic!("ouch"); +} + +#[unsafe(no_mangle)] +pub fn bounds_check(x: &[u8], idx: usize) -> &u8 { + // CHECK-LABEL: @bounds_check( + // CHECK-NEXT: start: + // CHECK-NEXT: icmp ult + // CHECK-NEXT: br i1 + // CHECK: bb1: + // CHECK-NEXT: getelementptr inbounds nuw i8 + // CHECK-NEXT: ret ptr + // CHECK: panic: + // CHECK-NEXT: tail call void @llvm.trap() + &x[idx] +} + +#[unsafe(no_mangle)] +pub fn str_bounds_check(x: &str, idx: usize) -> &str { + // CHECK-LABEL: @str_bounds_check( + // CHECK-NOT: call + // CHECK: tail call void @llvm.trap() + // CHECK-NOT: call + &x[idx..] +} + +#[unsafe(no_mangle)] +pub fn unsigned_integer_div(x: u16, y: u16) -> u16 { + // CHECK-LABEL: @unsigned_integer_div( + // CHECK-NEXT: start: + // CHECK-NEXT: icmp eq i16 + // CHECK-NEXT: br i1 + // CHECK: bb1: + // CHECK-NEXT: udiv i16 + // CHECK-NEXT: ret i16 + // CHECK: panic: + // CHECK-NEXT: tail call void @llvm.trap() + x / y +} + +#[unsafe(no_mangle)] +pub fn refcell_already_borrowed() { + // CHECK-LABEL: @refcell_already_borrowed( + // CHECK-NOT: call + // CHECK: tail call void @llvm.trap() + // CHECK-NOT: call + let r = core::cell::RefCell::new(0u8); + let _guard = r.borrow_mut(); + r.borrow_mut(); +} diff --git a/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs b/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs new file mode 100644 index 0000000000000..d7a7a8bfd8c3b --- /dev/null +++ b/tests/run-make-cargo/panic-immediate-abort-codegen/rmake.rs @@ -0,0 +1,46 @@ +// This is a codegen test which checks that when code is compiled with panic=immediate-abort, +// we get a `tail call void @llvm.trap()` in user code instead of a call into the standard +// library's panic formatting code (such as panic_fmt) or one of the numerous panic outlining shims +// (such as slice_index_fail). + +#![deny(warnings)] + +use run_make_support::{cargo, llvm_filecheck, path, rfs, target}; + +fn main() { + let target_dir = path("target"); + + cargo() + .args(&[ + "build", + "--release", + "--lib", + "--manifest-path", + "Cargo.toml", + "-Zbuild-std=core", + "--target", + &target(), + ]) + .env("RUSTFLAGS", "-Zunstable-options -Cpanic=immediate-abort") + .env("CARGO_TARGET_DIR", &target_dir) + .env("RUSTC_BOOTSTRAP", "1") + // Visual Studio 2022 requires that the LIB env var be set so it can + // find the Windows SDK. + .env("LIB", std::env::var("LIB").unwrap_or_default()) + .run(); + + let out_dir = target_dir.join(target()).join("release").join("deps"); + let ir_file = rfs::read_dir(out_dir) + .find_map(|e| { + let path = e.unwrap().path(); + let file_name = path.file_name().unwrap().to_str().unwrap(); + if file_name.starts_with("panic_scenarios") && file_name.ends_with(".ll") { + Some(path) + } else { + None + } + }) + .unwrap(); + + llvm_filecheck().patterns("lib.rs").input_file(ir_file).run(); +} diff --git a/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml b/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml new file mode 100644 index 0000000000000..1e278d557c082 --- /dev/null +++ b/tests/run-make-cargo/panic-immediate-abort-works/hello/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2024" diff --git a/tests/run-make/pdb-buildinfo-cl-cmd/main.rs b/tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs similarity index 100% rename from tests/run-make/pdb-buildinfo-cl-cmd/main.rs rename to tests/run-make-cargo/panic-immediate-abort-works/hello/src/main.rs diff --git a/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs b/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs new file mode 100644 index 0000000000000..3eeef38c962dc --- /dev/null +++ b/tests/run-make-cargo/panic-immediate-abort-works/rmake.rs @@ -0,0 +1,39 @@ +// This test ensures we are able to compile and link a simple binary with panic=immediate-abort. +// The test panic-immediate-abort-codegen checks that panic strategy produces the desired codegen, +// but is based on compiling a library crate (which is the norm for codegen tests because it is +// cleaner and more portable). So this test ensures that we didn't mix up a cfg or a compiler +// implementation detail in a way that makes panic=immediate-abort encounter errors at link time. + +// Ideally this test would be run for most targets, but unfortunately: +// This test is currently written using `fn main() {}` which requires std. +// And since the default linker is only a linker for the host, we can't handle cross-compilation. +// Both of these shortcomings could be addressed at the cost of making the test more complicated. +//@ needs-target-std +//@ ignore-cross-compile + +#![deny(warnings)] + +use run_make_support::{cargo, path, target}; + +fn main() { + let target_dir = path("target"); + + cargo() + .current_dir("hello") + .args(&[ + "build", + "--release", + "--manifest-path", + "Cargo.toml", + "-Zbuild-std", + "--target", + &target(), + ]) + .env("RUSTFLAGS", "-Zunstable-options -Cpanic=immediate-abort") + .env("CARGO_TARGET_DIR", &target_dir) + .env("RUSTC_BOOTSTRAP", "1") + // Visual Studio 2022 requires that the LIB env var be set so it can + // find the Windows SDK. + .env("LIB", std::env::var("LIB").unwrap_or_default()) + .run(); +} diff --git a/tests/run-make/apple-deployment-target/rmake.rs b/tests/run-make/apple-deployment-target/rmake.rs index 7297a8622240d..5d4512843d534 100644 --- a/tests/run-make/apple-deployment-target/rmake.rs +++ b/tests/run-make/apple-deployment-target/rmake.rs @@ -33,6 +33,7 @@ fn main() { // armv7s-apple-ios and i386-apple-ios only supports iOS 10.0 "ios" if target() == "armv7s-apple-ios" || target() == "i386-apple-ios" => ("10.0", "10.0"), "ios" => ("15.0", "16.0"), + "watchos" if target() == "aarch64-apple-watchos" => ("28.0", "30.0"), "watchos" => ("7.0", "9.0"), "tvos" => ("14.0", "15.0"), "visionos" => ("1.1", "1.2"), diff --git a/tests/run-make/autodiff/type-trees/array-typetree/array.check b/tests/run-make/autodiff/type-trees/array-typetree/array.check new file mode 100644 index 0000000000000..0d38bdec17e84 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/array-typetree/array.check @@ -0,0 +1,4 @@ +; Check that array TypeTree metadata is correctly generated +; Should show Float@double at each array element offset (0, 8, 16, 24, 32 bytes) + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_array{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs new file mode 100644 index 0000000000000..20b6a06690625 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/array-typetree/rmake.rs @@ -0,0 +1,9 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + llvm_filecheck().patterns("array.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/array-typetree/test.rs b/tests/run-make/autodiff/type-trees/array-typetree/test.rs new file mode 100644 index 0000000000000..f54ebf5a4c7b5 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/array-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_array(arr: &[f64; 5]) -> f64 { + arr[0] + arr[1] + arr[2] + arr[3] + arr[4] +} + +fn main() { + let arr = [1.0, 2.0, 3.0, 4.0, 5.0]; + let mut d_arr = [0.0; 5]; + let _result = d_test(&arr, &mut d_arr, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check new file mode 100644 index 0000000000000..0e6351ac4d39d --- /dev/null +++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy-ir.check @@ -0,0 +1,8 @@ +; Check that enzyme_type attributes are present in the LLVM IR function definition +; This verifies our TypeTree system correctly attaches metadata for Enzyme + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_memcpy({{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}" + +; Check that llvm.memcpy exists (either call or declare) +CHECK: {{(call|declare).*}}@llvm.memcpy + diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check new file mode 100644 index 0000000000000..ae70830297a78 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.check @@ -0,0 +1,13 @@ +CHECK: force_memcpy + +CHECK: @llvm.memcpy.p0.p0.i64 + +CHECK: test_memcpy - {[-1]:Float@double} |{[-1]:Pointer}:{} + +CHECK-DAG: ptr %{{[0-9]+}}: {[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double, [-1,24]:Float@double} + +CHECK-DAG: load double{{.*}}: {[-1]:Float@double} + +CHECK-DAG: fmul double{{.*}}: {[-1]:Float@double} + +CHECK-DAG: fadd double{{.*}}: {[-1]:Float@double} \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs new file mode 100644 index 0000000000000..3c1029190c88a --- /dev/null +++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/memcpy.rs @@ -0,0 +1,36 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; +use std::ptr; + +#[inline(never)] +fn force_memcpy(src: *const f64, dst: *mut f64, count: usize) { + unsafe { + ptr::copy_nonoverlapping(src, dst, count); + } +} + +#[autodiff_reverse(d_test_memcpy, Duplicated, Active)] +#[no_mangle] +fn test_memcpy(input: &[f64; 128]) -> f64 { + let mut local_data = [0.0f64; 128]; + + // Use a separate function to prevent inlining and optimization + force_memcpy(input.as_ptr(), local_data.as_mut_ptr(), 128); + + // Sum only first few elements to keep the computation simple + local_data[0] * local_data[0] + + local_data[1] * local_data[1] + + local_data[2] * local_data[2] + + local_data[3] * local_data[3] +} + +fn main() { + let input = [1.0; 128]; + let mut d_input = [0.0; 128]; + let result = test_memcpy(&input); + let result_d = d_test_memcpy(&input, &mut d_input, 1.0); + + assert_eq!(result, result_d); + println!("Memcpy test passed: result = {}", result); +} diff --git a/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs new file mode 100644 index 0000000000000..b4c650330fe94 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/memcpy-typetree/rmake.rs @@ -0,0 +1,39 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // First, compile to LLVM IR to check for enzyme_type attributes + let _ir_output = rustc() + .input("memcpy.rs") + .arg("-Zautodiff=Enable") + .arg("-Zautodiff=NoPostopt") + .opt_level("0") + .arg("--emit=llvm-ir") + .arg("-o") + .arg("main.ll") + .run(); + + // Then compile with TypeTree analysis output for the existing checks + let output = rustc() + .input("memcpy.rs") + .arg("-Zautodiff=Enable,PrintTAFn=test_memcpy") + .arg("-Zautodiff=NoPostopt") + .opt_level("3") + .arg("-Clto=fat") + .arg("-g") + .run(); + + let stdout = output.stdout_utf8(); + let stderr = output.stderr_utf8(); + let ir_content = rfs::read_to_string("main.ll"); + + rfs::write("memcpy.stdout", &stdout); + rfs::write("memcpy.stderr", &stderr); + rfs::write("main.ir", &ir_content); + + llvm_filecheck().patterns("memcpy.check").stdin_buf(stdout).run(); + + llvm_filecheck().patterns("memcpy-ir.check").stdin_buf(ir_content).run(); +} diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check new file mode 100644 index 0000000000000..584f584084358 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/mixed.check @@ -0,0 +1,2 @@ +; Check that mixed struct with large array generates correct detailed type tree +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@float}"{{.*}}@test_mixed_struct{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,8]:Float@float}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs new file mode 100644 index 0000000000000..1c19963bc3612 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/rmake.rs @@ -0,0 +1,16 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc() + .input("test.rs") + .arg("-Zautodiff=Enable") + .arg("-Zautodiff=NoPostopt") + .opt_level("0") + .emit("llvm-ir") + .run(); + + llvm_filecheck().patterns("mixed.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs new file mode 100644 index 0000000000000..7a734980e617c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/mixed-struct-typetree/test.rs @@ -0,0 +1,23 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[repr(C)] +struct Container { + header: i64, + data: [f32; 1000], +} + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +#[inline(never)] +fn test_mixed_struct(container: &Container) -> f32 { + container.data[0] + container.data[999] +} + +fn main() { + let container = Container { header: 42, data: [1.0; 1000] }; + let mut d_container = Container { header: 0, data: [0.0; 1000] }; + let result = d_test(&container, &mut d_container, 1.0); + std::hint::black_box(result); +} diff --git a/tests/run-make/autodiff/type-trees/nott-flag/nott.check b/tests/run-make/autodiff/type-trees/nott-flag/nott.check new file mode 100644 index 0000000000000..8d23e2ee31957 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/nott-flag/nott.check @@ -0,0 +1,5 @@ +// Check that enzyme_type attributes are NOT present when NoTT flag is used +// This verifies the NoTT flag correctly disables TypeTree metadata + +CHECK: define{{.*}}@square +CHECK-NOT: "enzyme_type" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs new file mode 100644 index 0000000000000..de540b990cabd --- /dev/null +++ b/tests/run-make/autodiff/type-trees/nott-flag/rmake.rs @@ -0,0 +1,30 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Test with NoTT flag - should not generate TypeTree metadata + rustc() + .input("test.rs") + .arg("-Zautodiff=Enable,NoTT") + .emit("llvm-ir") + .arg("-o") + .arg("nott.ll") + .run(); + + // Test without NoTT flag - should generate TypeTree metadata + rustc() + .input("test.rs") + .arg("-Zautodiff=Enable") + .emit("llvm-ir") + .arg("-o") + .arg("with_tt.ll") + .run(); + + // Verify NoTT version does NOT have enzyme_type attributes + llvm_filecheck().patterns("nott.check").stdin_buf(rfs::read("nott.ll")).run(); + + // Verify TypeTree version DOES have enzyme_type attributes + llvm_filecheck().patterns("with_tt.check").stdin_buf(rfs::read("with_tt.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/nott-flag/test.rs b/tests/run-make/autodiff/type-trees/nott-flag/test.rs new file mode 100644 index 0000000000000..de3549c37c679 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/nott-flag/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_square, Duplicated, Active)] +#[no_mangle] +fn square(x: &f64) -> f64 { + x * x +} + +fn main() { + let x = 2.0; + let mut dx = 0.0; + let _result = d_square(&x, &mut dx, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check b/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check new file mode 100644 index 0000000000000..0b4c91191798b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/nott-flag/with_tt.check @@ -0,0 +1,4 @@ +// Check that enzyme_type attributes are present when TypeTree is enabled +// This verifies our TypeTree metadata attachment is working + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@square{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check b/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check new file mode 100644 index 0000000000000..1960e7b816c5f --- /dev/null +++ b/tests/run-make/autodiff/type-trees/recursion-typetree/recursion.check @@ -0,0 +1,3 @@ +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_deep{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}" +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_graph{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer, [-1,8]:Integer, [-1,16]:Integer, [-1,24]:Float@double}" +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_node{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs new file mode 100644 index 0000000000000..78718f3a21595 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/recursion-typetree/rmake.rs @@ -0,0 +1,9 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + llvm_filecheck().patterns("recursion.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs b/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs new file mode 100644 index 0000000000000..9d40bec1bf1d1 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/recursion-typetree/test.rs @@ -0,0 +1,100 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +// Self-referential struct to test recursion detection +#[derive(Clone)] +struct Node { + value: f64, + next: Option>, +} + +// Mutually recursive structs to test cycle detection +#[derive(Clone)] +struct GraphNodeA { + value: f64, + connections: Vec, +} + +#[derive(Clone)] +struct GraphNodeB { + weight: f64, + target: Option>, +} + +#[autodiff_reverse(d_test_node, Duplicated, Active)] +#[no_mangle] +fn test_node(node: &Node) -> f64 { + node.value * 2.0 +} + +#[autodiff_reverse(d_test_graph, Duplicated, Active)] +#[no_mangle] +fn test_graph(a: &GraphNodeA) -> f64 { + a.value * 3.0 +} + +// Simple depth test - deeply nested but not circular +#[derive(Clone)] +struct Level1 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level2 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level3 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level4 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level5 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level6 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level7 { + val: f64, + next: Option>, +} +#[derive(Clone)] +struct Level8 { + val: f64, +} + +#[autodiff_reverse(d_test_deep, Duplicated, Active)] +#[no_mangle] +fn test_deep(deep: &Level1) -> f64 { + deep.val * 4.0 +} + +fn main() { + let node = Node { value: 1.0, next: None }; + + let graph = GraphNodeA { value: 2.0, connections: vec![] }; + + let deep = Level1 { val: 5.0, next: None }; + + let mut d_node = Node { value: 0.0, next: None }; + + let mut d_graph = GraphNodeA { value: 0.0, connections: vec![] }; + + let mut d_deep = Level1 { val: 0.0, next: None }; + + let _result1 = d_test_node(&node, &mut d_node, 1.0); + let _result2 = d_test_graph(&graph, &mut d_graph, 1.0); + let _result3 = d_test_deep(&deep, &mut d_deep, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check new file mode 100644 index 0000000000000..23db64eea52aa --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/f128.check @@ -0,0 +1,4 @@ +; Check that f128 TypeTree metadata is correctly generated +; Should show Float@fp128 for f128 values and Pointer for references + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@fp128}"{{.*}}@test_f128{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@fp128}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs new file mode 100644 index 0000000000000..44320ecdd5714 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/rmake.rs @@ -0,0 +1,12 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile with TypeTree enabled and emit LLVM IR + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + + // Check that f128 TypeTree metadata is correctly generated + llvm_filecheck().patterns("f128.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs new file mode 100644 index 0000000000000..5c71baa3e6999 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f128-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff, f128)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_f128(x: &f128) -> f128 { + *x * *x +} + +fn main() { + let x = 2.0_f128; + let mut dx = 0.0_f128; + let _result = d_test(&x, &mut dx, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check new file mode 100644 index 0000000000000..9adff68d36f34 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/f16.check @@ -0,0 +1,4 @@ +; Check that f16 TypeTree metadata is correctly generated +; Should show Float@half for f16 values and Pointer for references + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@half}"{{.*}}@test_f16{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@half}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs new file mode 100644 index 0000000000000..0aebdbf55209b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/rmake.rs @@ -0,0 +1,12 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile with TypeTree enabled and emit LLVM IR + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + + // Check that f16 TypeTree metadata is correctly generated + llvm_filecheck().patterns("f16.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs new file mode 100644 index 0000000000000..6b68e8252f4c0 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f16-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff, f16)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_f16(x: &f16) -> f16 { + *x * *x +} + +fn main() { + let x = 2.0_f16; + let mut dx = 0.0_f16; + let _result = d_test(&x, &mut dx, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check new file mode 100644 index 0000000000000..176630f57e8f7 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/f32.check @@ -0,0 +1,4 @@ +; Check that f32 TypeTree metadata is correctly generated +; Should show Float@float for f32 values and Pointer for references + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@float}"{{.*}}@test_f32{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@float}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs new file mode 100644 index 0000000000000..ee3ab753bf505 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/rmake.rs @@ -0,0 +1,12 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile with TypeTree enabled and emit LLVM IR + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + + // Check that f32 TypeTree metadata is correctly generated + llvm_filecheck().patterns("f32.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs new file mode 100644 index 0000000000000..56c118399ee4b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f32-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_f32(x: &f32) -> f32 { + x * x +} + +fn main() { + let x = 2.0_f32; + let mut dx = 0.0_f32; + let _result = d_test(&x, &mut dx, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check new file mode 100644 index 0000000000000..929cd379694ac --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/f64.check @@ -0,0 +1,4 @@ +; Check that f64 TypeTree metadata is correctly generated +; Should show Float@double for f64 values and Pointer for references + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_f64{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs new file mode 100644 index 0000000000000..5fac9b23bc80f --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/rmake.rs @@ -0,0 +1,12 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile with TypeTree enabled and emit LLVM IR + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + + // Check that f64 TypeTree metadata is correctly generated + llvm_filecheck().patterns("f64.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs new file mode 100644 index 0000000000000..235360b76b23d --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/f64-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_f64(x: &f64) -> f64 { + x * x +} + +fn main() { + let x = 2.0_f64; + let mut dx = 0.0_f64; + let _result = d_test(&x, &mut dx, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check new file mode 100644 index 0000000000000..dee4aa5bbb6b2 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/i32.check @@ -0,0 +1,4 @@ +; Check that i32 TypeTree metadata is correctly generated +; Should show Integer for i32 values and Pointer for references + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Integer}"{{.*}}@test_i32{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Integer}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs new file mode 100644 index 0000000000000..a40fd55d88adf --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/rmake.rs @@ -0,0 +1,12 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + // Compile with TypeTree enabled and emit LLVM IR + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + + // Check that i32 TypeTree metadata is correctly generated + llvm_filecheck().patterns("i32.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs new file mode 100644 index 0000000000000..249803c5d9f7a --- /dev/null +++ b/tests/run-make/autodiff/type-trees/scalar-types/i32-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_i32(x: &i32) -> i32 { + x * x +} + +fn main() { + let x = 5_i32; + let mut dx = 0_i32; + let _result = d_test(&x, &mut dx, 1); +} diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs new file mode 100644 index 0000000000000..b81fb50bf1a75 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-typetree/rmake.rs @@ -0,0 +1,9 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + llvm_filecheck().patterns("slice.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/slice.check b/tests/run-make/autodiff/type-trees/slice-typetree/slice.check new file mode 100644 index 0000000000000..6543b61611538 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-typetree/slice.check @@ -0,0 +1,4 @@ +; Check that slice TypeTree metadata is correctly generated +; Should show Float@double for slice elements + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_slice{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,-1]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/slice-typetree/test.rs b/tests/run-make/autodiff/type-trees/slice-typetree/test.rs new file mode 100644 index 0000000000000..7117fa3844f59 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/slice-typetree/test.rs @@ -0,0 +1,16 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_slice(slice: &[f64]) -> f64 { + slice.iter().sum() +} + +fn main() { + let arr = [1.0, 2.0, 3.0, 4.0, 5.0]; + let slice = &arr[..]; + let mut d_slice = [0.0; 5]; + let _result = d_test(slice, &mut d_slice[..], 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs new file mode 100644 index 0000000000000..0af1b65ee181b --- /dev/null +++ b/tests/run-make/autodiff/type-trees/struct-typetree/rmake.rs @@ -0,0 +1,9 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + llvm_filecheck().patterns("struct.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/struct.check b/tests/run-make/autodiff/type-trees/struct-typetree/struct.check new file mode 100644 index 0000000000000..54956317e1e95 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/struct-typetree/struct.check @@ -0,0 +1,4 @@ +; Check that struct TypeTree metadata is correctly generated +; Should show Float@double at offsets 0, 8, 16 for Point struct fields + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_struct{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/struct-typetree/test.rs b/tests/run-make/autodiff/type-trees/struct-typetree/test.rs new file mode 100644 index 0000000000000..cbe7b10e40974 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/struct-typetree/test.rs @@ -0,0 +1,22 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[repr(C)] +struct Point { + x: f64, + y: f64, + z: f64, +} + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_struct(point: &Point) -> f64 { + point.x + point.y * 2.0 + point.z * 3.0 +} + +fn main() { + let point = Point { x: 1.0, y: 2.0, z: 3.0 }; + let mut d_point = Point { x: 0.0, y: 0.0, z: 0.0 }; + let _result = d_test(&point, &mut d_point, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs new file mode 100644 index 0000000000000..76913828901c6 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/tuple-typetree/rmake.rs @@ -0,0 +1,9 @@ +//@ needs-enzyme +//@ ignore-cross-compile + +use run_make_support::{llvm_filecheck, rfs, rustc}; + +fn main() { + rustc().input("test.rs").arg("-Zautodiff=Enable").emit("llvm-ir").run(); + llvm_filecheck().patterns("tuple.check").stdin_buf(rfs::read("test.ll")).run(); +} diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs b/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs new file mode 100644 index 0000000000000..32187b587a383 --- /dev/null +++ b/tests/run-make/autodiff/type-trees/tuple-typetree/test.rs @@ -0,0 +1,15 @@ +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(d_test, Duplicated, Active)] +#[no_mangle] +fn test_tuple(tuple: &(f64, f64, f64)) -> f64 { + tuple.0 + tuple.1 * 2.0 + tuple.2 * 3.0 +} + +fn main() { + let tuple = (1.0, 2.0, 3.0); + let mut d_tuple = (0.0, 0.0, 0.0); + let _result = d_test(&tuple, &mut d_tuple, 1.0); +} diff --git a/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check b/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check new file mode 100644 index 0000000000000..47647e78cc35c --- /dev/null +++ b/tests/run-make/autodiff/type-trees/tuple-typetree/tuple.check @@ -0,0 +1,4 @@ +; Check that tuple TypeTree metadata is correctly generated +; Should show Float@double at offsets 0, 8, 16 for (f64, f64, f64) + +CHECK: define{{.*}}"enzyme_type"="{[-1]:Float@double}"{{.*}}@test_tuple{{.*}}"enzyme_type"="{[-1]:Pointer, [-1,0]:Float@double, [-1,8]:Float@double, [-1,16]:Float@double}" \ No newline at end of file diff --git a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check index dcf9508b69d6f..cdb70eb83fc19 100644 --- a/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check +++ b/tests/run-make/autodiff/type-trees/type-analysis/vec/vec.check @@ -1,7 +1,7 @@ // CHECK: callee - {[-1]:Float@float} |{[-1]:Pointer}:{} // CHECK: ptr %{{[0-9]+}}: {[-1]:Pointer} // CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 8, !dbg !{{[0-9]+}}: {[-1]:Pointer} -// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !102, !noundef !{{[0-9]+}}: {} +// CHECK-DAG: %{{[0-9]+}} = load ptr, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !nonnull !{{[0-9]+}}, !noundef !{{[0-9]+}}: {} // CHECK-DAG: %{{[0-9]+}} = getelementptr inbounds nuw i8, ptr %{{[0-9]+}}, i64 16, !dbg !{{[0-9]+}}: {[-1]:Pointer} // CHECK-DAG: %{{[0-9]+}} = load i64, ptr %{{[0-9]+}}, align 8, !dbg !{{[0-9]+}}, !noundef !{{[0-9]+}}: {} // CHECK-DAG: %{{[0-9]+}} = icmp eq i64 %{{[0-9]+}}, 0, !dbg !{{[0-9]+}}: {[-1]:Integer} diff --git a/tests/run-make/bin-emit-no-symbols/rmake.rs b/tests/run-make/bin-emit-no-symbols/rmake.rs index 2faeb20025bb7..0822bd6dfd6a8 100644 --- a/tests/run-make/bin-emit-no-symbols/rmake.rs +++ b/tests/run-make/bin-emit-no-symbols/rmake.rs @@ -14,5 +14,5 @@ fn main() { let out = llvm_readobj().input("app.o").arg("--symbols").run(); out.assert_stdout_contains("rust_begin_unwind"); out.assert_stdout_contains("rust_eh_personality"); - out.assert_stdout_contains("__rg_oom"); + out.assert_stdout_contains("__rust_alloc_error_handler"); } diff --git a/tests/run-make/crate-loading/multiple-dep-versions-3.rs b/tests/run-make/crate-loading/dep-2-reexport.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-3.rs rename to tests/run-make/crate-loading/dep-2-reexport.rs diff --git a/tests/run-make/crate-loading/multiple-dep-versions-1.rs b/tests/run-make/crate-loading/dependency-1.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-1.rs rename to tests/run-make/crate-loading/dependency-1.rs diff --git a/tests/run-make/crate-loading/multiple-dep-versions-2.rs b/tests/run-make/crate-loading/dependency-2.rs similarity index 100% rename from tests/run-make/crate-loading/multiple-dep-versions-2.rs rename to tests/run-make/crate-loading/dependency-2.rs diff --git a/tests/run-make/crate-loading/rmake.rs b/tests/run-make/crate-loading/rmake.rs index 6ad456e3e3e57..8f2577861239d 100644 --- a/tests/run-make/crate-loading/rmake.rs +++ b/tests/run-make/crate-loading/rmake.rs @@ -6,12 +6,9 @@ use run_make_support::{diff, rust_lib_name, rustc}; fn main() { - rustc().input("multiple-dep-versions-1.rs").run(); - rustc().input("multiple-dep-versions-2.rs").extra_filename("2").metadata("2").run(); - rustc() - .input("multiple-dep-versions-3.rs") - .extern_("dependency", rust_lib_name("dependency2")) - .run(); + rustc().input("dependency-1.rs").run(); + rustc().input("dependency-2.rs").extra_filename("2").metadata("2").run(); + rustc().input("dep-2-reexport.rs").extern_("dependency", rust_lib_name("dependency2")).run(); let out = rustc() .input("multiple-dep-versions.rs") diff --git a/tests/run-make/doctests-compilation-time-info/rmake.rs b/tests/run-make/doctests-compilation-time-info/rmake.rs new file mode 100644 index 0000000000000..2bcf664923f2a --- /dev/null +++ b/tests/run-make/doctests-compilation-time-info/rmake.rs @@ -0,0 +1,119 @@ +//@ ignore-cross-compile (needs to run doctests) + +use run_make_support::rfs::write; +use run_make_support::{cwd, rustdoc}; + +fn assert_presence_of_compilation_time_report( + content: &str, + success: bool, + should_contain_compile_time: bool, +) { + let mut cmd = rustdoc(); + let file = cwd().join("foo.rs"); + + write(&file, content); + cmd.input(&file).arg("--test").edition("2024").env("RUST_BACKTRACE", "0"); + let output = if success { cmd.run() } else { cmd.run_fail() }; + + assert_eq!( + output + .stdout_utf8() + .split("all doctests ran in ") + .last() + .is_some_and(|s| s.contains("; merged doctests compilation took")), + should_contain_compile_time, + ); +} + +fn main() { + // Checking with only successful merged doctests. + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! let x = 12; +//! ```", + true, + true, + ); + // Checking with only failing merged doctests. + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! panic!(); +//! ```", + false, + true, + ); + // Checking with mix of successful doctests. + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! let x = 12; +//! ``` +//! +//! ```compile_fail +//! let x +//! ```", + true, + true, + ); + // Checking with mix of failing doctests. + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! panic!(); +//! ``` +//! +//! ```compile_fail +//! let x +//! ```", + false, + true, + ); + // Checking with mix of failing doctests (v2). + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! let x = 12; +//! ``` +//! +//! ```compile_fail +//! let x = 12; +//! ```", + false, + true, + ); + // Checking with mix of failing doctests (v3). + assert_presence_of_compilation_time_report( + "\ +//! ``` +//! panic!(); +//! ``` +//! +//! ```compile_fail +//! let x = 12; +//! ```", + false, + true, + ); + // Checking with successful non-merged doctests. + assert_presence_of_compilation_time_report( + "\ +//! ```compile_fail +//! let x +//! ```", + true, + // If there is no merged doctests, then we should not display compilation time. + false, + ); + // Checking with failing non-merged doctests. + assert_presence_of_compilation_time_report( + "\ +//! ```compile_fail +//! let x = 12; +//! ```", + false, + // If there is no merged doctests, then we should not display compilation time. + false, + ); +} diff --git a/tests/run-make/doctests-merge/doctest-2024.stdout b/tests/run-make/doctests-merge/doctest-2024.stdout index 7da08d68faae3..a7e139bbd23dc 100644 --- a/tests/run-make/doctests-merge/doctest-2024.stdout +++ b/tests/run-make/doctests-merge/doctest-2024.stdout @@ -5,3 +5,4 @@ test doctest.rs - init (line 8) ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/run-make/doctests-merge/rmake.rs b/tests/run-make/doctests-merge/rmake.rs index 7893d4988ebba..f2a1e8e13ddfe 100644 --- a/tests/run-make/doctests-merge/rmake.rs +++ b/tests/run-make/doctests-merge/rmake.rs @@ -20,6 +20,8 @@ fn test_and_compare(input_file: &str, stdout_file: &str, edition: &str, dep: &Pa .expected_file(stdout_file) .actual_text("output", output.stdout_utf8()) .normalize(r#"finished in \d+\.\d+s"#, "finished in $$TIME") + .normalize(r#"ran in \d+\.\d+s"#, "ran in $$TIME") + .normalize(r#"compilation took \d+\.\d+s"#, "compilation took $$TIME") .run(); } diff --git a/tests/run-make/duplicate-dependency/foo-v1.rs b/tests/run-make/duplicate-dependency/foo-v1.rs new file mode 100644 index 0000000000000..4a835673a596b --- /dev/null +++ b/tests/run-make/duplicate-dependency/foo-v1.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/duplicate-dependency/foo-v2.rs b/tests/run-make/duplicate-dependency/foo-v2.rs new file mode 100644 index 0000000000000..4a835673a596b --- /dev/null +++ b/tests/run-make/duplicate-dependency/foo-v2.rs @@ -0,0 +1 @@ +pub struct Foo; diff --git a/tests/run-make/duplicate-dependency/main.rs b/tests/run-make/duplicate-dependency/main.rs new file mode 100644 index 0000000000000..b22d9581c9a40 --- /dev/null +++ b/tests/run-make/duplicate-dependency/main.rs @@ -0,0 +1,15 @@ +struct Bar; + +impl From for foo::Foo { + fn from(_: Bar) -> Self { + foo::Foo + } +} + +fn main() { + // The user might wrongly expect this to work since From for Foo + // implies Into for Bar. What the user missed is that different + // versions of Foo exist in the dependency graph, and the impl is for the + // wrong version. + re_export_foo::into_foo(Bar); +} diff --git a/tests/run-make/duplicate-dependency/main.stderr b/tests/run-make/duplicate-dependency/main.stderr new file mode 100644 index 0000000000000..36d54988788f4 --- /dev/null +++ b/tests/run-make/duplicate-dependency/main.stderr @@ -0,0 +1,24 @@ +error[E0277]: the trait bound `re_export_foo::foo::Foo: From` is not satisfied + --> main.rs:14:29 + | +LL | re_export_foo::into_foo(Bar); + | ----------------------- ^^^ the trait `From` is not implemented for `re_export_foo::foo::Foo` + | | + | required by a bound introduced by this call + | +help: item with same name found + --> $DIR/foo-v1.rs:1:1 + | +LL | pub struct Foo; + | ^^^^^^^^^^^^^^ + = note: perhaps two different versions of crate `foo` are being used? + = note: required for `Bar` to implement `Into` +note: required by a bound in `into_foo` + --> $DIR/re-export-foo.rs:3:25 + | +LL | pub fn into_foo(_: impl Into) {} + | ^^^^^^^^^^^^^^ required by this bound in `into_foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/run-make/duplicate-dependency/re-export-foo.rs b/tests/run-make/duplicate-dependency/re-export-foo.rs new file mode 100644 index 0000000000000..b346cfcee9b1f --- /dev/null +++ b/tests/run-make/duplicate-dependency/re-export-foo.rs @@ -0,0 +1,3 @@ +pub use foo; + +pub fn into_foo(_: impl Into) {} diff --git a/tests/run-make/duplicate-dependency/rmake.rs b/tests/run-make/duplicate-dependency/rmake.rs new file mode 100644 index 0000000000000..762d97e4311f4 --- /dev/null +++ b/tests/run-make/duplicate-dependency/rmake.rs @@ -0,0 +1,45 @@ +//@ needs-target-std + +use run_make_support::{Rustc, cwd, diff, rust_lib_name, rustc}; + +fn rustc_with_common_args() -> Rustc { + let mut rustc = rustc(); + rustc.remap_path_prefix(cwd(), "$DIR"); + rustc.edition("2018"); // Don't require `extern crate` + rustc +} + +fn main() { + rustc_with_common_args() + .input("foo-v1.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v1") + .metadata("-v1") + .run(); + + rustc_with_common_args() + .input("foo-v2.rs") + .crate_type("rlib") + .crate_name("foo") + .extra_filename("-v2") + .metadata("-v2") + .run(); + + rustc_with_common_args() + .input("re-export-foo.rs") + .crate_type("rlib") + .extern_("foo", rust_lib_name("foo-v2")) + .run(); + + let stderr = rustc_with_common_args() + .input("main.rs") + .extern_("foo", rust_lib_name("foo-v1")) + .extern_("re_export_foo", rust_lib_name("re_export_foo")) + .library_search_path(cwd()) + .ui_testing() + .run_fail() + .stderr_utf8(); + + diff().expected_file("main.stderr").normalize(r"\\", "/").actual_text("(rustc)", &stderr).run(); +} diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs index 9ea706af50356..a31b08d6c6956 100644 --- a/tests/run-make/linker-warning/rmake.rs +++ b/tests/run-make/linker-warning/rmake.rs @@ -61,14 +61,13 @@ fn main() { diff() .expected_file("short-error.txt") .actual_text("(linker error)", out.stderr()) - .normalize(r#"/rustc[^/_-]*/"#, "/rustc/") - .normalize("libpanic_abort", "libpanic_unwind") .normalize( regex::escape( run_make_support::build_root().canonicalize().unwrap().to_str().unwrap(), ), "/build-root", ) + .normalize("libpanic_abort", "libpanic_unwind") .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"") .normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"") .run(); diff --git a/tests/run-make/lto-long-filenames/rmake.rs b/tests/run-make/lto-long-filenames/rmake.rs index 9e0ba63e9f5b8..98ce54e5efc82 100644 --- a/tests/run-make/lto-long-filenames/rmake.rs +++ b/tests/run-make/lto-long-filenames/rmake.rs @@ -9,8 +9,6 @@ //@ ignore-cross-compile -use std::fs; - use run_make_support::{rfs, rustc}; // This test make sure we don't get such following error: diff --git a/tests/run-make/lto-long-filenames_cn/rmake.rs b/tests/run-make/lto-long-filenames_cn/rmake.rs new file mode 100644 index 0000000000000..fc25a2ac166b2 --- /dev/null +++ b/tests/run-make/lto-long-filenames_cn/rmake.rs @@ -0,0 +1,25 @@ +//@ ignore-cross-compile +// gnu ld is confused with intermediate files having multibytes characters in their names: +// = note: ld.exe: cannot find f0d5ff18d6510ebc-???_???_??????????_?_?????_?_???????.d50c2 \ +// 4c0c4ea93cc-cgu.0.rcgu.o: Invalid argument +// as this is not something rustc can fix by itself, +// we just skip the test on windows-gnu for now. Hence: +//@ ignore-windows-gnu + +use run_make_support::{rfs, rustc}; + +// This test make sure we don't crash when lto creates output files with long names. +// cn characters can be multi-byte and thus trigger the long filename reduction code more easily. +// we need to make sure that the code is properly generating names at char boundaries. +// as reported in issue #147975 +fn main() { + let lto_flags = ["-Clto", "-Clto=yes", "-Clto=off", "-Clto=thin", "-Clto=fat"]; + for prefix_len in 0..4 { + let prefix: String = std::iter::repeat("_").take(prefix_len).collect(); + let main_file = format!("{}ⵅⴻⵎⵎⴻⵎ_ⴷⵉⵎⴰ_ⵖⴻⴼ_ⵢⵉⵙⴻⴽⴽⵉⵍⴻⵏ_ⵏ_ⵡⴰⵟⴰⵙ_ⵏ_ⵢⵉⴱⵢⵜⴻⵏ.rs", prefix); + rfs::write(&main_file, "fn main() {}\n"); + for flag in lto_flags { + rustc().input(&main_file).arg(flag).run(); + } + } +} diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs index 7bb54e2739c9d..e9d09e359c686 100644 --- a/tests/run-make/musl-default-linking/rmake.rs +++ b/tests/run-make/musl-default-linking/rmake.rs @@ -4,7 +4,7 @@ use run_make_support::{rustc, serde_json}; // Per https://github.com/rust-lang/compiler-team/issues/422, // we should be trying to move these targets to dynamically link // musl libc by default. -//@ needs-llvm-components: aarch64 arm mips powerpc riscv systemz x86 +//@ needs-llvm-components: aarch64 arm powerpc x86 static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[ "aarch64-unknown-linux-musl", "arm-unknown-linux-musleabi", @@ -14,16 +14,7 @@ static LEGACY_STATIC_LINKING_TARGETS: &[&'static str] = &[ "armv7-unknown-linux-musleabihf", "i586-unknown-linux-musl", "i686-unknown-linux-musl", - "mips64-unknown-linux-musl", - "mips64-unknown-linux-muslabi64", - "mips64el-unknown-linux-muslabi64", - "powerpc-unknown-linux-musl", - "powerpc-unknown-linux-muslspe", - "powerpc64-unknown-linux-musl", "powerpc64le-unknown-linux-musl", - "riscv32gc-unknown-linux-musl", - "s390x-unknown-linux-musl", - "thumbv7neon-unknown-linux-musleabihf", "x86_64-unknown-linux-musl", ]; diff --git a/tests/run-make/panic-abort-eh_frame/rmake.rs b/tests/run-make/panic-abort-eh_frame/rmake.rs index 23d95dc577491..2eccde627955c 100644 --- a/tests/run-make/panic-abort-eh_frame/rmake.rs +++ b/tests/run-make/panic-abort-eh_frame/rmake.rs @@ -1,9 +1,11 @@ // An `.eh_frame` section in an object file is a symptom of an UnwindAction::Terminate // being inserted, useful for determining whether or not unwinding is necessary. -// This is useless when panics would NEVER unwind due to -C panic=abort. This section should -// therefore never appear in the emit file of a -C panic=abort compilation, and this test -// checks that this is respected. -// See https://github.com/rust-lang/rust/pull/112403 +// This is useless when panics would NEVER unwind due to -C panic=abort and when we don't need +// being able to generate backtraces (which depend on unwind tables on linux). This section should +// therefore never appear in the emit file of a -C panic=abort compilation +// with -C force-unwind-tables=no, and this test checks that this is respected. +// See https://github.com/rust-lang/rust/pull/112403 and +// https://github.com/rust-lang/rust/pull/143613. //@ only-linux // FIXME(Oneirical): the DW_CFA symbol appears on Windows-gnu, because uwtable @@ -19,6 +21,7 @@ fn main() { .panic("abort") .edition("2021") .arg("-Zvalidate-mir") + .arg("-Cforce-unwind-tables=no") .run(); llvm_objdump().arg("--dwarf=frames").input("foo.o").run().assert_stdout_not_contains("DW_CFA"); } diff --git a/tests/run-make/pdb-buildinfo-cl-cmd/filecheck.txt b/tests/run-make/pdb-buildinfo-cl-cmd/filecheck.txt deleted file mode 100644 index a01999d5bdf76..0000000000000 --- a/tests/run-make/pdb-buildinfo-cl-cmd/filecheck.txt +++ /dev/null @@ -1,4 +0,0 @@ -CHECK: LF_BUILDINFO -CHECK: rustc.exe -CHECK: main.rs -CHECK: "-g" "--crate-name" "my_crate_name" "--crate-type" "bin" "-Cmetadata=dc9ef878b0a48666" diff --git a/tests/run-make/pdb-buildinfo-cl-cmd/rmake.rs b/tests/run-make/pdb-buildinfo-cl-cmd/rmake.rs deleted file mode 100644 index 9418f4f8d84d3..0000000000000 --- a/tests/run-make/pdb-buildinfo-cl-cmd/rmake.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Check if the pdb file contains the following information in the LF_BUILDINFO: -// 1. full path to the compiler (cl) -// 2. the commandline args to compile it (cmd) -// This is because these used to be missing in #96475. -// See https://github.com/rust-lang/rust/pull/113492 - -//@ only-windows-msvc -// Reason: pdb files are unique to this architecture - -use run_make_support::{llvm, rustc}; - -fn main() { - rustc() - .input("main.rs") - .arg("-g") - .crate_name("my_crate_name") - .crate_type("bin") - .metadata("dc9ef878b0a48666") - .run(); - - let pdbutil_result = - llvm::llvm_pdbutil().arg("dump").arg("-ids").input("my_crate_name.pdb").run(); - - llvm::llvm_filecheck().patterns("filecheck.txt").stdin_buf(pdbutil_result.stdout_utf8()).run(); -} diff --git a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs index 0a2186b095389..2ac5fdee063c2 100644 --- a/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs +++ b/tests/run-make/pointer-auth-link-with-c-lto-clang/rmake.rs @@ -1,12 +1,14 @@ // `-Z branch protection` is an unstable compiler feature which adds pointer-authentication // code (PAC), a useful hashing measure for verifying that pointers have not been modified. // This test checks that compilation and execution is successful when this feature is activated, -// with some of its possible extra arguments (bti, pac-ret, leaf) when doing LTO. +// with some of its possible extra arguments (bti, gcs, pac-ret, leaf) when doing LTO. // See https://github.com/rust-lang/rust/pull/88354 //@ needs-force-clang-based-tests //@ only-aarch64 // Reason: branch protection is not supported on other architectures +//@ ignore-apple +// Reason: XCode needs updating to support gcs //@ ignore-cross-compile // Reason: the compiled binary is executed @@ -19,7 +21,7 @@ fn main() { clang() .arg("-v") .lto("thin") - .arg("-mbranch-protection=bti+pac-ret+b-key+leaf") + .arg("-mbranch-protection=bti+gcs+pac-ret+b-key+leaf") .arg("-c") .out_exe("test.o") .input("test.c") @@ -30,7 +32,7 @@ fn main() { .opt_level("2") .linker(&env_var("CLANG")) .link_arg("-fuse-ld=lld") - .arg("-Zbranch-protection=bti,pac-ret,leaf") + .arg("-Zbranch-protection=bti,gcs,pac-ret,leaf") .input("test.rs") .output("test.bin") .run(); diff --git a/tests/run-make/pointer-auth-link-with-c/rmake.rs b/tests/run-make/pointer-auth-link-with-c/rmake.rs index a4d7454e5755a..1ddcb79d64ff4 100644 --- a/tests/run-make/pointer-auth-link-with-c/rmake.rs +++ b/tests/run-make/pointer-auth-link-with-c/rmake.rs @@ -1,11 +1,13 @@ // `-Z branch protection` is an unstable compiler feature which adds pointer-authentication // code (PAC), a useful hashing measure for verifying that pointers have not been modified. // This test checks that compilation and execution is successful when this feature is activated, -// with some of its possible extra arguments (bti, pac-ret, pc, leaf, b-key). +// with some of its possible extra arguments (bti, gcs, pac-ret, pc, leaf, b-key). // See https://github.com/rust-lang/rust/pull/88354 //@ only-aarch64 // Reason: branch protection is not supported on other architectures +//@ ignore-apple +// Reason: XCode needs updating to support gcs //@ ignore-cross-compile // Reason: the compiled binary is executed @@ -13,17 +15,17 @@ use run_make_support::{build_native_static_lib, cc, is_windows_msvc, llvm_ar, ru fn main() { build_native_static_lib("test"); - rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run(); + rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); run("test"); cc().arg("-v") .arg("-c") .out_exe("test") .input("test.c") - .arg("-mbranch-protection=bti+pac-ret+leaf") + .arg("-mbranch-protection=bti+gcs+pac-ret+leaf") .run(); let obj_file = if is_windows_msvc() { "test.obj" } else { "test" }; llvm_ar().obj_to_ar().output_input("libtest.a", &obj_file).run(); - rustc().arg("-Zbranch-protection=bti,pac-ret,leaf").input("test.rs").run(); + rustc().arg("-Zbranch-protection=bti,gcs,pac-ret,leaf").input("test.rs").run(); run("test"); // FIXME: +pc was only recently added to LLVM diff --git a/tests/run-make/rustdoc-dep-info/rmake.rs b/tests/run-make/rustdoc-dep-info/rmake.rs index 166e8d5702fc3..5d6176b18e886 100644 --- a/tests/run-make/rustdoc-dep-info/rmake.rs +++ b/tests/run-make/rustdoc-dep-info/rmake.rs @@ -45,4 +45,15 @@ fn main() { assert!(!path("precedence1.d").exists()); assert!(!path("precedence2.d").exists()); assert!(path("precedence3.d").exists()); + + // stdout (-) also wins if being the last. + let result = rustdoc() + .input("lib.rs") + .arg("-Zunstable-options") + .emit("dep-info=precedence1.d") + .emit("dep-info=-") + .run(); + assert!(!path("precedence1.d").exists()); + assert!(!path("-").exists()); // `-` shouldn't be treated as a file path + assert!(!result.stdout().is_empty()); // Something emitted to stdout } diff --git a/tests/run-make/rustdoc-doctest-output-format/file.rs b/tests/run-make/rustdoc-doctest-output-format/file.rs new file mode 100644 index 0000000000000..51d17849fd718 --- /dev/null +++ b/tests/run-make/rustdoc-doctest-output-format/file.rs @@ -0,0 +1,3 @@ +//! ``` +//! let x = 12; +//! ``` diff --git a/tests/run-make/rustdoc-doctest-output-format/rmake.rs b/tests/run-make/rustdoc-doctest-output-format/rmake.rs new file mode 100644 index 0000000000000..61b5c0c4fd11d --- /dev/null +++ b/tests/run-make/rustdoc-doctest-output-format/rmake.rs @@ -0,0 +1,83 @@ +//! Regression test to ensure that the output format is respected for doctests. +//! +//! Regression test for . + +//@ ignore-cross-compile + +use run_make_support::{rustdoc, serde_json}; + +fn run_test(edition: &str, format: Option<&str>) -> String { + let mut r = rustdoc(); + r.input("file.rs").edition(edition).arg("--test"); + if let Some(format) = format { + r.args(&[ + "--test-args", + "-Zunstable-options", + "--test-args", + "--format", + "--test-args", + format, + ]); + } + r.run().stdout_utf8() +} + +fn check_json_output(edition: &str, expected_reports: usize) { + let out = run_test(edition, Some("json")); + let mut found_report = 0; + for (line_nb, line) in out.lines().enumerate() { + match serde_json::from_str::(&line) { + Ok(value) => { + if value.get("type") == Some(&serde_json::json!("report")) { + found_report += 1; + } + } + Err(error) => panic!( + "failed for {edition} edition (json format) at line {}: non-JSON value: {error}\n\ + ====== output ======\n{out}", + line_nb + 1, + ), + } + } + if found_report != expected_reports { + panic!( + "failed for {edition} edition (json format): expected {expected_reports} doctest \ + time `report`, found {found_report}\n====== output ======\n{out}", + ); + } +} + +fn check_non_json_output(edition: &str, expected_reports: usize) { + let out = run_test(edition, None); + let mut found_report = 0; + for (line_nb, line) in out.lines().enumerate() { + if line.starts_with('{') && serde_json::from_str::(&line).is_ok() { + panic!( + "failed for {edition} edition: unexpected json at line {}: `{line}`\n\ + ====== output ======\n{out}", + line_nb + 1 + ); + } + if line.starts_with("all doctests ran in") + && line.contains("; merged doctests compilation took ") + { + found_report += 1; + } + } + if found_report != expected_reports { + panic!( + "failed for {edition} edition: expected {expected_reports} doctest time `report`, \ + found {found_report}\n====== output ======\n{out}", + ); + } +} + +fn main() { + // Only the merged doctests generate the "times report". + check_json_output("2021", 0); + check_json_output("2024", 1); + + // Only the merged doctests generate the "times report". + check_non_json_output("2021", 0); + check_non_json_output("2024", 1); +} diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs new file mode 100644 index 0000000000000..0b1e1948d5fcc --- /dev/null +++ b/tests/run-make/rustdoc-merge-no-input-finalize/rmake.rs @@ -0,0 +1,28 @@ +// Running --merge=finalize without an input crate root should not trigger ICE. +// Issue: https://github.com/rust-lang/rust/issues/146646 + +//@ needs-target-std + +use run_make_support::{path, rustdoc}; + +fn main() { + let out_dir = path("out"); + let merged_dir = path("merged"); + let parts_out_dir = path("parts"); + rustdoc() + .input("sierra.rs") + .out_dir(&out_dir) + .arg("-Zunstable-options") + .arg(format!("--parts-out-dir={}", parts_out_dir.display())) + .arg("--merge=none") + .run(); + assert!(parts_out_dir.join("crate-info").exists()); + + let output = rustdoc() + .arg("-Zunstable-options") + .out_dir(&out_dir) + .arg(format!("--include-parts-dir={}", parts_out_dir.display())) + .arg("--merge=finalize") + .run(); + output.assert_stderr_not_contains("error: the compiler unexpectedly panicked. this is a bug."); +} diff --git a/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs b/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs new file mode 100644 index 0000000000000..f8fc48341ed6b --- /dev/null +++ b/tests/run-make/rustdoc-merge-no-input-finalize/sierra.rs @@ -0,0 +1 @@ +pub struct Sierra; diff --git a/tests/run-make/rustdoc-target-modifiers/rmake.rs b/tests/run-make/rustdoc-target-modifiers/rmake.rs index ee522501fd286..ffe87f3f7650e 100644 --- a/tests/run-make/rustdoc-target-modifiers/rmake.rs +++ b/tests/run-make/rustdoc-target-modifiers/rmake.rs @@ -25,4 +25,43 @@ fn main() { .target("aarch64-unknown-none-softfloat") .arg("-Zfixed-x18") .run(); + + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("-Zfixed-x18") + .arg("--test") + .run(); + + rustdoc() + .input("c.rs") + .edition("2024") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("-Zfixed-x18") + .arg("--test") + .run(); + + // rustdoc --test detects ABI mismatch + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("--test") + .run_fail() + .assert_stderr_contains("mixing `-Zfixed-x18` will cause an ABI mismatch"); + + // rustdoc --test -Cunsafe-allow-abi-mismatch=... ignores the mismatch + rustdoc() + .input("c.rs") + .crate_type("rlib") + .extern_("d", "libd.rmeta") + .target("aarch64-unknown-none-softfloat") + .arg("--test") + .arg("-Cunsafe-allow-abi-mismatch=fixed-x18") + .run(); } diff --git a/tests/run-make/split-debuginfo/rmake.rs b/tests/run-make/split-debuginfo/rmake.rs index e8de5aed17260..e53b710107812 100644 --- a/tests/run-make/split-debuginfo/rmake.rs +++ b/tests/run-make/split-debuginfo/rmake.rs @@ -187,6 +187,25 @@ enum UnstableOptions { Unspecified, } +#[track_caller] +fn dwo_out_filenames(dwo_out: Option<&str>) -> BTreeSet { + let dwo_out = if let Some(d) = dwo_out { + d + } else { + return BTreeSet::new(); + }; + let files = shallow_find_files(dwo_out, |path| { + // Fiilter out source files + !has_extension(path, "rs") + }); + files + .iter() + .map(|p| { + format!("{}/{}", dwo_out, p.file_name().unwrap().to_os_string().into_string().unwrap()) + }) + .collect() +} + #[track_caller] fn cwd_filenames() -> BTreeSet { let files = shallow_find_files(cwd(), |path| { @@ -196,6 +215,17 @@ fn cwd_filenames() -> BTreeSet { files.iter().map(|p| p.file_name().unwrap().to_os_string().into_string().unwrap()).collect() } +#[track_caller] +fn dwo_out_dwo_filenames(dwo_out: &str) -> BTreeSet { + let files = shallow_find_files(dwo_out, |p| has_extension(p, "dwo")); + files + .iter() + .map(|p| { + format!("{}/{}", dwo_out, p.file_name().unwrap().to_os_string().into_string().unwrap()) + }) + .collect() +} + #[track_caller] fn cwd_dwo_filenames() -> BTreeSet { let files = shallow_find_files(cwd(), |path| has_extension(path, "dwo")); @@ -376,17 +406,19 @@ mod shared_linux_other_tests { lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, + split_dwarf_output_directory: Option<&str>, ) { run_in_tmpdir(|| { println!( - "checking: unstable_options={:?} + split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?}", + "checking: unstable_options={:?} + split_kind={:?} + level={:?} + split_dwarf_kind={:?} + lto={:?} + remap_path_prefix={:?} + remap_path_scope={:?} + split_dwarf_out_dir={:?}", unstable_options, split_kind, level, split_dwarf_kind, lto, remap_path_prefix, - remap_path_scope + remap_path_scope, + split_dwarf_output_directory, ); match cross_crate_test { @@ -398,6 +430,7 @@ mod shared_linux_other_tests { lto, remap_path_prefix, remap_path_scope, + split_dwarf_output_directory, ), CrossCrateTest::No => simple_split_debuginfo( unstable_options, @@ -407,6 +440,7 @@ mod shared_linux_other_tests { lto, remap_path_prefix, remap_path_scope, + split_dwarf_output_directory, ), } }); @@ -420,7 +454,11 @@ mod shared_linux_other_tests { lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, + split_dwarf_output_directory: Option<&str>, ) { + if let Some(dwo_out) = split_dwarf_output_directory { + run_make_support::rfs::create_dir(dwo_out); + } match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) { // packed-crosscrate-split // - Debuginfo in `.dwo` files @@ -531,13 +569,19 @@ mod shared_linux_other_tests { .input("bar.rs") .crate_type("lib") .split_debuginfo(split_kind.cli_value()) + .split_dwarf_out_dir(split_dwarf_output_directory) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); - let bar_found_files = cwd_filenames(); + let mut bar_found_files = cwd_filenames(); + bar_found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory)); - let bar_dwo_files = cwd_dwo_filenames(); + let bar_dwo_files = if let Some(dwo_out) = split_dwarf_output_directory { + dwo_out_dwo_filenames(dwo_out) + } else { + cwd_dwo_filenames() + }; assert_eq!(bar_dwo_files.len(), 1); let mut bar_expected_files = BTreeSet::new(); @@ -553,13 +597,19 @@ mod shared_linux_other_tests { .extern_("bar", "libbar.rlib") .input("main.rs") .split_debuginfo(split_kind.cli_value()) + .split_dwarf_out_dir(split_dwarf_output_directory) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); - let overall_found_files = cwd_filenames(); + let mut overall_found_files = cwd_filenames(); + overall_found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory)); - let overall_dwo_files = cwd_dwo_filenames(); + let overall_dwo_files = if let Some(dwo_out) = split_dwarf_output_directory { + dwo_out_dwo_filenames(dwo_out) + } else { + cwd_dwo_filenames() + }; assert_eq!(overall_dwo_files.len(), 2); let mut overall_expected_files = BTreeSet::new(); @@ -648,7 +698,11 @@ mod shared_linux_other_tests { lto: LinkerPluginLto, remap_path_prefix: RemapPathPrefix, remap_path_scope: RemapPathScope, + split_dwarf_output_directory: Option<&str>, ) { + if let Some(dwo_out) = split_dwarf_output_directory { + run_make_support::rfs::create_dir(dwo_out); + } match (split_kind, level, split_dwarf_kind, lto, remap_path_prefix, remap_path_scope) { // off (unspecified): // - Debuginfo in `.o` files @@ -921,14 +975,19 @@ mod shared_linux_other_tests { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) + .split_dwarf_out_dir(split_dwarf_output_directory) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .run(); - let found_files = cwd_filenames(); - - let dwo_files = cwd_dwo_filenames(); + let mut found_files = cwd_filenames(); + found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory)); + + let dwo_files = if let Some(dwo_dir) = split_dwarf_output_directory { + dwo_out_dwo_filenames(dwo_dir) + } else { + cwd_dwo_filenames() + }; assert_eq!(dwo_files.len(), 1); - let mut expected_files = BTreeSet::new(); expected_files.extend(dwo_files); expected_files.insert("foo".to_string()); @@ -1056,14 +1115,20 @@ mod shared_linux_other_tests { rustc(unstable_options) .input("foo.rs") .split_debuginfo(split_kind.cli_value()) + .split_dwarf_out_dir(split_dwarf_output_directory) .debuginfo(level.cli_value()) .arg(format!("-Zsplit-dwarf-kind={}", split_dwarf_kind.cli_value())) .remap_path_prefix(cwd(), remapped_prefix) .run(); - let found_files = cwd_filenames(); + let mut found_files = cwd_filenames(); + found_files.append(&mut dwo_out_filenames(split_dwarf_output_directory)); - let dwo_files = cwd_dwo_filenames(); + let dwo_files = if let Some(dwo_out) = split_dwarf_output_directory { + dwo_out_dwo_filenames(dwo_out) + } else { + cwd_dwo_filenames() + }; assert_eq!(dwo_files.len(), 1); let mut expected_files = BTreeSet::new(); @@ -1358,6 +1423,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // off @@ -1370,6 +1436,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // packed-split @@ -1382,6 +1449,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // packed-single @@ -1394,6 +1462,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // packed-lto-split @@ -1406,6 +1475,7 @@ fn main() { LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // packed-lto-single @@ -1418,6 +1488,7 @@ fn main() { LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // FIXME: the remapping tests probably need to be reworked, see @@ -1433,6 +1504,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, + None, ); // packed-remapped-single @@ -1445,6 +1517,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, + None, ); // packed-remapped-scope @@ -1457,6 +1530,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("debuginfo"), + None, ); // packed-remapped-wrong-scope @@ -1469,6 +1543,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("macro"), + None, ); // packed-crosscrate-split @@ -1481,6 +1556,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // packed-crosscrate-single @@ -1493,6 +1569,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // unpacked-split @@ -1505,6 +1582,20 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, + ); + + // unpacked-split with split-dwarf-out-dir + shared_linux_other_tests::split_debuginfo( + CrossCrateTest::No, + UnstableOptions::Yes, + SplitDebuginfo::Unpacked, + DebuginfoLevel::Full, + SplitDwarfKind::Split, + LinkerPluginLto::Unspecified, + RemapPathPrefix::Unspecified, + RemapPathScope::Unspecified, + Some("other-dir"), ); // unpacked-single @@ -1517,6 +1608,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // unpacked-lto-split @@ -1529,6 +1621,7 @@ fn main() { LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // unpacked-lto-single @@ -1541,6 +1634,7 @@ fn main() { LinkerPluginLto::Yes, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); // unpacked-remapped-split @@ -1553,6 +1647,20 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, + None, + ); + + // unpacked-remapped-split with split-dwarf-out-dir + shared_linux_other_tests::split_debuginfo( + CrossCrateTest::No, + UnstableOptions::Yes, + SplitDebuginfo::Unpacked, + DebuginfoLevel::Full, + SplitDwarfKind::Split, + LinkerPluginLto::Unspecified, + RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, + RemapPathScope::Unspecified, + Some("other-dir"), ); // unpacked-remapped-single @@ -1565,6 +1673,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Unspecified, + None, ); // unpacked-remapped-scope @@ -1577,6 +1686,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("debuginfo"), + None, ); // unpacked-remapped-wrong-scope @@ -1589,6 +1699,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Yes { remapped_prefix: "/__MY_REMAPPED_PATH__" }, RemapPathScope::Yes("macro"), + None, ); // unpacked-crosscrate-split @@ -1601,6 +1712,20 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, + ); + + // unpacked-crosscrate-split with split-dwarf-out-dir + shared_linux_other_tests::split_debuginfo( + CrossCrateTest::Yes, + UnstableOptions::Yes, + SplitDebuginfo::Unpacked, + DebuginfoLevel::Full, + SplitDwarfKind::Split, + LinkerPluginLto::Unspecified, + RemapPathPrefix::Unspecified, + RemapPathScope::Unspecified, + Some("other-dir"), ); // unpacked-crosscrate-single @@ -1613,6 +1738,7 @@ fn main() { LinkerPluginLto::Unspecified, RemapPathPrefix::Unspecified, RemapPathScope::Unspecified, + None, ); } } diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index fe0f64010895c..e5c11651bd27d 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -5,7 +5,7 @@ include: "utils.goml" define-function: ( "check-search-color", [ - theme, count_color, desc_color, path_color, bottom_border_color, keyword_color, + theme, count_color, path_color, bottom_border_color, keyword_color, struct_color, associatedtype_color, tymethod_color, method_color, structfield_color, structfield_hover_color, macro_color, fn_color, hover_path_color, hover_background, attribute_color, grey @@ -21,10 +21,6 @@ define-function: ( {"color": |count_color|}, ALL, ) - assert-css: ( - "//*[@class='desc'][normalize-space()='Just a normal struct.']", - {"color": |desc_color|}, - ) assert-css: ( "//*[@class='result-name']//*[normalize-space()='test_docs::']", {"color": |path_color|}, @@ -97,16 +93,6 @@ define-function: ( ALL, ) - // Checking color and background on hover. - move-cursor-to: "//*[@class='desc'][normalize-space()='Just a normal struct.']" - assert-css: ( - "//*[@class='result-name']//*[normalize-space()='test_docs::']", - {"color": |hover_path_color|}, - ) - assert-css: ( - "//*[@class='result-name']//*[normalize-space()='test_docs::']/ancestor::a", - {"color": |hover_path_color|, "background-color": |hover_background|}, - ) } ) @@ -157,7 +143,6 @@ show-text: true call-function: ("check-search-color", { "theme": "ayu", "count_color": "#888", - "desc_color": "#c5c5c5", "path_color": "#0096cf", "bottom_border_color": "#aaa3", "keyword_color": "#39afd7", @@ -179,7 +164,6 @@ call-function: ("check-search-color", { call-function: ("check-search-color", { "theme": "dark", "count_color": "#888", - "desc_color": "#ddd", "path_color": "#ddd", "bottom_border_color": "#aaa3", "keyword_color": "#d2991d", @@ -201,7 +185,6 @@ call-function: ("check-search-color", { call-function: ("check-search-color", { "theme": "light", "count_color": "#888", - "desc_color": "#000", "path_color": "#000", "bottom_border_color": "#aaa3", "keyword_color": "#3873ad", @@ -226,12 +209,27 @@ call-function: ("perform-search", {"query": "thisisanalias"}) define-function: ( "check-alias", - [theme, alias, grey], + [theme, alias, grey, desc_color, hover_path_color, hover_background], block { call-function: ("switch-theme", {"theme": |theme|}) // Checking that the colors for the alias element are the ones expected. assert-css: (".result-name .path .alias", {"color": |alias|}) assert-css: (".result-name .path .alias > .grey", {"color": |grey|}) + assert-css: ( + "//*[@class='desc'][normalize-space()='Just a normal enum.']", + {"color": |desc_color|}, + ) + // Checking color and background on hover. + move-cursor-to: "//*[@class='desc'][normalize-space()='Just a normal enum.']" + assert-css: ( + "//*[@class='result-name']//*[normalize-space()='test_docs::']", + {"color": |hover_path_color|}, + ) + assert-css: ( + "//*[@class='result-name']//*[normalize-space()='test_docs::']/ancestor::a", + {"color": |hover_path_color|, "background-color": |hover_background|}, + ) + }, ) @@ -239,14 +237,23 @@ call-function: ("check-alias", { "theme": "ayu", "alias": "#c5c5c5", "grey": "#999", + "desc_color": "#c5c5c5", + "hover_path_color": "#fff", + "hover_background": "#3c3c3c", }) call-function: ("check-alias", { "theme": "dark", "alias": "#fff", "grey": "#ccc", + "desc_color": "#ddd", + "hover_path_color": "#ddd", + "hover_background": "#616161", }) call-function: ("check-alias", { "theme": "light", "alias": "#000", "grey": "#999", + "desc_color": "#000", + "hover_path_color": "#000", + "hover_background": "#ccc", }) diff --git a/tests/rustdoc-gui/search-tab.goml b/tests/rustdoc-gui/search-tab.goml index 00ca952033dc6..0a3cfc231e50a 100644 --- a/tests/rustdoc-gui/search-tab.goml +++ b/tests/rustdoc-gui/search-tab.goml @@ -79,7 +79,7 @@ call-function: ("check-colors", { set-window-size: (851, 600) // Check the size and count in tabs -assert-text: ("#search-tabs > button:nth-child(1) > .count", " (27) ") +assert-text: ("#search-tabs > button:nth-child(1) > .count", " (25) ") assert-text: ("#search-tabs > button:nth-child(2) > .count", " (7)  ") assert-text: ("#search-tabs > button:nth-child(3) > .count", " (0)  ") store-property: ("#search-tabs > button:nth-child(1)", {"offsetWidth": buttonWidth}) diff --git a/tests/rustdoc-gui/search-throbber.goml b/tests/rustdoc-gui/search-throbber.goml new file mode 100644 index 0000000000000..9d41f933af8c1 --- /dev/null +++ b/tests/rustdoc-gui/search-throbber.goml @@ -0,0 +1,23 @@ +// We are intentionally triggering errors for race-free throbber test +fail-on-request-error: false +fail-on-js-error: false + +// First, make sure the throbber goes away when done +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=" +wait-for: ".search-input" +wait-for-false: ".search-form.loading" +write-into: (".search-input", "test") +press-key: 'Enter' +wait-for-false: ".search-form.loading" + +// Make sure the throbber shows up if we prevent the search from +// ever finishing (this tactic is needed to make sure we don't get stuck +// with any race conditions). +go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=" +block-network-request: "*/desc/*.js" +reload: +wait-for: ".search-input" +wait-for-false: ".search-form.loading" +write-into: (".search-input", "test") +press-key: 'Enter' +wait-for: ".search-form.loading" diff --git a/tests/rustdoc-gui/search-title.goml b/tests/rustdoc-gui/search-title.goml index 83321a05f2bbb..5808ed845a3b1 100644 --- a/tests/rustdoc-gui/search-title.goml +++ b/tests/rustdoc-gui/search-title.goml @@ -20,3 +20,15 @@ assert-document-property: {"title": '"another one" Search - Rust'} press-key: "Escape" assert-document-property: {"title": |title|} + +// check that all.html does it correctly, too. +go-to: "file://" + |DOC_PATH| + "/test_docs/all.html" +assert-document-property: {"title": "List of all items in this crate"} +call-function: ("perform-search", {"query": "verify"}) +assert-document-property: {"title": '"verify" Search - Rust'} + +// check that index.html does it correctly, too. +go-to: "file://" + |DOC_PATH| + "/index.html" +assert-document-property: {"title": "Index of crates"} +call-function: ("perform-search", {"query": "verify"}) +assert-document-property: {"title": '"verify" Search - Rust'} diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 5ec0008ad8afe..0d371c8c6a46f 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -1,5 +1,7 @@ // Checks multiple things on the sidebar display (width of its elements, colors, etc). include: "utils.goml" +// Disable animations so they don't mess up color assertions later. +emulate-media-features: { "prefers-reduced-motion": "reduce" } go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" assert-property: (".sidebar", {"clientWidth": "199"}) show-text: true diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs index 8db754f91ce61..400488cbe8570 100644 --- a/tests/rustdoc-gui/src/lib2/lib.rs +++ b/tests/rustdoc-gui/src/lib2/lib.rs @@ -1,7 +1,6 @@ // ignore-tidy-linelength #![feature(doc_cfg)] -#![feature(doc_auto_cfg)] pub mod another_folder; pub mod another_mod; diff --git a/tests/rustdoc-gui/src/test_docs/lib.rs b/tests/rustdoc-gui/src/test_docs/lib.rs index 42f2fbd93b1ee..c0771583ab658 100644 --- a/tests/rustdoc-gui/src/test_docs/lib.rs +++ b/tests/rustdoc-gui/src/test_docs/lib.rs @@ -1,3 +1,4 @@ +//@ compile-flags: --enable-index-page -Z unstable-options //! The point of this crate is to be able to have enough different "kinds" of //! documentation generated so we can test each different features. #![doc(html_playground_url="https://play.rust-lang.org/")] @@ -459,10 +460,10 @@ pub fn safe_fn() {} #[repr(C)] pub struct WithGenerics { - s: S, - t: T, - e: E, - p: P, + pub s: S, + pub t: T, + pub e: E, + pub p: P, } pub struct StructWithPublicUndocumentedFields { diff --git a/tests/rustdoc-js-std/asrawfd.js b/tests/rustdoc-js-std/asrawfd.js index 5dbc4ba95d9a7..da08eeb8a53c8 100644 --- a/tests/rustdoc-js-std/asrawfd.js +++ b/tests/rustdoc-js-std/asrawfd.js @@ -1,12 +1,10 @@ // ignore-order const EXPECTED = { - 'query': 'RawFd::as_raw_fd', + 'query': 'method:RawFd::as_raw_fd', 'others': [ // Reproduction test for https://github.com/rust-lang/rust/issues/78724 // Validate that type alias methods get the correct path. - { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, { 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' }, ], }; diff --git a/tests/rustdoc-js-std/bufread-fill-buf.js b/tests/rustdoc-js-std/bufread-fill-buf.js deleted file mode 100644 index 6b9309f686408..0000000000000 --- a/tests/rustdoc-js-std/bufread-fill-buf.js +++ /dev/null @@ -1,16 +0,0 @@ -// ignore-order - -const EXPECTED = [ - { - 'query': 'bufread -> result<[u8]>', - 'others': [ - { 'path': 'std::boxed::Box', 'name': 'fill_buf' }, - ], - }, - { - 'query': 'split -> option>>', - 'others': [ - { 'path': 'std::io::Split', 'name': 'next' }, - ], - }, -]; diff --git a/tests/rustdoc-js-std/parser-errors.js b/tests/rustdoc-js-std/parser-errors.js index 6e11dda8532fa..612118607b5cc 100644 --- a/tests/rustdoc-js-std/parser-errors.js +++ b/tests/rustdoc-js-std/parser-errors.js @@ -165,7 +165,7 @@ const PARSED = [ foundElems: 0, userQuery: "_:", returned: [], - error: "Unexpected `_` (not a valid identifier)", + error: "Unexpected `_` in type filter (before `:`)", }, { query: "ab:", diff --git a/tests/rustdoc-js-std/quoted.js b/tests/rustdoc-js-std/quoted.js index 8a9275019255c..a8ca6521208ef 100644 --- a/tests/rustdoc-js-std/quoted.js +++ b/tests/rustdoc-js-std/quoted.js @@ -1,21 +1,21 @@ +// make sure quoted search works both for items and and without generics // ignore-order const FILTER_CRATE = 'std'; const EXPECTED = { - 'query': '"error"', + 'query': '"result"', 'others': [ - { 'path': 'std', 'name': 'error' }, - { 'path': 'std::fmt', 'name': 'Error' }, - { 'path': 'std::io', 'name': 'Error' }, + { 'path': 'std', 'name': 'result' }, + { 'path': 'std::result', 'name': 'Result' }, + { 'path': 'std::fmt', 'name': 'Result' }, ], 'in_args': [ - { 'path': 'std::fmt::Error', 'name': 'eq' }, - { 'path': 'std::fmt::Error', 'name': 'cmp' }, - { 'path': 'std::fmt::Error', 'name': 'partial_cmp' }, - + { 'path': 'std::result::Result', 'name': 'branch' }, + { 'path': 'std::result::Result', 'name': 'ok' }, + { 'path': 'std::result::Result', 'name': 'unwrap' }, ], 'returned': [ - { 'path': 'std::fmt::LowerExp', 'name': 'fmt' }, + { 'path': 'std::bool', 'name': 'try_into' }, ], }; diff --git a/tests/rustdoc-js-std/search-by-number.js b/tests/rustdoc-js-std/search-by-number.js new file mode 100644 index 0000000000000..9d1cb5314dcaa --- /dev/null +++ b/tests/rustdoc-js-std/search-by-number.js @@ -0,0 +1,19 @@ +// regression test for https://github.com/rust-lang/rust/issues/147763 +// +// identifiers in search queries should not be required to follow the +// same strict rules around ID_Start that identifers in rust code follow, +// as searches frequently use substrings of identifers. +// +// for example, identifiers cannot start with digits, +// but they can contain them, so we allow search idents to start with digits. + +const EXPECTED = { + 'query': '8', + 'others': [ + { + 'path': 'std', + 'name': 'i8', + 'href': '../std/primitive.i8.html', + }, + ] +}; diff --git a/tests/rustdoc-js-std/trait-unbox.js b/tests/rustdoc-js-std/trait-unbox.js new file mode 100644 index 0000000000000..44ddc0c1e75ce --- /dev/null +++ b/tests/rustdoc-js-std/trait-unbox.js @@ -0,0 +1,16 @@ +// make sure type-based searches with traits get unboxed too + +const EXPECTED = [ + { + 'query': 'any -> result', + 'others': [ + { 'path': 'std::boxed::Box', 'name': 'downcast' }, + ], + }, + { + 'query': 'split -> option>>', + 'others': [ + { 'path': 'std::io::Split', 'name': 'next' }, + ], + }, +]; diff --git a/tests/rustdoc-js/trait-methods.js b/tests/rustdoc-js/trait-methods.js index dafad5e43784f..083e52439f4ae 100644 --- a/tests/rustdoc-js/trait-methods.js +++ b/tests/rustdoc-js/trait-methods.js @@ -9,4 +9,24 @@ const EXPECTED = [ { 'path': 'trait_methods::MyTrait', 'name': 'next' }, ], }, + // the traitParent deduplication pass should remove + // Empty::next, as it would be redundant + { + 'query': 'next', + 'correction': null, + 'in_args': [], + 'others': [ + { 'path': 'trait_methods::MyTrait', 'name': 'next' }, + ], + }, + // if the trait does not match, no deduplication happens + { + 'query': '-> option<()>', + 'correction': null, + 'in_args': [], + 'others': [ + { 'path': 'trait_methods::Empty', 'name': 'next' }, + { 'path': 'trait_methods::Void', 'name': 'next' }, + ], + }, ]; diff --git a/tests/rustdoc-js/trait-methods.rs b/tests/rustdoc-js/trait-methods.rs index c88f5edfd55b7..a741b361a3392 100644 --- a/tests/rustdoc-js/trait-methods.rs +++ b/tests/rustdoc-js/trait-methods.rs @@ -2,3 +2,21 @@ pub trait MyTrait { type Item; fn next(&mut self) -> Option; } + +pub struct Empty; + +impl MyTrait for Empty { + type Item = (); + fn next(&mut self) -> Option<()> { + None + } +} + +pub struct Void; + +impl MyTrait for Void { + type Item = (); + fn next(&mut self) -> Option<()> { + Some(()) + } +} diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.rs b/tests/rustdoc-ui/cfg-hide-show-conflict.rs new file mode 100644 index 0000000000000..8e98b95c85bb9 --- /dev/null +++ b/tests/rustdoc-ui/cfg-hide-show-conflict.rs @@ -0,0 +1,3 @@ +#![feature(doc_cfg)] +#![doc(auto_cfg(hide(target_os = "linux")))] +#![doc(auto_cfg(show(windows, target_os = "linux")))] //~ ERROR diff --git a/tests/rustdoc-ui/cfg-hide-show-conflict.stderr b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr new file mode 100644 index 0000000000000..22231e82cd7bf --- /dev/null +++ b/tests/rustdoc-ui/cfg-hide-show-conflict.stderr @@ -0,0 +1,14 @@ +error: same `cfg` was in `auto_cfg(hide(...))` and `auto_cfg(show(...))` on the same item + --> $DIR/cfg-hide-show-conflict.rs:3:31 + | +LL | #![doc(auto_cfg(show(windows, target_os = "linux")))] + | ^^^^^^^^^^^^^^^^^^^ + | +note: first change was here + --> $DIR/cfg-hide-show-conflict.rs:2:22 + | +LL | #![doc(auto_cfg(hide(target_os = "linux")))] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.rs b/tests/rustdoc-ui/doc-alias-assoc-const.rs index d95324734be47..cbbc3fe4e21f3 100644 --- a/tests/rustdoc-ui/doc-alias-assoc-const.rs +++ b/tests/rustdoc-ui/doc-alias-assoc-const.rs @@ -1,5 +1,3 @@ -#![feature(trait_alias)] - pub struct Foo; pub trait Bar { diff --git a/tests/rustdoc-ui/doc-alias-assoc-const.stderr b/tests/rustdoc-ui/doc-alias-assoc-const.stderr index cd3ad4ab393a5..cc628c39400b1 100644 --- a/tests/rustdoc-ui/doc-alias-assoc-const.stderr +++ b/tests/rustdoc-ui/doc-alias-assoc-const.stderr @@ -1,5 +1,5 @@ error: `#[doc(alias = "...")]` isn't allowed on associated constant in trait implementation block - --> $DIR/doc-alias-assoc-const.rs:10:11 + --> $DIR/doc-alias-assoc-const.rs:8:11 | LL | #[doc(alias = "CONST_BAZ")] | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/rustdoc-ui/doc-cfg.rs b/tests/rustdoc-ui/doc-cfg.rs index 14943bbc3418e..d72643e23556b 100644 --- a/tests/rustdoc-ui/doc-cfg.rs +++ b/tests/rustdoc-ui/doc-cfg.rs @@ -8,4 +8,15 @@ //~^^ WARN unexpected `cfg` condition name: `bar` #[doc(cfg())] //~ ERROR #[doc(cfg(foo, bar))] //~ ERROR +#[doc(auto_cfg(42))] //~ ERROR +#[doc(auto_cfg(hide(true)))] //~ ERROR +#[doc(auto_cfg(hide(42)))] //~ ERROR +#[doc(auto_cfg(hide("a")))] //~ ERROR +#[doc(auto_cfg(hide(foo::bar)))] //~ ERROR +#[doc(auto_cfg = 42)] //~ ERROR +#[doc(auto_cfg = "a")] //~ ERROR +// Shouldn't lint +#[doc(auto_cfg(hide(windows)))] +#[doc(auto_cfg(hide(feature = "windows")))] +#[doc(auto_cfg(hide(foo)))] pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg.stderr b/tests/rustdoc-ui/doc-cfg.stderr index 1233ee010de21..49e8c324facfd 100644 --- a/tests/rustdoc-ui/doc-cfg.stderr +++ b/tests/rustdoc-ui/doc-cfg.stderr @@ -1,26 +1,46 @@ -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:3:7 +error: only `hide` or `show` are allowed in `#[doc(auto_cfg(...))]` + --> $DIR/doc-cfg.rs:11:7 | -LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` +LL | #[doc(auto_cfg(42))] + | ^^^^^^^^^^^^ + | + = note: `#[deny(invalid_doc_attributes)]` on by default -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:3:23 +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg.rs:12:21 | -LL | #[doc(cfg(), cfg(foo, bar))] - | ^^^ +LL | #[doc(auto_cfg(hide(true)))] + | ^^^^ -error: `cfg` predicate is not specified - --> $DIR/doc-cfg.rs:9:7 +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg.rs:13:21 | -LL | #[doc(cfg())] - | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` +LL | #[doc(auto_cfg(hide(42)))] + | ^^ -error: multiple `cfg` predicates are specified - --> $DIR/doc-cfg.rs:10:16 +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg.rs:14:21 | -LL | #[doc(cfg(foo, bar))] - | ^^^ +LL | #[doc(auto_cfg(hide("a")))] + | ^^^ + +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc-cfg.rs:15:21 + | +LL | #[doc(auto_cfg(hide(foo::bar)))] + | ^^^^^^^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg.rs:16:7 + | +LL | #[doc(auto_cfg = 42)] + | ^^^^^^^^^^^^^ + +error: expected boolean for `#[doc(auto_cfg = ...)]` + --> $DIR/doc-cfg.rs:17:7 + | +LL | #[doc(auto_cfg = "a")] + | ^^^^^^^^^^^^^^ warning: unexpected `cfg` condition name: `foo` --> $DIR/doc-cfg.rs:6:11 @@ -42,5 +62,29 @@ LL | #[doc(cfg(foo), cfg(bar))] = help: to expect this configuration use `--check-cfg=cfg(bar)` = note: see for more information about checking conditional configuration -error: aborting due to 4 previous errors; 2 warnings emitted +error: `cfg` predicate is not specified + --> $DIR/doc-cfg.rs:3:7 + | +LL | #[doc(cfg(), cfg(foo, bar))] + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/doc-cfg.rs:3:23 + | +LL | #[doc(cfg(), cfg(foo, bar))] + | ^^^ + +error: `cfg` predicate is not specified + --> $DIR/doc-cfg.rs:9:7 + | +LL | #[doc(cfg())] + | ^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/doc-cfg.rs:10:16 + | +LL | #[doc(cfg(foo, bar))] + | ^^^ + +error: aborting due to 11 previous errors; 2 warnings emitted diff --git a/tests/rustdoc-ui/doctest/check-attr-test.rs b/tests/rustdoc-ui/doctest/check-attr-test.rs index 81281db624b3d..d69dae63860ee 100644 --- a/tests/rustdoc-ui/doctest/check-attr-test.rs +++ b/tests/rustdoc-ui/doctest/check-attr-test.rs @@ -2,6 +2,9 @@ #![deny(rustdoc::invalid_codeblock_attributes)] +//~vvv ERROR unknown attribute `compile-fail` +//~| ERROR unknown attribute `compilefail` +//~| ERROR unknown attribute `comPile_fail` /// foo /// /// ```compile-fail,compilefail,comPile_fail @@ -9,6 +12,9 @@ /// ``` pub fn foo() {} +//~vvv ERROR unknown attribute `should-panic` +//~| ERROR unknown attribute `shouldpanic` +//~| ERROR unknown attribute `shOuld_panic` /// bar /// /// ```should-panic,shouldpanic,shOuld_panic @@ -16,6 +22,9 @@ pub fn foo() {} /// ``` pub fn bar() {} +//~vvv ERROR unknown attribute `no-run` +//~| ERROR unknown attribute `norun` +//~| ERROR unknown attribute `nO_run` /// foobar /// /// ```no-run,norun,nO_run @@ -23,6 +32,9 @@ pub fn bar() {} /// ``` pub fn foobar() {} +//~vvv ERROR unknown attribute `test-harness` +//~| ERROR unknown attribute `testharness` +//~| ERROR unknown attribute `tesT_harness` /// b /// /// ```test-harness,testharness,tesT_harness diff --git a/tests/rustdoc-ui/doctest/check-attr-test.stderr b/tests/rustdoc-ui/doctest/check-attr-test.stderr index 257136d1633d3..1fc7ab592de0c 100644 --- a/tests/rustdoc-ui/doctest/check-attr-test.stderr +++ b/tests/rustdoc-ui/doctest/check-attr-test.stderr @@ -1,159 +1,159 @@ error: unknown attribute `compile-fail` - --> $DIR/check-attr-test.rs:5:1 - | -5 | / /// foo -6 | | /// -7 | | /// ```compile-fail,compilefail,comPile_fail -8 | | /// boo -9 | | /// ``` - | |_______^ - | - = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can - = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + --> $DIR/check-attr-test.rs:8:1 + | +LL | / /// foo +LL | | /// +LL | | /// ```compile-fail,compilefail,comPile_fail +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` note: the lint level is defined here - --> $DIR/check-attr-test.rs:3:9 - | -3 | #![deny(rustdoc::invalid_codeblock_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + --> $DIR/check-attr-test.rs:3:9 + | +LL | #![deny(rustdoc::invalid_codeblock_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unknown attribute `compilefail` - --> $DIR/check-attr-test.rs:5:1 - | -5 | / /// foo -6 | | /// -7 | | /// ```compile-fail,compilefail,comPile_fail -8 | | /// boo -9 | | /// ``` - | |_______^ - | - = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can - = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + --> $DIR/check-attr-test.rs:8:1 + | +LL | / /// foo +LL | | /// +LL | | /// ```compile-fail,compilefail,comPile_fail +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `comPile_fail` - --> $DIR/check-attr-test.rs:5:1 - | -5 | / /// foo -6 | | /// -7 | | /// ```compile-fail,compilefail,comPile_fail -8 | | /// boo -9 | | /// ``` - | |_______^ - | - = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can - = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` + --> $DIR/check-attr-test.rs:8:1 + | +LL | / /// foo +LL | | /// +LL | | /// ```compile-fail,compilefail,comPile_fail +LL | | /// boo +LL | | /// ``` + | |_______^ + | + = help: use `compile_fail` to invert the results of this test, so that it passes if it cannot be compiled and fails if it can + = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `should-panic` - --> $DIR/check-attr-test.rs:12:1 + --> $DIR/check-attr-test.rs:18:1 | -12 | / /// bar -13 | | /// -14 | | /// ```should-panic,shouldpanic,shOuld_panic -15 | | /// boo -16 | | /// ``` +LL | / /// bar +LL | | /// +LL | | /// ```should-panic,shouldpanic,shOuld_panic +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `shouldpanic` - --> $DIR/check-attr-test.rs:12:1 + --> $DIR/check-attr-test.rs:18:1 | -12 | / /// bar -13 | | /// -14 | | /// ```should-panic,shouldpanic,shOuld_panic -15 | | /// boo -16 | | /// ``` +LL | / /// bar +LL | | /// +LL | | /// ```should-panic,shouldpanic,shOuld_panic +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `shOuld_panic` - --> $DIR/check-attr-test.rs:12:1 + --> $DIR/check-attr-test.rs:18:1 | -12 | / /// bar -13 | | /// -14 | | /// ```should-panic,shouldpanic,shOuld_panic -15 | | /// boo -16 | | /// ``` +LL | / /// bar +LL | | /// +LL | | /// ```should-panic,shouldpanic,shOuld_panic +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `should_panic` to invert the results of this test, so that if passes if it panics and fails if it does not = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `no-run` - --> $DIR/check-attr-test.rs:19:1 + --> $DIR/check-attr-test.rs:28:1 | -19 | / /// foobar -20 | | /// -21 | | /// ```no-run,norun,nO_run -22 | | /// boo -23 | | /// ``` +LL | / /// foobar +LL | | /// +LL | | /// ```no-run,norun,nO_run +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `no_run` to compile, but not run, the code sample during testing = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `norun` - --> $DIR/check-attr-test.rs:19:1 + --> $DIR/check-attr-test.rs:28:1 | -19 | / /// foobar -20 | | /// -21 | | /// ```no-run,norun,nO_run -22 | | /// boo -23 | | /// ``` +LL | / /// foobar +LL | | /// +LL | | /// ```no-run,norun,nO_run +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `no_run` to compile, but not run, the code sample during testing = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `nO_run` - --> $DIR/check-attr-test.rs:19:1 + --> $DIR/check-attr-test.rs:28:1 | -19 | / /// foobar -20 | | /// -21 | | /// ```no-run,norun,nO_run -22 | | /// boo -23 | | /// ``` +LL | / /// foobar +LL | | /// +LL | | /// ```no-run,norun,nO_run +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `no_run` to compile, but not run, the code sample during testing = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `test-harness` - --> $DIR/check-attr-test.rs:26:1 + --> $DIR/check-attr-test.rs:38:1 | -26 | / /// b -27 | | /// -28 | | /// ```test-harness,testharness,tesT_harness -29 | | /// boo -30 | | /// ``` +LL | / /// b +LL | | /// +LL | | /// ```test-harness,testharness,tesT_harness +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `testharness` - --> $DIR/check-attr-test.rs:26:1 + --> $DIR/check-attr-test.rs:38:1 | -26 | / /// b -27 | | /// -28 | | /// ```test-harness,testharness,tesT_harness -29 | | /// boo -30 | | /// ``` +LL | / /// b +LL | | /// +LL | | /// ```test-harness,testharness,tesT_harness +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function = help: this code block may be skipped during testing, because unknown attributes are treated as markers for code samples written in other programming languages, unless it is also explicitly marked as `rust` error: unknown attribute `tesT_harness` - --> $DIR/check-attr-test.rs:26:1 + --> $DIR/check-attr-test.rs:38:1 | -26 | / /// b -27 | | /// -28 | | /// ```test-harness,testharness,tesT_harness -29 | | /// boo -30 | | /// ``` +LL | / /// b +LL | | /// +LL | | /// ```test-harness,testharness,tesT_harness +LL | | /// boo +LL | | /// ``` | |_______^ | = help: use `test_harness` to run functions marked `#[test]` instead of a potentially-implicit `main` function diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout index 0e2e30390ad93..2ff7174577e87 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout +++ b/tests/rustdoc-ui/doctest/doctest-output.edition2015.stdout @@ -1,8 +1,8 @@ running 3 tests -test $DIR/doctest-output.rs - (line 12) ... ok -test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok -test $DIR/doctest-output.rs - foo::bar (line 22) ... ok +test $DIR/doctest-output.rs - (line 14) ... ok +test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok +test $DIR/doctest-output.rs - foo::bar (line 24) ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout index 0e2e30390ad93..20bfd7e7086eb 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout +++ b/tests/rustdoc-ui/doctest/doctest-output.edition2024.stdout @@ -1,8 +1,9 @@ running 3 tests -test $DIR/doctest-output.rs - (line 12) ... ok -test $DIR/doctest-output.rs - ExpandedStruct (line 28) ... ok -test $DIR/doctest-output.rs - foo::bar (line 22) ... ok +test $DIR/doctest-output.rs - (line 14) ... ok +test $DIR/doctest-output.rs - ExpandedStruct (line 30) ... ok +test $DIR/doctest-output.rs - foo::bar (line 24) ... ok test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/doctest-output.rs b/tests/rustdoc-ui/doctest/doctest-output.rs index 04bd1813b4c81..943f59e8b1565 100644 --- a/tests/rustdoc-ui/doctest/doctest-output.rs +++ b/tests/rustdoc-ui/doctest/doctest-output.rs @@ -7,6 +7,8 @@ //@[edition2024]compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" //@ check-pass //! ``` diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs index ca5dd78746789..05e4a348d1190 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.rs @@ -9,6 +9,7 @@ /// /// /// ```rust +//~^ WARN the `main` function of this doctest won't be run /// struct S {}; /// /// fn main() { diff --git a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr index 113fb7ccb60ee..cffda43ba1c94 100644 --- a/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr +++ b/tests/rustdoc-ui/doctest/failed-doctest-extra-semicolon-on-item.stderr @@ -1,7 +1,7 @@ warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function --> $DIR/failed-doctest-extra-semicolon-on-item.rs:11:1 | -11 | /// ```rust +LL | /// ```rust | ^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.rs b/tests/rustdoc-ui/doctest/main-alongside-stmts.rs index 5965f928cdd13..595de13393293 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-stmts.rs +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.rs @@ -14,6 +14,7 @@ //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass +//~v WARN the `main` function of this doctest won't be run //! ``` //! # if cfg!(miri) { return; } //! use std::ops::Deref; @@ -22,6 +23,7 @@ //! assert!(false); //! } //! ``` +//~v WARN the `main` function of this doctest won't be run //! //! ``` //! let x = 2; diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr b/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr index d90a289ca6989..b7a5421f8f737 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.stderr @@ -1,14 +1,14 @@ warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function - --> $DIR/main-alongside-stmts.rs:17:1 + --> $DIR/main-alongside-stmts.rs:18:1 | -17 | //! ``` +LL | //! ``` | ^^^^^^^ warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function - --> $DIR/main-alongside-stmts.rs:26:1 + --> $DIR/main-alongside-stmts.rs:27:1 | -26 | //! ``` - | ^^^^^^^ +LL | //! + | ^^^ warning: 2 warnings emitted diff --git a/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout b/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout index 9b9a3fe8a68f7..bebaeb49c5a90 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout +++ b/tests/rustdoc-ui/doctest/main-alongside-stmts.stdout @@ -1,7 +1,7 @@ running 2 tests -test $DIR/main-alongside-stmts.rs - (line 17) ... ok -test $DIR/main-alongside-stmts.rs - (line 26) ... ok +test $DIR/main-alongside-stmts.rs - (line 18) ... ok +test $DIR/main-alongside-stmts.rs - (line 27) ... ok test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs index 7dac64e6de420..f92bea74bfef4 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.rs @@ -2,6 +2,8 @@ //@ compile-flags:--test --test-args=--test-threads=1 //@ normalize-stdout: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout: "ran in \d+\.\d+s" -> "ran in $$TIME" +//@ normalize-stdout: "compilation took \d+\.\d+s" -> "compilation took $$TIME" //@ check-pass /// ```ignore (test) diff --git a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout index a32da0aeb9649..6714cdb0b8098 100644 --- a/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout +++ b/tests/rustdoc-ui/doctest/merged-ignore-no_run.stdout @@ -1,7 +1,8 @@ running 2 tests -test $DIR/merged-ignore-no_run.rs - ignored (line 7) ... ignored -test $DIR/merged-ignore-no_run.rs - no_run (line 12) - compile ... ok +test $DIR/merged-ignore-no_run.rs - ignored (line 9) ... ignored +test $DIR/merged-ignore-no_run.rs - no_run (line 14) - compile ... ok test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in $TIME +all doctests ran in $TIME; merged doctests compilation took $TIME diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs index c53a8b48749ce..3bb0083d849ff 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.rs +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.rs @@ -9,6 +9,8 @@ #![deny(warnings)] //! ```standalone +//~^ ERROR unknown attribute `standalone` +//~| ERROR unknown attribute `standalone-crate` //! bla //! ``` //! diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr index ce65557c2c4a4..db0d53a204ced 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr @@ -1,13 +1,13 @@ error: unknown attribute `standalone` --> $DIR/standalone-warning-2024.rs:11:1 | -11 | / //! ```standalone -12 | | //! bla -13 | | //! ``` -14 | | //! -15 | | //! ```standalone-crate -16 | | //! bla -17 | | //! ``` +LL | / //! ```standalone +LL | | +LL | | +LL | | //! bla +... | +LL | | //! bla +LL | | //! ``` | |_______^ | = help: use `standalone_crate` to compile this code block separately @@ -15,20 +15,20 @@ error: unknown attribute `standalone` note: the lint level is defined here --> $DIR/standalone-warning-2024.rs:9:9 | - 9 | #![deny(warnings)] +LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(warnings)]` error: unknown attribute `standalone-crate` --> $DIR/standalone-warning-2024.rs:11:1 | -11 | / //! ```standalone -12 | | //! bla -13 | | //! ``` -14 | | //! -15 | | //! ```standalone-crate -16 | | //! bla -17 | | //! ``` +LL | / //! ```standalone +LL | | +LL | | +LL | | //! bla +... | +LL | | //! bla +LL | | //! ``` | |_______^ | = help: use `standalone_crate` to compile this code block separately diff --git a/tests/rustdoc-ui/doctest/test-compile-fail1.rs b/tests/rustdoc-ui/doctest/test-compile-fail1.rs index 278f01f4c8389..c692c4c61bcce 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail1.rs +++ b/tests/rustdoc-ui/doctest/test-compile-fail1.rs @@ -6,3 +6,4 @@ pub fn f() {} pub fn f() {} +//~^ ERROR the name `f` is defined multiple times diff --git a/tests/rustdoc-ui/doctest/test-compile-fail1.stderr b/tests/rustdoc-ui/doctest/test-compile-fail1.stderr index 02f4d8d754f9b..aa5cc2e14d6d6 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail1.stderr +++ b/tests/rustdoc-ui/doctest/test-compile-fail1.stderr @@ -1,13 +1,13 @@ error[E0428]: the name `f` is defined multiple times - --> $DIR/test-compile-fail1.rs:8:1 - | -6 | pub fn f() {} - | ---------- previous definition of the value `f` here -7 | -8 | pub fn f() {} - | ^^^^^^^^^^ `f` redefined here - | - = note: `f` must be defined only once in the value namespace of this module + --> $DIR/test-compile-fail1.rs:8:1 + | +LL | pub fn f() {} + | ---------- previous definition of the value `f` here +LL | +LL | pub fn f() {} + | ^^^^^^^^^^ `f` redefined here + | + = note: `f` must be defined only once in the value namespace of this module error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doctest/test-compile-fail2.rs b/tests/rustdoc-ui/doctest/test-compile-fail2.rs index 7432cc9f8263b..8239440262d81 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail2.rs +++ b/tests/rustdoc-ui/doctest/test-compile-fail2.rs @@ -1,3 +1,4 @@ //@ compile-flags:--test fail +//~^ ERROR diff --git a/tests/rustdoc-ui/doctest/test-compile-fail2.stderr b/tests/rustdoc-ui/doctest/test-compile-fail2.stderr index f0ad40eb6ca81..9f50c857275c6 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail2.stderr +++ b/tests/rustdoc-ui/doctest/test-compile-fail2.stderr @@ -1,8 +1,8 @@ error: expected one of `!` or `::`, found `` - --> $DIR/test-compile-fail2.rs:3:1 - | -3 | fail - | ^^^^ expected one of `!` or `::` + --> $DIR/test-compile-fail2.rs:3:1 + | +LL | fail + | ^^^^ expected one of `!` or `::` error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doctest/test-compile-fail3.rs b/tests/rustdoc-ui/doctest/test-compile-fail3.rs index a2486d9dc6f22..272ba95396c6d 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail3.rs +++ b/tests/rustdoc-ui/doctest/test-compile-fail3.rs @@ -1,3 +1,4 @@ //@ compile-flags:--test "fail +//~^ ERROR diff --git a/tests/rustdoc-ui/doctest/test-compile-fail3.stderr b/tests/rustdoc-ui/doctest/test-compile-fail3.stderr index 09d78b2f34673..8061097e73acd 100644 --- a/tests/rustdoc-ui/doctest/test-compile-fail3.stderr +++ b/tests/rustdoc-ui/doctest/test-compile-fail3.stderr @@ -1,8 +1,9 @@ error[E0765]: unterminated double quote string - --> $DIR/test-compile-fail3.rs:3:1 - | -3 | "fail - | ^^^^^ + --> $DIR/test-compile-fail3.rs:3:1 + | +LL | / "fail +LL | | + | |___________^ error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/doctest/unstable-opts-143930.rs b/tests/rustdoc-ui/doctest/unstable-opts-143930.rs new file mode 100644 index 0000000000000..30c47f5b7e9e3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unstable-opts-143930.rs @@ -0,0 +1,14 @@ +// This test verifies that unstable options like `-Zcrate-attr` are respected when `--test` is +// passed. +// +// +// +// NOTE: If any of these command line arguments or features get stabilized, please replace with +// another unstable one. + +//@ check-pass +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ compile-flags: --test -Zcrate-attr=feature(register_tool) -Zcrate-attr=register_tool(rapx) + +#[rapx::tag] +fn f() {} diff --git a/tests/rustdoc-ui/doctest/unstable-opts-143930.stdout b/tests/rustdoc-ui/doctest/unstable-opts-143930.stdout new file mode 100644 index 0000000000000..7326c0a25a069 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unstable-opts-143930.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/unstable-opts-147276.crate_attr.stdout b/tests/rustdoc-ui/doctest/unstable-opts-147276.crate_attr.stdout new file mode 100644 index 0000000000000..7326c0a25a069 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unstable-opts-147276.crate_attr.stdout @@ -0,0 +1,5 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/doctest/unstable-opts-147276.normal.stderr b/tests/rustdoc-ui/doctest/unstable-opts-147276.normal.stderr new file mode 100644 index 0000000000000..eebf4f307f127 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unstable-opts-147276.normal.stderr @@ -0,0 +1,13 @@ +error[E0658]: `#[used(linker)]` is currently unstable + --> $DIR/unstable-opts-147276.rs:15:1 + | +LL | #[used(linker)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #93798 for more information + = help: add `#![feature(used_with_arg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/doctest/unstable-opts-147276.rs b/tests/rustdoc-ui/doctest/unstable-opts-147276.rs new file mode 100644 index 0000000000000..64cafcaaff4e3 --- /dev/null +++ b/tests/rustdoc-ui/doctest/unstable-opts-147276.rs @@ -0,0 +1,17 @@ +// This test verifies that unstable options like `-Zcrate-attr` are respected when `--test` is +// passed. +// +// +// +// NOTE: If any of these command line arguments or features get stabilized, please replace with +// another unstable one. + +//@ revisions: normal crate_attr +//@ compile-flags: --test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" +//@[crate_attr] check-pass +//@[crate_attr] compile-flags: -Zcrate-attr=feature(used_with_arg) + +#[used(linker)] +//[normal]~^ ERROR `#[used(linker)]` is currently unstable +static REPRO: isize = 1; diff --git a/tests/rustdoc-ui/doctest/warn-main-not-called.rs b/tests/rustdoc-ui/doctest/warn-main-not-called.rs index 25d92e9cee9f4..ec762486d5d42 100644 --- a/tests/rustdoc-ui/doctest/warn-main-not-called.rs +++ b/tests/rustdoc-ui/doctest/warn-main-not-called.rs @@ -8,6 +8,7 @@ // won't be called. //! ``` +//~^ WARN the `main` function of this doctest won't be run //! macro_rules! bla { //! ($($x:tt)*) => {} //! } @@ -17,6 +18,7 @@ //! ``` //! //! ``` +//~^^ WARN the `main` function of this doctest won't be run //! let x = 12; //! fn main() {} //! ``` diff --git a/tests/rustdoc-ui/doctest/warn-main-not-called.stderr b/tests/rustdoc-ui/doctest/warn-main-not-called.stderr index 3a079f47555b6..5feca6f9175fe 100644 --- a/tests/rustdoc-ui/doctest/warn-main-not-called.stderr +++ b/tests/rustdoc-ui/doctest/warn-main-not-called.stderr @@ -1,14 +1,14 @@ warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function --> $DIR/warn-main-not-called.rs:10:1 | -10 | //! ``` +LL | //! ``` | ^^^^^^^ warning: the `main` function of this doctest won't be run as it contains expressions at the top level, meaning that the whole doctest code will be wrapped in a function --> $DIR/warn-main-not-called.rs:19:1 | -19 | //! ``` - | ^^^^^^^ +LL | //! + | ^^^ warning: 2 warnings emitted diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg.rs b/tests/rustdoc-ui/feature-gate-doc_cfg.rs new file mode 100644 index 0000000000000..b474a1524bc19 --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-doc_cfg.rs @@ -0,0 +1,6 @@ +#![doc(auto_cfg)] //~ ERROR +#![doc(auto_cfg(false))] //~ ERROR +#![doc(auto_cfg(true))] //~ ERROR +#![doc(auto_cfg(hide(feature = "solecism")))] //~ ERROR +#![doc(auto_cfg(show(feature = "bla")))] //~ ERROR +#![doc(cfg(feature = "solecism"))] //~ ERROR diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg.stderr b/tests/rustdoc-ui/feature-gate-doc_cfg.stderr new file mode 100644 index 0000000000000..68a86c1abb777 --- /dev/null +++ b/tests/rustdoc-ui/feature-gate-doc_cfg.stderr @@ -0,0 +1,63 @@ +error[E0658]: `#[doc(auto_cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:1:1 + | +LL | #![doc(auto_cfg)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[doc(auto_cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:2:1 + | +LL | #![doc(auto_cfg(false))] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[doc(auto_cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:3:1 + | +LL | #![doc(auto_cfg(true))] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[doc(auto_cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:4:1 + | +LL | #![doc(auto_cfg(hide(feature = "solecism")))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[doc(auto_cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:5:1 + | +LL | #![doc(auto_cfg(show(feature = "bla")))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `#[doc(cfg)]` is experimental + --> $DIR/feature-gate-doc_cfg.rs:6:1 + | +LL | #![doc(cfg(feature = "solecism"))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #43781 for more information + = help: add `#![feature(doc_cfg)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs deleted file mode 100644 index 17812018b9b7a..0000000000000 --- a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![doc(cfg_hide(test))] -//~^ ERROR `#[doc(cfg_hide)]` is experimental - -#[cfg(not(test))] -pub fn public_fn() {} -#[cfg(test)] -pub fn internal_use_only() {} diff --git a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr b/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr deleted file mode 100644 index 55135986ffe76..0000000000000 --- a/tests/rustdoc-ui/feature-gate-doc_cfg_hide.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0658]: `#[doc(cfg_hide)]` is experimental - --> $DIR/feature-gate-doc_cfg_hide.rs:1:1 - | -LL | #![doc(cfg_hide(test))] - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #43781 for more information - = help: add `#![feature(doc_cfg_hide)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc-ui/intra-doc/hidden-check.rs b/tests/rustdoc-ui/intra-doc/hidden-check.rs new file mode 100644 index 0000000000000..db2a6dd1dbda2 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/hidden-check.rs @@ -0,0 +1,14 @@ +// This test ensures that `doc(hidden)` items intra-doc links are checked whereas private +// items are ignored. + +//@ compile-flags: -Zunstable-options --document-hidden-items + +#![deny(rustdoc::broken_intra_doc_links)] + +/// [not::exist] +//~^ ERROR unresolved link to `not::exist` +#[doc(hidden)] +pub struct X; + +/// [not::exist] +struct Y; diff --git a/tests/rustdoc-ui/intra-doc/hidden-check.stderr b/tests/rustdoc-ui/intra-doc/hidden-check.stderr new file mode 100644 index 0000000000000..4fffb80106405 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/hidden-check.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `not::exist` + --> $DIR/hidden-check.rs:8:6 + | +LL | /// [not::exist] + | ^^^^^^^^^^ no item named `not` in scope + | +note: the lint level is defined here + --> $DIR/hidden-check.rs:6:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/private-check.rs b/tests/rustdoc-ui/intra-doc/private-check.rs new file mode 100644 index 0000000000000..2f987d1a44cf5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private-check.rs @@ -0,0 +1,14 @@ +// This test ensures that private items intra-doc links are checked whereas `doc(hidden)` +// items are ignored. + +//@ compile-flags: -Zunstable-options --document-private-items + +#![deny(rustdoc::broken_intra_doc_links)] + +/// [not::exist] +#[doc(hidden)] +pub struct X; + +/// [not::exist] +//~^ ERROR unresolved link to `not::exist` +struct Y; diff --git a/tests/rustdoc-ui/intra-doc/private-check.stderr b/tests/rustdoc-ui/intra-doc/private-check.stderr new file mode 100644 index 0000000000000..2ec162809eae7 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/private-check.stderr @@ -0,0 +1,14 @@ +error: unresolved link to `not::exist` + --> $DIR/private-check.rs:12:6 + | +LL | /// [not::exist] + | ^^^^^^^^^^ no item named `not` in scope + | +note: the lint level is defined here + --> $DIR/private-check.rs:6:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.rs b/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.rs new file mode 100644 index 0000000000000..c4527c626d9c5 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.rs @@ -0,0 +1,21 @@ +// Ensure that no warning is emitted if the disambiguator is used for type alias. +// Regression test for . + +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; + +#[allow(non_camel_case_types)] +pub type f32 = Foo; + +/// This function returns [`f32`]. +//~^ ERROR: `f32` is both a type alias and a primitive type +//~| HELP: to link to the type alias, prefix with `tyalias@` +//~| HELP: to link to the primitive type, prefix with `prim@` +pub fn my_fn() -> f32 {} + +/// This function returns [type@f32]. +//~^ ERROR: `f32` is both a type alias and a primitive type +//~| HELP: to link to the type alias, prefix with `tyalias@` +//~| HELP: to link to the primitive type, prefix with `prim@` +pub fn my_fn2() -> f32 {} diff --git a/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.stderr b/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.stderr new file mode 100644 index 0000000000000..c99e7d1d10434 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/type-alias-primitive-suggestion.stderr @@ -0,0 +1,39 @@ +error: `f32` is both a type alias and a primitive type + --> $DIR/type-alias-primitive-suggestion.rs:11:29 + | +LL | /// This function returns [`f32`]. + | ^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/type-alias-primitive-suggestion.rs:4:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the type alias, prefix with `tyalias@` + | +LL | /// This function returns [`tyalias@f32`]. + | ++++++++ +help: to link to the primitive type, prefix with `prim@` + | +LL | /// This function returns [`prim@f32`]. + | +++++ + +error: `f32` is both a type alias and a primitive type + --> $DIR/type-alias-primitive-suggestion.rs:17:28 + | +LL | /// This function returns [type@f32]. + | ^^^^^^^^ ambiguous link + | +help: to link to the type alias, prefix with `tyalias@` + | +LL - /// This function returns [type@f32]. +LL + /// This function returns [tyalias@f32]. + | +help: to link to the primitive type, prefix with `prim@` + | +LL - /// This function returns [type@f32]. +LL + /// This function returns [prim@f32]. + | + +error: aborting due to 2 previous errors + diff --git a/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs b/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs new file mode 100644 index 0000000000000..62b2c83eeca47 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/type-alias-primitive.rs @@ -0,0 +1,14 @@ +// Ensure that no warning is emitted if the disambiguator is used for type alias. +// Regression test for . + +//@ check-pass + +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; + +#[allow(non_camel_case_types)] +pub type f32 = Foo; + +/// This function returns [`tyalias@f32`] and not [`prim@f32`]. +pub fn my_fn() -> f32 {} diff --git a/tests/rustdoc-ui/invalid-cfg.rs b/tests/rustdoc-ui/invalid-cfg.rs index d237b8605c068..7e54aeea1defb 100644 --- a/tests/rustdoc-ui/invalid-cfg.rs +++ b/tests/rustdoc-ui/invalid-cfg.rs @@ -1,4 +1,21 @@ #![feature(doc_cfg)] #[doc(cfg = "x")] //~ ERROR not followed by parentheses #[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates -struct S {} +pub struct S {} + +// We check it also fails on private items. +#[doc(cfg = "x")] //~ ERROR not followed by parentheses +#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +struct X {} + +// We check it also fails on hidden items. +#[doc(cfg = "x")] //~ ERROR not followed by parentheses +#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(hidden)] +pub struct Y {} + +// We check it also fails on hidden AND private items. +#[doc(cfg = "x")] //~ ERROR not followed by parentheses +#[doc(cfg(x, y))] //~ ERROR multiple `cfg` predicates +#[doc(hidden)] +struct Z {} diff --git a/tests/rustdoc-ui/invalid-cfg.stderr b/tests/rustdoc-ui/invalid-cfg.stderr index dae238b052b8a..455626e07bd58 100644 --- a/tests/rustdoc-ui/invalid-cfg.stderr +++ b/tests/rustdoc-ui/invalid-cfg.stderr @@ -10,5 +10,41 @@ error: multiple `cfg` predicates are specified LL | #[doc(cfg(x, y))] | ^ -error: aborting due to 2 previous errors +error: `cfg` is not followed by parentheses + --> $DIR/invalid-cfg.rs:7:7 + | +LL | #[doc(cfg = "x")] + | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/invalid-cfg.rs:8:14 + | +LL | #[doc(cfg(x, y))] + | ^ + +error: `cfg` is not followed by parentheses + --> $DIR/invalid-cfg.rs:12:7 + | +LL | #[doc(cfg = "x")] + | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/invalid-cfg.rs:13:14 + | +LL | #[doc(cfg(x, y))] + | ^ + +error: `cfg` is not followed by parentheses + --> $DIR/invalid-cfg.rs:18:7 + | +LL | #[doc(cfg = "x")] + | ^^^^^^^^^ help: expected syntax is: `cfg(/* predicate */)` + +error: multiple `cfg` predicates are specified + --> $DIR/invalid-cfg.rs:19:14 + | +LL | #[doc(cfg(x, y))] + | ^ + +error: aborting due to 8 previous errors diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index 30aadfe89f424..c0cd454e8f3ad 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,11 +1,11 @@ Available passes for running rustdoc: check-doc-cfg - checks `#[doc(cfg(...))]` for stability feature and unexpected cfgs check_doc_test_visibility - run various visibility-related lints on doctests + propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items strip-aliased-non-local - strips all non-local private aliased items from the output strip-hidden - strips all `#[doc(hidden)]` items from the output strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate - propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items propagate-stability - propagates stability to child items collect-intra-doc-links - resolves intra-doc links collect-trait-impls - retrieves trait impls for items in the crate @@ -17,11 +17,11 @@ Default passes for rustdoc: check_doc_test_visibility check-doc-cfg strip-aliased-non-local + propagate-doc-cfg strip-hidden (when not --document-hidden-items) strip-private (when not --document-private-items) strip-priv-imports (when --document-private-items) collect-intra-doc-links - propagate-doc-cfg propagate-stability run-lints diff --git a/tests/rustdoc-ui/lints/check.rs b/tests/rustdoc-ui/lints/check.rs index 0943f9f6053e9..9a4cc96094108 100644 --- a/tests/rustdoc-ui/lints/check.rs +++ b/tests/rustdoc-ui/lints/check.rs @@ -2,7 +2,7 @@ //@ compile-flags: -Z unstable-options --check //@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" -#![feature(rustdoc_missing_doc_code_examples)] +#![feature(rustdoc_missing_doc_code_examples)] //~ WARN no documentation found for this crate's top-level module //~^ WARN #![warn(missing_docs)] @@ -12,5 +12,3 @@ pub fn foo() {} //~^ WARN //~^^ WARN - -//~? WARN no documentation found for this crate's top-level module diff --git a/tests/rustdoc-ui/lints/check.stderr b/tests/rustdoc-ui/lints/check.stderr index dcdf25dda649c..52c8c176084a2 100644 --- a/tests/rustdoc-ui/lints/check.stderr +++ b/tests/rustdoc-ui/lints/check.stderr @@ -22,6 +22,15 @@ LL | pub fn foo() {} | ^^^^^^^^^^^^ warning: no documentation found for this crate's top-level module + --> $DIR/check.rs:5:1 + | +LL | / #![feature(rustdoc_missing_doc_code_examples)] +LL | | +LL | | +LL | | #![warn(missing_docs)] +... | +LL | | pub fn foo() {} + | |_______________^ | = help: The following guide may be of use: https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.rs b/tests/rustdoc-ui/lints/doc_cfg_hide.rs index 9a8bce2a92aa5..397b21393e5c7 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.rs +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.rs @@ -1,7 +1,4 @@ -#![feature(doc_cfg_hide)] - -#![doc(cfg_hide = "test")] //~ ERROR -#![doc(cfg_hide)] //~ ERROR - -#[doc(cfg_hide(doc))] //~ ERROR -pub fn foo() {} +#![feature(doc_cfg)] +#![doc(auto_cfg(hide = "test"))] //~ ERROR +#![doc(auto_cfg(hide))] //~ ERROR +#![doc(auto_cfg(hide(not(windows))))] //~ ERROR diff --git a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr index 0c9d0879b0ac7..c63c8d607fa02 100644 --- a/tests/rustdoc-ui/lints/doc_cfg_hide.stderr +++ b/tests/rustdoc-ui/lints/doc_cfg_hide.stderr @@ -1,27 +1,22 @@ -error: this attribute can only be applied at the crate level - --> $DIR/doc_cfg_hide.rs:6:7 +error: `#![doc(auto_cfg(hide(...)))]` expects a list of items + --> $DIR/doc_cfg_hide.rs:2:8 | -LL | #[doc(cfg_hide(doc))] - | ^^^^^^^^^^^^^ +LL | #![doc(auto_cfg(hide = "test"))] + | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: read for more information = note: `#[deny(invalid_doc_attributes)]` on by default -help: to apply to the crate, use an inner attribute - | -LL | #![doc(cfg_hide(doc))] - | + -error: `#[doc(cfg_hide(...))]` takes a list of attributes +error: `#![doc(auto_cfg(hide(...)))]` expects a list of items --> $DIR/doc_cfg_hide.rs:3:8 | -LL | #![doc(cfg_hide = "test")] - | ^^^^^^^^^^^^^^^^^ +LL | #![doc(auto_cfg(hide))] + | ^^^^^^^^^^^^^^ -error: `#[doc(cfg_hide(...))]` takes a list of attributes - --> $DIR/doc_cfg_hide.rs:4:8 +error: `#![doc(auto_cfg(hide(...)))]` only accepts identifiers or key/value items + --> $DIR/doc_cfg_hide.rs:4:22 | -LL | #![doc(cfg_hide)] - | ^^^^^^^^ +LL | #![doc(auto_cfg(hide(not(windows))))] + | ^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs new file mode 100644 index 0000000000000..d7efc201e7e39 --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.rs @@ -0,0 +1,25 @@ +// this test ensures that bad HTML with multiline tags doesn't cause an ICE +// regression test for https://github.com/rust-lang/rust/issues/146890 +#[deny(rustdoc::invalid_html_tags)] + +/// +/// +/// +///
key +/// +/// value +/// +///
+pub fn foo() {} diff --git a/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr new file mode 100644 index 0000000000000..64a82b3a952aa --- /dev/null +++ b/tests/rustdoc-ui/lints/invalid-html-tags-ice-146890.stderr @@ -0,0 +1,38 @@ +error: unopened HTML tag `TD` + --> $DIR/invalid-html-tags-ice-146890.rs:12:5 + | +LL | /// + | |_____^ + | +note: the lint level is defined here + --> $DIR/invalid-html-tags-ice-146890.rs:3:8 + | +LL | #[deny(rustdoc::invalid_html_tags)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unopened HTML tag `TD` + --> $DIR/invalid-html-tags-ice-146890.rs:18:5 + | +LL | /// + | |_____^ + +error: unclosed HTML tag `TH` + --> $DIR/invalid-html-tags-ice-146890.rs:9:5 + | +LL | /// $DIR/invalid-html-tags-ice-146890.rs:15:5 + | +LL | /// "$$CHANNEL" -#![deny(rustdoc::missing_crate_level_docs)] +#![deny(rustdoc::missing_crate_level_docs)] //~ ERROR no documentation found for this crate's top-level module //^~ NOTE defined here pub fn foo() {} - -//~? ERROR no documentation found for this crate's top-level module diff --git a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr index 721d3662c93ba..8d2b9b4fc8e81 100644 --- a/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr +++ b/tests/rustdoc-ui/lints/no-crate-level-doc-lint.stderr @@ -1,4 +1,10 @@ error: no documentation found for this crate's top-level module + --> $DIR/no-crate-level-doc-lint.rs:2:1 + | +LL | / #![deny(rustdoc::missing_crate_level_docs)] +... | +LL | | pub fn foo() {} + | |_______________^ | = help: The following guide may be of use: https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html diff --git a/tests/rustdoc/attribute-rendering.rs b/tests/rustdoc/attribute-rendering.rs deleted file mode 100644 index fb40d0a9887cf..0000000000000 --- a/tests/rustdoc/attribute-rendering.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![crate_name = "foo"] - -//@ has 'foo/fn.f.html' -//@ has - //*[@'class="code-attribute"]' '#[unsafe(export_name = "f")]' -//@ has - //*[@'class="rust item-decl"]' 'pub fn f()' -#[unsafe(export_name = "\ -f")] -pub fn f() {} diff --git a/tests/rustdoc/attributes.rs b/tests/rustdoc/attributes.rs index 33e4e31bec6e3..429a42a7252cd 100644 --- a/tests/rustdoc/attributes.rs +++ b/tests/rustdoc/attributes.rs @@ -9,6 +9,18 @@ pub extern "C" fn f() {} #[unsafe(export_name = "bar")] pub extern "C" fn g() {} +//@ has foo/fn.escape_special.html '//*[@class="code-attribute"]' \ +// '#[unsafe(export_name = "\n\"\n")]' +#[unsafe(export_name = "\n\" +")] +pub extern "C" fn escape_special() {} + +// issue: +//@ has foo/fn.escape_html.html '//*[@class="code-attribute"]' \ +// '#[unsafe(export_name = "")]' +#[unsafe(export_name = "")] +pub extern "C" fn escape_html() {} + //@ has foo/fn.example.html '//*[@class="code-attribute"]' '#[unsafe(link_section = ".text")]' #[unsafe(link_section = ".text")] pub extern "C" fn example() {} diff --git a/tests/rustdoc/auxiliary/ext-repr.rs b/tests/rustdoc/auxiliary/ext-repr.rs new file mode 100644 index 0000000000000..25acaa49449e6 --- /dev/null +++ b/tests/rustdoc/auxiliary/ext-repr.rs @@ -0,0 +1,5 @@ +#[repr(i8)] +pub enum ReprI8 { + Var0, + Var1, +} diff --git a/tests/rustdoc/doc-auto-cfg-public-in-private.rs b/tests/rustdoc/doc-auto-cfg-public-in-private.rs new file mode 100644 index 0000000000000..b78e3f1b932c2 --- /dev/null +++ b/tests/rustdoc/doc-auto-cfg-public-in-private.rs @@ -0,0 +1,16 @@ +// This test ensures that even though private items are removed from generated docs, +// their `cfg`s will still impact their child items. + +#![feature(doc_cfg)] +#![crate_name = "foo"] + +pub struct X; + +#[cfg(not(feature = "blob"))] +fn foo() { + impl X { + //@ has 'foo/struct.X.html' + //@ has - '//*[@class="stab portability"]' 'Available on non-crate feature blob only.' + pub fn bar() {} + } +} diff --git a/tests/rustdoc/doc-auto-cfg.rs b/tests/rustdoc/doc-auto-cfg.rs index b3fe8922fd788..e56cf18d08a0c 100644 --- a/tests/rustdoc/doc-auto-cfg.rs +++ b/tests/rustdoc/doc-auto-cfg.rs @@ -1,4 +1,4 @@ -#![feature(doc_auto_cfg)] +#![feature(doc_cfg)] #![crate_name = "foo"] //@ has foo/fn.foo.html diff --git a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs index ceb1f99fae0d1..e919206d3a478 100644 --- a/tests/rustdoc/doc-cfg/doc-cfg-hide.rs +++ b/tests/rustdoc/doc-cfg/doc-cfg-hide.rs @@ -1,7 +1,7 @@ #![crate_name = "oud"] -#![feature(doc_auto_cfg, doc_cfg, doc_cfg_hide)] +#![feature(doc_cfg)] -#![doc(cfg_hide(feature = "solecism"))] +#![doc(auto_cfg(hide(feature = "solecism")))] //@ has 'oud/struct.Solecism.html' //@ count - '//*[@class="stab portability"]' 0 @@ -18,7 +18,7 @@ pub struct Scribacious; //@ has 'oud/struct.Hyperdulia.html' //@ count - '//*[@class="stab portability"]' 1 -//@ matches - '//*[@class="stab portability"]' 'crate feature hyperdulia' +//@ matches - '//*[@class="stab portability"]' 'crate features hyperdulia only' //@ compile-flags:--cfg feature="hyperdulia" #[cfg(feature = "solecism")] #[cfg(feature = "hyperdulia")] @@ -26,7 +26,7 @@ pub struct Hyperdulia; //@ has 'oud/struct.Oystercatcher.html' //@ count - '//*[@class="stab portability"]' 1 -//@ matches - '//*[@class="stab portability"]' 'crate feature oystercatcher only' +//@ matches - '//*[@class="stab portability"]' 'crate features oystercatcher only' //@ compile-flags:--cfg feature="oystercatcher" #[cfg(all(feature = "solecism", feature = "oystercatcher"))] pub struct Oystercatcher; diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs index b5b8d0f427bf7..9ae8b8fca4f7a 100644 --- a/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs +++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit-gate.rs @@ -1,7 +1,8 @@ //@ compile-flags:--cfg feature="worricow" +#![feature(doc_cfg)] #![crate_name = "xenogenous"] //@ has 'xenogenous/struct.Worricow.html' -//@ count - '//*[@class="stab portability"]' 0 +//@ count - '//*[@class="stab portability"]' 1 #[cfg(feature = "worricow")] pub struct Worricow; diff --git a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs index 69b10867ee3ac..c092675ee5cf9 100644 --- a/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs +++ b/tests/rustdoc/doc-cfg/doc-cfg-implicit.rs @@ -1,5 +1,5 @@ #![crate_name = "funambulism"] -#![feature(doc_auto_cfg, doc_cfg)] +#![feature(doc_cfg)] //@ has 'funambulism/struct.Disorbed.html' //@ count - '//*[@class="stab portability"]' 1 diff --git a/tests/rustdoc/doc_auto_cfg.rs b/tests/rustdoc/doc_auto_cfg.rs new file mode 100644 index 0000000000000..19ef174c1778d --- /dev/null +++ b/tests/rustdoc/doc_auto_cfg.rs @@ -0,0 +1,77 @@ +// Test covering RFC 3631 features. + +#![crate_name = "foo"] +#![feature(doc_cfg)] +#![doc(auto_cfg(hide(feature = "hidden")))] + +//@ has 'foo/index.html' +//@ !has - '//*[@class="stab portability"]' 'Non-moustache' +//@ has - '//*[@class="stab portability"]' 'Non-pistache' +//@ count - '//*[@class="stab portability"]' 1 + +//@ has 'foo/m/index.html' +//@ count - '//*[@title="Available on non-crate feature `hidden` only"]' 2 +#[cfg(not(feature = "hidden"))] +pub mod m { + //@ count 'foo/m/struct.A.html' '//*[@class="stab portability"]' 0 + pub struct A; + + //@ has 'foo/m/inner/index.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.' + #[doc(auto_cfg(show(feature = "hidden")))] + pub mod inner { + //@ has 'foo/m/inner/struct.B.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.' + pub struct B; + + //@ count 'foo/m/inner/struct.A.html' '//*[@class="stab portability"]' 0 + #[doc(auto_cfg(hide(feature = "hidden")))] + pub struct A; + } + + //@ has 'foo/m/struct.B.html' '//*[@class="stab portability"]' 'Available on non-crate feature hidden only.' + #[doc(auto_cfg(show(feature = "hidden")))] + pub struct B; +} + +//@ count 'foo/n/index.html' '//*[@title="Available on non-crate feature `moustache` only"]' 3 +//@ count - '//dl/dt' 4 +#[cfg(not(feature = "moustache"))] +#[doc(auto_cfg = false)] +pub mod n { + // Should not have `moustache` listed. + //@ count 'foo/n/struct.X.html' '//*[@class="stab portability"]' 0 + pub struct X; + + // Should re-enable `auto_cfg` and make `moustache` listed. + //@ has 'foo/n/struct.Y.html' '//*[@class="stab portability"]' \ + // 'Available on non-crate feature moustache only.' + #[doc(auto_cfg)] + pub struct Y; + + // Should re-enable `auto_cfg` and make `moustache` listed for itself + // and for `Y`. + //@ has 'foo/n/inner/index.html' '//*[@class="stab portability"]' \ + // 'Available on non-crate feature moustache only.' + #[doc(auto_cfg = true)] + pub mod inner { + //@ has 'foo/n/inner/struct.Y.html' '//*[@class="stab portability"]' \ + // 'Available on non-crate feature moustache only.' + pub struct Y; + } + + // Should re-enable `auto_cfg` and make `moustache` listed. + //@ has 'foo/n/struct.Z.html' '//*[@class="stab portability"]' \ + // 'Available on non-crate feature moustache only.' + #[doc(auto_cfg(hide(feature = "hidden")))] + pub struct Z; +} + +// Checking inheritance. +//@ has 'foo/o/index.html' '//*[@class="stab portability"]' \ +// 'Available on non-crate feature pistache only.' +#[doc(cfg(not(feature = "pistache")))] +pub mod o { + //@ has 'foo/o/struct.A.html' '//*[@class="stab portability"]' \ + // 'Available on non-crate feature pistache and non-crate feature tarte only.' + #[doc(cfg(not(feature = "tarte")))] + pub struct A; +} diff --git a/tests/rustdoc/doc_auto_cfg_reexports.rs b/tests/rustdoc/doc_auto_cfg_reexports.rs new file mode 100644 index 0000000000000..ecfe9aabcfed4 --- /dev/null +++ b/tests/rustdoc/doc_auto_cfg_reexports.rs @@ -0,0 +1,35 @@ +// Checks that `cfg` are correctly applied on inlined reexports. + +#![crate_name = "foo"] +#![feature(doc_cfg)] + +// Check with `std` item. +//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-moustache' +//@ has 'foo/struct.C.html' '//*[@class="stab portability"]' \ +// 'Available on non-crate feature moustache only.' +#[cfg(not(feature = "moustache"))] +pub use std::cell::RefCell as C; + +// Check with local item. +mod x { + pub struct B; +} + +//@ has 'foo/index.html' '//*[@class="stab portability"]' 'Non-pistache' +//@ has 'foo/struct.B.html' '//*[@class="stab portability"]' \ +// 'Available on non-crate feature pistache only.' +#[cfg(not(feature = "pistache"))] +pub use crate::x::B; + +// Now checking that `cfg`s are not applied on non-inlined reexports. +pub mod pub_sub_mod { + //@ has 'foo/pub_sub_mod/index.html' + // There should be only only item with `cfg` note. + //@ count - '//*[@class="stab portability"]' 1 + // And obviously the item should be "blabla". + //@ has - '//dt' 'blablaNon-pistache' + #[cfg(not(feature = "pistache"))] + pub fn blabla() {} + + pub use self::blabla as another; +} diff --git a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs index f85d7b236372d..f24ebcd52acb6 100644 --- a/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs +++ b/tests/rustdoc/impl/doc_auto_cfg_nested_impl.rs @@ -1,6 +1,6 @@ // Regression test for . -#![feature(doc_auto_cfg)] +#![feature(doc_cfg)] #![crate_type = "lib"] #![crate_name = "foo"] diff --git a/tests/rustdoc/inline_cross/attributes.rs b/tests/rustdoc/inline_cross/attributes.rs index 4747f8ad67c1f..1657b7bdc8f77 100644 --- a/tests/rustdoc/inline_cross/attributes.rs +++ b/tests/rustdoc/inline_cross/attributes.rs @@ -1,7 +1,20 @@ +// Ensure that we render attributes on inlined cross-crate re-exported items. +// issue: + //@ aux-crate:attributes=attributes.rs //@ edition:2021 #![crate_name = "user"] -//@ has 'user/struct.NonExhaustive.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[non_exhaustive]' +//@ has 'user/fn.no_mangle.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]' +pub use attributes::no_mangle; + +//@ has 'user/fn.link_section.html' '//pre[@class="rust item-decl"]' \ +// '#[unsafe(link_section = ".here")]' +pub use attributes::link_section; + +//@ has 'user/fn.export_name.html' '//pre[@class="rust item-decl"]' \ +// '#[unsafe(export_name = "exonym")]' +pub use attributes::export_name; + +//@ has 'user/struct.NonExhaustive.html' '//pre[@class="rust item-decl"]' '#[non_exhaustive]' pub use attributes::NonExhaustive; diff --git a/tests/rustdoc/inline_cross/auxiliary/attributes.rs b/tests/rustdoc/inline_cross/auxiliary/attributes.rs index c6f155d4ba5a9..6068d38558586 100644 --- a/tests/rustdoc/inline_cross/auxiliary/attributes.rs +++ b/tests/rustdoc/inline_cross/auxiliary/attributes.rs @@ -1,2 +1,11 @@ +#[unsafe(no_mangle)] +pub fn no_mangle() {} + +#[unsafe(link_section = ".here")] +pub fn link_section() {} + +#[unsafe(export_name = "exonym")] +pub fn export_name() {} + #[non_exhaustive] pub struct NonExhaustive; diff --git a/tests/rustdoc/inline_cross/auxiliary/repr.rs b/tests/rustdoc/inline_cross/auxiliary/repr.rs deleted file mode 100644 index 0211e1a86588f..0000000000000 --- a/tests/rustdoc/inline_cross/auxiliary/repr.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![feature(repr_simd)] - -#[repr(C, align(8))] -pub struct ReprC { - field: u8, -} -#[repr(simd, packed(2))] -pub struct ReprSimd { - field: [u8; 1], -} -#[repr(transparent)] -pub struct ReprTransparent { - pub field: u8, -} -#[repr(isize)] -pub enum ReprIsize { - Bla, -} -#[repr(u8)] -pub enum ReprU8 { - Bla, -} - -#[repr(transparent)] // private -pub struct ReprTransparentPrivField { - field: u32, // non-1-ZST field -} - -#[repr(transparent)] // public -pub struct ReprTransparentPriv1ZstFields { - marker0: Marker, - pub main: u64, // non-1-ZST field - marker1: Marker, -} - -#[repr(transparent)] // private -pub struct ReprTransparentPrivFieldPub1ZstFields { - main: [u16; 0], // non-1-ZST field - pub marker: Marker, -} - -pub struct Marker; // 1-ZST diff --git a/tests/rustdoc/inline_cross/repr.rs b/tests/rustdoc/inline_cross/repr.rs deleted file mode 100644 index d13e560b8d77f..0000000000000 --- a/tests/rustdoc/inline_cross/repr.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Regression test for . -// This test ensures that the re-exported items still have the `#[repr(...)]` attribute. - -//@ aux-build:repr.rs - -#![crate_name = "foo"] - -extern crate repr; - -//@ has 'foo/struct.ReprC.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C, align(8))]' -pub use repr::ReprC; -//@ has 'foo/struct.ReprSimd.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(simd, packed(2))]' -pub use repr::ReprSimd; -//@ has 'foo/struct.ReprTransparent.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -pub use repr::ReprTransparent; -//@ has 'foo/enum.ReprIsize.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(isize)]' -pub use repr::ReprIsize; -//@ has 'foo/enum.ReprU8.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(u8)]' -pub use repr::ReprU8; - -// Regression test for . -// Check that we show `#[repr(transparent)]` iff the non-1-ZST field is public or at least one -// field is public in case all fields are 1-ZST fields. - -//@ has 'foo/struct.ReprTransparentPrivField.html' -//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -pub use repr::ReprTransparentPrivField; - -//@ has 'foo/struct.ReprTransparentPriv1ZstFields.html' -//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -pub use repr::ReprTransparentPriv1ZstFields; - -//@ has 'foo/struct.ReprTransparentPrivFieldPub1ZstFields.html' -//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -pub use repr::ReprTransparentPrivFieldPub1ZstFields; diff --git a/tests/rustdoc/intra-doc/type-alias-primitive.rs b/tests/rustdoc/intra-doc/type-alias-primitive.rs new file mode 100644 index 0000000000000..7504166cbcce2 --- /dev/null +++ b/tests/rustdoc/intra-doc/type-alias-primitive.rs @@ -0,0 +1,21 @@ +// Ensure that no warning is emitted if the disambiguator is used for type alias. +// Regression test for . + +#![crate_name = "foo"] +#![deny(rustdoc::broken_intra_doc_links)] + +pub struct Foo; + +#[allow(non_camel_case_types)] +pub type f32 = Foo; + +/// This function returns [`tyalias@f32`] and not [bla][`prim@f32`]. +//@ has 'foo/fn.my_fn.html' +//@ has - '//a[@href="https://github.com/type.f32.html"]' "f32" +//@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/std/primitive.f32.html"]' "bla" +pub fn my_fn() -> f32 { 0. } + +/// This function returns [`typealias@f32`]. +//@ has 'foo/fn.my_other_fn.html' +//@ has - '//a[@href="https://github.com/type.f32.html"]' "f32" +pub fn my_other_fn() -> f32 { 0. } diff --git a/tests/rustdoc/jump-to-def-assoc-items.rs b/tests/rustdoc/jump-to-def-assoc-items.rs new file mode 100644 index 0000000000000..0dfe3c7bdc155 --- /dev/null +++ b/tests/rustdoc/jump-to-def-assoc-items.rs @@ -0,0 +1,57 @@ +// This test ensures that patterns also get a link generated. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +//@ has 'src/foo/jump-to-def-assoc-items.rs.html' + +pub trait Trait { + type T; +} +pub trait Another { + type T; + const X: u32; +} + +pub struct Foo; + +impl Foo { + pub fn new() -> Self { Foo } +} + +pub struct C; + +impl C { + pub fn wat() {} +} + +//@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/fmt/macros/macro.Debug.html"]' 'Debug' +//@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/cmp/macro.PartialEq.html"]' 'PartialEq' +#[derive(Debug, PartialEq)] +pub struct Bar; +impl Trait for Bar { + type T = Foo; +} +impl Another for Bar { + type T = C; + const X: u32 = 12; +} + +pub fn bar() { + //@ has - '//a[@href="#20"]' 'new' + ::T::new(); + //@ has - '//a[@href="#26"]' 'wat' + ::T::wat(); + + match 12u32 { + //@ has - '//a[@href="#14"]' 'X' + ::X => {} + _ => {} + } +} + +pub struct Far { + //@ has - '//a[@href="#10"]' 'T' + x: ::T, +} diff --git a/tests/rustdoc/jump-to-def-ice-assoc-types.rs b/tests/rustdoc/jump-to-def-ice-assoc-types.rs new file mode 100644 index 0000000000000..9915c53668f0d --- /dev/null +++ b/tests/rustdoc/jump-to-def-ice-assoc-types.rs @@ -0,0 +1,20 @@ +// This test ensures that associated types don't crash rustdoc jump to def. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + + +#![crate_name = "foo"] + +//@ has 'src/foo/jump-to-def-ice-assoc-types.rs.html' + +pub trait Trait { + type Node; +} + +pub fn y() { + struct X(G); + + impl Trait for X { + type Node = G::Node; + } +} diff --git a/tests/rustdoc/jump-to-def-ice.rs b/tests/rustdoc/jump-to-def-ice.rs new file mode 100644 index 0000000000000..5578b9af3d74f --- /dev/null +++ b/tests/rustdoc/jump-to-def-ice.rs @@ -0,0 +1,24 @@ +// This test ensures that items with no body don't panic when generating +// jump to def links. + +//@ compile-flags: -Zunstable-options --generate-link-to-definition + +#![crate_name = "foo"] + +//@ has 'src/foo/jump-to-def-ice.rs.html' + +pub trait A { + type T; + type U; +} + +impl A for () { + type T = Self::U; + type U = (); +} + +pub trait C { + type X; +} + +pub struct F(pub T::X); diff --git a/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs b/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs index 618569787733c..55e59f23b6f28 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs +++ b/tests/rustdoc/jump-to-def/jump-to-def-doc-links-calls.rs @@ -8,7 +8,7 @@ pub struct Bar; impl std::default::Default for Bar { - //@ has - '//a[@href="#20-22"]' 'Self::new' + //@ has - '//a[@href="#20-22"]' 'new' fn default() -> Self { Self::new() } @@ -16,7 +16,7 @@ impl std::default::Default for Bar { //@ has - '//a[@href="#8"]' 'Bar' impl Bar { - //@ has - '//a[@href="#24-26"]' 'Self::bar' + //@ has - '//a[@href="#24-26"]' 'bar' pub fn new()-> Self { Self::bar() } diff --git a/tests/rustdoc/jump-to-def/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def/jump-to-def-pats.rs index 147902b44cf5c..852eba208db01 100644 --- a/tests/rustdoc/jump-to-def/jump-to-def-pats.rs +++ b/tests/rustdoc/jump-to-def/jump-to-def-pats.rs @@ -30,13 +30,13 @@ pub fn foo() -> Result<(), ()> { impl fmt::Display for MyEnum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - //@ has - '//a[@href="#12"]' 'Self::Ok' + //@ has - '//a[@href="#12"]' 'Ok' Self::Ok(_) => f.write_str("MyEnum::Ok"), - //@ has - '//a[@href="#13"]' 'MyEnum::Err' + //@ has - '//a[@href="#13"]' 'Err' MyEnum::Err(_) => f.write_str("MyEnum::Err"), - //@ has - '//a[@href="#14"]' 'Self::Some' + //@ has - '//a[@href="#14"]' 'Some' Self::Some(_) => f.write_str("MyEnum::Some"), - //@ has - '//a[@href="#15"]' 'Self::None' + //@ has - '//a[@href="#15"]' 'None' Self::None => f.write_str("MyEnum::None"), } } @@ -45,7 +45,7 @@ impl fmt::Display for MyEnum { impl X { fn p(&self) -> &str { match self { - //@ has - '//a[@href="#19"]' 'Self::A' + //@ has - '//a[@href="#19"]' 'A' Self::A => "X::A", } } diff --git a/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs index e2f530425f0db..1d6d6b8d18faa 100644 --- a/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs +++ b/tests/rustdoc/jump-to-def/jump-to-non-local-method.rs @@ -21,9 +21,10 @@ pub fn bar2(readable: T) { } pub fn bar() { - //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/sync/atomic/struct.AtomicIsize.html#method.new"]' 'AtomicIsize::new' + //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/sync/atomic/struct.AtomicIsize.html"]' 'AtomicIsize' + //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/sync/atomic/struct.AtomicIsize.html#method.new"]' 'new' let _ = AtomicIsize::new(0); - //@ has - '//a[@href="#48"]' 'local_private' + //@ has - '//a[@href="#49"]' 'local_private' local_private(); } @@ -39,7 +40,7 @@ pub fn macro_call() -> Result<(), ()> { } pub fn variant() { - //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/cmp/enum.Ordering.html#variant.Less"]' 'Ordering::Less' + //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/cmp/enum.Ordering.html#variant.Less"]' 'Less' let _ = Ordering::Less; //@ has - '//a[@href="https://github.com/%7B%7Bchannel%7D%7D/core/marker/struct.PhantomData.html"]' 'PhantomData' let _: PhantomData:: = PhantomData; diff --git a/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs b/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs deleted file mode 100644 index 96fa8209cde84..0000000000000 --- a/tests/rustdoc/reexport/auxiliary/reexports-attrs.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[unsafe(no_mangle)] -pub fn f0() {} - -#[unsafe(link_section = ".here")] -pub fn f1() {} - -#[unsafe(export_name = "f2export")] -pub fn f2() {} - -#[repr(u8)] -pub enum T0 { V1 } - -#[non_exhaustive] -pub enum T1 {} diff --git a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs index 76b25127a9c64..f8ec4afc0313e 100644 --- a/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs +++ b/tests/rustdoc/reexport/doc_auto_cfg-reexport-foreign-113982.rs @@ -1,7 +1,7 @@ //@ aux-build: issue-113982-doc_auto_cfg-reexport-foreign.rs // https://github.com/rust-lang/rust/issues/113982 -#![feature(no_core, doc_auto_cfg)] +#![feature(no_core, doc_cfg)] #![no_core] #![crate_name = "foo"] diff --git a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs index d0a2165ec8abb..0aed2b0c46208 100644 --- a/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs +++ b/tests/rustdoc/reexport/glob-reexport-attribute-merge-doc-auto-cfg.rs @@ -2,7 +2,7 @@ // the reexported item whereas glob reexports do with the `doc_auto_cfg` feature. #![crate_name = "foo"] -#![feature(doc_auto_cfg)] +#![feature(doc_cfg)] //@ has 'foo/index.html' // There are two items. diff --git a/tests/rustdoc/reexport/private-mod-override-reexport.rs b/tests/rustdoc/reexport/private-mod-override-reexport.rs new file mode 100644 index 0000000000000..849acc5fdaecd --- /dev/null +++ b/tests/rustdoc/reexport/private-mod-override-reexport.rs @@ -0,0 +1,13 @@ +// https://github.com/rust-lang/rust/issues/60926 +#![crate_name = "foo"] + +mod m1 { + pub mod m2 { + pub struct Foo; + } +} + +pub use m1::*; +use crate::m1::m2; + +//@ count foo/index.html '//a[@class="mod"]' 0 diff --git a/tests/rustdoc/reexport/reexport-attrs.rs b/tests/rustdoc/reexport/reexport-attrs.rs deleted file mode 100644 index aec0a11c0c6a0..0000000000000 --- a/tests/rustdoc/reexport/reexport-attrs.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ aux-build: reexports-attrs.rs - -#![crate_name = "foo"] - -extern crate reexports_attrs; - -//@ has 'foo/fn.f0.html' '//pre[@class="rust item-decl"]' '#[unsafe(no_mangle)]' -pub use reexports_attrs::f0; - -//@ has 'foo/fn.f1.html' '//pre[@class="rust item-decl"]' '#[unsafe(link_section = ".here")]' -pub use reexports_attrs::f1; - -//@ has 'foo/fn.f2.html' '//pre[@class="rust item-decl"]' '#[unsafe(export_name = "f2export")]' -pub use reexports_attrs::f2; - -//@ has 'foo/enum.T0.html' '//pre[@class="rust item-decl"]' '#[repr(u8)]' -pub use reexports_attrs::T0; - -//@ has 'foo/enum.T1.html' '//pre[@class="rust item-decl"]' '#[non_exhaustive]' -pub use reexports_attrs::T1; diff --git a/tests/rustdoc/reexport/reexport-cfg.rs b/tests/rustdoc/reexport/reexport-cfg.rs index 73b6682431663..b624e5acf502e 100644 --- a/tests/rustdoc/reexport/reexport-cfg.rs +++ b/tests/rustdoc/reexport/reexport-cfg.rs @@ -2,7 +2,7 @@ // include `cfg`s from the previous chained items. #![crate_name = "foo"] -#![feature(doc_auto_cfg, doc_cfg)] +#![feature(doc_cfg)] mod foo { #[cfg(not(feature = "foo"))] diff --git a/tests/rustdoc/repr.rs b/tests/rustdoc/repr.rs index f4f683b3d81a2..1e8fad6ec0a66 100644 --- a/tests/rustdoc/repr.rs +++ b/tests/rustdoc/repr.rs @@ -1,29 +1,163 @@ -// Regression test for . -// Check that we show `#[repr(transparent)]` iff the non-1-ZST field is public or at least one -// field is public in case all fields are 1-ZST fields. +// Test the rendering of `#[repr]` on ADTs. +#![feature(repr_simd)] // only used for the `ReprSimd` test case + +// Check the "local case" (HIR cleaning) // + +// Don't render the default repr which is `Rust`. +//@ has 'repr/struct.ReprDefault.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(Rust)]' +pub struct ReprDefault; + +// Don't render the `Rust` repr — even if given explicitly — since it's the default. +//@ has 'repr/struct.ReprRust.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(Rust)]' +#[repr(Rust)] // omitted +pub struct ReprRust; + +//@ has 'repr/struct.ReprCPubFields.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C)]' +#[repr(C)] // public +pub struct ReprCPubFields { + pub a: u32, + pub b: u32, +} + +//@ has 'repr/struct.ReprCPrivField.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C)]' +#[repr(C)] // private... +pub struct ReprCPrivField { + a: u32, // ...since this is private + pub b: u32, +} + +//@ has 'repr/enum.ReprIsize.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(isize)]' +#[repr(isize)] // public +pub enum ReprIsize { + Bla, +} + +//@ has 'repr/enum.ReprU32HiddenVariant.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(u32)]' +#[repr(u32)] // private... +pub enum ReprU32HiddenVariant { + #[doc(hidden)] + Hidden, // ...since this is hidden + Public, +} + +//@ has 'repr/struct.ReprAlignHiddenField.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(align(4))]' +#[repr(align(4))] // private... +pub struct ReprAlignHiddenField { + #[doc(hidden)] + pub hidden: i16, // ...since this field is hidden +} + +//@ has 'repr/struct.ReprSimd.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(simd, packed(2))]' +#[repr(simd, packed(2))] // public +pub struct ReprSimd { + pub field: [u8; 1], +} + +//@ has 'repr/enum.ReprU32Align.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(u32, align(8))]' +#[repr(u32, align(8))] // public +pub enum ReprU32Align { + Variant(u16), +} + +//@ has 'repr/enum.ReprCHiddenVariantField.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C)]' +#[repr(C)] // private... +pub enum ReprCHiddenVariantField { + Variant { #[doc(hidden)] field: () }, //...since this field is hidden +} //@ has 'repr/struct.ReprTransparentPrivField.html' //@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -#[repr(transparent)] // private +#[repr(transparent)] // private... pub struct ReprTransparentPrivField { - field: u32, // non-1-ZST field + field: u32, // ...since the non-1-ZST field is private } //@ has 'repr/struct.ReprTransparentPriv1ZstFields.html' //@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -#[repr(transparent)] // public +#[repr(transparent)] // public... pub struct ReprTransparentPriv1ZstFields { marker0: Marker, - pub main: u64, // non-1-ZST field + pub main: u64, // ...since the non-1-ZST field is public and visible marker1: Marker, +} // the two private 1-ZST fields don't matter + +//@ has 'repr/struct.ReprTransparentPrivFieldPub1ZstField.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // private... +pub struct ReprTransparentPrivFieldPub1ZstField { + main: [u16; 0], // ...since the non-1-ZST field is private + pub marker: Marker, // this public 1-ZST field doesn't matter } //@ has 'repr/struct.ReprTransparentPub1ZstField.html' //@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' -#[repr(transparent)] // public +#[repr(transparent)] // public... pub struct ReprTransparentPub1ZstField { - marker0: Marker, - pub marker1: Marker, + marker0: Marker, // ...since we don't have a non-1-ZST field... + pub marker1: Marker, // ...and this field is public and visible +} + +//@ has 'repr/struct.ReprTransparentUnitStruct.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // public +pub struct ReprTransparentUnitStruct; + +//@ has 'repr/enum.ReprTransparentEnumUnitVariant.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // public +pub enum ReprTransparentEnumUnitVariant { + Variant, +} + +//@ has 'repr/enum.ReprTransparentEnumHiddenUnitVariant.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // private +pub enum ReprTransparentEnumHiddenUnitVariant { + #[doc(hidden)] Variant(u32), +} + +//@ has 'repr/enum.ReprTransparentEnumPub1ZstField.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // public... +pub enum ReprTransparentEnumPub1ZstField { + Variant { + field: u64, // ...since the non-1-ZST field is public + #[doc(hidden)] + marker: Marker, // this hidden 1-ZST field doesn't matter + }, +} + +//@ has 'repr/enum.ReprTransparentEnumHidden1ZstField.html' +//@ !has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(transparent)]' +#[repr(transparent)] // private... +pub enum ReprTransparentEnumHidden1ZstField { + Variant { + #[doc(hidden)] + field: u64, // ...since the non-1-ZST field is public + }, } struct Marker; // 1-ZST + +// Check the "extern case" (middle cleaning) // + +// Internally, HIR and middle cleaning share `#[repr]` rendering. +// Thus we'll only test the very basics in this section. + +//@ aux-build: ext-repr.rs +extern crate ext_repr as ext; + +// Regression test for . +//@ has 'repr/enum.ReprI8.html' +//@ has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(i8)]' +pub use ext::ReprI8; diff --git a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs index d701b88bf9fd0..a7b944fa2f6fc 100644 --- a/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs +++ b/tests/rustdoc/source-code-pages/check-source-code-urls-to-def.rs @@ -34,7 +34,7 @@ fn babar() {} // The 5 links to line 23 and the line 23 itself. //@ count - '//pre[@class="rust"]//a[@href="#23"]' 6 //@ has - '//pre[@class="rust"]//a[@href="https://github.com/source_code/struct.SourceCode.html"]' \ -// 'source_code::SourceCode' +// 'SourceCode' pub fn foo(a: u32, b: &str, c: String, d: Foo, e: bar::Bar, f: source_code::SourceCode) { let x = 12; let y: Foo = Foo; diff --git a/tests/rustdoc/target-feature.rs b/tests/rustdoc/target-feature.rs index 59a08a0ca949e..f2686f81fbff0 100644 --- a/tests/rustdoc/target-feature.rs +++ b/tests/rustdoc/target-feature.rs @@ -1,3 +1,5 @@ +#![feature(doc_cfg)] + #![crate_name = "foo"] //@ has 'foo/index.html' diff --git a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs index 8449479287f0f..48f328f4fad36 100644 --- a/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs +++ b/tests/ui-fulldeps/codegen-backend/auxiliary/the_backend.rs @@ -33,6 +33,10 @@ impl CodegenBackend for TheBackend { "" } + fn name(&self) -> &'static str { + "the-backend" + } + fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { Box::new(CodegenResults { modules: vec![], diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index df5f29e35fe69..86f2d5f5954a4 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -2,7 +2,6 @@ // Testing that a librustc_ast can parse modules with canonicalized base path //@ ignore-cross-compile //@ ignore-remote -// no-remap-src-base: Reading `file!()` (expectedly) fails when enabled. #![feature(rustc_private)] diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index 87504b8301f03..241d9e7efbd72 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -74,7 +74,6 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path make_codegen_backend: None, registry: rustc_driver::diagnostics_registry(), using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES, - expanded_args: Default::default(), }; interface::run_compiler(config, |compiler| { diff --git a/tests/ui-fulldeps/try-from-u32/errors.rs b/tests/ui-fulldeps/try-from-u32/errors.rs deleted file mode 100644 index a25069c0a53cb..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/errors.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![feature(rustc_private)] -//@ edition: 2021 - -// Checks the error messages produced by `#[derive(TryFromU32)]`. - -extern crate rustc_macros; - -use rustc_macros::TryFromU32; - -#[derive(TryFromU32)] -struct MyStruct {} //~ ERROR type is not an enum - -#[derive(TryFromU32)] -enum NonTrivial { - A, - B(), - C {}, - D(bool), //~ ERROR enum variant cannot have fields - E(bool, bool), //~ ERROR enum variant cannot have fields - F { x: bool }, //~ ERROR enum variant cannot have fields - G { x: bool, y: bool }, //~ ERROR enum variant cannot have fields -} - -fn main() {} diff --git a/tests/ui-fulldeps/try-from-u32/errors.stderr b/tests/ui-fulldeps/try-from-u32/errors.stderr deleted file mode 100644 index d20567061d7bb..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/errors.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error: type is not an enum (TryFromU32) - --> $DIR/errors.rs:11:1 - | -LL | struct MyStruct {} - | ^^^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:18:7 - | -LL | D(bool), - | ^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:19:7 - | -LL | E(bool, bool), - | ^^^^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:20:9 - | -LL | F { x: bool }, - | ^ - -error: enum variant cannot have fields (TryFromU32) - --> $DIR/errors.rs:21:9 - | -LL | G { x: bool, y: bool }, - | ^ - -error: aborting due to 5 previous errors - diff --git a/tests/ui-fulldeps/try-from-u32/hygiene.rs b/tests/ui-fulldeps/try-from-u32/hygiene.rs deleted file mode 100644 index e0655a64a64db..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/hygiene.rs +++ /dev/null @@ -1,32 +0,0 @@ -#![feature(rustc_private)] -//@ edition: 2021 -//@ check-pass - -// Checks that the derive macro still works even if the surrounding code has -// shadowed the relevant library types. - -extern crate rustc_macros; - -mod submod { - use rustc_macros::TryFromU32; - - struct Result; - trait TryFrom {} - #[allow(non_camel_case_types)] - struct u32; - struct Ok; - struct Err; - mod core {} - mod std {} - - #[derive(TryFromU32)] - pub(crate) enum MyEnum { - Zero, - One, - } -} - -fn main() { - use submod::MyEnum; - let _: Result = MyEnum::try_from(1u32); -} diff --git a/tests/ui-fulldeps/try-from-u32/values.rs b/tests/ui-fulldeps/try-from-u32/values.rs deleted file mode 100644 index 180a8f2beb75b..0000000000000 --- a/tests/ui-fulldeps/try-from-u32/values.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![feature(assert_matches)] -#![feature(rustc_private)] -//@ edition: 2021 -//@ run-pass - -// Checks the values accepted by the `TryFrom` impl produced by `#[derive(TryFromU32)]`. - -extern crate rustc_macros; - -use core::assert_matches::assert_matches; -use rustc_macros::TryFromU32; - -#[derive(TryFromU32, Debug, PartialEq)] -#[repr(u32)] -enum Repr { - Zero, - One(), - Seven = 7, -} - -#[derive(TryFromU32, Debug)] -enum NoRepr { - Zero, - One, -} - -fn main() { - assert_eq!(Repr::try_from(0u32), Ok(Repr::Zero)); - assert_eq!(Repr::try_from(1u32), Ok(Repr::One())); - assert_eq!(Repr::try_from(2u32), Err(2)); - assert_eq!(Repr::try_from(7u32), Ok(Repr::Seven)); - - assert_matches!(NoRepr::try_from(0u32), Ok(NoRepr::Zero)); - assert_matches!(NoRepr::try_from(1u32), Ok(NoRepr::One)); - assert_matches!(NoRepr::try_from(2u32), Err(2)); -} diff --git a/tests/ui/README.md b/tests/ui/README.md index 66c1bb905a792..3b28ef694dd30 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -350,6 +350,12 @@ Tests for FFI with C varargs (`va_list`). Tests for detection and handling of cyclic trait dependencies. +## `tests/ui/darwin-objc/`: Darwin Objective-C + +Tests exercising `#![feature(darwin_objc)]`. + +See [Tracking Issue for `darwin_objc` #145496](https://github.com/rust-lang/rust/issues/145496). + ## `tests/ui/dataflow_const_prop/` Contains a single regression test for const prop in `SwitchInt` pass crashing when `ptr2int` transmute is involved. diff --git a/tests/ui/abi/abi-sysv64-arg-passing.rs b/tests/ui/abi/abi-sysv64-arg-passing.rs index c18752418a1d6..362a1862f9d4c 100644 --- a/tests/ui/abi/abi-sysv64-arg-passing.rs +++ b/tests/ui/abi/abi-sysv64-arg-passing.rs @@ -28,6 +28,7 @@ //@ ignore-arm //@ ignore-aarch64 //@ ignore-windows +//@ ignore-backends: gcc // Windows is ignored because bootstrap doesn't yet know to compile rust_test_helpers with // the sysv64 ABI on Windows. diff --git a/tests/ui/abi/abi-sysv64-register-usage.rs b/tests/ui/abi/abi-sysv64-register-usage.rs index d2fb2ae53ac73..cf1620db6f7be 100644 --- a/tests/ui/abi/abi-sysv64-register-usage.rs +++ b/tests/ui/abi/abi-sysv64-register-usage.rs @@ -6,6 +6,7 @@ //@ ignore-arm //@ ignore-aarch64 //@ needs-asm-support +//@ ignore-backends: gcc #[cfg(target_arch = "x86_64")] pub extern "sysv64" fn all_the_registers( diff --git a/tests/ui/abi/arm-unadjusted-intrinsic.rs b/tests/ui/abi/arm-unadjusted-intrinsic.rs index dcf0d9f39f673..6421f9a00847f 100644 --- a/tests/ui/abi/arm-unadjusted-intrinsic.rs +++ b/tests/ui/abi/arm-unadjusted-intrinsic.rs @@ -6,6 +6,7 @@ //@ revisions: aarch64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@[aarch64] needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![feature( no_core, lang_items, link_llvm_intrinsics, abi_unadjusted, repr_simd, arm_target_feature, diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr index 5e09145a27122..d050bfcbaa173 100644 --- a/tests/ui/abi/c-zst.aarch64-darwin.stderr +++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr @@ -60,7 +60,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr index ec6b9b8f02742..e79b3fcec8b97 100644 --- a/tests/ui/abi/c-zst.powerpc-linux.stderr +++ b/tests/ui/abi/c-zst.powerpc-linux.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.rs b/tests/ui/abi/c-zst.rs index c1dac41f876a2..2d55b61f57a10 100644 --- a/tests/ui/abi/c-zst.rs +++ b/tests/ui/abi/c-zst.rs @@ -51,6 +51,7 @@ extern "C" fn(i32, (), i32); //@ revisions: x86_64-pc-windows-gnu //@[x86_64-pc-windows-gnu] compile-flags: --target x86_64-pc-windows-gnu //@[x86_64-pc-windows-gnu] needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs)] diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr index ec6b9b8f02742..e79b3fcec8b97 100644 --- a/tests/ui/abi/c-zst.s390x-linux.stderr +++ b/tests/ui/abi/c-zst.s390x-linux.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr index ec6b9b8f02742..e79b3fcec8b97 100644 --- a/tests/ui/abi/c-zst.sparc64-linux.stderr +++ b/tests/ui/abi/c-zst.sparc64-linux.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr index 5e09145a27122..d050bfcbaa173 100644 --- a/tests/ui/abi/c-zst.x86_64-linux.stderr +++ b/tests/ui/abi/c-zst.x86_64-linux.stderr @@ -60,7 +60,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr index ec6b9b8f02742..e79b3fcec8b97 100644 --- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr +++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr @@ -71,7 +71,7 @@ error: fn_abi_of(pass_zst) = FnAbi { conv: C, can_unwind: false, } - --> $DIR/c-zst.rs:64:1 + --> $DIR/c-zst.rs:65:1 | LL | extern "C" fn pass_zst(_: ()) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/cannot-be-called.avr.stderr b/tests/ui/abi/cannot-be-called.avr.stderr index ed3fa4a20c5da..2128991d83cdf 100644 --- a/tests/ui/abi/cannot-be-called.avr.stderr +++ b/tests/ui/abi/cannot-be-called.avr.stderr @@ -1,71 +1,71 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:41:8 + --> $DIR/cannot-be-called.rs:42:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:43:8 + --> $DIR/cannot-be-called.rs:44:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:45:8 + --> $DIR/cannot-be-called.rs:46:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:78:26 + --> $DIR/cannot-be-called.rs:79:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:84:26 + --> $DIR/cannot-be-called.rs:85:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:90:22 + --> $DIR/cannot-be-called.rs:91:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:52:5 + --> $DIR/cannot-be-called.rs:53:5 | LL | avr(); | ^^^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:52:5 + --> $DIR/cannot-be-called.rs:53:5 | LL | avr(); | ^^^^^ error: functions with the "avr-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:68:5 + --> $DIR/cannot-be-called.rs:69:5 | LL | f() | ^^^ | note: an `extern "avr-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:68:5 + --> $DIR/cannot-be-called.rs:69:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.i686.stderr b/tests/ui/abi/cannot-be-called.i686.stderr index 6ccb10c44fdf9..9b1755921aea4 100644 --- a/tests/ui/abi/cannot-be-called.i686.stderr +++ b/tests/ui/abi/cannot-be-called.i686.stderr @@ -1,71 +1,71 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:41:8 + --> $DIR/cannot-be-called.rs:42:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:43:8 + --> $DIR/cannot-be-called.rs:44:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:78:26 + --> $DIR/cannot-be-called.rs:79:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:84:26 + --> $DIR/cannot-be-called.rs:85:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.msp430.stderr b/tests/ui/abi/cannot-be-called.msp430.stderr index 0bd5bb40b715a..9a047b11cf795 100644 --- a/tests/ui/abi/cannot-be-called.msp430.stderr +++ b/tests/ui/abi/cannot-be-called.msp430.stderr @@ -1,71 +1,71 @@ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:41:8 + --> $DIR/cannot-be-called.rs:42:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:43:8 + --> $DIR/cannot-be-called.rs:44:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:45:8 + --> $DIR/cannot-be-called.rs:46:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:78:26 + --> $DIR/cannot-be-called.rs:79:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:84:26 + --> $DIR/cannot-be-called.rs:85:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:90:22 + --> $DIR/cannot-be-called.rs:91:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:54:5 + --> $DIR/cannot-be-called.rs:55:5 | LL | msp430(); | ^^^^^^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:54:5 + --> $DIR/cannot-be-called.rs:55:5 | LL | msp430(); | ^^^^^^^^ error: functions with the "msp430-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:74:5 + --> $DIR/cannot-be-called.rs:75:5 | LL | f() | ^^^ | note: an `extern "msp430-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:74:5 + --> $DIR/cannot-be-called.rs:75:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.riscv32.stderr b/tests/ui/abi/cannot-be-called.riscv32.stderr index 6d763bd63796b..135b20c50d58a 100644 --- a/tests/ui/abi/cannot-be-called.riscv32.stderr +++ b/tests/ui/abi/cannot-be-called.riscv32.stderr @@ -1,83 +1,83 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:45:8 + --> $DIR/cannot-be-called.rs:46:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:90:22 + --> $DIR/cannot-be-called.rs:91:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:56:5 + --> $DIR/cannot-be-called.rs:57:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:56:5 + --> $DIR/cannot-be-called.rs:57:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:58:5 + --> $DIR/cannot-be-called.rs:59:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:58:5 + --> $DIR/cannot-be-called.rs:59:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:80:5 + --> $DIR/cannot-be-called.rs:81:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:80:5 + --> $DIR/cannot-be-called.rs:81:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:86:5 + --> $DIR/cannot-be-called.rs:87:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:86:5 + --> $DIR/cannot-be-called.rs:87:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.riscv64.stderr b/tests/ui/abi/cannot-be-called.riscv64.stderr index 6d763bd63796b..135b20c50d58a 100644 --- a/tests/ui/abi/cannot-be-called.riscv64.stderr +++ b/tests/ui/abi/cannot-be-called.riscv64.stderr @@ -1,83 +1,83 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:45:8 + --> $DIR/cannot-be-called.rs:46:8 | LL | extern "x86-interrupt" fn x86(_x: *const u8) {} | ^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:90:22 + --> $DIR/cannot-be-called.rs:91:22 | LL | fn x86_ptr(f: extern "x86-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:56:5 + --> $DIR/cannot-be-called.rs:57:5 | LL | riscv_m(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:56:5 + --> $DIR/cannot-be-called.rs:57:5 | LL | riscv_m(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:58:5 + --> $DIR/cannot-be-called.rs:59:5 | LL | riscv_s(); | ^^^^^^^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:58:5 + --> $DIR/cannot-be-called.rs:59:5 | LL | riscv_s(); | ^^^^^^^^^ error: functions with the "riscv-interrupt-m" ABI cannot be called - --> $DIR/cannot-be-called.rs:80:5 + --> $DIR/cannot-be-called.rs:81:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-m"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:80:5 + --> $DIR/cannot-be-called.rs:81:5 | LL | f() | ^^^ error: functions with the "riscv-interrupt-s" ABI cannot be called - --> $DIR/cannot-be-called.rs:86:5 + --> $DIR/cannot-be-called.rs:87:5 | LL | f() | ^^^ | note: an `extern "riscv-interrupt-s"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:86:5 + --> $DIR/cannot-be-called.rs:87:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.rs b/tests/ui/abi/cannot-be-called.rs index b0267cfa37e1a..e5385ed6d69d5 100644 --- a/tests/ui/abi/cannot-be-called.rs +++ b/tests/ui/abi/cannot-be-called.rs @@ -20,6 +20,7 @@ So we test that they error in essentially all of the same places. //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature( no_core, diff --git a/tests/ui/abi/cannot-be-called.x64.stderr b/tests/ui/abi/cannot-be-called.x64.stderr index 6ccb10c44fdf9..9b1755921aea4 100644 --- a/tests/ui/abi/cannot-be-called.x64.stderr +++ b/tests/ui/abi/cannot-be-called.x64.stderr @@ -1,71 +1,71 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:41:8 + --> $DIR/cannot-be-called.rs:42:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:43:8 + --> $DIR/cannot-be-called.rs:44:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:78:26 + --> $DIR/cannot-be-called.rs:79:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:84:26 + --> $DIR/cannot-be-called.rs:85:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-called.x64_win.stderr b/tests/ui/abi/cannot-be-called.x64_win.stderr index 6ccb10c44fdf9..9b1755921aea4 100644 --- a/tests/ui/abi/cannot-be-called.x64_win.stderr +++ b/tests/ui/abi/cannot-be-called.x64_win.stderr @@ -1,71 +1,71 @@ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:37:8 + --> $DIR/cannot-be-called.rs:38:8 | LL | extern "msp430-interrupt" fn msp430() {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:39:8 + --> $DIR/cannot-be-called.rs:40:8 | LL | extern "avr-interrupt" fn avr() {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:41:8 + --> $DIR/cannot-be-called.rs:42:8 | LL | extern "riscv-interrupt-m" fn riscv_m() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:43:8 + --> $DIR/cannot-be-called.rs:44:8 | LL | extern "riscv-interrupt-s" fn riscv_s() {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:66:22 + --> $DIR/cannot-be-called.rs:67:22 | LL | fn avr_ptr(f: extern "avr-interrupt" fn()) { | ^^^^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:72:25 + --> $DIR/cannot-be-called.rs:73:25 | LL | fn msp430_ptr(f: extern "msp430-interrupt" fn()) { | ^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:78:26 + --> $DIR/cannot-be-called.rs:79:26 | LL | fn riscv_m_ptr(f: extern "riscv-interrupt-m" fn()) { | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-s" is not a supported ABI for the current target - --> $DIR/cannot-be-called.rs:84:26 + --> $DIR/cannot-be-called.rs:85:26 | LL | fn riscv_s_ptr(f: extern "riscv-interrupt-s" fn()) { | ^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:60:5 + --> $DIR/cannot-be-called.rs:61:5 | LL | x86(&raw const BYTE); | ^^^^^^^^^^^^^^^^^^^^ error: functions with the "x86-interrupt" ABI cannot be called - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ | note: an `extern "x86-interrupt"` function can only be called using inline assembly - --> $DIR/cannot-be-called.rs:92:5 + --> $DIR/cannot-be-called.rs:93:5 | LL | f() | ^^^ diff --git a/tests/ui/abi/cannot-be-coroutine.avr.stderr b/tests/ui/abi/cannot-be-coroutine.avr.stderr index 027f98c95c4c6..11bc93b1eef11 100644 --- a/tests/ui/abi/cannot-be-coroutine.avr.stderr +++ b/tests/ui/abi/cannot-be-coroutine.avr.stderr @@ -1,5 +1,5 @@ error: functions with the "avr-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:36:1 + --> $DIR/cannot-be-coroutine.rs:37:1 | LL | async extern "avr-interrupt" fn avr() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "avr-interrupt" fn avr() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.i686.stderr b/tests/ui/abi/cannot-be-coroutine.i686.stderr index 230847ff2695f..4a344bb090200 100644 --- a/tests/ui/abi/cannot-be-coroutine.i686.stderr +++ b/tests/ui/abi/cannot-be-coroutine.i686.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:52:1 + --> $DIR/cannot-be-coroutine.rs:53:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.msp430.stderr b/tests/ui/abi/cannot-be-coroutine.msp430.stderr index 4b639cea9c19b..c2867705df78c 100644 --- a/tests/ui/abi/cannot-be-coroutine.msp430.stderr +++ b/tests/ui/abi/cannot-be-coroutine.msp430.stderr @@ -1,5 +1,5 @@ error: functions with the "msp430-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:40:1 + --> $DIR/cannot-be-coroutine.rs:41:1 | LL | async extern "msp430-interrupt" fn msp430() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "msp430-interrupt" fn msp430() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr index 1b18bc51f8381..398f888205dfb 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv32.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv32.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:44:1 + --> $DIR/cannot-be-coroutine.rs:45:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:48:1 + --> $DIR/cannot-be-coroutine.rs:49:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr index 1b18bc51f8381..398f888205dfb 100644 --- a/tests/ui/abi/cannot-be-coroutine.riscv64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.riscv64.stderr @@ -1,5 +1,5 @@ error: functions with the "riscv-interrupt-m" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:44:1 + --> $DIR/cannot-be-coroutine.rs:45:1 | LL | async extern "riscv-interrupt-m" fn riscv_m() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m() { | error: functions with the "riscv-interrupt-s" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:48:1 + --> $DIR/cannot-be-coroutine.rs:49:1 | LL | async extern "riscv-interrupt-s" fn riscv_s() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s() { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.rs b/tests/ui/abi/cannot-be-coroutine.rs index e3d3d45c632f1..5548b8cb8d60e 100644 --- a/tests/ui/abi/cannot-be-coroutine.rs +++ b/tests/ui/abi/cannot-be-coroutine.rs @@ -16,6 +16,7 @@ //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature( no_core, diff --git a/tests/ui/abi/cannot-be-coroutine.x64.stderr b/tests/ui/abi/cannot-be-coroutine.x64.stderr index 230847ff2695f..4a344bb090200 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:52:1 + --> $DIR/cannot-be-coroutine.rs:53:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr index 230847ff2695f..4a344bb090200 100644 --- a/tests/ui/abi/cannot-be-coroutine.x64_win.stderr +++ b/tests/ui/abi/cannot-be-coroutine.x64_win.stderr @@ -1,5 +1,5 @@ error: functions with the "x86-interrupt" ABI cannot be `async` - --> $DIR/cannot-be-coroutine.rs:52:1 + --> $DIR/cannot-be-coroutine.rs:53:1 | LL | async extern "x86-interrupt" fn x86(_p: *mut ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL + extern "x86-interrupt" fn x86(_p: *mut ()) { | error: requires `ResumeTy` lang_item - --> $DIR/cannot-be-coroutine.rs:32:19 + --> $DIR/cannot-be-coroutine.rs:33:19 | LL | async fn vanilla(){ | ___________________^ diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs index 68706f1e821ac..4ffc81eb5f6f5 100644 --- a/tests/ui/abi/compatibility.rs +++ b/tests/ui/abi/compatibility.rs @@ -59,6 +59,7 @@ //@ revisions: nvptx64 //@[nvptx64] compile-flags: --target nvptx64-nvidia-cuda //@[nvptx64] needs-llvm-components: nvptx +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![feature(unsized_fn_params, transparent_unions)] #![no_core] diff --git a/tests/ui/abi/debug.generic.stderr b/tests/ui/abi/debug.generic.stderr index 47341da221fb3..fd4c43591425c 100644 --- a/tests/ui/abi/debug.generic.stderr +++ b/tests/ui/abi/debug.generic.stderr @@ -89,7 +89,7 @@ error: fn_abi_of(test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:30:1 + --> $DIR/debug.rs:31:1 | LL | fn test(_x: u8) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:36:1 + --> $DIR/debug.rs:37:1 | LL | type TestFnPtr = fn(bool) -> u8; | ^^^^^^^^^^^^^^ @@ -263,13 +263,13 @@ error: fn_abi_of(test_generic) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:39:1 + --> $DIR/debug.rs:40:1 | LL | fn test_generic(_x: *const T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:42:1 + --> $DIR/debug.rs:43:1 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -419,7 +419,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:58:1 + --> $DIR/debug.rs:59:1 | LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ @@ -571,7 +571,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:61:1 + --> $DIR/debug.rs:62:1 | LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); | ^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:64:1 + --> $DIR/debug.rs:65:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -870,13 +870,13 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:68:1 + --> $DIR/debug.rs:69:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:71:46 + --> $DIR/debug.rs:72:46 | LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -885,13 +885,13 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = note: only the last element of a tuple may have a dynamically sized type error: unrecognized argument - --> $DIR/debug.rs:73:13 + --> $DIR/debug.rs:74:13 | LL | #[rustc_abi("assert_eq")] | ^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:46:5 + --> $DIR/debug.rs:47:5 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -981,7 +981,7 @@ error: fn_abi_of(assoc_test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:51:5 + --> $DIR/debug.rs:52:5 | LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/debug.loongarch64.stderr b/tests/ui/abi/debug.loongarch64.stderr index 94a01a8087314..95351b42092a4 100644 --- a/tests/ui/abi/debug.loongarch64.stderr +++ b/tests/ui/abi/debug.loongarch64.stderr @@ -89,7 +89,7 @@ error: fn_abi_of(test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:30:1 + --> $DIR/debug.rs:31:1 | LL | fn test(_x: u8) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:36:1 + --> $DIR/debug.rs:37:1 | LL | type TestFnPtr = fn(bool) -> u8; | ^^^^^^^^^^^^^^ @@ -263,13 +263,13 @@ error: fn_abi_of(test_generic) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:39:1 + --> $DIR/debug.rs:40:1 | LL | fn test_generic(_x: *const T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:42:1 + --> $DIR/debug.rs:43:1 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -419,7 +419,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:58:1 + --> $DIR/debug.rs:59:1 | LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ @@ -571,7 +571,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:61:1 + --> $DIR/debug.rs:62:1 | LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); | ^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:64:1 + --> $DIR/debug.rs:65:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -870,13 +870,13 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:68:1 + --> $DIR/debug.rs:69:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:71:46 + --> $DIR/debug.rs:72:46 | LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -885,13 +885,13 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = note: only the last element of a tuple may have a dynamically sized type error: unrecognized argument - --> $DIR/debug.rs:73:13 + --> $DIR/debug.rs:74:13 | LL | #[rustc_abi("assert_eq")] | ^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:46:5 + --> $DIR/debug.rs:47:5 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -981,7 +981,7 @@ error: fn_abi_of(assoc_test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:51:5 + --> $DIR/debug.rs:52:5 | LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/debug.riscv64.stderr b/tests/ui/abi/debug.riscv64.stderr index 94a01a8087314..95351b42092a4 100644 --- a/tests/ui/abi/debug.riscv64.stderr +++ b/tests/ui/abi/debug.riscv64.stderr @@ -89,7 +89,7 @@ error: fn_abi_of(test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:30:1 + --> $DIR/debug.rs:31:1 | LL | fn test(_x: u8) -> bool { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -185,7 +185,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:36:1 + --> $DIR/debug.rs:37:1 | LL | type TestFnPtr = fn(bool) -> u8; | ^^^^^^^^^^^^^^ @@ -263,13 +263,13 @@ error: fn_abi_of(test_generic) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:39:1 + --> $DIR/debug.rs:40:1 | LL | fn test_generic(_x: *const T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:42:1 + --> $DIR/debug.rs:43:1 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -419,7 +419,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:58:1 + --> $DIR/debug.rs:59:1 | LL | type TestAbiNe = (fn(u8), fn(u32)); | ^^^^^^^^^^^^^^ @@ -571,7 +571,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:61:1 + --> $DIR/debug.rs:62:1 | LL | type TestAbiNeLarger = (fn([u8; 32]), fn([u32; 32])); | ^^^^^^^^^^^^^^^^^^^^ @@ -720,7 +720,7 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:64:1 + --> $DIR/debug.rs:65:1 | LL | type TestAbiNeFloat = (fn(f32), fn(u32)); | ^^^^^^^^^^^^^^^^^^^ @@ -870,13 +870,13 @@ error: ABIs are not compatible conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:68:1 + --> $DIR/debug.rs:69:1 | LL | type TestAbiNeSign = (fn(i32), fn(u32)); | ^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/debug.rs:71:46 + --> $DIR/debug.rs:72:46 | LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); | ^^^^^^^^^^ doesn't have a size known at compile-time @@ -885,13 +885,13 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); = note: only the last element of a tuple may have a dynamically sized type error: unrecognized argument - --> $DIR/debug.rs:73:13 + --> $DIR/debug.rs:74:13 | LL | #[rustc_abi("assert_eq")] | ^^^^^^^^^^^ error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions - --> $DIR/debug.rs:46:5 + --> $DIR/debug.rs:47:5 | LL | const C: () = (); | ^^^^^^^^^^^ @@ -981,7 +981,7 @@ error: fn_abi_of(assoc_test) = FnAbi { conv: Rust, can_unwind: $SOME_BOOL, } - --> $DIR/debug.rs:51:5 + --> $DIR/debug.rs:52:5 | LL | fn assoc_test(&self) {} | ^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/debug.rs b/tests/ui/abi/debug.rs index 59c0908041d23..7cd275376faf6 100644 --- a/tests/ui/abi/debug.rs +++ b/tests/ui/abi/debug.rs @@ -15,6 +15,7 @@ //@ [loongarch64] needs-llvm-components: loongarch //@ [generic] ignore-riscv64 //@ [generic] ignore-loongarch64 +//@ ignore-backends: gcc #![feature(rustc_attrs)] #![crate_type = "lib"] #![feature(no_core)] diff --git a/tests/ui/abi/fixed_x18.rs b/tests/ui/abi/fixed_x18.rs index baf215ba9031d..0f09b0105fca5 100644 --- a/tests/ui/abi/fixed_x18.rs +++ b/tests/ui/abi/fixed_x18.rs @@ -15,6 +15,7 @@ //@ [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib //@ [riscv64] needs-llvm-components: riscv //@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core, lang_items)] diff --git a/tests/ui/abi/homogenous-floats-target-feature-mixup.rs b/tests/ui/abi/homogenous-floats-target-feature-mixup.rs index 2c78b794a8d74..21c6c276bb1c7 100644 --- a/tests/ui/abi/homogenous-floats-target-feature-mixup.rs +++ b/tests/ui/abi/homogenous-floats-target-feature-mixup.rs @@ -6,6 +6,8 @@ //@ run-pass //@ needs-subprocess +//@ ignore-backends: gcc +//@ ignore-i586 (no SSE2) #![allow(overflowing_literals)] #![allow(unused_variables)] @@ -18,16 +20,6 @@ fn main() { return test::main(&level) } - match std::env::var("TARGET") { - Ok(s) => { - // Skip this tests on i586-unknown-linux-gnu where sse2 is disabled - if s.contains("i586") { - return - } - } - Err(_) => return, - } - let me = env::current_exe().unwrap(); for level in ["sse", "avx", "avx512"].iter() { let status = Command::new(&me).arg(level).status().unwrap(); diff --git a/tests/ui/abi/interrupt-invalid-signature.avr.stderr b/tests/ui/abi/interrupt-invalid-signature.avr.stderr index 91f5ca2022e38..1cf91a33c523b 100644 --- a/tests/ui/abi/interrupt-invalid-signature.avr.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.avr.stderr @@ -1,5 +1,5 @@ error: invalid signature for `extern "avr-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:44:35 + --> $DIR/interrupt-invalid-signature.rs:45:35 | LL | extern "avr-interrupt" fn avr_arg(_byte: u8) {} | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL + extern "avr-interrupt" fn avr_arg() {} | error: invalid signature for `extern "avr-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:59:40 + --> $DIR/interrupt-invalid-signature.rs:60:40 | LL | extern "avr-interrupt" fn avr_ret() -> u8 { | ^^ diff --git a/tests/ui/abi/interrupt-invalid-signature.i686.stderr b/tests/ui/abi/interrupt-invalid-signature.i686.stderr index df8e318bf0ac4..3a8a0c057448b 100644 --- a/tests/ui/abi/interrupt-invalid-signature.i686.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.i686.stderr @@ -1,18 +1,18 @@ error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:83:53 + --> $DIR/interrupt-invalid-signature.rs:84:53 | LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 { | ^^ | = note: functions with the "x86-interrupt" ABI cannot have a return type help: remove the return type - --> $DIR/interrupt-invalid-signature.rs:83:53 + --> $DIR/interrupt-invalid-signature.rs:84:53 | LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 { | ^^ error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:89:1 + --> $DIR/interrupt-invalid-signature.rs:90:1 | LL | extern "x86-interrupt" fn x86_0() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | extern "x86-interrupt" fn x86_0() { = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 0) error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:100:33 + --> $DIR/interrupt-invalid-signature.rs:101:33 | LL | extern "x86-interrupt" fn x86_3(_p1: *const u8, _p2: *const u8, _p3: *const u8) { | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/interrupt-invalid-signature.msp430.stderr b/tests/ui/abi/interrupt-invalid-signature.msp430.stderr index 38479f93de58f..3fff6492b7ea9 100644 --- a/tests/ui/abi/interrupt-invalid-signature.msp430.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.msp430.stderr @@ -1,5 +1,5 @@ error: invalid signature for `extern "msp430-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:40:41 + --> $DIR/interrupt-invalid-signature.rs:41:41 | LL | extern "msp430-interrupt" fn msp430_arg(_byte: u8) {} | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL + extern "msp430-interrupt" fn msp430_arg() {} | error: invalid signature for `extern "msp430-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:65:46 + --> $DIR/interrupt-invalid-signature.rs:66:46 | LL | extern "msp430-interrupt" fn msp430_ret() -> u8 { | ^^ diff --git a/tests/ui/abi/interrupt-invalid-signature.riscv32.stderr b/tests/ui/abi/interrupt-invalid-signature.riscv32.stderr index d632b17ab83f7..8aea68e65006c 100644 --- a/tests/ui/abi/interrupt-invalid-signature.riscv32.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.riscv32.stderr @@ -1,5 +1,5 @@ error: invalid signature for `extern "riscv-interrupt-m"` function - --> $DIR/interrupt-invalid-signature.rs:48:43 + --> $DIR/interrupt-invalid-signature.rs:49:43 | LL | extern "riscv-interrupt-m" fn riscv_m_arg(_byte: u8) {} | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m_arg() {} | error: invalid signature for `extern "riscv-interrupt-s"` function - --> $DIR/interrupt-invalid-signature.rs:52:43 + --> $DIR/interrupt-invalid-signature.rs:53:43 | LL | extern "riscv-interrupt-s" fn riscv_s_arg(_byte: u8) {} | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s_arg() {} | error: invalid signature for `extern "riscv-interrupt-m"` function - --> $DIR/interrupt-invalid-signature.rs:71:48 + --> $DIR/interrupt-invalid-signature.rs:72:48 | LL | extern "riscv-interrupt-m" fn riscv_m_ret() -> u8 { | ^^ @@ -38,7 +38,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m_ret() { | error: invalid signature for `extern "riscv-interrupt-s"` function - --> $DIR/interrupt-invalid-signature.rs:77:48 + --> $DIR/interrupt-invalid-signature.rs:78:48 | LL | extern "riscv-interrupt-s" fn riscv_s_ret() -> u8 { | ^^ diff --git a/tests/ui/abi/interrupt-invalid-signature.riscv64.stderr b/tests/ui/abi/interrupt-invalid-signature.riscv64.stderr index d632b17ab83f7..8aea68e65006c 100644 --- a/tests/ui/abi/interrupt-invalid-signature.riscv64.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.riscv64.stderr @@ -1,5 +1,5 @@ error: invalid signature for `extern "riscv-interrupt-m"` function - --> $DIR/interrupt-invalid-signature.rs:48:43 + --> $DIR/interrupt-invalid-signature.rs:49:43 | LL | extern "riscv-interrupt-m" fn riscv_m_arg(_byte: u8) {} | ^^^^^^^^^ @@ -12,7 +12,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m_arg() {} | error: invalid signature for `extern "riscv-interrupt-s"` function - --> $DIR/interrupt-invalid-signature.rs:52:43 + --> $DIR/interrupt-invalid-signature.rs:53:43 | LL | extern "riscv-interrupt-s" fn riscv_s_arg(_byte: u8) {} | ^^^^^^^^^ @@ -25,7 +25,7 @@ LL + extern "riscv-interrupt-s" fn riscv_s_arg() {} | error: invalid signature for `extern "riscv-interrupt-m"` function - --> $DIR/interrupt-invalid-signature.rs:71:48 + --> $DIR/interrupt-invalid-signature.rs:72:48 | LL | extern "riscv-interrupt-m" fn riscv_m_ret() -> u8 { | ^^ @@ -38,7 +38,7 @@ LL + extern "riscv-interrupt-m" fn riscv_m_ret() { | error: invalid signature for `extern "riscv-interrupt-s"` function - --> $DIR/interrupt-invalid-signature.rs:77:48 + --> $DIR/interrupt-invalid-signature.rs:78:48 | LL | extern "riscv-interrupt-s" fn riscv_s_ret() -> u8 { | ^^ diff --git a/tests/ui/abi/interrupt-invalid-signature.rs b/tests/ui/abi/interrupt-invalid-signature.rs index 09bda0d5faf13..e81a52e986780 100644 --- a/tests/ui/abi/interrupt-invalid-signature.rs +++ b/tests/ui/abi/interrupt-invalid-signature.rs @@ -22,6 +22,7 @@ This test uses `cfg` because it is not testing whether these ABIs work on the pl //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature( no_core, diff --git a/tests/ui/abi/interrupt-invalid-signature.x64.stderr b/tests/ui/abi/interrupt-invalid-signature.x64.stderr index df8e318bf0ac4..3a8a0c057448b 100644 --- a/tests/ui/abi/interrupt-invalid-signature.x64.stderr +++ b/tests/ui/abi/interrupt-invalid-signature.x64.stderr @@ -1,18 +1,18 @@ error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:83:53 + --> $DIR/interrupt-invalid-signature.rs:84:53 | LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 { | ^^ | = note: functions with the "x86-interrupt" ABI cannot have a return type help: remove the return type - --> $DIR/interrupt-invalid-signature.rs:83:53 + --> $DIR/interrupt-invalid-signature.rs:84:53 | LL | extern "x86-interrupt" fn x86_ret(_p: *const u8) -> u8 { | ^^ error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:89:1 + --> $DIR/interrupt-invalid-signature.rs:90:1 | LL | extern "x86-interrupt" fn x86_0() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | extern "x86-interrupt" fn x86_0() { = note: functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found 0) error: invalid signature for `extern "x86-interrupt"` function - --> $DIR/interrupt-invalid-signature.rs:100:33 + --> $DIR/interrupt-invalid-signature.rs:101:33 | LL | extern "x86-interrupt" fn x86_3(_p1: *const u8, _p2: *const u8, _p3: *const u8) { | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/interrupt-returns-never-or-unit.rs b/tests/ui/abi/interrupt-returns-never-or-unit.rs index 104b36363d0cb..bf7036f00b6df 100644 --- a/tests/ui/abi/interrupt-returns-never-or-unit.rs +++ b/tests/ui/abi/interrupt-returns-never-or-unit.rs @@ -21,6 +21,7 @@ This test uses `cfg` because it is not testing whether these ABIs work on the pl //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature( no_core, diff --git a/tests/ui/abi/issue-28676.rs b/tests/ui/abi/issue-28676.rs index 8640f5aad21c9..2abb4ce52b3b3 100644 --- a/tests/ui/abi/issue-28676.rs +++ b/tests/ui/abi/issue-28676.rs @@ -1,4 +1,6 @@ //@ run-pass +//@ ignore-backends: gcc + #![allow(dead_code)] #![allow(improper_ctypes)] diff --git a/tests/ui/abi/large-byval-align.rs b/tests/ui/abi/large-byval-align.rs index c1de841178fcd..69418e1cbc7b8 100644 --- a/tests/ui/abi/large-byval-align.rs +++ b/tests/ui/abi/large-byval-align.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Copt-level=0 //@ only-x86_64 //@ build-pass +//@ ignore-backends: gcc #[repr(align(536870912))] pub struct A(i64); diff --git a/tests/ui/abi/numbers-arithmetic/float-struct.rs b/tests/ui/abi/numbers-arithmetic/float-struct.rs index a958dc272722f..dc4c536a14e2d 100644 --- a/tests/ui/abi/numbers-arithmetic/float-struct.rs +++ b/tests/ui/abi/numbers-arithmetic/float-struct.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ ignore-backends: gcc use std::fmt::Debug; use std::hint::black_box; diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr index c71797b500d63..0378b9daafe79 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr @@ -1,5 +1,5 @@ error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:15:8 + --> $DIR/riscv-discoverability-guidance.rs:16:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ invalid ABI @@ -11,7 +11,7 @@ LL | extern "riscv-interrupt-m" fn isr() {} | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:20:8 + --> $DIR/riscv-discoverability-guidance.rs:21:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ invalid ABI diff --git a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr index c71797b500d63..0378b9daafe79 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr +++ b/tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr @@ -1,5 +1,5 @@ error[E0703]: invalid ABI: found `riscv-interrupt` - --> $DIR/riscv-discoverability-guidance.rs:15:8 + --> $DIR/riscv-discoverability-guidance.rs:16:8 | LL | extern "riscv-interrupt" fn isr() {} | ^^^^^^^^^^^^^^^^^ invalid ABI @@ -11,7 +11,7 @@ LL | extern "riscv-interrupt-m" fn isr() {} | ++ error[E0703]: invalid ABI: found `riscv-interrupt-u` - --> $DIR/riscv-discoverability-guidance.rs:20:8 + --> $DIR/riscv-discoverability-guidance.rs:21:8 | LL | extern "riscv-interrupt-u" fn isr_U() {} | ^^^^^^^^^^^^^^^^^^^ invalid ABI diff --git a/tests/ui/abi/riscv-discoverability-guidance.rs b/tests/ui/abi/riscv-discoverability-guidance.rs index 41cce35aefada..28309e7c62dbc 100644 --- a/tests/ui/abi/riscv-discoverability-guidance.rs +++ b/tests/ui/abi/riscv-discoverability-guidance.rs @@ -6,6 +6,7 @@ //@ [riscv32] compile-flags: --target=riscv32i-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib //@ [riscv64] needs-llvm-components: riscv //@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf -C target-feature=-unaligned-scalar-mem --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature(no_core, lang_items, abi_riscv_interrupt)] diff --git a/tests/ui/abi/segfault-no-out-of-stack.rs b/tests/ui/abi/segfault-no-out-of-stack.rs index 5e8b4e0dbf2a6..b122079d36f76 100644 --- a/tests/ui/abi/segfault-no-out-of-stack.rs +++ b/tests/ui/abi/segfault-no-out-of-stack.rs @@ -2,6 +2,7 @@ //@ needs-subprocess //@ compile-flags: -Zub-checks=no -Zmir-enable-passes=-CheckNull //@ ignore-fuchsia must translate zircon signal to SIGSEGV/SIGBUS, FIXME (#58590) +//@ ignore-backends: gcc #![feature(rustc_private)] diff --git a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs index b3bd0666ab21f..824327ad06d36 100644 --- a/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs +++ b/tests/ui/abi/shadow-call-stack-without-fixed-x18.rs @@ -1,6 +1,7 @@ //@ compile-flags: --target aarch64-unknown-none -Zsanitizer=shadow-call-stack //@ dont-check-compiler-stderr //@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![allow(internal_features)] #![crate_type = "rlib"] diff --git a/tests/ui/abi/simd-abi-checks-empty-list.rs b/tests/ui/abi/simd-abi-checks-empty-list.rs index d00445b29e055..f4b5ca7be7d98 100644 --- a/tests/ui/abi/simd-abi-checks-empty-list.rs +++ b/tests/ui/abi/simd-abi-checks-empty-list.rs @@ -4,6 +4,7 @@ //@ needs-llvm-components: sparc //@ compile-flags: --target=sparc-unknown-none-elf --crate-type=rlib //@ build-fail +//@ ignore-backends: gcc #![no_core] #![feature(no_core, repr_simd)] #![allow(improper_ctypes_definitions)] diff --git a/tests/ui/abi/simd-abi-checks-empty-list.stderr b/tests/ui/abi/simd-abi-checks-empty-list.stderr index 780afb3844fc5..603f5daeb2a10 100644 --- a/tests/ui/abi/simd-abi-checks-empty-list.stderr +++ b/tests/ui/abi/simd-abi-checks-empty-list.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `SimdVec` which is not currently supported with the chosen ABI - --> $DIR/simd-abi-checks-empty-list.rs:17:1 + --> $DIR/simd-abi-checks-empty-list.rs:18:1 | LL | pub extern "C" fn pass_by_vec(_: SimdVec) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.rs b/tests/ui/abi/simd-abi-checks-s390x.rs index 75232a66ab091..b2d64cecd5234 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.rs +++ b/tests/ui/abi/simd-abi-checks-s390x.rs @@ -8,6 +8,7 @@ // FIXME: +soft-float itself doesn't set -vector //@[z13_soft_float] compile-flags: --target s390x-unknown-linux-gnu -C target-cpu=z13 -C target-feature=-vector,+soft-float //@[z13_soft_float] needs-llvm-components: systemz +//@ ignore-backends: gcc //[z13_soft_float]~? WARN must be disabled to ensure that the ABI of the current target can be implemented correctly #![feature(no_core, repr_simd, s390x_target_feature)] diff --git a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr index e1cfa373c63cb..d5f6657c27e8e 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z10.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z10.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:39:1 + --> $DIR/simd-abi-checks-s390x.rs:40:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:44:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:90:1 + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:97:1 + --> $DIR/simd-abi-checks-s390x.rs:98:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:112:1 + --> $DIR/simd-abi-checks-s390x.rs:113:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:117:1 + --> $DIR/simd-abi-checks-s390x.rs:118:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:128:1 + --> $DIR/simd-abi-checks-s390x.rs:129:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:133:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:144:1 + --> $DIR/simd-abi-checks-s390x.rs:145:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:149:1 + --> $DIR/simd-abi-checks-s390x.rs:150:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr index e1cfa373c63cb..d5f6657c27e8e 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_no_vector.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:39:1 + --> $DIR/simd-abi-checks-s390x.rs:40:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +7,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:44:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -15,7 +15,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:90:1 + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -25,7 +25,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:97:1 + --> $DIR/simd-abi-checks-s390x.rs:98:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -35,7 +35,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:112:1 + --> $DIR/simd-abi-checks-s390x.rs:113:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -43,7 +43,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:117:1 + --> $DIR/simd-abi-checks-s390x.rs:118:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -51,7 +51,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:128:1 + --> $DIR/simd-abi-checks-s390x.rs:129:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -59,7 +59,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:133:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -67,7 +67,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:144:1 + --> $DIR/simd-abi-checks-s390x.rs:145:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -75,7 +75,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:149:1 + --> $DIR/simd-abi-checks-s390x.rs:150:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr index 577fcc23bf166..d993d6a4e9ea4 100644 --- a/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr +++ b/tests/ui/abi/simd-abi-checks-s390x.z13_soft_float.stderr @@ -4,7 +4,7 @@ warning: target feature `soft-float` must be disabled to ensure that the ABI of = note: for more information, see issue #116344 error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:39:1 + --> $DIR/simd-abi-checks-s390x.rs:40:1 | LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -12,7 +12,7 @@ LL | extern "C" fn vector_ret_small(x: &i8x8) -> i8x8 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:44:1 + --> $DIR/simd-abi-checks-s390x.rs:45:1 | LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -20,7 +20,7 @@ LL | extern "C" fn vector_ret(x: &i8x16) -> i8x16 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:90:1 + --> $DIR/simd-abi-checks-s390x.rs:91:1 | LL | / extern "C" fn vector_transparent_wrapper_ret_small( LL | | x: &TransparentWrapper, @@ -30,7 +30,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:97:1 + --> $DIR/simd-abi-checks-s390x.rs:98:1 | LL | / extern "C" fn vector_transparent_wrapper_ret( LL | | x: &TransparentWrapper, @@ -40,7 +40,7 @@ LL | | ) -> TransparentWrapper { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x8` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:112:1 + --> $DIR/simd-abi-checks-s390x.rs:113:1 | LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -48,7 +48,7 @@ LL | extern "C" fn vector_arg_small(x: i8x8) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `i8x16` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:117:1 + --> $DIR/simd-abi-checks-s390x.rs:118:1 | LL | extern "C" fn vector_arg(x: i8x16) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -56,7 +56,7 @@ LL | extern "C" fn vector_arg(x: i8x16) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:128:1 + --> $DIR/simd-abi-checks-s390x.rs:129:1 | LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -64,7 +64,7 @@ LL | extern "C" fn vector_wrapper_arg_small(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `Wrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:133:1 + --> $DIR/simd-abi-checks-s390x.rs:134:1 | LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -72,7 +72,7 @@ LL | extern "C" fn vector_wrapper_arg(x: Wrapper) -> i64 { = help: consider enabling it globally (`-C target-feature=+vector`) or locally (`#[target_feature(enable="vector")]`) error: this function definition uses SIMD vector type `TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:144:1 + --> $DIR/simd-abi-checks-s390x.rs:145:1 | LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -80,7 +80,7 @@ LL | extern "C" fn vector_transparent_wrapper_arg_small(x: TransparentWrapper` which (with the chosen ABI) requires the `vector` target feature, which is not enabled - --> $DIR/simd-abi-checks-s390x.rs:149:1 + --> $DIR/simd-abi-checks-s390x.rs:150:1 | LL | extern "C" fn vector_transparent_wrapper_arg(x: TransparentWrapper) -> i64 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/simd-abi-checks-sse.rs b/tests/ui/abi/simd-abi-checks-sse.rs index 817f9b6d13bc6..8e8379c23fc44 100644 --- a/tests/ui/abi/simd-abi-checks-sse.rs +++ b/tests/ui/abi/simd-abi-checks-sse.rs @@ -5,6 +5,7 @@ //@ add-core-stubs //@ build-fail //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, repr_simd)] #![no_core] #![allow(improper_ctypes_definitions)] diff --git a/tests/ui/abi/simd-abi-checks-sse.stderr b/tests/ui/abi/simd-abi-checks-sse.stderr index a5a2ba808c660..018d8b687d513 100644 --- a/tests/ui/abi/simd-abi-checks-sse.stderr +++ b/tests/ui/abi/simd-abi-checks-sse.stderr @@ -1,5 +1,5 @@ error: this function definition uses SIMD vector type `SseVector` which (with the chosen ABI) requires the `sse` target feature, which is not enabled - --> $DIR/simd-abi-checks-sse.rs:19:1 + --> $DIR/simd-abi-checks-sse.rs:20:1 | LL | pub unsafe extern "C" fn f(_: SseVector) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here diff --git a/tests/ui/abi/sparcv8plus-llvm19.rs b/tests/ui/abi/sparcv8plus-llvm19.rs deleted file mode 100644 index 3d6d8568b6e5a..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.rs +++ /dev/null @@ -1,42 +0,0 @@ -//@ add-core-stubs -//@ revisions: sparc sparcv8plus sparc_cpu_v9 sparc_feature_v8plus sparc_cpu_v9_feature_v8plus -//@[sparc] compile-flags: --target sparc-unknown-none-elf -//@[sparc] needs-llvm-components: sparc -//@[sparcv8plus] compile-flags: --target sparc-unknown-linux-gnu -//@[sparcv8plus] needs-llvm-components: sparc -//@[sparc_cpu_v9] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -//@[sparc_cpu_v9] needs-llvm-components: sparc -//@[sparc_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-feature=+v8plus -//@[sparc_feature_v8plus] needs-llvm-components: sparc -//@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus -//@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc -//@ exact-llvm-major-version: 19 - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items)] -#![no_core] - -extern crate minicore; -use minicore::*; - -#[rustc_builtin_macro] -macro_rules! compile_error { - () => {}; -} - -#[cfg(all(not(target_feature = "v8plus"), not(target_feature = "v9")))] -compile_error!("-v8plus,-v9"); -//[sparc]~^ ERROR -v8plus,-v9 - -// FIXME: sparc_cpu_v9 should be in "-v8plus,+v9" group (fixed in LLVM 20) -#[cfg(all(target_feature = "v8plus", target_feature = "v9"))] -compile_error!("+v8plus,+v9"); -//[sparcv8plus,sparc_cpu_v9_feature_v8plus,sparc_cpu_v9]~^ ERROR +v8plus,+v9 - -// FIXME: should be rejected -#[cfg(all(target_feature = "v8plus", not(target_feature = "v9")))] -compile_error!("+v8plus,-v9 (FIXME)"); -//[sparc_feature_v8plus]~^ ERROR +v8plus,-v9 (FIXME) - -#[cfg(all(not(target_feature = "v8plus"), target_feature = "v9"))] -compile_error!("-v8plus,+v9"); diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr deleted file mode 100644 index d3462ae87d338..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: -v8plus,-v9 - --> $DIR/sparcv8plus-llvm19.rs:28:1 - | -LL | compile_error!("-v8plus,-v9"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr deleted file mode 100644 index 9891aec94b860..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:33:1 - | -LL | compile_error!("+v8plus,+v9"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr deleted file mode 100644 index 9891aec94b860..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_cpu_v9_feature_v8plus.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:33:1 - | -LL | compile_error!("+v8plus,+v9"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr deleted file mode 100644 index dbcdb8ed121b3..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.sparc_feature_v8plus.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: +v8plus,-v9 (FIXME) - --> $DIR/sparcv8plus-llvm19.rs:38:1 - | -LL | compile_error!("+v8plus,-v9 (FIXME)"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr b/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr deleted file mode 100644 index 9891aec94b860..0000000000000 --- a/tests/ui/abi/sparcv8plus-llvm19.sparcv8plus.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: +v8plus,+v9 - --> $DIR/sparcv8plus-llvm19.rs:33:1 - | -LL | compile_error!("+v8plus,+v9"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/abi/sparcv8plus.rs b/tests/ui/abi/sparcv8plus.rs index 6c17f72183862..c03853b6a387c 100644 --- a/tests/ui/abi/sparcv8plus.rs +++ b/tests/ui/abi/sparcv8plus.rs @@ -10,7 +10,7 @@ //@[sparc_feature_v8plus] needs-llvm-components: sparc //@[sparc_cpu_v9_feature_v8plus] compile-flags: --target sparc-unknown-none-elf -C target-cpu=v9 -C target-feature=+v8plus //@[sparc_cpu_v9_feature_v8plus] needs-llvm-components: sparc -//@ min-llvm-version: 20 +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(no_core, rustc_attrs, lang_items)] diff --git a/tests/ui/abi/stack-probes-lto.rs b/tests/ui/abi/stack-probes-lto.rs index c6e5bea5f4225..6203be90590d3 100644 --- a/tests/ui/abi/stack-probes-lto.rs +++ b/tests/ui/abi/stack-probes-lto.rs @@ -13,5 +13,6 @@ //@ ignore-tvos Stack probes are enabled, but the SIGSEGV handler isn't //@ ignore-watchos Stack probes are enabled, but the SIGSEGV handler isn't //@ ignore-visionos Stack probes are enabled, but the SIGSEGV handler isn't +//@ ignore-backends: gcc include!("stack-probes.rs"); diff --git a/tests/ui/abi/stack-probes.rs b/tests/ui/abi/stack-probes.rs index f0fbd80d2e734..4d0301411e0fd 100644 --- a/tests/ui/abi/stack-probes.rs +++ b/tests/ui/abi/stack-probes.rs @@ -10,6 +10,7 @@ //@ ignore-tvos Stack probes are enabled, but the SIGSEGV handler isn't //@ ignore-watchos Stack probes are enabled, but the SIGSEGV handler isn't //@ ignore-visionos Stack probes are enabled, but the SIGSEGV handler isn't +//@ ignore-backends: gcc use std::env; use std::mem::MaybeUninit; diff --git a/tests/ui/abi/stack-protector.rs b/tests/ui/abi/stack-protector.rs index 29332861977b7..928b49c0eea50 100644 --- a/tests/ui/abi/stack-protector.rs +++ b/tests/ui/abi/stack-protector.rs @@ -4,6 +4,7 @@ //@ [ssp] compile-flags: -Z stack-protector=all //@ compile-flags: -C opt-level=2 //@ compile-flags: -g +//@ ignore-backends: gcc use std::env; use std::process::{Command, ExitStatus}; diff --git a/tests/ui/abi/struct-enums/struct-return.rs b/tests/ui/abi/struct-enums/struct-return.rs index 5b39c0de45467..5fe80d5f670b2 100644 --- a/tests/ui/abi/struct-enums/struct-return.rs +++ b/tests/ui/abi/struct-enums/struct-return.rs @@ -1,4 +1,6 @@ //@ run-pass +//@ ignore-backends: gcc + #![allow(dead_code)] #[repr(C)] diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr index f2b14e0707ba6..00cc31170b74f 100644 --- a/tests/ui/abi/unsupported.aarch64.stderr +++ b/tests/ui/abi/unsupported.aarch64.stderr @@ -1,89 +1,89 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:62:8 + --> $DIR/unsupported.rs:63:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:8 + --> $DIR/unsupported.rs:66:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:8 + --> $DIR/unsupported.rs:78:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -91,7 +91,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:26 + --> $DIR/unsupported.rs:82:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -99,7 +99,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:8 + --> $DIR/unsupported.rs:88:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:8 + --> $DIR/unsupported.rs:92:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -115,49 +115,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:111:8 + --> $DIR/unsupported.rs:112:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:29 + --> $DIR/unsupported.rs:114:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:8 + --> $DIR/unsupported.rs:118:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -168,7 +168,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -178,7 +178,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr index bc666b7ced1ba..23bdcc2272950 100644 --- a/tests/ui/abi/unsupported.arm.stderr +++ b/tests/ui/abi/unsupported.arm.stderr @@ -1,71 +1,71 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:62:8 + --> $DIR/unsupported.rs:63:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:8 + --> $DIR/unsupported.rs:66:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:8 + --> $DIR/unsupported.rs:78:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -73,7 +73,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:26 + --> $DIR/unsupported.rs:82:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -81,7 +81,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:8 + --> $DIR/unsupported.rs:88:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:8 + --> $DIR/unsupported.rs:92:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -97,49 +97,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:111:8 + --> $DIR/unsupported.rs:112:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:29 + --> $DIR/unsupported.rs:114:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:8 + --> $DIR/unsupported.rs:118:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -150,7 +150,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -170,7 +170,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr index 8478c4819416c..0b29b557c6d48 100644 --- a/tests/ui/abi/unsupported.i686.stderr +++ b/tests/ui/abi/unsupported.i686.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:62:8 + --> $DIR/unsupported.rs:63:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr index 722b1ec7713ed..ef1f1b53cdc56 100644 --- a/tests/ui/abi/unsupported.riscv32.stderr +++ b/tests/ui/abi/unsupported.riscv32.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:8 + --> $DIR/unsupported.rs:66:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:8 + --> $DIR/unsupported.rs:78:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:26 + --> $DIR/unsupported.rs:82:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:8 + --> $DIR/unsupported.rs:88:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:8 + --> $DIR/unsupported.rs:92:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,49 +109,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:111:8 + --> $DIR/unsupported.rs:112:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:29 + --> $DIR/unsupported.rs:114:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:8 + --> $DIR/unsupported.rs:118:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr index 722b1ec7713ed..ef1f1b53cdc56 100644 --- a/tests/ui/abi/unsupported.riscv64.stderr +++ b/tests/ui/abi/unsupported.riscv64.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "x86-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:65:8 + --> $DIR/unsupported.rs:66:8 | LL | extern "x86-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:8 + --> $DIR/unsupported.rs:78:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:26 + --> $DIR/unsupported.rs:82:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:8 + --> $DIR/unsupported.rs:88:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:8 + --> $DIR/unsupported.rs:92:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,49 +109,49 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:111:8 + --> $DIR/unsupported.rs:112:8 | LL | extern "vectorcall" fn vectorcall() {} | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:113:29 + --> $DIR/unsupported.rs:114:29 | LL | fn vectorcall_ptr(f: extern "vectorcall" fn()) { | ^^^^^^^^^^^^ error[E0570]: "vectorcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:117:8 + --> $DIR/unsupported.rs:118:8 | LL | extern "vectorcall" {} | ^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.rs b/tests/ui/abi/unsupported.rs index 828fcc147a560..a217b8eb87cff 100644 --- a/tests/ui/abi/unsupported.rs +++ b/tests/ui/abi/unsupported.rs @@ -15,6 +15,7 @@ //@ [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib //@ [riscv64] needs-llvm-components: riscv //@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature( no_core, diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr index 3bf19f9f19d2c..0c338849ae9d8 100644 --- a/tests/ui/abi/unsupported.x64.stderr +++ b/tests/ui/abi/unsupported.x64.stderr @@ -1,83 +1,83 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:62:8 + --> $DIR/unsupported.rs:63:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:8 + --> $DIR/unsupported.rs:78:8 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^ @@ -85,7 +85,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:26 + --> $DIR/unsupported.rs:82:26 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^ @@ -93,7 +93,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:8 + --> $DIR/unsupported.rs:88:8 | LL | extern "stdcall" {} | ^^^^^^^^^ @@ -101,7 +101,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` error[E0570]: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:8 + --> $DIR/unsupported.rs:92:8 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^ @@ -109,31 +109,31 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -144,7 +144,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -154,7 +154,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -164,7 +164,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/unsupported.x64_win.stderr b/tests/ui/abi/unsupported.x64_win.stderr index 70f63a14d768a..07c4eb691fe97 100644 --- a/tests/ui/abi/unsupported.x64_win.stderr +++ b/tests/ui/abi/unsupported.x64_win.stderr @@ -1,107 +1,107 @@ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:36:8 + --> $DIR/unsupported.rs:37:8 | LL | extern "ptx-kernel" fn ptx() {} | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:38:22 + --> $DIR/unsupported.rs:39:22 | LL | fn ptx_ptr(f: extern "ptx-kernel" fn()) { | ^^^^^^^^^^^^ error[E0570]: "ptx-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:42:8 + --> $DIR/unsupported.rs:43:8 | LL | extern "ptx-kernel" {} | ^^^^^^^^^^^^ error[E0570]: "gpu-kernel" is not a supported ABI for the current target - --> $DIR/unsupported.rs:44:8 + --> $DIR/unsupported.rs:45:8 | LL | extern "gpu-kernel" fn gpu() {} | ^^^^^^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:47:8 + --> $DIR/unsupported.rs:48:8 | LL | extern "aapcs" fn aapcs() {} | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:49:24 + --> $DIR/unsupported.rs:50:24 | LL | fn aapcs_ptr(f: extern "aapcs" fn()) { | ^^^^^^^ error[E0570]: "aapcs" is not a supported ABI for the current target - --> $DIR/unsupported.rs:53:8 + --> $DIR/unsupported.rs:54:8 | LL | extern "aapcs" {} | ^^^^^^^ error[E0570]: "msp430-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:56:8 + --> $DIR/unsupported.rs:57:8 | LL | extern "msp430-interrupt" {} | ^^^^^^^^^^^^^^^^^^ error[E0570]: "avr-interrupt" is not a supported ABI for the current target - --> $DIR/unsupported.rs:59:8 + --> $DIR/unsupported.rs:60:8 | LL | extern "avr-interrupt" {} | ^^^^^^^^^^^^^^^ error[E0570]: "riscv-interrupt-m" is not a supported ABI for the current target - --> $DIR/unsupported.rs:62:8 + --> $DIR/unsupported.rs:63:8 | LL | extern "riscv-interrupt-m" {} | ^^^^^^^^^^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:68:8 + --> $DIR/unsupported.rs:69:8 | LL | extern "thiscall" fn thiscall() {} | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:70:27 + --> $DIR/unsupported.rs:71:27 | LL | fn thiscall_ptr(f: extern "thiscall" fn()) { | ^^^^^^^^^^ error[E0570]: "thiscall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:74:8 + --> $DIR/unsupported.rs:75:8 | LL | extern "thiscall" {} | ^^^^^^^^^^ error[E0570]: "cmse-nonsecure-call" is not a supported ABI for the current target - --> $DIR/unsupported.rs:120:28 + --> $DIR/unsupported.rs:121:28 | LL | fn cmse_call_ptr(f: extern "cmse-nonsecure-call" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:125:8 + --> $DIR/unsupported.rs:126:8 | LL | extern "cmse-nonsecure-entry" fn cmse_entry() {} | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:127:29 + --> $DIR/unsupported.rs:128:29 | LL | fn cmse_entry_ptr(f: extern "cmse-nonsecure-entry" fn()) { | ^^^^^^^^^^^^^^^^^^^^^^ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/unsupported.rs:131:8 + --> $DIR/unsupported.rs:132:8 | LL | extern "cmse-nonsecure-entry" {} | ^^^^^^^^^^^^^^^^^^^^^^ warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:81:19 + --> $DIR/unsupported.rs:82:19 | LL | fn stdcall_ptr(f: extern "stdcall" fn()) { | ^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +112,7 @@ LL | fn stdcall_ptr(f: extern "stdcall" fn()) { = note: `#[warn(unsupported_calling_conventions)]` (part of `#[warn(future_incompatible)]`) on by default warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:87:1 + --> $DIR/unsupported.rs:88:1 | LL | extern "stdcall" {} | ^^^^^^^^^^^^^^^^^^^ @@ -122,7 +122,7 @@ LL | extern "stdcall" {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: "stdcall-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:91:1 + --> $DIR/unsupported.rs:92:1 | LL | extern "stdcall-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | extern "stdcall-unwind" {} = help: if you need `extern "stdcall-unwind"` on win32 and `extern "C-unwind"` everywhere else, use `extern "system-unwind"` warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:99:17 + --> $DIR/unsupported.rs:100:17 | LL | fn cdecl_ptr(f: extern "cdecl" fn()) { | ^^^^^^^^^^^^^^^^^^^ @@ -142,7 +142,7 @@ LL | fn cdecl_ptr(f: extern "cdecl" fn()) { = help: use `extern "C"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:104:1 + --> $DIR/unsupported.rs:105:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -152,7 +152,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "cdecl-unwind" is not a supported ABI for the current target - --> $DIR/unsupported.rs:107:1 + --> $DIR/unsupported.rs:108:1 | LL | extern "cdecl-unwind" {} | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -162,7 +162,7 @@ LL | extern "cdecl-unwind" {} = help: use `extern "C-unwind"` instead warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:136:1 + --> $DIR/unsupported.rs:137:1 | LL | extern "cdecl" {} | ^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ LL | extern "cdecl" {} = help: use `extern "C"` instead warning: "stdcall" is not a supported ABI for the current target - --> $DIR/unsupported.rs:77:1 + --> $DIR/unsupported.rs:78:1 | LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | extern "stdcall" fn stdcall() {} = help: if you need `extern "stdcall"` on win32 and `extern "C"` everywhere else, use `extern "system"` warning: "cdecl" is not a supported ABI for the current target - --> $DIR/unsupported.rs:96:1 + --> $DIR/unsupported.rs:97:1 | LL | extern "cdecl" fn cdecl() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/abi/variadic-ffi.rs b/tests/ui/abi/variadic-ffi.rs index 6cfae0f2a320f..dfdbff33264be 100644 --- a/tests/ui/abi/variadic-ffi.rs +++ b/tests/ui/abi/variadic-ffi.rs @@ -1,4 +1,6 @@ //@ run-pass +//@ ignore-backends: gcc + #![feature(c_variadic)] use std::ffi::VaList; diff --git a/tests/ui/abi/vectorcall-abi-checks.rs b/tests/ui/abi/vectorcall-abi-checks.rs index f3f399e0e3139..14ad1ef32b627 100644 --- a/tests/ui/abi/vectorcall-abi-checks.rs +++ b/tests/ui/abi/vectorcall-abi-checks.rs @@ -3,6 +3,7 @@ //@ build-fail //@ ignore-pass (test emits codegen-time errors) //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, abi_vectorcall)] #![no_core] diff --git a/tests/ui/abi/vectorcall-abi-checks.stderr b/tests/ui/abi/vectorcall-abi-checks.stderr index 671ebc25b42a0..12c257fc6707d 100644 --- a/tests/ui/abi/vectorcall-abi-checks.stderr +++ b/tests/ui/abi/vectorcall-abi-checks.stderr @@ -1,5 +1,5 @@ error: this function definition uses ABI "vectorcall" which requires the `sse2` target feature, which is not enabled - --> $DIR/vectorcall-abi-checks.rs:13:1 + --> $DIR/vectorcall-abi-checks.rs:14:1 | LL | pub extern "vectorcall" fn f() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function defined here @@ -7,7 +7,7 @@ LL | pub extern "vectorcall" fn f() { = help: consider enabling it globally (`-C target-feature=+sse2`) or locally (`#[target_feature(enable="sse2")]`) error: this function call uses ABI "vectorcall" which requires the `sse2` target feature, which is not enabled in the caller - --> $DIR/vectorcall-abi-checks.rs:19:5 + --> $DIR/vectorcall-abi-checks.rs:20:5 | LL | f(); | ^^^ function called here diff --git a/tests/ui/abi/x86stdcall.rs b/tests/ui/abi/x86stdcall.rs index c1bd35b80d266..77866c30f0e49 100644 --- a/tests/ui/abi/x86stdcall.rs +++ b/tests/ui/abi/x86stdcall.rs @@ -1,5 +1,6 @@ //@ run-pass //@ only-windows +//@ ignore-backends: gcc // GetLastError doesn't seem to work with stack switching #[cfg(windows)] diff --git a/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.rs b/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.rs new file mode 100644 index 0000000000000..65408fd028604 --- /dev/null +++ b/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.rs @@ -0,0 +1,30 @@ +//@ only-linux +//@ compile-flags: --error-format=human --color=always + +// The hightlight span should be correct. See #147070 +struct Thingie; + +impl Thingie { + pub(crate) fn new( + _a: String, + _b: String, + _c: String, + _d: String, + _e: String, + _f: String, + ) -> Self { + unimplemented!() + } +} + +fn main() { + let foo = Thingie::new( + String::from(""), + String::from(""), + String::from(""), + String::from(""), + String::from(""), + String::from(""), + String::from(""), + ); +} diff --git a/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.svg b/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.svg new file mode 100644 index 0000000000000..549acee7cee54 --- /dev/null +++ b/tests/ui/argument-suggestions/wrong-highlight-span-extra-arguments-147070.svg @@ -0,0 +1,72 @@ + + + + + + + error[E0061]: this function takes 6 arguments but 7 arguments were supplied + + --> $DIR/wrong-highlight-span-extra-arguments-147070.rs:21:15 + + | + + LL | let foo = Thingie::new( + + | ^^^^^^^^^^^^ + + ... + + LL | String::from(""), + + | ---------------- unexpected argument #7 of type `String` + + | + + note: associated function defined here + + --> $DIR/wrong-highlight-span-extra-arguments-147070.rs:8:19 + + | + + LL | pub(crate) fn new( + + | ^^^ + + help: remove the extra argument + + | + + LL - String::from(""), + + | + + + + error: aborting due to 1 previous error + + + + For more information about this error, try `rustc --explain E0061`. + + + + + + diff --git a/tests/ui/array-slice-vec/box-of-array-of-drop-1.rs b/tests/ui/array-slice-vec/box-of-array-of-drop-1.rs index c7c05946c4ca9..5f4e381c983a2 100644 --- a/tests/ui/array-slice-vec/box-of-array-of-drop-1.rs +++ b/tests/ui/array-slice-vec/box-of-array-of-drop-1.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc #![allow(overflowing_literals)] diff --git a/tests/ui/array-slice-vec/box-of-array-of-drop-2.rs b/tests/ui/array-slice-vec/box-of-array-of-drop-2.rs index 98175a26ec0d1..ea37d3e721264 100644 --- a/tests/ui/array-slice-vec/box-of-array-of-drop-2.rs +++ b/tests/ui/array-slice-vec/box-of-array-of-drop-2.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc #![allow(overflowing_literals)] diff --git a/tests/ui/array-slice-vec/large-zst-array-compilation-time-68010.rs b/tests/ui/array-slice-vec/large-zst-array-compilation-time-68010.rs new file mode 100644 index 0000000000000..607104dbaa12f --- /dev/null +++ b/tests/ui/array-slice-vec/large-zst-array-compilation-time-68010.rs @@ -0,0 +1,6 @@ +// https://github.com/rust-lang/rust/issues/68010 +//@ build-pass + +fn main() { + println!("{}", [(); usize::MAX].len()); +} diff --git a/tests/ui/array-slice-vec/nested-vec-3.rs b/tests/ui/array-slice-vec/nested-vec-3.rs index 51975743742cf..e3c04ed6f6bf0 100644 --- a/tests/ui/array-slice-vec/nested-vec-3.rs +++ b/tests/ui/array-slice-vec/nested-vec-3.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc #![allow(overflowing_literals)] diff --git a/tests/ui/array-slice-vec/slice-panic-1.rs b/tests/ui/array-slice-vec/slice-panic-1.rs index a745dff96afc7..d7c1098fa2bda 100644 --- a/tests/ui/array-slice-vec/slice-panic-1.rs +++ b/tests/ui/array-slice-vec/slice-panic-1.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc // Test that if a slicing expr[..] fails, the correct cleanups happen. diff --git a/tests/ui/array-slice-vec/slice-panic-2.rs b/tests/ui/array-slice-vec/slice-panic-2.rs index 483a4cbe245db..157e716a95d49 100644 --- a/tests/ui/array-slice-vec/slice-panic-2.rs +++ b/tests/ui/array-slice-vec/slice-panic-2.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc // Test that if a slicing expr[..] fails, the correct cleanups happen. diff --git a/tests/ui/asm/aarch64/arm64ec-sve.rs b/tests/ui/asm/aarch64/arm64ec-sve.rs index 38d1c5a551dd5..f11b9de375ef2 100644 --- a/tests/ui/asm/aarch64/arm64ec-sve.rs +++ b/tests/ui/asm/aarch64/arm64ec-sve.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target arm64ec-pc-windows-msvc //@ needs-asm-support //@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(no_core)] diff --git a/tests/ui/asm/aarch64/arm64ec-sve.stderr b/tests/ui/asm/aarch64/arm64ec-sve.stderr index d654eb4ba1a19..cbae807e804a2 100644 --- a/tests/ui/asm/aarch64/arm64ec-sve.stderr +++ b/tests/ui/asm/aarch64/arm64ec-sve.stderr @@ -1,11 +1,11 @@ error: cannot use register `p0`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC - --> $DIR/arm64ec-sve.rs:18:18 + --> $DIR/arm64ec-sve.rs:19:18 | LL | asm!("", out("p0") _); | ^^^^^^^^^^^ error: cannot use register `ffr`: x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC - --> $DIR/arm64ec-sve.rs:20:18 + --> $DIR/arm64ec-sve.rs:21:18 | LL | asm!("", out("ffr") _); | ^^^^^^^^^^^^ diff --git a/tests/ui/asm/arm-low-dreg.rs b/tests/ui/asm/arm-low-dreg.rs index ed6c7c8af195f..8190076477de6 100644 --- a/tests/ui/asm/arm-low-dreg.rs +++ b/tests/ui/asm/arm-low-dreg.rs @@ -2,6 +2,7 @@ //@ build-pass //@ compile-flags: --target=armv7-unknown-linux-gnueabihf //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(no_core)] #![crate_type = "rlib"] #![no_core] diff --git a/tests/ui/asm/bad-template.aarch64.stderr b/tests/ui/asm/bad-template.aarch64.stderr index ff4ddf70a76b4..30c793f3a4476 100644 --- a/tests/ui/asm/bad-template.aarch64.stderr +++ b/tests/ui/asm/bad-template.aarch64.stderr @@ -1,5 +1,5 @@ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:19:15 + --> $DIR/bad-template.rs:20:15 | LL | asm!("{}"); | ^^ from here @@ -7,7 +7,7 @@ LL | asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:21:15 + --> $DIR/bad-template.rs:22:15 | LL | asm!("{1}", in(reg) foo); | ^^^ from here @@ -15,7 +15,7 @@ LL | asm!("{1}", in(reg) foo); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:21:21 + --> $DIR/bad-template.rs:22:21 | LL | asm!("{1}", in(reg) foo); | ^^^^^^^^^^^ argument never used @@ -23,13 +23,13 @@ LL | asm!("{1}", in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:24:16 + --> $DIR/bad-template.rs:25:16 | LL | asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:26:15 + --> $DIR/bad-template.rs:27:15 | LL | asm!("{}", a = in(reg) foo); | ^^ --------------- named argument @@ -38,13 +38,13 @@ LL | asm!("{}", a = in(reg) foo); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:26:20 + --> $DIR/bad-template.rs:27:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:26:20 + --> $DIR/bad-template.rs:27:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -52,7 +52,7 @@ LL | asm!("{}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:29:15 + --> $DIR/bad-template.rs:30:15 | LL | asm!("{1}", a = in(reg) foo); | ^^^ from here @@ -60,7 +60,7 @@ LL | asm!("{1}", a = in(reg) foo); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:29:21 + --> $DIR/bad-template.rs:30:21 | LL | asm!("{1}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -68,7 +68,7 @@ LL | asm!("{1}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:36:15 + --> $DIR/bad-template.rs:37:15 | LL | asm!("{}", in("x0") foo); | ^^ ------------ explicit register argument @@ -77,24 +77,24 @@ LL | asm!("{}", in("x0") foo); | = note: no positional arguments were given note: explicit register arguments cannot be used in the asm template - --> $DIR/bad-template.rs:36:20 + --> $DIR/bad-template.rs:37:20 | LL | asm!("{}", in("x0") foo); | ^^^^^^^^^^^^ help: use the register name directly in the assembly code - --> $DIR/bad-template.rs:36:20 + --> $DIR/bad-template.rs:37:20 | LL | asm!("{}", in("x0") foo); | ^^^^^^^^^^^^ error: asm template modifier must be a single character - --> $DIR/bad-template.rs:38:17 + --> $DIR/bad-template.rs:39:17 | LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:41:18 + --> $DIR/bad-template.rs:42:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -104,7 +104,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:47:14 + --> $DIR/bad-template.rs:48:14 | LL | global_asm!("{}"); | ^^ from here @@ -112,7 +112,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:49:14 + --> $DIR/bad-template.rs:50:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:49:20 + --> $DIR/bad-template.rs:50:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:52:15 + --> $DIR/bad-template.rs:53:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:54:14 + --> $DIR/bad-template.rs:55:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:54:19 + --> $DIR/bad-template.rs:55:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:54:19 + --> $DIR/bad-template.rs:55:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:57:14 + --> $DIR/bad-template.rs:58:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:57:20 + --> $DIR/bad-template.rs:58:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:60:16 + --> $DIR/bad-template.rs:61:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:62:17 + --> $DIR/bad-template.rs:63:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` warning: formatting may not be suitable for sub-register argument - --> $DIR/bad-template.rs:38:15 + --> $DIR/bad-template.rs:39:15 | LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument diff --git a/tests/ui/asm/bad-template.rs b/tests/ui/asm/bad-template.rs index 524b9f7c2e8f1..0bed9fc480be3 100644 --- a/tests/ui/asm/bad-template.rs +++ b/tests/ui/asm/bad-template.rs @@ -6,6 +6,7 @@ //@ [x86_64] needs-llvm-components: x86 //@ [aarch64] needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/asm/bad-template.x86_64.stderr b/tests/ui/asm/bad-template.x86_64.stderr index 229bd8f272266..6b3f95677d07a 100644 --- a/tests/ui/asm/bad-template.x86_64.stderr +++ b/tests/ui/asm/bad-template.x86_64.stderr @@ -1,5 +1,5 @@ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:19:15 + --> $DIR/bad-template.rs:20:15 | LL | asm!("{}"); | ^^ from here @@ -7,7 +7,7 @@ LL | asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:21:15 + --> $DIR/bad-template.rs:22:15 | LL | asm!("{1}", in(reg) foo); | ^^^ from here @@ -15,7 +15,7 @@ LL | asm!("{1}", in(reg) foo); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:21:21 + --> $DIR/bad-template.rs:22:21 | LL | asm!("{1}", in(reg) foo); | ^^^^^^^^^^^ argument never used @@ -23,13 +23,13 @@ LL | asm!("{1}", in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:24:16 + --> $DIR/bad-template.rs:25:16 | LL | asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:26:15 + --> $DIR/bad-template.rs:27:15 | LL | asm!("{}", a = in(reg) foo); | ^^ --------------- named argument @@ -38,13 +38,13 @@ LL | asm!("{}", a = in(reg) foo); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:26:20 + --> $DIR/bad-template.rs:27:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:26:20 + --> $DIR/bad-template.rs:27:20 | LL | asm!("{}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -52,7 +52,7 @@ LL | asm!("{}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:29:15 + --> $DIR/bad-template.rs:30:15 | LL | asm!("{1}", a = in(reg) foo); | ^^^ from here @@ -60,7 +60,7 @@ LL | asm!("{1}", a = in(reg) foo); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:29:21 + --> $DIR/bad-template.rs:30:21 | LL | asm!("{1}", a = in(reg) foo); | ^^^^^^^^^^^^^^^ named argument never used @@ -68,7 +68,7 @@ LL | asm!("{1}", a = in(reg) foo); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:33:15 + --> $DIR/bad-template.rs:34:15 | LL | asm!("{}", in("eax") foo); | ^^ ------------- explicit register argument @@ -77,24 +77,24 @@ LL | asm!("{}", in("eax") foo); | = note: no positional arguments were given note: explicit register arguments cannot be used in the asm template - --> $DIR/bad-template.rs:33:20 + --> $DIR/bad-template.rs:34:20 | LL | asm!("{}", in("eax") foo); | ^^^^^^^^^^^^^ help: use the register name directly in the assembly code - --> $DIR/bad-template.rs:33:20 + --> $DIR/bad-template.rs:34:20 | LL | asm!("{}", in("eax") foo); | ^^^^^^^^^^^^^ error: asm template modifier must be a single character - --> $DIR/bad-template.rs:38:17 + --> $DIR/bad-template.rs:39:17 | LL | asm!("{:foo}", in(reg) foo); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:41:18 + --> $DIR/bad-template.rs:42:18 | LL | asm!("", in(reg) 0, in(reg) 1); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -104,7 +104,7 @@ LL | asm!("", in(reg) 0, in(reg) 1); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:47:14 + --> $DIR/bad-template.rs:48:14 | LL | global_asm!("{}"); | ^^ from here @@ -112,7 +112,7 @@ LL | global_asm!("{}"); = note: no arguments were given error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:49:14 + --> $DIR/bad-template.rs:50:14 | LL | global_asm!("{1}", const FOO); | ^^^ from here @@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO); = note: there is 1 argument error: argument never used - --> $DIR/bad-template.rs:49:20 + --> $DIR/bad-template.rs:50:20 | LL | global_asm!("{1}", const FOO); | ^^^^^^^^^ argument never used @@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"` error: there is no argument named `a` - --> $DIR/bad-template.rs:52:15 + --> $DIR/bad-template.rs:53:15 | LL | global_asm!("{a}"); | ^ error: invalid reference to argument at index 0 - --> $DIR/bad-template.rs:54:14 + --> $DIR/bad-template.rs:55:14 | LL | global_asm!("{}", a = const FOO); | ^^ ------------- named argument @@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO); | = note: no positional arguments were given note: named arguments cannot be referenced by position - --> $DIR/bad-template.rs:54:19 + --> $DIR/bad-template.rs:55:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ error: named argument never used - --> $DIR/bad-template.rs:54:19 + --> $DIR/bad-template.rs:55:19 | LL | global_asm!("{}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: invalid reference to argument at index 1 - --> $DIR/bad-template.rs:57:14 + --> $DIR/bad-template.rs:58:14 | LL | global_asm!("{1}", a = const FOO); | ^^^ from here @@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO); = note: no positional arguments were given error: named argument never used - --> $DIR/bad-template.rs:57:20 + --> $DIR/bad-template.rs:58:20 | LL | global_asm!("{1}", a = const FOO); | ^^^^^^^^^^^^^ named argument never used @@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO); = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"` error: asm template modifier must be a single character - --> $DIR/bad-template.rs:60:16 + --> $DIR/bad-template.rs:61:16 | LL | global_asm!("{:foo}", const FOO); | ^^^ error: multiple unused asm arguments - --> $DIR/bad-template.rs:62:17 + --> $DIR/bad-template.rs:63:17 | LL | global_asm!("", const FOO, const FOO); | ^^^^^^^^^ ^^^^^^^^^ argument never used @@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO); = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"` warning: formatting may not be suitable for sub-register argument - --> $DIR/bad-template.rs:38:15 + --> $DIR/bad-template.rs:39:15 | LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument diff --git a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs index aef25d057d4ba..94dab4235e093 100644 --- a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs +++ b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs @@ -18,6 +18,7 @@ //@ build-pass //@ needs-asm-support +//@ ignore-backends: gcc use std::arch::global_asm; diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr index 5b4eb3cc1409c..14e32c38884ce 100644 --- a/tests/ui/asm/inline-syntax.arm.stderr +++ b/tests/ui/asm/inline-syntax.arm.stderr @@ -15,7 +15,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:21:15 + --> $DIR/inline-syntax.rs:22:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | .intel_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:24:15 + --> $DIR/inline-syntax.rs:25:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | .intel_syntax aaa noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:27:15 + --> $DIR/inline-syntax.rs:28:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | .att_syntax noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:30:15 + --> $DIR/inline-syntax.rs:31:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ LL | .att_syntax bbb noprefix | ^ error: unknown directive - --> $DIR/inline-syntax.rs:33:15 + --> $DIR/inline-syntax.rs:34:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -75,7 +75,7 @@ LL | .intel_syntax noprefix; nop | ^ error: unknown directive - --> $DIR/inline-syntax.rs:39:13 + --> $DIR/inline-syntax.rs:40:13 | LL | .intel_syntax noprefix | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs index 5f2f4e357f9ce..dae70094e711f 100644 --- a/tests/ui/asm/inline-syntax.rs +++ b/tests/ui/asm/inline-syntax.rs @@ -8,6 +8,7 @@ //@[arm] build-fail //@[arm] needs-llvm-components: arm //@ needs-asm-support +//@ ignore-backends: gcc #![feature(no_core)] #![crate_type = "rlib"] diff --git a/tests/ui/asm/inline-syntax.x86_64.stderr b/tests/ui/asm/inline-syntax.x86_64.stderr index 2d8091c204411..76f4cc054ef98 100644 --- a/tests/ui/asm/inline-syntax.x86_64.stderr +++ b/tests/ui/asm/inline-syntax.x86_64.stderr @@ -1,5 +1,5 @@ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:47:14 + --> $DIR/inline-syntax.rs:48:14 | LL | global_asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop"); = note: `#[warn(bad_asm_style)]` on by default warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:21:15 + --> $DIR/inline-syntax.rs:22:15 | LL | asm!(".intel_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:24:15 + --> $DIR/inline-syntax.rs:25:15 | LL | asm!(".intel_syntax aaa noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:27:15 + --> $DIR/inline-syntax.rs:28:15 | LL | asm!(".att_syntax noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead - --> $DIR/inline-syntax.rs:30:15 + --> $DIR/inline-syntax.rs:31:15 | LL | asm!(".att_syntax bbb noprefix", "nop"); | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:33:15 + --> $DIR/inline-syntax.rs:34:15 | LL | asm!(".intel_syntax noprefix; nop"); | ^^^^^^^^^^^^^^^^^^^^^^ warning: avoid using `.intel_syntax`, Intel syntax is the default - --> $DIR/inline-syntax.rs:39:13 + --> $DIR/inline-syntax.rs:40:13 | LL | .intel_syntax noprefix | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/asm/issue-85247.rs b/tests/ui/asm/issue-85247.rs index f54c868dd5610..f81c08fd5bd0f 100644 --- a/tests/ui/asm/issue-85247.rs +++ b/tests/ui/asm/issue-85247.rs @@ -6,6 +6,7 @@ //@ [ropi] needs-llvm-components: arm //@ [rwpi] needs-llvm-components: arm //@ [ropi] build-pass +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/asm/issue-85247.rwpi.stderr b/tests/ui/asm/issue-85247.rwpi.stderr index 8d51b62ac090b..b9b2004df8f73 100644 --- a/tests/ui/asm/issue-85247.rwpi.stderr +++ b/tests/ui/asm/issue-85247.rwpi.stderr @@ -1,5 +1,5 @@ error: cannot use register `r9`: the RWPI static base register (r9) cannot be used as an operand for inline asm - --> $DIR/issue-85247.rs:20:18 + --> $DIR/issue-85247.rs:21:18 | LL | asm!("", out("r9") _); | ^^^^^^^^^^^ diff --git a/tests/ui/asm/issue-92378.rs b/tests/ui/asm/issue-92378.rs index e8a15b119461e..8f9c91373f9a1 100644 --- a/tests/ui/asm/issue-92378.rs +++ b/tests/ui/asm/issue-92378.rs @@ -3,6 +3,7 @@ //@ needs-llvm-components: arm //@ needs-asm-support //@ build-pass +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/asm/issue-99071.rs b/tests/ui/asm/issue-99071.rs index 522ac1fe8877c..6eb179daa7881 100644 --- a/tests/ui/asm/issue-99071.rs +++ b/tests/ui/asm/issue-99071.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv6m-none-eabi //@ needs-llvm-components: arm //@ needs-asm-support +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/asm/issue-99071.stderr b/tests/ui/asm/issue-99071.stderr index 1a8074b01d66d..b869f9a70b4cf 100644 --- a/tests/ui/asm/issue-99071.stderr +++ b/tests/ui/asm/issue-99071.stderr @@ -1,5 +1,5 @@ error: cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code - --> $DIR/issue-99071.rs:15:18 + --> $DIR/issue-99071.rs:16:18 | LL | asm!("", in("r8") 0); | ^^^^^^^^^^ diff --git a/tests/ui/asm/label-operand.rs b/tests/ui/asm/label-operand.rs new file mode 100644 index 0000000000000..f1be5d7d85609 --- /dev/null +++ b/tests/ui/asm/label-operand.rs @@ -0,0 +1,53 @@ +//@ run-pass +//@ reference: asm.operand-type.supported-operands.label +//@ revisions: aarch64 arm arm64ec riscv32 riscv64 x86 x86_64 +//@ needs-asm-support +//@[aarch64] only-aarch64 +//@[arm64ec] only-arm64ec +//@[arm] only-arm +//@[riscv32] only-riscv32 +//@[riscv64] only-riscv64 +//@[x86] only-x86 +//@[x86_64] only-x86_64 + +#[cfg(any(aarch64, arm, arm64ec))] +fn make_true(value: &mut bool) { + unsafe { + core::arch::asm!( + "b {}", + label { + *value = true; + } + ); + } +} + +#[cfg(any(riscv32, riscv64))] +fn make_true(value: &mut bool) { + unsafe { + core::arch::asm!( + "j {}", + label { + *value = true; + } + ); + } +} + +#[cfg(any(x86, x86_64))] +fn make_true(value: &mut bool) { + unsafe { + core::arch::asm!( + "jmp {}", + label { + *value = true; + } + ); + } +} + +fn main() { + let mut value = false; + make_true(&mut value); + assert!(value); +} diff --git a/tests/ui/asm/loongarch/bad-reg.rs b/tests/ui/asm/loongarch/bad-reg.rs index 0d3eba07f14da..5c20f9de5472d 100644 --- a/tests/ui/asm/loongarch/bad-reg.rs +++ b/tests/ui/asm/loongarch/bad-reg.rs @@ -1,7 +1,6 @@ //@ add-core-stubs //@ needs-asm-support //@ revisions: loongarch32_ilp32d loongarch32_ilp32s loongarch64_lp64d loongarch64_lp64s -//@ min-llvm-version: 20 //@[loongarch32_ilp32d] compile-flags: --target loongarch32-unknown-none //@[loongarch32_ilp32d] needs-llvm-components: loongarch //@[loongarch32_ilp32s] compile-flags: --target loongarch32-unknown-none-softfloat @@ -10,6 +9,7 @@ //@[loongarch64_lp64d] needs-llvm-components: loongarch //@[loongarch64_lp64s] compile-flags: --target loongarch64-unknown-none-softfloat //@[loongarch64_lp64s] needs-llvm-components: loongarch +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core)] diff --git a/tests/ui/asm/naked-function-shim.rs b/tests/ui/asm/naked-function-shim.rs index 4694d0cd963e3..55fe9291ba5dd 100644 --- a/tests/ui/asm/naked-function-shim.rs +++ b/tests/ui/asm/naked-function-shim.rs @@ -8,6 +8,7 @@ //@ [aarch64] needs-llvm-components: aarch64 //@ [x86_64] compile-flags: --target x86_64-unknown-none //@ [x86_64] needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, lang_items)] #![crate_type = "lib"] diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs index 69927a56aabb3..9a2437389d602 100644 --- a/tests/ui/asm/naked-functions-instruction-set.rs +++ b/tests/ui/asm/naked-functions-instruction-set.rs @@ -3,6 +3,7 @@ //@ needs-llvm-components: arm //@ needs-asm-support //@ build-pass +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core)] diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr index 33bbfc885da97..923d2de1f323d 100644 --- a/tests/ui/asm/naked-invalid-attr.stderr +++ b/tests/ui/asm/naked-invalid-attr.stderr @@ -18,7 +18,7 @@ error: `#[naked]` attribute cannot be used on foreign functions LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ | - = help: `#[naked]` can be applied to methods and functions + = help: `#[naked]` can be applied to functions and methods error: `#[naked]` attribute cannot be used on structs --> $DIR/naked-invalid-attr.rs:13:1 @@ -50,7 +50,7 @@ error: `#[naked]` attribute cannot be used on closures LL | #[unsafe(naked)] | ^^^^^^^^^^^^^^^^ | - = help: `#[naked]` can be applied to methods and functions + = help: `#[naked]` can be applied to functions and methods error[E0736]: attribute incompatible with `#[unsafe(naked)]` --> $DIR/naked-invalid-attr.rs:56:3 diff --git a/tests/ui/asm/powerpc/bad-reg.aix64.stderr b/tests/ui/asm/powerpc/bad-reg.aix64.stderr index 124013f89afa9..fb3ed07f5c65b 100644 --- a/tests/ui/asm/powerpc/bad-reg.aix64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.aix64.stderr @@ -1,101 +1,137 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ -error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 - | -LL | asm!("", out("lr") _); - | ^^^^^^^^^^^ - -error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 - | -LL | asm!("", out("ctr") _); - | ^^^^^^^^^^^^ - error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:138:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:18 + --> $DIR/bad-reg.rs:141:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:144:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:109:26 + --> $DIR/bad-reg.rs:147:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:151:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:154:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:157:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:160:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:164:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:167:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:170:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:173:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:113:18 + --> $DIR/bad-reg.rs:177:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:116:18 + --> $DIR/bad-reg.rs:180:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:183:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:26 + --> $DIR/bad-reg.rs:186:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:190:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:192:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:194:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:132:31 + --> $DIR/bad-reg.rs:196:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:198:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -151,21 +187,533 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` | | | register `cr` +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:207:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:209:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:211:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:213:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:215:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:217:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:219:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:221:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:223:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:225:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:227:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:229:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:231:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:233:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:235:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:237:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:239:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:241:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:243:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:245:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:247:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:249:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:251:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:253:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:255:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:257:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:259:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:261:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:263:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:265:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:267:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:269:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:271:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:273:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:275:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:277:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:279:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:281:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:283:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:285:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:287:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:289:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:291:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:293:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:295:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:297:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:299:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:301:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:303:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:305:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:307:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:309:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:311:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:313:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:315:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:317:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:319:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:321:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:323:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:325:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:327:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:329:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:331:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:333:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:67:27 + --> $DIR/bad-reg.rs:64:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -173,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:70:28 + --> $DIR/bad-reg.rs:67:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -181,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:78:35 + --> $DIR/bad-reg.rs:75:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -189,7 +737,31 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:27 + --> $DIR/bad-reg.rs:105:28 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:108:29 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:115:36 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:138:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:103:28 + --> $DIR/bad-reg.rs:141:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:33 + --> $DIR/bad-reg.rs:144:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +785,55 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:113:28 + --> $DIR/bad-reg.rs:151:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:154:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:157:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:164:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:167:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:170:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:177:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:29 + --> $DIR/bad-reg.rs:180:29 | LL | asm!("", out("xer") x); | ^ @@ -229,12 +849,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:119:34 + --> $DIR/bad-reg.rs:183:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 34 previous errors +error: aborting due to 113 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr index b11c946f80da5..1f137b7e180b7 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc.stderr @@ -1,101 +1,137 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ -error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 - | -LL | asm!("", out("lr") _); - | ^^^^^^^^^^^ - -error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 - | -LL | asm!("", out("ctr") _); - | ^^^^^^^^^^^^ - error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:138:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:18 + --> $DIR/bad-reg.rs:141:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:144:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:109:26 + --> $DIR/bad-reg.rs:147:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:151:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:154:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:157:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:160:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:164:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:167:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:170:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:173:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:113:18 + --> $DIR/bad-reg.rs:177:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:116:18 + --> $DIR/bad-reg.rs:180:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:183:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:26 + --> $DIR/bad-reg.rs:186:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:190:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:192:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:194:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:132:31 + --> $DIR/bad-reg.rs:196:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:198:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -151,81 +187,653 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` | | | register `cr` +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:207:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:209:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:211:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:213:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:215:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:217:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:219:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:221:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:223:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:225:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:227:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:229:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:231:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:233:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:235:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:237:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:239:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:241:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:243:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:245:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:247:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:249:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:251:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:253:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:255:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:257:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:259:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:261:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:263:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:265:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:267:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:269:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:271:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:273:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:275:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:277:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:279:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:281:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:283:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:285:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:287:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:289:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:291:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:293:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:295:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:297:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:299:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:301:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:303:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:305:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:307:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:309:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:311:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:313:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:315:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:317:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:319:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:321:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:323:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:325:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:327:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:329:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:331:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:333:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", in("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("v0") v32x4); // requires altivec | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:64:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:70:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:73:26 + --> $DIR/bad-reg.rs:70:26 | LL | asm!("/* {} */", in(vreg) v32x4); // requires altivec | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:75:26 + --> $DIR/bad-reg.rs:72:26 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:78:26 + --> $DIR/bad-reg.rs:75:26 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^^^^^^^^^^ error: register class `vreg` requires at least one of the following target features: altivec, vsx - --> $DIR/bad-reg.rs:81:26 + --> $DIR/bad-reg.rs:78:26 | LL | asm!("/* {} */", out(vreg) _); // requires altivec | ^^^^^^^^^^^ +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:97:18 + | +LL | asm!("", in("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:99:18 + | +LL | asm!("", out("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:101:18 + | +LL | asm!("", in("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:103:18 + | +LL | asm!("", out("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:105:18 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:108:18 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:111:26 + | +LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:113:26 + | +LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:115:26 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:118:26 + | +LL | asm!("/* {} */", out(vsreg) _); // requires vsx + | ^^^^^^^^^^^^ + error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:27 + --> $DIR/bad-reg.rs:138:27 | LL | asm!("", in("cr") x); | ^ @@ -233,7 +841,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:103:28 + --> $DIR/bad-reg.rs:141:28 | LL | asm!("", out("cr") x); | ^ @@ -241,7 +849,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:33 + --> $DIR/bad-reg.rs:144:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -249,7 +857,55 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:113:28 + --> $DIR/bad-reg.rs:151:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:154:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:157:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:164:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:167:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:170:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:177:28 | LL | asm!("", in("xer") x); | ^ @@ -257,7 +913,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:29 + --> $DIR/bad-reg.rs:180:29 | LL | asm!("", out("xer") x); | ^ @@ -265,12 +921,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:119:34 + --> $DIR/bad-reg.rs:183:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 41 previous errors +error: aborting due to 127 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr index a93b2b018df0e..d5ca6e331edaf 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64.stderr @@ -1,101 +1,137 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ -error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 - | -LL | asm!("", out("lr") _); - | ^^^^^^^^^^^ - -error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 - | -LL | asm!("", out("ctr") _); - | ^^^^^^^^^^^^ - error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:138:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:18 + --> $DIR/bad-reg.rs:141:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:144:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:109:26 + --> $DIR/bad-reg.rs:147:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:151:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:154:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:157:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:160:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:164:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:167:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:170:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:173:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:113:18 + --> $DIR/bad-reg.rs:177:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:116:18 + --> $DIR/bad-reg.rs:180:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:183:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:26 + --> $DIR/bad-reg.rs:186:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:190:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:192:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:194:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:132:31 + --> $DIR/bad-reg.rs:196:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:198:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -151,21 +187,533 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` | | | register `cr` +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:207:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:209:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:211:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:213:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:215:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:217:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:219:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:221:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:223:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:225:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:227:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:229:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:231:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:233:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:235:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:237:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:239:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:241:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:243:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:245:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:247:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:249:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:251:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:253:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:255:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:257:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:259:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:261:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:263:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:265:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:267:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:269:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:271:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:273:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:275:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:277:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:279:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:281:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:283:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:285:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:287:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:289:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:291:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:293:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:295:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:297:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:299:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:301:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:303:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:305:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:307:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:309:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:311:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:313:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:315:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:317:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:319:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:321:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:323:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:325:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:327:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:329:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:331:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:333:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:61:27 + --> $DIR/bad-reg.rs:58:27 | LL | asm!("", in("v0") v64x2); // requires vsx | ^^^^^ @@ -173,7 +721,7 @@ LL | asm!("", in("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:64:28 + --> $DIR/bad-reg.rs:61:28 | LL | asm!("", out("v0") v64x2); // requires vsx | ^^^^^ @@ -181,7 +729,7 @@ LL | asm!("", out("v0") v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:67:27 + --> $DIR/bad-reg.rs:64:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -189,7 +737,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:70:28 + --> $DIR/bad-reg.rs:67:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -197,7 +745,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: `vsx` target feature is not enabled - --> $DIR/bad-reg.rs:75:35 + --> $DIR/bad-reg.rs:72:35 | LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx | ^^^^^ @@ -205,15 +753,75 @@ LL | asm!("/* {} */", in(vreg) v64x2); // requires vsx = note: this is required to use type `i64x2` with register class `vreg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:78:35 + --> $DIR/bad-reg.rs:75:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ | = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:97:18 + | +LL | asm!("", in("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:99:18 + | +LL | asm!("", out("vs0") v32x4); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:101:18 + | +LL | asm!("", in("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:103:18 + | +LL | asm!("", out("vs0") v64x2); // requires vsx + | ^^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:105:18 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:108:18 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:111:26 + | +LL | asm!("/* {} */", in(vsreg) v32x4); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:113:26 + | +LL | asm!("/* {} */", in(vsreg) v64x2); // requires vsx + | ^^^^^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:115:26 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^^^^^^^^^^^ + +error: register class `vsreg` requires the `vsx` target feature + --> $DIR/bad-reg.rs:118:26 + | +LL | asm!("/* {} */", out(vsreg) _); // requires vsx + | ^^^^^^^^^^^^ + error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:27 + --> $DIR/bad-reg.rs:138:27 | LL | asm!("", in("cr") x); | ^ @@ -221,7 +829,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:103:28 + --> $DIR/bad-reg.rs:141:28 | LL | asm!("", out("cr") x); | ^ @@ -229,7 +837,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:33 + --> $DIR/bad-reg.rs:144:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -237,7 +845,55 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:113:28 + --> $DIR/bad-reg.rs:151:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:154:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:157:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:164:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:167:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:170:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:177:28 | LL | asm!("", in("xer") x); | ^ @@ -245,7 +901,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:29 + --> $DIR/bad-reg.rs:180:29 | LL | asm!("", out("xer") x); | ^ @@ -253,12 +909,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:119:34 + --> $DIR/bad-reg.rs:183:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 37 previous errors +error: aborting due to 123 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr index 124013f89afa9..fb3ed07f5c65b 100644 --- a/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr +++ b/tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr @@ -1,101 +1,137 @@ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `r2`: r2 is a system reserved register and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("r2") _); | ^^^^^^^^^^^ error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:42:18 + --> $DIR/bad-reg.rs:43:18 | LL | asm!("", out("r29") _); | ^^^^^^^^^^^^ error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:44:18 + --> $DIR/bad-reg.rs:45:18 | LL | asm!("", out("r30") _); | ^^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ -error: invalid register `lr`: the link register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:48:18 - | -LL | asm!("", out("lr") _); - | ^^^^^^^^^^^ - -error: invalid register `ctr`: the counter register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:50:18 - | -LL | asm!("", out("ctr") _); - | ^^^^^^^^^^^^ - error: invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("vrsave") _); | ^^^^^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:18 + --> $DIR/bad-reg.rs:138:18 | LL | asm!("", in("cr") x); | ^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:18 + --> $DIR/bad-reg.rs:141:18 | LL | asm!("", out("cr") x); | ^^^^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:106:26 + --> $DIR/bad-reg.rs:144:26 | LL | asm!("/* {} */", in(cr) x); | ^^^^^^^^ error: register class `cr` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:109:26 + --> $DIR/bad-reg.rs:147:26 | LL | asm!("/* {} */", out(cr) _); | ^^^^^^^^^ +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:151:18 + | +LL | asm!("", in("ctr") x); + | ^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:154:18 + | +LL | asm!("", out("ctr") x); + | ^^^^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:157:26 + | +LL | asm!("/* {} */", in(ctr) x); + | ^^^^^^^^^ + +error: register class `ctr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:160:26 + | +LL | asm!("/* {} */", out(ctr) _); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:164:18 + | +LL | asm!("", in("lr") x); + | ^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:167:18 + | +LL | asm!("", out("lr") x); + | ^^^^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:170:26 + | +LL | asm!("/* {} */", in(lr) x); + | ^^^^^^^^ + +error: register class `lr` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:173:26 + | +LL | asm!("/* {} */", out(lr) _); + | ^^^^^^^^^ + error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:113:18 + --> $DIR/bad-reg.rs:177:18 | LL | asm!("", in("xer") x); | ^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:116:18 + --> $DIR/bad-reg.rs:180:18 | LL | asm!("", out("xer") x); | ^^^^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:119:26 + --> $DIR/bad-reg.rs:183:26 | LL | asm!("/* {} */", in(xer) x); | ^^^^^^^^^ error: register class `xer` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:122:26 + --> $DIR/bad-reg.rs:186:26 | LL | asm!("/* {} */", out(xer) _); | ^^^^^^^^^^ error: register `cr0` conflicts with register `cr` - --> $DIR/bad-reg.rs:126:31 + --> $DIR/bad-reg.rs:190:31 | LL | asm!("", out("cr") _, out("cr0") _); | ----------- ^^^^^^^^^^^^ register `cr0` @@ -103,7 +139,7 @@ LL | asm!("", out("cr") _, out("cr0") _); | register `cr` error: register `cr1` conflicts with register `cr` - --> $DIR/bad-reg.rs:128:31 + --> $DIR/bad-reg.rs:192:31 | LL | asm!("", out("cr") _, out("cr1") _); | ----------- ^^^^^^^^^^^^ register `cr1` @@ -111,7 +147,7 @@ LL | asm!("", out("cr") _, out("cr1") _); | register `cr` error: register `cr2` conflicts with register `cr` - --> $DIR/bad-reg.rs:130:31 + --> $DIR/bad-reg.rs:194:31 | LL | asm!("", out("cr") _, out("cr2") _); | ----------- ^^^^^^^^^^^^ register `cr2` @@ -119,7 +155,7 @@ LL | asm!("", out("cr") _, out("cr2") _); | register `cr` error: register `cr3` conflicts with register `cr` - --> $DIR/bad-reg.rs:132:31 + --> $DIR/bad-reg.rs:196:31 | LL | asm!("", out("cr") _, out("cr3") _); | ----------- ^^^^^^^^^^^^ register `cr3` @@ -127,7 +163,7 @@ LL | asm!("", out("cr") _, out("cr3") _); | register `cr` error: register `cr4` conflicts with register `cr` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:198:31 | LL | asm!("", out("cr") _, out("cr4") _); | ----------- ^^^^^^^^^^^^ register `cr4` @@ -135,7 +171,7 @@ LL | asm!("", out("cr") _, out("cr4") _); | register `cr` error: register `cr5` conflicts with register `cr` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:200:31 | LL | asm!("", out("cr") _, out("cr5") _); | ----------- ^^^^^^^^^^^^ register `cr5` @@ -143,7 +179,7 @@ LL | asm!("", out("cr") _, out("cr5") _); | register `cr` error: register `cr6` conflicts with register `cr` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:202:31 | LL | asm!("", out("cr") _, out("cr6") _); | ----------- ^^^^^^^^^^^^ register `cr6` @@ -151,21 +187,533 @@ LL | asm!("", out("cr") _, out("cr6") _); | register `cr` error: register `cr7` conflicts with register `cr` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:204:31 | LL | asm!("", out("cr") _, out("cr7") _); | ----------- ^^^^^^^^^^^^ register `cr7` | | | register `cr` +error: register `vs0` conflicts with register `f0` + --> $DIR/bad-reg.rs:207:31 + | +LL | asm!("", out("f0") _, out("vs0") _); + | ----------- ^^^^^^^^^^^^ register `vs0` + | | + | register `f0` + +error: register `vs1` conflicts with register `f1` + --> $DIR/bad-reg.rs:209:31 + | +LL | asm!("", out("f1") _, out("vs1") _); + | ----------- ^^^^^^^^^^^^ register `vs1` + | | + | register `f1` + +error: register `vs2` conflicts with register `f2` + --> $DIR/bad-reg.rs:211:31 + | +LL | asm!("", out("f2") _, out("vs2") _); + | ----------- ^^^^^^^^^^^^ register `vs2` + | | + | register `f2` + +error: register `vs3` conflicts with register `f3` + --> $DIR/bad-reg.rs:213:31 + | +LL | asm!("", out("f3") _, out("vs3") _); + | ----------- ^^^^^^^^^^^^ register `vs3` + | | + | register `f3` + +error: register `vs4` conflicts with register `f4` + --> $DIR/bad-reg.rs:215:31 + | +LL | asm!("", out("f4") _, out("vs4") _); + | ----------- ^^^^^^^^^^^^ register `vs4` + | | + | register `f4` + +error: register `vs5` conflicts with register `f5` + --> $DIR/bad-reg.rs:217:31 + | +LL | asm!("", out("f5") _, out("vs5") _); + | ----------- ^^^^^^^^^^^^ register `vs5` + | | + | register `f5` + +error: register `vs6` conflicts with register `f6` + --> $DIR/bad-reg.rs:219:31 + | +LL | asm!("", out("f6") _, out("vs6") _); + | ----------- ^^^^^^^^^^^^ register `vs6` + | | + | register `f6` + +error: register `vs7` conflicts with register `f7` + --> $DIR/bad-reg.rs:221:31 + | +LL | asm!("", out("f7") _, out("vs7") _); + | ----------- ^^^^^^^^^^^^ register `vs7` + | | + | register `f7` + +error: register `vs8` conflicts with register `f8` + --> $DIR/bad-reg.rs:223:31 + | +LL | asm!("", out("f8") _, out("vs8") _); + | ----------- ^^^^^^^^^^^^ register `vs8` + | | + | register `f8` + +error: register `vs9` conflicts with register `f9` + --> $DIR/bad-reg.rs:225:31 + | +LL | asm!("", out("f9") _, out("vs9") _); + | ----------- ^^^^^^^^^^^^ register `vs9` + | | + | register `f9` + +error: register `vs10` conflicts with register `f10` + --> $DIR/bad-reg.rs:227:32 + | +LL | asm!("", out("f10") _, out("vs10") _); + | ------------ ^^^^^^^^^^^^^ register `vs10` + | | + | register `f10` + +error: register `vs11` conflicts with register `f11` + --> $DIR/bad-reg.rs:229:32 + | +LL | asm!("", out("f11") _, out("vs11") _); + | ------------ ^^^^^^^^^^^^^ register `vs11` + | | + | register `f11` + +error: register `vs12` conflicts with register `f12` + --> $DIR/bad-reg.rs:231:32 + | +LL | asm!("", out("f12") _, out("vs12") _); + | ------------ ^^^^^^^^^^^^^ register `vs12` + | | + | register `f12` + +error: register `vs13` conflicts with register `f13` + --> $DIR/bad-reg.rs:233:32 + | +LL | asm!("", out("f13") _, out("vs13") _); + | ------------ ^^^^^^^^^^^^^ register `vs13` + | | + | register `f13` + +error: register `vs14` conflicts with register `f14` + --> $DIR/bad-reg.rs:235:32 + | +LL | asm!("", out("f14") _, out("vs14") _); + | ------------ ^^^^^^^^^^^^^ register `vs14` + | | + | register `f14` + +error: register `vs15` conflicts with register `f15` + --> $DIR/bad-reg.rs:237:32 + | +LL | asm!("", out("f15") _, out("vs15") _); + | ------------ ^^^^^^^^^^^^^ register `vs15` + | | + | register `f15` + +error: register `vs16` conflicts with register `f16` + --> $DIR/bad-reg.rs:239:32 + | +LL | asm!("", out("f16") _, out("vs16") _); + | ------------ ^^^^^^^^^^^^^ register `vs16` + | | + | register `f16` + +error: register `vs17` conflicts with register `f17` + --> $DIR/bad-reg.rs:241:32 + | +LL | asm!("", out("f17") _, out("vs17") _); + | ------------ ^^^^^^^^^^^^^ register `vs17` + | | + | register `f17` + +error: register `vs18` conflicts with register `f18` + --> $DIR/bad-reg.rs:243:32 + | +LL | asm!("", out("f18") _, out("vs18") _); + | ------------ ^^^^^^^^^^^^^ register `vs18` + | | + | register `f18` + +error: register `vs19` conflicts with register `f19` + --> $DIR/bad-reg.rs:245:32 + | +LL | asm!("", out("f19") _, out("vs19") _); + | ------------ ^^^^^^^^^^^^^ register `vs19` + | | + | register `f19` + +error: register `vs20` conflicts with register `f20` + --> $DIR/bad-reg.rs:247:32 + | +LL | asm!("", out("f20") _, out("vs20") _); + | ------------ ^^^^^^^^^^^^^ register `vs20` + | | + | register `f20` + +error: register `vs21` conflicts with register `f21` + --> $DIR/bad-reg.rs:249:32 + | +LL | asm!("", out("f21") _, out("vs21") _); + | ------------ ^^^^^^^^^^^^^ register `vs21` + | | + | register `f21` + +error: register `vs22` conflicts with register `f22` + --> $DIR/bad-reg.rs:251:32 + | +LL | asm!("", out("f22") _, out("vs22") _); + | ------------ ^^^^^^^^^^^^^ register `vs22` + | | + | register `f22` + +error: register `vs23` conflicts with register `f23` + --> $DIR/bad-reg.rs:253:32 + | +LL | asm!("", out("f23") _, out("vs23") _); + | ------------ ^^^^^^^^^^^^^ register `vs23` + | | + | register `f23` + +error: register `vs24` conflicts with register `f24` + --> $DIR/bad-reg.rs:255:32 + | +LL | asm!("", out("f24") _, out("vs24") _); + | ------------ ^^^^^^^^^^^^^ register `vs24` + | | + | register `f24` + +error: register `vs25` conflicts with register `f25` + --> $DIR/bad-reg.rs:257:32 + | +LL | asm!("", out("f25") _, out("vs25") _); + | ------------ ^^^^^^^^^^^^^ register `vs25` + | | + | register `f25` + +error: register `vs26` conflicts with register `f26` + --> $DIR/bad-reg.rs:259:32 + | +LL | asm!("", out("f26") _, out("vs26") _); + | ------------ ^^^^^^^^^^^^^ register `vs26` + | | + | register `f26` + +error: register `vs27` conflicts with register `f27` + --> $DIR/bad-reg.rs:261:32 + | +LL | asm!("", out("f27") _, out("vs27") _); + | ------------ ^^^^^^^^^^^^^ register `vs27` + | | + | register `f27` + +error: register `vs28` conflicts with register `f28` + --> $DIR/bad-reg.rs:263:32 + | +LL | asm!("", out("f28") _, out("vs28") _); + | ------------ ^^^^^^^^^^^^^ register `vs28` + | | + | register `f28` + +error: register `vs29` conflicts with register `f29` + --> $DIR/bad-reg.rs:265:32 + | +LL | asm!("", out("f29") _, out("vs29") _); + | ------------ ^^^^^^^^^^^^^ register `vs29` + | | + | register `f29` + +error: register `vs30` conflicts with register `f30` + --> $DIR/bad-reg.rs:267:32 + | +LL | asm!("", out("f30") _, out("vs30") _); + | ------------ ^^^^^^^^^^^^^ register `vs30` + | | + | register `f30` + +error: register `vs31` conflicts with register `f31` + --> $DIR/bad-reg.rs:269:32 + | +LL | asm!("", out("f31") _, out("vs31") _); + | ------------ ^^^^^^^^^^^^^ register `vs31` + | | + | register `f31` + +error: register `v0` conflicts with register `vs32` + --> $DIR/bad-reg.rs:271:33 + | +LL | asm!("", out("vs32") _, out("v0") _); + | ------------- ^^^^^^^^^^^ register `v0` + | | + | register `vs32` + +error: register `v1` conflicts with register `vs33` + --> $DIR/bad-reg.rs:273:33 + | +LL | asm!("", out("vs33") _, out("v1") _); + | ------------- ^^^^^^^^^^^ register `v1` + | | + | register `vs33` + +error: register `v2` conflicts with register `vs34` + --> $DIR/bad-reg.rs:275:33 + | +LL | asm!("", out("vs34") _, out("v2") _); + | ------------- ^^^^^^^^^^^ register `v2` + | | + | register `vs34` + +error: register `v3` conflicts with register `vs35` + --> $DIR/bad-reg.rs:277:33 + | +LL | asm!("", out("vs35") _, out("v3") _); + | ------------- ^^^^^^^^^^^ register `v3` + | | + | register `vs35` + +error: register `v4` conflicts with register `vs36` + --> $DIR/bad-reg.rs:279:33 + | +LL | asm!("", out("vs36") _, out("v4") _); + | ------------- ^^^^^^^^^^^ register `v4` + | | + | register `vs36` + +error: register `v5` conflicts with register `vs37` + --> $DIR/bad-reg.rs:281:33 + | +LL | asm!("", out("vs37") _, out("v5") _); + | ------------- ^^^^^^^^^^^ register `v5` + | | + | register `vs37` + +error: register `v6` conflicts with register `vs38` + --> $DIR/bad-reg.rs:283:33 + | +LL | asm!("", out("vs38") _, out("v6") _); + | ------------- ^^^^^^^^^^^ register `v6` + | | + | register `vs38` + +error: register `v7` conflicts with register `vs39` + --> $DIR/bad-reg.rs:285:33 + | +LL | asm!("", out("vs39") _, out("v7") _); + | ------------- ^^^^^^^^^^^ register `v7` + | | + | register `vs39` + +error: register `v8` conflicts with register `vs40` + --> $DIR/bad-reg.rs:287:33 + | +LL | asm!("", out("vs40") _, out("v8") _); + | ------------- ^^^^^^^^^^^ register `v8` + | | + | register `vs40` + +error: register `v9` conflicts with register `vs41` + --> $DIR/bad-reg.rs:289:33 + | +LL | asm!("", out("vs41") _, out("v9") _); + | ------------- ^^^^^^^^^^^ register `v9` + | | + | register `vs41` + +error: register `v10` conflicts with register `vs42` + --> $DIR/bad-reg.rs:291:33 + | +LL | asm!("", out("vs42") _, out("v10") _); + | ------------- ^^^^^^^^^^^^ register `v10` + | | + | register `vs42` + +error: register `v11` conflicts with register `vs43` + --> $DIR/bad-reg.rs:293:33 + | +LL | asm!("", out("vs43") _, out("v11") _); + | ------------- ^^^^^^^^^^^^ register `v11` + | | + | register `vs43` + +error: register `v12` conflicts with register `vs44` + --> $DIR/bad-reg.rs:295:33 + | +LL | asm!("", out("vs44") _, out("v12") _); + | ------------- ^^^^^^^^^^^^ register `v12` + | | + | register `vs44` + +error: register `v13` conflicts with register `vs45` + --> $DIR/bad-reg.rs:297:33 + | +LL | asm!("", out("vs45") _, out("v13") _); + | ------------- ^^^^^^^^^^^^ register `v13` + | | + | register `vs45` + +error: register `v14` conflicts with register `vs46` + --> $DIR/bad-reg.rs:299:33 + | +LL | asm!("", out("vs46") _, out("v14") _); + | ------------- ^^^^^^^^^^^^ register `v14` + | | + | register `vs46` + +error: register `v15` conflicts with register `vs47` + --> $DIR/bad-reg.rs:301:33 + | +LL | asm!("", out("vs47") _, out("v15") _); + | ------------- ^^^^^^^^^^^^ register `v15` + | | + | register `vs47` + +error: register `v16` conflicts with register `vs48` + --> $DIR/bad-reg.rs:303:33 + | +LL | asm!("", out("vs48") _, out("v16") _); + | ------------- ^^^^^^^^^^^^ register `v16` + | | + | register `vs48` + +error: register `v17` conflicts with register `vs49` + --> $DIR/bad-reg.rs:305:33 + | +LL | asm!("", out("vs49") _, out("v17") _); + | ------------- ^^^^^^^^^^^^ register `v17` + | | + | register `vs49` + +error: register `v18` conflicts with register `vs50` + --> $DIR/bad-reg.rs:307:33 + | +LL | asm!("", out("vs50") _, out("v18") _); + | ------------- ^^^^^^^^^^^^ register `v18` + | | + | register `vs50` + +error: register `v19` conflicts with register `vs51` + --> $DIR/bad-reg.rs:309:33 + | +LL | asm!("", out("vs51") _, out("v19") _); + | ------------- ^^^^^^^^^^^^ register `v19` + | | + | register `vs51` + +error: register `v20` conflicts with register `vs52` + --> $DIR/bad-reg.rs:311:33 + | +LL | asm!("", out("vs52") _, out("v20") _); + | ------------- ^^^^^^^^^^^^ register `v20` + | | + | register `vs52` + +error: register `v21` conflicts with register `vs53` + --> $DIR/bad-reg.rs:313:33 + | +LL | asm!("", out("vs53") _, out("v21") _); + | ------------- ^^^^^^^^^^^^ register `v21` + | | + | register `vs53` + +error: register `v22` conflicts with register `vs54` + --> $DIR/bad-reg.rs:315:33 + | +LL | asm!("", out("vs54") _, out("v22") _); + | ------------- ^^^^^^^^^^^^ register `v22` + | | + | register `vs54` + +error: register `v23` conflicts with register `vs55` + --> $DIR/bad-reg.rs:317:33 + | +LL | asm!("", out("vs55") _, out("v23") _); + | ------------- ^^^^^^^^^^^^ register `v23` + | | + | register `vs55` + +error: register `v24` conflicts with register `vs56` + --> $DIR/bad-reg.rs:319:33 + | +LL | asm!("", out("vs56") _, out("v24") _); + | ------------- ^^^^^^^^^^^^ register `v24` + | | + | register `vs56` + +error: register `v25` conflicts with register `vs57` + --> $DIR/bad-reg.rs:321:33 + | +LL | asm!("", out("vs57") _, out("v25") _); + | ------------- ^^^^^^^^^^^^ register `v25` + | | + | register `vs57` + +error: register `v26` conflicts with register `vs58` + --> $DIR/bad-reg.rs:323:33 + | +LL | asm!("", out("vs58") _, out("v26") _); + | ------------- ^^^^^^^^^^^^ register `v26` + | | + | register `vs58` + +error: register `v27` conflicts with register `vs59` + --> $DIR/bad-reg.rs:325:33 + | +LL | asm!("", out("vs59") _, out("v27") _); + | ------------- ^^^^^^^^^^^^ register `v27` + | | + | register `vs59` + +error: register `v28` conflicts with register `vs60` + --> $DIR/bad-reg.rs:327:33 + | +LL | asm!("", out("vs60") _, out("v28") _); + | ------------- ^^^^^^^^^^^^ register `v28` + | | + | register `vs60` + +error: register `v29` conflicts with register `vs61` + --> $DIR/bad-reg.rs:329:33 + | +LL | asm!("", out("vs61") _, out("v29") _); + | ------------- ^^^^^^^^^^^^ register `v29` + | | + | register `vs61` + +error: register `v30` conflicts with register `vs62` + --> $DIR/bad-reg.rs:331:33 + | +LL | asm!("", out("vs62") _, out("v30") _); + | ------------- ^^^^^^^^^^^^ register `v30` + | | + | register `vs62` + +error: register `v31` conflicts with register `vs63` + --> $DIR/bad-reg.rs:333:33 + | +LL | asm!("", out("vs63") _, out("v31") _); + | ------------- ^^^^^^^^^^^^ register `v31` + | | + | register `vs63` + error: cannot use register `r13`: r13 is a reserved register on this target - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("r13") _); | ^^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:67:27 + --> $DIR/bad-reg.rs:64:27 | LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -173,7 +721,7 @@ LL | asm!("", in("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:70:28 + --> $DIR/bad-reg.rs:67:28 | LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available | ^ @@ -181,7 +729,7 @@ LL | asm!("", out("v0") x); // FIXME: should be ok if vsx is available = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:78:35 + --> $DIR/bad-reg.rs:75:35 | LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is available | ^ @@ -189,7 +737,31 @@ LL | asm!("/* {} */", in(vreg) x); // FIXME: should be ok if vsx is avai = note: register class `vreg` supports these types: i8x16, i16x8, i32x4, f32x4, f32, f64, i64x2, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:27 + --> $DIR/bad-reg.rs:105:28 + | +LL | asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:108:29 + | +LL | asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:115:36 + | +LL | asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + | ^ + | + = note: register class `vsreg` supports these types: f32, f64, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:138:27 | LL | asm!("", in("cr") x); | ^ @@ -197,7 +769,7 @@ LL | asm!("", in("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:103:28 + --> $DIR/bad-reg.rs:141:28 | LL | asm!("", out("cr") x); | ^ @@ -205,7 +777,7 @@ LL | asm!("", out("cr") x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:106:33 + --> $DIR/bad-reg.rs:144:33 | LL | asm!("/* {} */", in(cr) x); | ^ @@ -213,7 +785,55 @@ LL | asm!("/* {} */", in(cr) x); = note: register class `cr` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:113:28 + --> $DIR/bad-reg.rs:151:28 + | +LL | asm!("", in("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:154:29 + | +LL | asm!("", out("ctr") x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:157:34 + | +LL | asm!("/* {} */", in(ctr) x); + | ^ + | + = note: register class `ctr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:164:27 + | +LL | asm!("", in("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:167:28 + | +LL | asm!("", out("lr") x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:170:33 + | +LL | asm!("/* {} */", in(lr) x); + | ^ + | + = note: register class `lr` supports these types: + +error: type `i32` cannot be used with this register class + --> $DIR/bad-reg.rs:177:28 | LL | asm!("", in("xer") x); | ^ @@ -221,7 +841,7 @@ LL | asm!("", in("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:116:29 + --> $DIR/bad-reg.rs:180:29 | LL | asm!("", out("xer") x); | ^ @@ -229,12 +849,12 @@ LL | asm!("", out("xer") x); = note: register class `xer` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:119:34 + --> $DIR/bad-reg.rs:183:34 | LL | asm!("/* {} */", in(xer) x); | ^ | = note: register class `xer` supports these types: -error: aborting due to 34 previous errors +error: aborting due to 113 previous errors diff --git a/tests/ui/asm/powerpc/bad-reg.rs b/tests/ui/asm/powerpc/bad-reg.rs index 5598f8379603d..d133dae3da62e 100644 --- a/tests/ui/asm/powerpc/bad-reg.rs +++ b/tests/ui/asm/powerpc/bad-reg.rs @@ -9,6 +9,7 @@ //@[aix64] compile-flags: --target powerpc64-ibm-aix //@[aix64] needs-llvm-components: powerpc //@ needs-asm-support +//@ ignore-backends: gcc // ignore-tidy-linelength #![crate_type = "rlib"] @@ -45,10 +46,6 @@ fn f() { //~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm asm!("", out("fp") _); //~^ ERROR invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - asm!("", out("lr") _); - //~^ ERROR invalid register `lr`: the link register cannot be used as an operand for inline asm - asm!("", out("ctr") _); - //~^ ERROR invalid register `ctr`: the counter register cannot be used as an operand for inline asm asm!("", out("vrsave") _); //~^ ERROR invalid register `vrsave`: the vrsave register cannot be used as an operand for inline asm @@ -80,7 +77,7 @@ fn f() { //[powerpc64,powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(vreg) _); // requires altivec //[powerpc]~^ ERROR register class `vreg` requires at least one of the following target features: altivec, vsx - // v20-v31 are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). + // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). asm!("", out("v20") _); asm!("", out("v21") _); asm!("", out("v22") _); @@ -94,6 +91,47 @@ fn f() { asm!("", out("v30") _); asm!("", out("v31") _); + + // vsreg + asm!("", out("vs0") _); // always ok + asm!("", in("vs0") v32x4); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("", out("vs0") v32x4); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("", in("vs0") v64x2); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("", out("vs0") v64x2); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("", in("vs0") x); // FIXME: should be ok if vsx is available + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("", out("vs0") x); // FIXME: should be ok if vsx is available + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("/* {} */", in(vsreg) v32x4); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("/* {} */", in(vsreg) v64x2); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + asm!("/* {} */", in(vsreg) x); // FIXME: should be ok if vsx is available + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + //[powerpc64le,aix64]~^^ ERROR type `i32` cannot be used with this register class + asm!("/* {} */", out(vsreg) _); // requires vsx + //[powerpc,powerpc64]~^ ERROR register class `vsreg` requires the `vsx` target feature + + // v20-v31 (vs52-vs63) are reserved on AIX with vec-default ABI (this ABI is not currently used in Rust's builtin AIX targets). + asm!("", out("vs52") _); + asm!("", out("vs53") _); + asm!("", out("vs54") _); + asm!("", out("vs55") _); + asm!("", out("vs56") _); + asm!("", out("vs57") _); + asm!("", out("vs58") _); + asm!("", out("vs59") _); + asm!("", out("vs60") _); + asm!("", out("vs61") _); + asm!("", out("vs62") _); + asm!("", out("vs63") _); + // Clobber-only registers // cr asm!("", out("cr") _); // ok @@ -108,6 +146,32 @@ fn f() { //~| ERROR type `i32` cannot be used with this register class asm!("/* {} */", out(cr) _); //~^ ERROR can only be used as a clobber + // ctr + asm!("", out("ctr") _); // ok + asm!("", in("ctr") x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("", out("ctr") x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("/* {} */", in(ctr) x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("/* {} */", out(ctr) _); + //~^ ERROR can only be used as a clobber + // lr + asm!("", out("lr") _); // ok + asm!("", in("lr") x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("", out("lr") x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("/* {} */", in(lr) x); + //~^ ERROR can only be used as a clobber + //~| ERROR type `i32` cannot be used with this register class + asm!("/* {} */", out(lr) _); + //~^ ERROR can only be used as a clobber // xer asm!("", out("xer") _); // ok asm!("", in("xer") x); @@ -140,5 +204,133 @@ fn f() { asm!("", out("cr") _, out("cr7") _); //~^ ERROR register `cr7` conflicts with register `cr` asm!("", out("f0") _, out("v0") _); // ok + asm!("", out("f0") _, out("vs0") _); + //~^ ERROR register `vs0` conflicts with register `f0` + asm!("", out("f1") _, out("vs1") _); + //~^ ERROR register `vs1` conflicts with register `f1` + asm!("", out("f2") _, out("vs2") _); + //~^ ERROR register `vs2` conflicts with register `f2` + asm!("", out("f3") _, out("vs3") _); + //~^ ERROR register `vs3` conflicts with register `f3` + asm!("", out("f4") _, out("vs4") _); + //~^ ERROR register `vs4` conflicts with register `f4` + asm!("", out("f5") _, out("vs5") _); + //~^ ERROR register `vs5` conflicts with register `f5` + asm!("", out("f6") _, out("vs6") _); + //~^ ERROR register `vs6` conflicts with register `f6` + asm!("", out("f7") _, out("vs7") _); + //~^ ERROR register `vs7` conflicts with register `f7` + asm!("", out("f8") _, out("vs8") _); + //~^ ERROR register `vs8` conflicts with register `f8` + asm!("", out("f9") _, out("vs9") _); + //~^ ERROR register `vs9` conflicts with register `f9` + asm!("", out("f10") _, out("vs10") _); + //~^ ERROR register `vs10` conflicts with register `f10` + asm!("", out("f11") _, out("vs11") _); + //~^ ERROR register `vs11` conflicts with register `f11` + asm!("", out("f12") _, out("vs12") _); + //~^ ERROR register `vs12` conflicts with register `f12` + asm!("", out("f13") _, out("vs13") _); + //~^ ERROR register `vs13` conflicts with register `f13` + asm!("", out("f14") _, out("vs14") _); + //~^ ERROR register `vs14` conflicts with register `f14` + asm!("", out("f15") _, out("vs15") _); + //~^ ERROR register `vs15` conflicts with register `f15` + asm!("", out("f16") _, out("vs16") _); + //~^ ERROR register `vs16` conflicts with register `f16` + asm!("", out("f17") _, out("vs17") _); + //~^ ERROR register `vs17` conflicts with register `f17` + asm!("", out("f18") _, out("vs18") _); + //~^ ERROR register `vs18` conflicts with register `f18` + asm!("", out("f19") _, out("vs19") _); + //~^ ERROR register `vs19` conflicts with register `f19` + asm!("", out("f20") _, out("vs20") _); + //~^ ERROR register `vs20` conflicts with register `f20` + asm!("", out("f21") _, out("vs21") _); + //~^ ERROR register `vs21` conflicts with register `f21` + asm!("", out("f22") _, out("vs22") _); + //~^ ERROR register `vs22` conflicts with register `f22` + asm!("", out("f23") _, out("vs23") _); + //~^ ERROR register `vs23` conflicts with register `f23` + asm!("", out("f24") _, out("vs24") _); + //~^ ERROR register `vs24` conflicts with register `f24` + asm!("", out("f25") _, out("vs25") _); + //~^ ERROR register `vs25` conflicts with register `f25` + asm!("", out("f26") _, out("vs26") _); + //~^ ERROR register `vs26` conflicts with register `f26` + asm!("", out("f27") _, out("vs27") _); + //~^ ERROR register `vs27` conflicts with register `f27` + asm!("", out("f28") _, out("vs28") _); + //~^ ERROR register `vs28` conflicts with register `f28` + asm!("", out("f29") _, out("vs29") _); + //~^ ERROR register `vs29` conflicts with register `f29` + asm!("", out("f30") _, out("vs30") _); + //~^ ERROR register `vs30` conflicts with register `f30` + asm!("", out("f31") _, out("vs31") _); + //~^ ERROR register `vs31` conflicts with register `f31` + asm!("", out("vs32") _, out("v0") _); + //~^ ERROR register `v0` conflicts with register `vs32` + asm!("", out("vs33") _, out("v1") _); + //~^ ERROR register `v1` conflicts with register `vs33` + asm!("", out("vs34") _, out("v2") _); + //~^ ERROR register `v2` conflicts with register `vs34` + asm!("", out("vs35") _, out("v3") _); + //~^ ERROR register `v3` conflicts with register `vs35` + asm!("", out("vs36") _, out("v4") _); + //~^ ERROR register `v4` conflicts with register `vs36` + asm!("", out("vs37") _, out("v5") _); + //~^ ERROR register `v5` conflicts with register `vs37` + asm!("", out("vs38") _, out("v6") _); + //~^ ERROR register `v6` conflicts with register `vs38` + asm!("", out("vs39") _, out("v7") _); + //~^ ERROR register `v7` conflicts with register `vs39` + asm!("", out("vs40") _, out("v8") _); + //~^ ERROR register `v8` conflicts with register `vs40` + asm!("", out("vs41") _, out("v9") _); + //~^ ERROR register `v9` conflicts with register `vs41` + asm!("", out("vs42") _, out("v10") _); + //~^ ERROR register `v10` conflicts with register `vs42` + asm!("", out("vs43") _, out("v11") _); + //~^ ERROR register `v11` conflicts with register `vs43` + asm!("", out("vs44") _, out("v12") _); + //~^ ERROR register `v12` conflicts with register `vs44` + asm!("", out("vs45") _, out("v13") _); + //~^ ERROR register `v13` conflicts with register `vs45` + asm!("", out("vs46") _, out("v14") _); + //~^ ERROR register `v14` conflicts with register `vs46` + asm!("", out("vs47") _, out("v15") _); + //~^ ERROR register `v15` conflicts with register `vs47` + asm!("", out("vs48") _, out("v16") _); + //~^ ERROR register `v16` conflicts with register `vs48` + asm!("", out("vs49") _, out("v17") _); + //~^ ERROR register `v17` conflicts with register `vs49` + asm!("", out("vs50") _, out("v18") _); + //~^ ERROR register `v18` conflicts with register `vs50` + asm!("", out("vs51") _, out("v19") _); + //~^ ERROR register `v19` conflicts with register `vs51` + asm!("", out("vs52") _, out("v20") _); + //~^ ERROR register `v20` conflicts with register `vs52` + asm!("", out("vs53") _, out("v21") _); + //~^ ERROR register `v21` conflicts with register `vs53` + asm!("", out("vs54") _, out("v22") _); + //~^ ERROR register `v22` conflicts with register `vs54` + asm!("", out("vs55") _, out("v23") _); + //~^ ERROR register `v23` conflicts with register `vs55` + asm!("", out("vs56") _, out("v24") _); + //~^ ERROR register `v24` conflicts with register `vs56` + asm!("", out("vs57") _, out("v25") _); + //~^ ERROR register `v25` conflicts with register `vs57` + asm!("", out("vs58") _, out("v26") _); + //~^ ERROR register `v26` conflicts with register `vs58` + asm!("", out("vs59") _, out("v27") _); + //~^ ERROR register `v27` conflicts with register `vs59` + asm!("", out("vs60") _, out("v28") _); + //~^ ERROR register `v28` conflicts with register `vs60` + asm!("", out("vs61") _, out("v29") _); + //~^ ERROR register `v29` conflicts with register `vs61` + asm!("", out("vs62") _, out("v30") _); + //~^ ERROR register `v30` conflicts with register `vs62` + asm!("", out("vs63") _, out("v31") _); + //~^ ERROR register `v31` conflicts with register `vs63` } } diff --git a/tests/ui/asm/reg-conflict.rs b/tests/ui/asm/reg-conflict.rs index 0c1f0eb570b7a..bcb3ceb23c042 100644 --- a/tests/ui/asm/reg-conflict.rs +++ b/tests/ui/asm/reg-conflict.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target armv7-unknown-linux-gnueabihf //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/asm/reg-conflict.stderr b/tests/ui/asm/reg-conflict.stderr index 00e7e952a2150..403c9316ae951 100644 --- a/tests/ui/asm/reg-conflict.stderr +++ b/tests/ui/asm/reg-conflict.stderr @@ -1,5 +1,5 @@ error: register `s1` conflicts with register `d0` - --> $DIR/reg-conflict.rs:14:31 + --> $DIR/reg-conflict.rs:15:31 | LL | asm!("", out("d0") _, out("s1") _); | ----------- ^^^^^^^^^^^ register `s1` diff --git a/tests/ui/asm/riscv/bad-reg.riscv32e.stderr b/tests/ui/asm/riscv/bad-reg.riscv32e.stderr index 27c8e958e536a..3999f9cf07612 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv32e.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv32e.stderr @@ -1,185 +1,185 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: cannot use register `x16`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", out("x16") _); | ^^^^^^^^^^^^ error: cannot use register `x17`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:48:18 + --> $DIR/bad-reg.rs:49:18 | LL | asm!("", out("x17") _); | ^^^^^^^^^^^^ error: cannot use register `x18`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:50:18 + --> $DIR/bad-reg.rs:51:18 | LL | asm!("", out("x18") _); | ^^^^^^^^^^^^ error: cannot use register `x19`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:52:18 + --> $DIR/bad-reg.rs:53:18 | LL | asm!("", out("x19") _); | ^^^^^^^^^^^^ error: cannot use register `x20`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:54:18 + --> $DIR/bad-reg.rs:55:18 | LL | asm!("", out("x20") _); | ^^^^^^^^^^^^ error: cannot use register `x21`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:56:18 + --> $DIR/bad-reg.rs:57:18 | LL | asm!("", out("x21") _); | ^^^^^^^^^^^^ error: cannot use register `x22`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:58:18 + --> $DIR/bad-reg.rs:59:18 | LL | asm!("", out("x22") _); | ^^^^^^^^^^^^ error: cannot use register `x23`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:60:18 + --> $DIR/bad-reg.rs:61:18 | LL | asm!("", out("x23") _); | ^^^^^^^^^^^^ error: cannot use register `x24`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:62:18 + --> $DIR/bad-reg.rs:63:18 | LL | asm!("", out("x24") _); | ^^^^^^^^^^^^ error: cannot use register `x25`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:64:18 + --> $DIR/bad-reg.rs:65:18 | LL | asm!("", out("x25") _); | ^^^^^^^^^^^^ error: cannot use register `x26`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:66:18 + --> $DIR/bad-reg.rs:67:18 | LL | asm!("", out("x26") _); | ^^^^^^^^^^^^ error: cannot use register `x27`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:68:18 + --> $DIR/bad-reg.rs:69:18 | LL | asm!("", out("x27") _); | ^^^^^^^^^^^^ error: cannot use register `x28`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:70:18 + --> $DIR/bad-reg.rs:71:18 | LL | asm!("", out("x28") _); | ^^^^^^^^^^^^ error: cannot use register `x29`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:72:18 + --> $DIR/bad-reg.rs:73:18 | LL | asm!("", out("x29") _); | ^^^^^^^^^^^^ error: cannot use register `x30`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:75:18 | LL | asm!("", out("x30") _); | ^^^^^^^^^^^^ error: cannot use register `x31`: register can't be used with the `e` target feature - --> $DIR/bad-reg.rs:76:18 + --> $DIR/bad-reg.rs:77:18 | LL | asm!("", out("x31") _); | ^^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:80:26 + --> $DIR/bad-reg.rs:81:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:26 + --> $DIR/bad-reg.rs:83:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:84:26 + --> $DIR/bad-reg.rs:85:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:87:26 + --> $DIR/bad-reg.rs:88:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -187,7 +187,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -195,7 +195,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.riscv32gc.stderr b/tests/ui/asm/riscv/bad-reg.riscv32gc.stderr index 4ff03d819e60f..0e458d2a47e28 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv32gc.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv32gc.stderr @@ -1,65 +1,65 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -67,7 +67,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -75,7 +75,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.riscv32i.stderr b/tests/ui/asm/riscv/bad-reg.riscv32i.stderr index fbe63eb0563c3..18af1957d0870 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv32i.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv32i.stderr @@ -1,89 +1,89 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:80:26 + --> $DIR/bad-reg.rs:81:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:26 + --> $DIR/bad-reg.rs:83:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:84:26 + --> $DIR/bad-reg.rs:85:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:87:26 + --> $DIR/bad-reg.rs:88:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -91,7 +91,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -99,7 +99,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.riscv32imafc.stderr b/tests/ui/asm/riscv/bad-reg.riscv32imafc.stderr index 57664cfe893b7..d3b74d1bd0dc5 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv32imafc.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv32imafc.stderr @@ -1,65 +1,65 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: `d` target feature is not enabled - --> $DIR/bad-reg.rs:84:35 + --> $DIR/bad-reg.rs:85:35 | LL | asm!("/* {} */", in(freg) d); | ^ @@ -67,7 +67,7 @@ LL | asm!("/* {} */", in(freg) d); = note: this is required to use type `f64` with register class `freg` error: `d` target feature is not enabled - --> $DIR/bad-reg.rs:87:36 + --> $DIR/bad-reg.rs:88:36 | LL | asm!("/* {} */", out(freg) d); | ^ @@ -75,7 +75,7 @@ LL | asm!("/* {} */", out(freg) d); = note: this is required to use type `f64` with register class `freg` error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -83,7 +83,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -91,7 +91,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.riscv64gc.stderr b/tests/ui/asm/riscv/bad-reg.riscv64gc.stderr index 4ff03d819e60f..0e458d2a47e28 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv64gc.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv64gc.stderr @@ -1,65 +1,65 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -67,7 +67,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -75,7 +75,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.riscv64imac.stderr b/tests/ui/asm/riscv/bad-reg.riscv64imac.stderr index fbe63eb0563c3..18af1957d0870 100644 --- a/tests/ui/asm/riscv/bad-reg.riscv64imac.stderr +++ b/tests/ui/asm/riscv/bad-reg.riscv64imac.stderr @@ -1,89 +1,89 @@ error: invalid register `s1`: s1 is used internally by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("s1") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `gp`: the global pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("gp") _); | ^^^^^^^^^^^ error: invalid register `tp`: the thread pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("tp") _); | ^^^^^^^^^^^ error: invalid register `zero`: the zero register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("zero") _); | ^^^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:94:18 + --> $DIR/bad-reg.rs:95:18 | LL | asm!("", in("v0") x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:97:18 + --> $DIR/bad-reg.rs:98:18 | LL | asm!("", out("v0") x); | ^^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) x); | ^^^^^^^^^^ error: register class `vreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:103:26 + --> $DIR/bad-reg.rs:104:26 | LL | asm!("/* {} */", out(vreg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:80:26 + --> $DIR/bad-reg.rs:81:26 | LL | asm!("/* {} */", in(freg) f); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:82:26 + --> $DIR/bad-reg.rs:83:26 | LL | asm!("/* {} */", out(freg) _); | ^^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:84:26 + --> $DIR/bad-reg.rs:85:26 | LL | asm!("/* {} */", in(freg) d); | ^^^^^^^^^^ error: register class `freg` requires at least one of the following target features: d, f - --> $DIR/bad-reg.rs:87:26 + --> $DIR/bad-reg.rs:88:26 | LL | asm!("/* {} */", out(freg) d); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:94:27 + --> $DIR/bad-reg.rs:95:27 | LL | asm!("", in("v0") x); | ^ @@ -91,7 +91,7 @@ LL | asm!("", in("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:97:28 + --> $DIR/bad-reg.rs:98:28 | LL | asm!("", out("v0") x); | ^ @@ -99,7 +99,7 @@ LL | asm!("", out("v0") x); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) x); | ^ diff --git a/tests/ui/asm/riscv/bad-reg.rs b/tests/ui/asm/riscv/bad-reg.rs index 7d032d277aa9b..e2ff311851bae 100644 --- a/tests/ui/asm/riscv/bad-reg.rs +++ b/tests/ui/asm/riscv/bad-reg.rs @@ -13,6 +13,7 @@ //@[riscv64imac] needs-llvm-components: riscv //@[riscv64gc] compile-flags: --target riscv64gc-unknown-linux-gnu //@[riscv64gc] needs-llvm-components: riscv +//@ ignore-backends: gcc // Unlike riscv32e-registers.rs, this tests if the rustc can reject invalid registers // usage in the asm! API (in, out, inout, etc.). diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr index 5d527cd70b81a..4ae29b78b54aa 100644 --- a/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr +++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32e.stderr @@ -1,5 +1,5 @@ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:42:11 + --> $DIR/riscv32e-registers.rs:43:11 | LL | asm!("li x16, 0"); | ^^^^^^^^^ @@ -11,7 +11,7 @@ LL | li x16, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:45:11 + --> $DIR/riscv32e-registers.rs:46:11 | LL | asm!("li x17, 0"); | ^^^^^^^^^ @@ -23,7 +23,7 @@ LL | li x17, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:48:11 + --> $DIR/riscv32e-registers.rs:49:11 | LL | asm!("li x18, 0"); | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | li x18, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:51:11 + --> $DIR/riscv32e-registers.rs:52:11 | LL | asm!("li x19, 0"); | ^^^^^^^^^ @@ -47,7 +47,7 @@ LL | li x19, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:54:11 + --> $DIR/riscv32e-registers.rs:55:11 | LL | asm!("li x20, 0"); | ^^^^^^^^^ @@ -59,7 +59,7 @@ LL | li x20, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:57:11 + --> $DIR/riscv32e-registers.rs:58:11 | LL | asm!("li x21, 0"); | ^^^^^^^^^ @@ -71,7 +71,7 @@ LL | li x21, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:60:11 + --> $DIR/riscv32e-registers.rs:61:11 | LL | asm!("li x22, 0"); | ^^^^^^^^^ @@ -83,7 +83,7 @@ LL | li x22, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:63:11 + --> $DIR/riscv32e-registers.rs:64:11 | LL | asm!("li x23, 0"); | ^^^^^^^^^ @@ -95,7 +95,7 @@ LL | li x23, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:66:11 + --> $DIR/riscv32e-registers.rs:67:11 | LL | asm!("li x24, 0"); | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | li x24, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:69:11 + --> $DIR/riscv32e-registers.rs:70:11 | LL | asm!("li x25, 0"); | ^^^^^^^^^ @@ -119,7 +119,7 @@ LL | li x25, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:72:11 + --> $DIR/riscv32e-registers.rs:73:11 | LL | asm!("li x26, 0"); | ^^^^^^^^^ @@ -131,7 +131,7 @@ LL | li x26, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:75:11 + --> $DIR/riscv32e-registers.rs:76:11 | LL | asm!("li x27, 0"); | ^^^^^^^^^ @@ -143,7 +143,7 @@ LL | li x27, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:78:11 + --> $DIR/riscv32e-registers.rs:79:11 | LL | asm!("li x28, 0"); | ^^^^^^^^^ @@ -155,7 +155,7 @@ LL | li x28, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:81:11 + --> $DIR/riscv32e-registers.rs:82:11 | LL | asm!("li x29, 0"); | ^^^^^^^^^ @@ -167,7 +167,7 @@ LL | li x29, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:84:11 + --> $DIR/riscv32e-registers.rs:85:11 | LL | asm!("li x30, 0"); | ^^^^^^^^^ @@ -179,7 +179,7 @@ LL | li x30, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:87:11 + --> $DIR/riscv32e-registers.rs:88:11 | LL | asm!("li x31, 0"); | ^^^^^^^^^ diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr index 5d527cd70b81a..4ae29b78b54aa 100644 --- a/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr +++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32em.stderr @@ -1,5 +1,5 @@ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:42:11 + --> $DIR/riscv32e-registers.rs:43:11 | LL | asm!("li x16, 0"); | ^^^^^^^^^ @@ -11,7 +11,7 @@ LL | li x16, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:45:11 + --> $DIR/riscv32e-registers.rs:46:11 | LL | asm!("li x17, 0"); | ^^^^^^^^^ @@ -23,7 +23,7 @@ LL | li x17, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:48:11 + --> $DIR/riscv32e-registers.rs:49:11 | LL | asm!("li x18, 0"); | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | li x18, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:51:11 + --> $DIR/riscv32e-registers.rs:52:11 | LL | asm!("li x19, 0"); | ^^^^^^^^^ @@ -47,7 +47,7 @@ LL | li x19, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:54:11 + --> $DIR/riscv32e-registers.rs:55:11 | LL | asm!("li x20, 0"); | ^^^^^^^^^ @@ -59,7 +59,7 @@ LL | li x20, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:57:11 + --> $DIR/riscv32e-registers.rs:58:11 | LL | asm!("li x21, 0"); | ^^^^^^^^^ @@ -71,7 +71,7 @@ LL | li x21, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:60:11 + --> $DIR/riscv32e-registers.rs:61:11 | LL | asm!("li x22, 0"); | ^^^^^^^^^ @@ -83,7 +83,7 @@ LL | li x22, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:63:11 + --> $DIR/riscv32e-registers.rs:64:11 | LL | asm!("li x23, 0"); | ^^^^^^^^^ @@ -95,7 +95,7 @@ LL | li x23, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:66:11 + --> $DIR/riscv32e-registers.rs:67:11 | LL | asm!("li x24, 0"); | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | li x24, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:69:11 + --> $DIR/riscv32e-registers.rs:70:11 | LL | asm!("li x25, 0"); | ^^^^^^^^^ @@ -119,7 +119,7 @@ LL | li x25, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:72:11 + --> $DIR/riscv32e-registers.rs:73:11 | LL | asm!("li x26, 0"); | ^^^^^^^^^ @@ -131,7 +131,7 @@ LL | li x26, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:75:11 + --> $DIR/riscv32e-registers.rs:76:11 | LL | asm!("li x27, 0"); | ^^^^^^^^^ @@ -143,7 +143,7 @@ LL | li x27, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:78:11 + --> $DIR/riscv32e-registers.rs:79:11 | LL | asm!("li x28, 0"); | ^^^^^^^^^ @@ -155,7 +155,7 @@ LL | li x28, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:81:11 + --> $DIR/riscv32e-registers.rs:82:11 | LL | asm!("li x29, 0"); | ^^^^^^^^^ @@ -167,7 +167,7 @@ LL | li x29, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:84:11 + --> $DIR/riscv32e-registers.rs:85:11 | LL | asm!("li x30, 0"); | ^^^^^^^^^ @@ -179,7 +179,7 @@ LL | li x30, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:87:11 + --> $DIR/riscv32e-registers.rs:88:11 | LL | asm!("li x31, 0"); | ^^^^^^^^^ diff --git a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr index 5d527cd70b81a..4ae29b78b54aa 100644 --- a/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr +++ b/tests/ui/asm/riscv/riscv32e-registers.riscv32emc.stderr @@ -1,5 +1,5 @@ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:42:11 + --> $DIR/riscv32e-registers.rs:43:11 | LL | asm!("li x16, 0"); | ^^^^^^^^^ @@ -11,7 +11,7 @@ LL | li x16, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:45:11 + --> $DIR/riscv32e-registers.rs:46:11 | LL | asm!("li x17, 0"); | ^^^^^^^^^ @@ -23,7 +23,7 @@ LL | li x17, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:48:11 + --> $DIR/riscv32e-registers.rs:49:11 | LL | asm!("li x18, 0"); | ^^^^^^^^^ @@ -35,7 +35,7 @@ LL | li x18, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:51:11 + --> $DIR/riscv32e-registers.rs:52:11 | LL | asm!("li x19, 0"); | ^^^^^^^^^ @@ -47,7 +47,7 @@ LL | li x19, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:54:11 + --> $DIR/riscv32e-registers.rs:55:11 | LL | asm!("li x20, 0"); | ^^^^^^^^^ @@ -59,7 +59,7 @@ LL | li x20, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:57:11 + --> $DIR/riscv32e-registers.rs:58:11 | LL | asm!("li x21, 0"); | ^^^^^^^^^ @@ -71,7 +71,7 @@ LL | li x21, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:60:11 + --> $DIR/riscv32e-registers.rs:61:11 | LL | asm!("li x22, 0"); | ^^^^^^^^^ @@ -83,7 +83,7 @@ LL | li x22, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:63:11 + --> $DIR/riscv32e-registers.rs:64:11 | LL | asm!("li x23, 0"); | ^^^^^^^^^ @@ -95,7 +95,7 @@ LL | li x23, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:66:11 + --> $DIR/riscv32e-registers.rs:67:11 | LL | asm!("li x24, 0"); | ^^^^^^^^^ @@ -107,7 +107,7 @@ LL | li x24, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:69:11 + --> $DIR/riscv32e-registers.rs:70:11 | LL | asm!("li x25, 0"); | ^^^^^^^^^ @@ -119,7 +119,7 @@ LL | li x25, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:72:11 + --> $DIR/riscv32e-registers.rs:73:11 | LL | asm!("li x26, 0"); | ^^^^^^^^^ @@ -131,7 +131,7 @@ LL | li x26, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:75:11 + --> $DIR/riscv32e-registers.rs:76:11 | LL | asm!("li x27, 0"); | ^^^^^^^^^ @@ -143,7 +143,7 @@ LL | li x27, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:78:11 + --> $DIR/riscv32e-registers.rs:79:11 | LL | asm!("li x28, 0"); | ^^^^^^^^^ @@ -155,7 +155,7 @@ LL | li x28, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:81:11 + --> $DIR/riscv32e-registers.rs:82:11 | LL | asm!("li x29, 0"); | ^^^^^^^^^ @@ -167,7 +167,7 @@ LL | li x29, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:84:11 + --> $DIR/riscv32e-registers.rs:85:11 | LL | asm!("li x30, 0"); | ^^^^^^^^^ @@ -179,7 +179,7 @@ LL | li x30, 0 | ^ error: invalid operand for instruction - --> $DIR/riscv32e-registers.rs:87:11 + --> $DIR/riscv32e-registers.rs:88:11 | LL | asm!("li x31, 0"); | ^^^^^^^^^ diff --git a/tests/ui/asm/riscv/riscv32e-registers.rs b/tests/ui/asm/riscv/riscv32e-registers.rs index 96bfe2af06448..c07cd3c596a70 100644 --- a/tests/ui/asm/riscv/riscv32e-registers.rs +++ b/tests/ui/asm/riscv/riscv32e-registers.rs @@ -11,6 +11,7 @@ //@ [riscv32em] compile-flags: --target=riscv32em-unknown-none-elf //@ [riscv32emc] needs-llvm-components: riscv //@ [riscv32emc] compile-flags: --target=riscv32emc-unknown-none-elf +//@ ignore-backends: gcc // Unlike bad-reg.rs, this tests if the assembler can reject invalid registers // usage in assembly code. diff --git a/tests/ui/asm/s390x/bad-reg.rs b/tests/ui/asm/s390x/bad-reg.rs index eb9138755e76c..2915e874593ee 100644 --- a/tests/ui/asm/s390x/bad-reg.rs +++ b/tests/ui/asm/s390x/bad-reg.rs @@ -7,6 +7,7 @@ //@[s390x_vector] needs-llvm-components: systemz //@[s390x_vector_stable] compile-flags: --target s390x-unknown-linux-gnu -C target-feature=+vector //@[s390x_vector_stable] needs-llvm-components: systemz +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(no_core, repr_simd)] diff --git a/tests/ui/asm/s390x/bad-reg.s390x.stderr b/tests/ui/asm/s390x/bad-reg.s390x.stderr index 238419b376b7f..c89d43defa39e 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:66:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:70:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:121:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:124:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:127:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:130:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:151:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:153:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:155:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:157:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:159:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:161:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:163:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:165:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,73 +271,73 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:168:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:75:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:78:18 + --> $DIR/bad-reg.rs:79:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:83:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:86:18 + --> $DIR/bad-reg.rs:87:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:90:18 + --> $DIR/bad-reg.rs:91:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:95:18 + --> $DIR/bad-reg.rs:96:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:105:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:108:26 + --> $DIR/bad-reg.rs:109:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ error: register class `vreg` requires the `vector` target feature - --> $DIR/bad-reg.rs:113:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:121:27 | LL | asm!("", in("a2") x); | ^ @@ -345,7 +345,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:124:28 | LL | asm!("", out("a2") x); | ^ @@ -353,7 +353,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:127:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr index 897f872ae72af..3890e1442ccc8 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector.stderr @@ -1,149 +1,149 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:66:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:70:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:121:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:124:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:127:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:130:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -151,7 +151,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -159,7 +159,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -167,7 +167,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -175,7 +175,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -183,7 +183,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -191,7 +191,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -199,7 +199,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -207,7 +207,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:151:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -215,7 +215,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:153:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -223,7 +223,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:155:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -231,7 +231,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:157:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -239,7 +239,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:159:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -247,7 +247,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:161:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -255,7 +255,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:163:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -263,7 +263,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:165:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -271,13 +271,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:168:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 + --> $DIR/bad-reg.rs:91:27 | LL | asm!("", in("v0") b); | ^ @@ -285,7 +285,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 + --> $DIR/bad-reg.rs:96:28 | LL | asm!("", out("v0") b); | ^ @@ -293,7 +293,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 + --> $DIR/bad-reg.rs:109:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -301,7 +301,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: i32, f32, i64, f64, i128, f128, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2 error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:121:27 | LL | asm!("", in("a2") x); | ^ @@ -309,7 +309,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:124:28 | LL | asm!("", out("a2") x); | ^ @@ -317,7 +317,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:127:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr index e2b3eeef4e925..20d129ebb387f 100644 --- a/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr +++ b/tests/ui/asm/s390x/bad-reg.s390x_vector_stable.stderr @@ -1,125 +1,125 @@ error: invalid register `r11`: The frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:31:18 + --> $DIR/bad-reg.rs:32:18 | LL | asm!("", out("r11") _); | ^^^^^^^^^^^^ error: invalid register `r15`: The stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:33:18 + --> $DIR/bad-reg.rs:34:18 | LL | asm!("", out("r15") _); | ^^^^^^^^^^^^ error: invalid register `c0`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:36:18 | LL | asm!("", out("c0") _); | ^^^^^^^^^^^ error: invalid register `c1`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:38:18 | LL | asm!("", out("c1") _); | ^^^^^^^^^^^ error: invalid register `c2`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:39:18 + --> $DIR/bad-reg.rs:40:18 | LL | asm!("", out("c2") _); | ^^^^^^^^^^^ error: invalid register `c3`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:41:18 + --> $DIR/bad-reg.rs:42:18 | LL | asm!("", out("c3") _); | ^^^^^^^^^^^ error: invalid register `c4`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:43:18 + --> $DIR/bad-reg.rs:44:18 | LL | asm!("", out("c4") _); | ^^^^^^^^^^^ error: invalid register `c5`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:45:18 + --> $DIR/bad-reg.rs:46:18 | LL | asm!("", out("c5") _); | ^^^^^^^^^^^ error: invalid register `c6`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:47:18 + --> $DIR/bad-reg.rs:48:18 | LL | asm!("", out("c6") _); | ^^^^^^^^^^^ error: invalid register `c7`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("c7") _); | ^^^^^^^^^^^ error: invalid register `c8`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:51:18 + --> $DIR/bad-reg.rs:52:18 | LL | asm!("", out("c8") _); | ^^^^^^^^^^^ error: invalid register `c9`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:53:18 + --> $DIR/bad-reg.rs:54:18 | LL | asm!("", out("c9") _); | ^^^^^^^^^^^ error: invalid register `c10`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:55:18 + --> $DIR/bad-reg.rs:56:18 | LL | asm!("", out("c10") _); | ^^^^^^^^^^^^ error: invalid register `c11`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:57:18 + --> $DIR/bad-reg.rs:58:18 | LL | asm!("", out("c11") _); | ^^^^^^^^^^^^ error: invalid register `c12`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:59:18 + --> $DIR/bad-reg.rs:60:18 | LL | asm!("", out("c12") _); | ^^^^^^^^^^^^ error: invalid register `c13`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:61:18 + --> $DIR/bad-reg.rs:62:18 | LL | asm!("", out("c13") _); | ^^^^^^^^^^^^ error: invalid register `c14`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:63:18 + --> $DIR/bad-reg.rs:64:18 | LL | asm!("", out("c14") _); | ^^^^^^^^^^^^ error: invalid register `c15`: control registers are reserved by the kernel and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:65:18 + --> $DIR/bad-reg.rs:66:18 | LL | asm!("", out("c15") _); | ^^^^^^^^^^^^ error: invalid register `a0`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:67:18 + --> $DIR/bad-reg.rs:68:18 | LL | asm!("", out("a0") _); | ^^^^^^^^^^^ error: invalid register `a1`: a0 and a1 are reserved for system use and cannot be used as operands for inline asm - --> $DIR/bad-reg.rs:69:18 + --> $DIR/bad-reg.rs:70:18 | LL | asm!("", out("a1") _); | ^^^^^^^^^^^ error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:74:18 + --> $DIR/bad-reg.rs:75:18 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -129,7 +129,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:78:18 + --> $DIR/bad-reg.rs:79:18 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:82:18 + --> $DIR/bad-reg.rs:83:18 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:86:18 + --> $DIR/bad-reg.rs:87:18 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -159,7 +159,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:90:18 + --> $DIR/bad-reg.rs:91:18 | LL | asm!("", in("v0") b); | ^^^^^^^^^^ @@ -169,7 +169,7 @@ LL | asm!("", in("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:95:18 + --> $DIR/bad-reg.rs:96:18 | LL | asm!("", out("v0") b); | ^^^^^^^^^^^ @@ -179,7 +179,7 @@ LL | asm!("", out("v0") b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:100:26 + --> $DIR/bad-reg.rs:101:26 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -189,7 +189,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:104:26 + --> $DIR/bad-reg.rs:105:26 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^^^^^^^^^^ @@ -199,7 +199,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:108:26 + --> $DIR/bad-reg.rs:109:26 | LL | asm!("/* {} */", in(vreg) b); | ^^^^^^^^^^ @@ -209,7 +209,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: register class `vreg` can only be used as a clobber in stable - --> $DIR/bad-reg.rs:113:26 + --> $DIR/bad-reg.rs:114:26 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | ^^^^^^^^^^^ @@ -219,31 +219,31 @@ LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimenta = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:120:18 + --> $DIR/bad-reg.rs:121:18 | LL | asm!("", in("a2") x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:123:18 + --> $DIR/bad-reg.rs:124:18 | LL | asm!("", out("a2") x); | ^^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:126:26 + --> $DIR/bad-reg.rs:127:26 | LL | asm!("/* {} */", in(areg) x); | ^^^^^^^^^^ error: register class `areg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:129:26 + --> $DIR/bad-reg.rs:130:26 | LL | asm!("/* {} */", out(areg) _); | ^^^^^^^^^^^ error: register `f0` conflicts with register `v0` - --> $DIR/bad-reg.rs:134:31 + --> $DIR/bad-reg.rs:135:31 | LL | asm!("", out("v0") _, out("f0") _); | ----------- ^^^^^^^^^^^ register `f0` @@ -251,7 +251,7 @@ LL | asm!("", out("v0") _, out("f0") _); | register `v0` error: register `f1` conflicts with register `v1` - --> $DIR/bad-reg.rs:136:31 + --> $DIR/bad-reg.rs:137:31 | LL | asm!("", out("v1") _, out("f1") _); | ----------- ^^^^^^^^^^^ register `f1` @@ -259,7 +259,7 @@ LL | asm!("", out("v1") _, out("f1") _); | register `v1` error: register `f2` conflicts with register `v2` - --> $DIR/bad-reg.rs:138:31 + --> $DIR/bad-reg.rs:139:31 | LL | asm!("", out("v2") _, out("f2") _); | ----------- ^^^^^^^^^^^ register `f2` @@ -267,7 +267,7 @@ LL | asm!("", out("v2") _, out("f2") _); | register `v2` error: register `f3` conflicts with register `v3` - --> $DIR/bad-reg.rs:140:31 + --> $DIR/bad-reg.rs:141:31 | LL | asm!("", out("v3") _, out("f3") _); | ----------- ^^^^^^^^^^^ register `f3` @@ -275,7 +275,7 @@ LL | asm!("", out("v3") _, out("f3") _); | register `v3` error: register `f4` conflicts with register `v4` - --> $DIR/bad-reg.rs:142:31 + --> $DIR/bad-reg.rs:143:31 | LL | asm!("", out("v4") _, out("f4") _); | ----------- ^^^^^^^^^^^ register `f4` @@ -283,7 +283,7 @@ LL | asm!("", out("v4") _, out("f4") _); | register `v4` error: register `f5` conflicts with register `v5` - --> $DIR/bad-reg.rs:144:31 + --> $DIR/bad-reg.rs:145:31 | LL | asm!("", out("v5") _, out("f5") _); | ----------- ^^^^^^^^^^^ register `f5` @@ -291,7 +291,7 @@ LL | asm!("", out("v5") _, out("f5") _); | register `v5` error: register `f6` conflicts with register `v6` - --> $DIR/bad-reg.rs:146:31 + --> $DIR/bad-reg.rs:147:31 | LL | asm!("", out("v6") _, out("f6") _); | ----------- ^^^^^^^^^^^ register `f6` @@ -299,7 +299,7 @@ LL | asm!("", out("v6") _, out("f6") _); | register `v6` error: register `f7` conflicts with register `v7` - --> $DIR/bad-reg.rs:148:31 + --> $DIR/bad-reg.rs:149:31 | LL | asm!("", out("v7") _, out("f7") _); | ----------- ^^^^^^^^^^^ register `f7` @@ -307,7 +307,7 @@ LL | asm!("", out("v7") _, out("f7") _); | register `v7` error: register `f8` conflicts with register `v8` - --> $DIR/bad-reg.rs:150:31 + --> $DIR/bad-reg.rs:151:31 | LL | asm!("", out("v8") _, out("f8") _); | ----------- ^^^^^^^^^^^ register `f8` @@ -315,7 +315,7 @@ LL | asm!("", out("v8") _, out("f8") _); | register `v8` error: register `f9` conflicts with register `v9` - --> $DIR/bad-reg.rs:152:31 + --> $DIR/bad-reg.rs:153:31 | LL | asm!("", out("v9") _, out("f9") _); | ----------- ^^^^^^^^^^^ register `f9` @@ -323,7 +323,7 @@ LL | asm!("", out("v9") _, out("f9") _); | register `v9` error: register `f10` conflicts with register `v10` - --> $DIR/bad-reg.rs:154:32 + --> $DIR/bad-reg.rs:155:32 | LL | asm!("", out("v10") _, out("f10") _); | ------------ ^^^^^^^^^^^^ register `f10` @@ -331,7 +331,7 @@ LL | asm!("", out("v10") _, out("f10") _); | register `v10` error: register `f11` conflicts with register `v11` - --> $DIR/bad-reg.rs:156:32 + --> $DIR/bad-reg.rs:157:32 | LL | asm!("", out("v11") _, out("f11") _); | ------------ ^^^^^^^^^^^^ register `f11` @@ -339,7 +339,7 @@ LL | asm!("", out("v11") _, out("f11") _); | register `v11` error: register `f12` conflicts with register `v12` - --> $DIR/bad-reg.rs:158:32 + --> $DIR/bad-reg.rs:159:32 | LL | asm!("", out("v12") _, out("f12") _); | ------------ ^^^^^^^^^^^^ register `f12` @@ -347,7 +347,7 @@ LL | asm!("", out("v12") _, out("f12") _); | register `v12` error: register `f13` conflicts with register `v13` - --> $DIR/bad-reg.rs:160:32 + --> $DIR/bad-reg.rs:161:32 | LL | asm!("", out("v13") _, out("f13") _); | ------------ ^^^^^^^^^^^^ register `f13` @@ -355,7 +355,7 @@ LL | asm!("", out("v13") _, out("f13") _); | register `v13` error: register `f14` conflicts with register `v14` - --> $DIR/bad-reg.rs:162:32 + --> $DIR/bad-reg.rs:163:32 | LL | asm!("", out("v14") _, out("f14") _); | ------------ ^^^^^^^^^^^^ register `f14` @@ -363,7 +363,7 @@ LL | asm!("", out("v14") _, out("f14") _); | register `v14` error: register `f15` conflicts with register `v15` - --> $DIR/bad-reg.rs:164:32 + --> $DIR/bad-reg.rs:165:32 | LL | asm!("", out("v15") _, out("f15") _); | ------------ ^^^^^^^^^^^^ register `f15` @@ -371,13 +371,13 @@ LL | asm!("", out("v15") _, out("f15") _); | register `v15` error: invalid register `f16`: unknown register - --> $DIR/bad-reg.rs:167:32 + --> $DIR/bad-reg.rs:168:32 | LL | asm!("", out("v16") _, out("f16") _); | ^^^^^^^^^^^^ error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:74:27 + --> $DIR/bad-reg.rs:75:27 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | ^ @@ -387,7 +387,7 @@ LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:78:28 + --> $DIR/bad-reg.rs:79:28 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | ^ @@ -397,7 +397,7 @@ LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:82:27 + --> $DIR/bad-reg.rs:83:27 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | ^ @@ -407,7 +407,7 @@ LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:86:28 + --> $DIR/bad-reg.rs:87:28 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | ^ @@ -417,7 +417,7 @@ LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:90:27 + --> $DIR/bad-reg.rs:91:27 | LL | asm!("", in("v0") b); | ^ @@ -425,7 +425,7 @@ LL | asm!("", in("v0") b); = note: register class `vreg` supports these types: error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:95:28 + --> $DIR/bad-reg.rs:96:28 | LL | asm!("", out("v0") b); | ^ @@ -433,7 +433,7 @@ LL | asm!("", out("v0") b); = note: register class `vreg` supports these types: error[E0658]: type `i64x2` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:100:35 + --> $DIR/bad-reg.rs:101:35 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | ^ @@ -443,7 +443,7 @@ LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: type `i32` cannot be used with this register class in stable - --> $DIR/bad-reg.rs:104:35 + --> $DIR/bad-reg.rs:105:35 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | ^ @@ -453,7 +453,7 @@ LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: type `u8` cannot be used with this register class - --> $DIR/bad-reg.rs:108:35 + --> $DIR/bad-reg.rs:109:35 | LL | asm!("/* {} */", in(vreg) b); | ^ @@ -461,7 +461,7 @@ LL | asm!("/* {} */", in(vreg) b); = note: register class `vreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:120:27 + --> $DIR/bad-reg.rs:121:27 | LL | asm!("", in("a2") x); | ^ @@ -469,7 +469,7 @@ LL | asm!("", in("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:123:28 + --> $DIR/bad-reg.rs:124:28 | LL | asm!("", out("a2") x); | ^ @@ -477,7 +477,7 @@ LL | asm!("", out("a2") x); = note: register class `areg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:126:35 + --> $DIR/bad-reg.rs:127:35 | LL | asm!("/* {} */", in(areg) x); | ^ diff --git a/tests/ui/asm/sparc/bad-reg.rs b/tests/ui/asm/sparc/bad-reg.rs index 44af6c316bc4b..8b6fdc422120d 100644 --- a/tests/ui/asm/sparc/bad-reg.rs +++ b/tests/ui/asm/sparc/bad-reg.rs @@ -7,6 +7,7 @@ //@[sparc64] compile-flags: --target sparc64-unknown-linux-gnu //@[sparc64] needs-llvm-components: sparc //@ needs-asm-support +//@ ignore-backends: gcc #![crate_type = "rlib"] #![feature(no_core, asm_experimental_arch)] diff --git a/tests/ui/asm/sparc/bad-reg.sparc.stderr b/tests/ui/asm/sparc/bad-reg.sparc.stderr index e0580ad3232f5..84e56871ecc26 100644 --- a/tests/ui/asm/sparc/bad-reg.sparc.stderr +++ b/tests/ui/asm/sparc/bad-reg.sparc.stderr @@ -1,77 +1,77 @@ error: invalid register `g0`: g0 is always zero and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:22:18 + --> $DIR/bad-reg.rs:23:18 | LL | asm!("", out("g0") _); | ^^^^^^^^^^^ error: invalid register `g1`: reserved by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:25:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", out("g1") _); | ^^^^^^^^^^^ error: invalid register `g6`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("g6") _); | ^^^^^^^^^^^ error: invalid register `g7`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("g7") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `i7`: the return address register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("i7") _); | ^^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", in("y") x); | ^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("y") x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 | LL | asm!("/* {} */", in(yreg) x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", out(yreg) _); | ^^^^^^^^^^^ error: cannot use register `r5`: g5 is reserved for system on SPARC32 - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("g5") _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("", in("y") x); | ^ @@ -79,7 +79,7 @@ LL | asm!("", in("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:49:27 + --> $DIR/bad-reg.rs:50:27 | LL | asm!("", out("y") x); | ^ @@ -87,7 +87,7 @@ LL | asm!("", out("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:53:35 | LL | asm!("/* {} */", in(yreg) x); | ^ diff --git a/tests/ui/asm/sparc/bad-reg.sparc64.stderr b/tests/ui/asm/sparc/bad-reg.sparc64.stderr index bdeb8c328db66..4822eeab00c11 100644 --- a/tests/ui/asm/sparc/bad-reg.sparc64.stderr +++ b/tests/ui/asm/sparc/bad-reg.sparc64.stderr @@ -1,71 +1,71 @@ error: invalid register `g0`: g0 is always zero and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:22:18 + --> $DIR/bad-reg.rs:23:18 | LL | asm!("", out("g0") _); | ^^^^^^^^^^^ error: invalid register `g1`: reserved by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:25:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", out("g1") _); | ^^^^^^^^^^^ error: invalid register `g6`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("g6") _); | ^^^^^^^^^^^ error: invalid register `g7`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("g7") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `i7`: the return address register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("i7") _); | ^^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", in("y") x); | ^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("y") x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 | LL | asm!("/* {} */", in(yreg) x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", out(yreg) _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("", in("y") x); | ^ @@ -73,7 +73,7 @@ LL | asm!("", in("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:49:27 + --> $DIR/bad-reg.rs:50:27 | LL | asm!("", out("y") x); | ^ @@ -81,7 +81,7 @@ LL | asm!("", out("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:53:35 | LL | asm!("/* {} */", in(yreg) x); | ^ diff --git a/tests/ui/asm/sparc/bad-reg.sparcv8plus.stderr b/tests/ui/asm/sparc/bad-reg.sparcv8plus.stderr index e0580ad3232f5..84e56871ecc26 100644 --- a/tests/ui/asm/sparc/bad-reg.sparcv8plus.stderr +++ b/tests/ui/asm/sparc/bad-reg.sparcv8plus.stderr @@ -1,77 +1,77 @@ error: invalid register `g0`: g0 is always zero and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:22:18 + --> $DIR/bad-reg.rs:23:18 | LL | asm!("", out("g0") _); | ^^^^^^^^^^^ error: invalid register `g1`: reserved by LLVM and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:25:18 + --> $DIR/bad-reg.rs:26:18 | LL | asm!("", out("g1") _); | ^^^^^^^^^^^ error: invalid register `g6`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", out("g6") _); | ^^^^^^^^^^^ error: invalid register `g7`: reserved for system and cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:34:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", out("g7") _); | ^^^^^^^^^^^ error: invalid register `sp`: the stack pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:36:18 + --> $DIR/bad-reg.rs:37:18 | LL | asm!("", out("sp") _); | ^^^^^^^^^^^ error: invalid register `fp`: the frame pointer cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:38:18 + --> $DIR/bad-reg.rs:39:18 | LL | asm!("", out("fp") _); | ^^^^^^^^^^^ error: invalid register `i7`: the return address register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:40:18 + --> $DIR/bad-reg.rs:41:18 | LL | asm!("", out("i7") _); | ^^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:46:18 + --> $DIR/bad-reg.rs:47:18 | LL | asm!("", in("y") x); | ^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:49:18 + --> $DIR/bad-reg.rs:50:18 | LL | asm!("", out("y") x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:52:26 + --> $DIR/bad-reg.rs:53:26 | LL | asm!("/* {} */", in(yreg) x); | ^^^^^^^^^^ error: register class `yreg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:55:26 + --> $DIR/bad-reg.rs:56:26 | LL | asm!("/* {} */", out(yreg) _); | ^^^^^^^^^^^ error: cannot use register `r5`: g5 is reserved for system on SPARC32 - --> $DIR/bad-reg.rs:30:18 + --> $DIR/bad-reg.rs:31:18 | LL | asm!("", out("g5") _); | ^^^^^^^^^^^ error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:46:26 + --> $DIR/bad-reg.rs:47:26 | LL | asm!("", in("y") x); | ^ @@ -79,7 +79,7 @@ LL | asm!("", in("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:49:27 + --> $DIR/bad-reg.rs:50:27 | LL | asm!("", out("y") x); | ^ @@ -87,7 +87,7 @@ LL | asm!("", out("y") x); = note: register class `yreg` supports these types: error: type `i32` cannot be used with this register class - --> $DIR/bad-reg.rs:52:35 + --> $DIR/bad-reg.rs:53:35 | LL | asm!("/* {} */", in(yreg) x); | ^ diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs index 00a8e588f9673..455bb3239895b 100644 --- a/tests/ui/asm/x86_64/goto.rs +++ b/tests/ui/asm/x86_64/goto.rs @@ -1,6 +1,7 @@ //@ only-x86_64 //@ run-pass //@ needs-asm-support +//@ ignore-backends: gcc #![deny(unreachable_code)] #![feature(asm_goto_with_outputs)] @@ -68,6 +69,7 @@ fn goto_out_jump() { fn goto_out_jump_noreturn() { unsafe { let mut value = false; + //~^ WARN value assigned to `value` is never read let mut out: usize; asm!( "lea {}, [{} + 1]", diff --git a/tests/ui/asm/x86_64/goto.stderr b/tests/ui/asm/x86_64/goto.stderr index 78b726b3f3d31..da3f7d6763fa8 100644 --- a/tests/ui/asm/x86_64/goto.stderr +++ b/tests/ui/asm/x86_64/goto.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/goto.rs:143:9 + --> $DIR/goto.rs:145:9 | LL | / asm!( LL | | "jmp {}", @@ -13,10 +13,19 @@ LL | unreachable!(); | ^^^^^^^^^^^^^^ unreachable statement | note: the lint level is defined here - --> $DIR/goto.rs:133:8 + --> $DIR/goto.rs:135:8 | LL | #[warn(unreachable_code)] | ^^^^^^^^^^^^^^^^ -warning: 1 warning emitted +warning: value assigned to `value` is never read + --> $DIR/goto.rs:71:25 + | +LL | let mut value = false; + | ^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: 2 warnings emitted diff --git a/tests/ui/asm/x86_64/srcloc.rs b/tests/ui/asm/x86_64/srcloc.rs index 2938bafe5e70c..f4ffa8c5c3b2c 100644 --- a/tests/ui/asm/x86_64/srcloc.rs +++ b/tests/ui/asm/x86_64/srcloc.rs @@ -1,6 +1,7 @@ //@ only-x86_64 //@ build-fail //@ compile-flags: -Ccodegen-units=1 +//@ ignore-backends: gcc use std::arch::asm; diff --git a/tests/ui/asm/x86_64/srcloc.stderr b/tests/ui/asm/x86_64/srcloc.stderr index bb4e855163d77..b2079120ec065 100644 --- a/tests/ui/asm/x86_64/srcloc.stderr +++ b/tests/ui/asm/x86_64/srcloc.stderr @@ -1,5 +1,5 @@ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:11:15 + --> $DIR/srcloc.rs:12:15 | LL | asm!("invalid_instruction"); | ^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:15:13 + --> $DIR/srcloc.rs:16:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:20:13 + --> $DIR/srcloc.rs:21:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:26:13 + --> $DIR/srcloc.rs:27:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:33:13 + --> $DIR/srcloc.rs:34:13 | LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:38:14 + --> $DIR/srcloc.rs:39:14 | LL | asm!(concat!("invalid", "_", "instruction")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ warning: scale factor without index register is ignored - --> $DIR/srcloc.rs:41:15 + --> $DIR/srcloc.rs:42:15 | LL | asm!("movaps %xmm3, (%esi, 2)", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | movaps %xmm3, (%esi, 2) | ^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:45:14 + --> $DIR/srcloc.rs:46:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ @@ -95,7 +95,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:51:14 + --> $DIR/srcloc.rs:52:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ @@ -107,7 +107,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:58:14 + --> $DIR/srcloc.rs:59:14 | LL | "invalid_instruction", | ^^^^^^^^^^^^^^^^^^^ @@ -119,7 +119,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:65:13 + --> $DIR/srcloc.rs:66:13 | LL | concat!("invalid", "_", "instruction"), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -131,7 +131,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:72:13 + --> $DIR/srcloc.rs:73:13 | LL | concat!("invalid", "_", "instruction"), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ LL | invalid_instruction | ^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:79:14 + --> $DIR/srcloc.rs:80:14 | LL | "invalid_instruction1", | ^^^^^^^^^^^^^^^^^^^^ @@ -155,7 +155,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:80:14 + --> $DIR/srcloc.rs:81:14 | LL | "invalid_instruction2", | ^^^^^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:86:13 + --> $DIR/srcloc.rs:87:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -182,7 +182,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:86:13 + --> $DIR/srcloc.rs:87:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -197,7 +197,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:95:13 + --> $DIR/srcloc.rs:96:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -212,7 +212,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:95:13 + --> $DIR/srcloc.rs:96:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -227,7 +227,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:99:13 + --> $DIR/srcloc.rs:100:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -242,7 +242,7 @@ LL | invalid_instruction3 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:99:13 + --> $DIR/srcloc.rs:100:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -257,7 +257,7 @@ LL | invalid_instruction4 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction1' - --> $DIR/srcloc.rs:110:13 + --> $DIR/srcloc.rs:111:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -272,7 +272,7 @@ LL | invalid_instruction1 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction2' - --> $DIR/srcloc.rs:110:13 + --> $DIR/srcloc.rs:111:13 | LL | / concat!( LL | | "invalid", "_", "instruction1", "\n", @@ -287,7 +287,7 @@ LL | invalid_instruction2 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction3' - --> $DIR/srcloc.rs:114:13 + --> $DIR/srcloc.rs:115:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -302,7 +302,7 @@ LL | invalid_instruction3 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction4' - --> $DIR/srcloc.rs:114:13 + --> $DIR/srcloc.rs:115:13 | LL | / concat!( LL | | "invalid", "_", "instruction3", "\n", @@ -317,7 +317,7 @@ LL | invalid_instruction4 | ^^^^^^^^^^^^^^^^^^^^ error: invalid instruction mnemonic 'invalid_instruction' - --> $DIR/srcloc.rs:127:14 + --> $DIR/srcloc.rs:128:14 | LL | "invalid_instruction" | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs new file mode 100644 index 0000000000000..e5c1f47b9e02b --- /dev/null +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +// Regression test for #146467. +#![feature(inherent_associated_types)] +//~^ WARN the feature `inherent_associated_types` is incomplete + +struct Foo(T); + +impl<'a> Foo { + //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait + type Assoc = &'a (); +} + +fn foo(_: for<'a> fn(Foo::Assoc)) {} +//~^ ERROR mismatched types +//~| ERROR higher-ranked subtype error +fn main() {} diff --git a/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr new file mode 100644 index 0000000000000..4c0726d4ddca9 --- /dev/null +++ b/tests/ui/associated-inherent-types/hr-do-not-blame-outlives-static-ice.stderr @@ -0,0 +1,34 @@ +warning: the feature `inherent_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:4:12 + | +LL | #![feature(inherent_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #8995 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:9:6 + | +LL | impl<'a> Foo { + | ^^ unconstrained lifetime parameter + +error[E0308]: mismatched types + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:11 + | +LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other + | + = note: expected struct `Foo fn(&'a ())>` + found struct `Foo fn(&'a ())>` + +error: higher-ranked subtype error + --> $DIR/hr-do-not-blame-outlives-static-ice.rs:14:1 + | +LL | fn foo(_: for<'a> fn(Foo::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0308. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.rs b/tests/ui/associated-type-bounds/duplicate-bound-err.rs new file mode 100644 index 0000000000000..01cc05f2545f1 --- /dev/null +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.rs @@ -0,0 +1,114 @@ +//@ edition: 2024 + +#![feature(associated_const_equality, type_alias_impl_trait, return_type_notation)] +#![allow(refining_impl_trait_internal)] + +use std::iter; + +fn rpit1() -> impl Iterator { + iter::empty() + //~^ ERROR type annotations needed +} +fn rpit2() -> impl Iterator { + iter::empty() + //~^ ERROR type annotations needed +} +fn rpit3() -> impl Iterator { + iter::empty() + //~^ ERROR type annotations needed +} + +type Tait1> = impl Copy; +//~^ ERROR unconstrained opaque type +type Tait2> = impl Copy; +//~^ ERROR unconstrained opaque type +type Tait3> = impl Copy; +//~^ ERROR unconstrained opaque type + +type Tait4 = impl Iterator; +//~^ ERROR unconstrained opaque type +type Tait5 = impl Iterator; +//~^ ERROR unconstrained opaque type +type Tait6 = impl Iterator; +//~^ ERROR unconstrained opaque type + +fn mismatch() -> impl Iterator { + //~^ ERROR [E0277] + iter::empty::<*const ()>() +} + +fn mismatch_2() -> impl Iterator { + //~^ ERROR [E0277] + iter::empty::() +} + +trait Trait { + type Gat; + + const ASSOC: i32; + + fn foo() -> impl Sized; +} + +impl Trait for () { + type Gat = (); + + const ASSOC: i32 = 3; + + fn foo() {} +} + +impl Trait for u32 { + type Gat = (); + + const ASSOC: i32 = 4; + + fn foo() -> u32 { + 42 + } +} + +fn uncallable(_: impl Iterator) {} + +fn uncallable_const(_: impl Trait) {} + +fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} + +type MustFail = dyn Iterator; +//~^ ERROR [E0719] +//~| ERROR conflicting associated type bounds + +trait Trait2 { + const ASSOC: u32; +} + +type MustFail2 = dyn Trait2; +//~^ ERROR [E0719] +//~| ERROR conflicting associated type bounds + +type MustFail3 = dyn Iterator; +//~^ ERROR [E0719] + +type MustFail4 = dyn Trait2; +//~^ ERROR [E0719] + +trait Trait3 { + fn foo() -> impl Iterator; +} + +impl Trait3 for () { + fn foo() -> impl Iterator { + //~^ ERROR[E0271] + //~| ERROR[E0271] + [2u32].into_iter() + } +} + +fn main() { + uncallable(iter::empty::()); //~ ERROR [E0271] + uncallable(iter::empty::()); //~ ERROR [E0271] + uncallable_const(()); //~ ERROR [E0271] + uncallable_const(4u32); //~ ERROR [E0271] + uncallable_rtn(()); //~ ERROR [E0271] + uncallable_rtn(17u32); //~ ERROR [E0271] +} diff --git a/tests/ui/associated-type-bounds/duplicate-bound-err.stderr b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr new file mode 100644 index 0000000000000..1737d0dc5a385 --- /dev/null +++ b/tests/ui/associated-type-bounds/duplicate-bound-err.stderr @@ -0,0 +1,268 @@ +error[E0282]: type annotations needed + --> $DIR/duplicate-bound-err.rs:9:5 + | +LL | iter::empty() + | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` + | +help: consider specifying the generic argument + | +LL | iter::empty::() + | +++++ + +error[E0282]: type annotations needed + --> $DIR/duplicate-bound-err.rs:13:5 + | +LL | iter::empty() + | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` + | +help: consider specifying the generic argument + | +LL | iter::empty::() + | +++++ + +error[E0282]: type annotations needed + --> $DIR/duplicate-bound-err.rs:17:5 + | +LL | iter::empty() + | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` + | +help: consider specifying the generic argument + | +LL | iter::empty::() + | +++++ + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:21:51 + | +LL | type Tait1> = impl Copy; + | ^^^^^^^^^ + | + = note: `Tait1` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:23:51 + | +LL | type Tait2> = impl Copy; + | ^^^^^^^^^ + | + = note: `Tait2` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:25:57 + | +LL | type Tait3> = impl Copy; + | ^^^^^^^^^ + | + = note: `Tait3` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:28:14 + | +LL | type Tait4 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Tait4` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:30:14 + | +LL | type Tait5 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Tait5` must be used in combination with a concrete type within the same crate + +error: unconstrained opaque type + --> $DIR/duplicate-bound-err.rs:32:14 + | +LL | type Tait6 = impl Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Tait6` must be used in combination with a concrete type within the same crate + +error[E0277]: `*const ()` cannot be sent between threads safely + --> $DIR/duplicate-bound-err.rs:35:18 + | +LL | fn mismatch() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const ()` cannot be sent between threads safely +LL | +LL | iter::empty::<*const ()>() + | -------------------------- return type was inferred to be `std::iter::Empty<*const ()>` here + | + = help: the trait `Send` is not implemented for `*const ()` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/duplicate-bound-err.rs:40:20 + | +LL | fn mismatch_2() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` +LL | +LL | iter::empty::() + | ----------------------- return type was inferred to be `std::iter::Empty` here + +error[E0271]: expected `IntoIter` to be an iterator that yields `i32`, but it yields `u32` + --> $DIR/duplicate-bound-err.rs:100:17 + | +LL | fn foo() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` +... +LL | [2u32].into_iter() + | ------------------ return type was inferred to be `std::array::IntoIter` here + +error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified + --> $DIR/duplicate-bound-err.rs:77:42 + | +LL | type MustFail = dyn Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: conflicting associated type bounds for `Item` + --> $DIR/duplicate-bound-err.rs:77:17 + | +LL | type MustFail = dyn Iterator; + | ^^^^^^^^^^^^^----------^^----------^ + | | | + | | `Item` is specified to be `u32` here + | `Item` is specified to be `i32` here + +error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified + --> $DIR/duplicate-bound-err.rs:85:43 + | +LL | type MustFail2 = dyn Trait2; + | ------------ ^^^^^^^^^^^^ re-bound here + | | + | `ASSOC` bound here first + +error: conflicting associated type bounds for `ASSOC` + --> $DIR/duplicate-bound-err.rs:85:18 + | +LL | type MustFail2 = dyn Trait2; + | ^^^^^^^^^^^------------^^------------^ + | | | + | | `ASSOC` is specified to be `4` here + | `ASSOC` is specified to be `3` here + +error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified + --> $DIR/duplicate-bound-err.rs:89:43 + | +LL | type MustFail3 = dyn Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `ASSOC` in trait `Trait2` is already specified + --> $DIR/duplicate-bound-err.rs:92:43 + | +LL | type MustFail4 = dyn Trait2; + | ------------ ^^^^^^^^^^^^ re-bound here + | | + | `ASSOC` bound here first + +error[E0271]: expected `impl Iterator` to be an iterator that yields `i32`, but it yields `u32` + --> $DIR/duplicate-bound-err.rs:100:17 + | +LL | fn foo() -> impl Iterator { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` + | +note: required by a bound in `Trait3::foo::{anon_assoc#0}` + --> $DIR/duplicate-bound-err.rs:96:31 + | +LL | fn foo() -> impl Iterator; + | ^^^^^^^^^^ required by this bound in `Trait3::foo::{anon_assoc#0}` + +error[E0271]: expected `Empty` to be an iterator that yields `i32`, but it yields `u32` + --> $DIR/duplicate-bound-err.rs:108:16 + | +LL | uncallable(iter::empty::()); + | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32` + | | + | required by a bound introduced by this call + | +note: required by a bound in `uncallable` + --> $DIR/duplicate-bound-err.rs:71:32 + | +LL | fn uncallable(_: impl Iterator) {} + | ^^^^^^^^^^ required by this bound in `uncallable` + +error[E0271]: expected `Empty` to be an iterator that yields `u32`, but it yields `i32` + --> $DIR/duplicate-bound-err.rs:109:16 + | +LL | uncallable(iter::empty::()); + | ---------- ^^^^^^^^^^^^^^^^^^^^ expected `u32`, found `i32` + | | + | required by a bound introduced by this call + | +note: required by a bound in `uncallable` + --> $DIR/duplicate-bound-err.rs:71:44 + | +LL | fn uncallable(_: impl Iterator) {} + | ^^^^^^^^^^ required by this bound in `uncallable` + +error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` + --> $DIR/duplicate-bound-err.rs:110:22 + | +LL | uncallable_const(()); + | ---------------- ^^ expected `4`, found `3` + | | + | required by a bound introduced by this call + | + = note: expected constant `4` + found constant `3` +note: required by a bound in `uncallable_const` + --> $DIR/duplicate-bound-err.rs:73:46 + | +LL | fn uncallable_const(_: impl Trait) {} + | ^^^^^^^^^ required by this bound in `uncallable_const` + +error[E0271]: type mismatch resolving `::ASSOC == 3` + --> $DIR/duplicate-bound-err.rs:111:22 + | +LL | uncallable_const(4u32); + | ---------------- ^^^^ expected `3`, found `4` + | | + | required by a bound introduced by this call + | + = note: expected constant `3` + found constant `4` +note: required by a bound in `uncallable_const` + --> $DIR/duplicate-bound-err.rs:73:35 + | +LL | fn uncallable_const(_: impl Trait) {} + | ^^^^^^^^^ required by this bound in `uncallable_const` + +error[E0271]: type mismatch resolving `<() as Trait>::ASSOC == 4` + --> $DIR/duplicate-bound-err.rs:112:20 + | +LL | uncallable_rtn(()); + | -------------- ^^ expected `4`, found `3` + | | + | required by a bound introduced by this call + | + = note: expected constant `4` + found constant `3` +note: required by a bound in `uncallable_rtn` + --> $DIR/duplicate-bound-err.rs:75:75 + | +LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} + | ^^^^^^^^^ required by this bound in `uncallable_rtn` + +error[E0271]: type mismatch resolving `::ASSOC == 3` + --> $DIR/duplicate-bound-err.rs:113:20 + | +LL | uncallable_rtn(17u32); + | -------------- ^^^^^ expected `3`, found `4` + | | + | required by a bound introduced by this call + | + = note: expected constant `3` + found constant `4` +note: required by a bound in `uncallable_rtn` + --> $DIR/duplicate-bound-err.rs:75:48 + | +LL | fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} + | ^^^^^^^^^ required by this bound in `uncallable_rtn` + +error: aborting due to 25 previous errors + +Some errors have detailed explanations: E0271, E0277, E0282, E0719. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-type-bounds/duplicate-bound.rs b/tests/ui/associated-type-bounds/duplicate-bound.rs new file mode 100644 index 0000000000000..696710d76f6df --- /dev/null +++ b/tests/ui/associated-type-bounds/duplicate-bound.rs @@ -0,0 +1,240 @@ +//@ edition: 2024 +//@ run-pass + +#![feature(associated_const_equality, return_type_notation)] +#![allow(dead_code, refining_impl_trait_internal, type_alias_bounds)] + +use std::iter; +use std::mem::ManuallyDrop; + +struct Si1> { + f: T, +} +struct Si2> { + f: T, +} +struct Si3> { + f: T, +} +struct Sw1 +where + T: Iterator, +{ + f: T, +} +struct Sw2 +where + T: Iterator, +{ + f: T, +} +struct Sw3 +where + T: Iterator, +{ + f: T, +} + +enum Ei1> { + V(T), +} +enum Ei2> { + V(T), +} +enum Ei3> { + V(T), +} +enum Ew1 +where + T: Iterator, +{ + V(T), +} +enum Ew2 +where + T: Iterator, +{ + V(T), +} +enum Ew3 +where + T: Iterator, +{ + V(T), +} + +union Ui1> { + f: ManuallyDrop, +} +union Ui2> { + f: ManuallyDrop, +} +union Ui3> { + f: ManuallyDrop, +} +union Uw1 +where + T: Iterator, +{ + f: ManuallyDrop, +} +union Uw2 +where + T: Iterator, +{ + f: ManuallyDrop, +} +union Uw3 +where + T: Iterator, +{ + f: ManuallyDrop, +} + +fn fi1>() {} +fn fi2>() {} +fn fi3>() {} +fn fw1() +where + T: Iterator, +{ +} +fn fw2() +where + T: Iterator, +{ +} +fn fw3() +where + T: Iterator, +{ +} + +fn rpit1() -> impl Iterator { + iter::empty::() +} +fn rpit2() -> impl Iterator { + iter::empty::() +} +fn rpit3() -> impl Iterator { + iter::empty::() +} +fn apit1(_: impl Iterator) {} +fn apit2(_: impl Iterator) {} +fn apit3(_: impl Iterator) {} + +type Tait1> = T; +type Tait2> = T; +type Tait3> = T; +type Taw1 +where + T: Iterator, += T; +type Taw2 +where + T: Iterator, += T; +type Taw3 +where + T: Iterator, += T; + +trait Tri1> {} +trait Tri2> {} +trait Tri3> {} +trait Trs1: Iterator {} +trait Trs2: Iterator {} +trait Trs3: Iterator {} +trait Trw1 +where + T: Iterator, +{ +} +trait Trw2 +where + T: Iterator, +{ +} +trait Trw3 +where + T: Iterator, +{ +} +trait Trsw1 +where + Self: Iterator, +{ +} +trait Trsw2 +where + Self: Iterator, +{ +} +trait Trsw3 +where + Self: Iterator, +{ +} +trait Tra1 { + type A: Iterator; +} +trait Tra2 { + type A: Iterator; +} +trait Tra3 { + type A: Iterator; +} + +trait Trait { + type Gat; + + const ASSOC: i32; + + fn foo() -> impl Sized; +} + +impl Trait for () { + type Gat = (); + + const ASSOC: i32 = 3; + + fn foo() {} +} + +trait Subtrait: Trait = u32, Gat = u64> {} + +fn f = (), Gat = ()>>() { + let _: T::Gat = (); + let _: T::Gat = (); +} + +fn g = (), Gat = &'static str>>() { + let _: T::Gat = (); + let _: T::Gat = ""; +} + +fn uncallable(_: impl Iterator) {} + +fn callable(_: impl Iterator) {} + +fn uncallable_const(_: impl Trait) {} + +fn callable_const(_: impl Trait) {} + +fn uncallable_rtn(_: impl Trait, foo(..): Trait>) {} + +fn callable_rtn(_: impl Trait) {} + +trait Trait2 { + const ASSOC: u32; +} + +trait Trait3 { + fn foo() -> impl Iterator; +} + +fn main() { + callable(iter::empty::()); + callable_const(()); + callable_rtn(()); +} diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs deleted file mode 100644 index e9d94787e9829..0000000000000 --- a/tests/ui/associated-type-bounds/duplicate.rs +++ /dev/null @@ -1,278 +0,0 @@ -#![feature(type_alias_impl_trait)] - -use std::iter; -use std::mem::ManuallyDrop; - -struct SI1> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: T, -} -struct SI2> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: T, -} -struct SI3> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: T, -} -struct SW1 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: T, -} -struct SW2 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: T, -} -struct SW3 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: T, -} - -enum EI1> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - V(T), -} -enum EI2> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - V(T), -} -enum EI3> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - V(T), -} -enum EW1 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - V(T), -} -enum EW2 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - V(T), -} -enum EW3 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - V(T), -} - -union UI1> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: ManuallyDrop, -} -union UI2> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: ManuallyDrop, -} -union UI3> { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - f: ManuallyDrop, -} -union UW1 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: ManuallyDrop, -} -union UW2 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: ManuallyDrop, -} -union UW3 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ - f: ManuallyDrop, -} - -fn FI1>() {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -fn FI2>() {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -fn FI3>() {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -fn FW1() -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -fn FW2() -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -fn FW3() -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} - -fn FRPIT1() -> impl Iterator { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - iter::empty() - //~^ ERROR type annotations needed -} -fn FRPIT2() -> impl Iterator { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - iter::empty() - //~^ ERROR type annotations needed -} -fn FRPIT3() -> impl Iterator { - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - iter::empty() - //~^ ERROR type annotations needed -} -fn FAPIT1(_: impl Iterator) {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -fn FAPIT2(_: impl Iterator) {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -fn FAPIT3(_: impl Iterator) {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - -type TAI1> = T; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -type TAI2> = T; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -type TAI3> = T; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -type TAW1 -where - T: Iterator, -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -= T; -type TAW2 -where - T: Iterator, -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -= T; -type TAW3 -where - T: Iterator, -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -= T; - -type ETAI1> = impl Copy; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type -type ETAI2> = impl Copy; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type -type ETAI3> = impl Copy; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type -type ETAI4 = impl Iterator; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type -type ETAI5 = impl Iterator; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type -type ETAI6 = impl Iterator; -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR unconstrained opaque type - -trait TRI1> {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRI2> {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRI3> {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRS1: Iterator {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRS2: Iterator {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRS3: Iterator {} -//~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -//~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -trait TRW1 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRW2 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRW3 -where - T: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRSW1 -where - Self: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRSW2 -where - Self: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRSW3 -where - Self: Iterator, - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -{ -} -trait TRA1 { - type A: Iterator; - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -} -trait TRA2 { - type A: Iterator; - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -} -trait TRA3 { - type A: Iterator; - //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] - //~| ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719] -} - -fn main() {} diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr deleted file mode 100644 index 68fbb345f6f93..0000000000000 --- a/tests/ui/associated-type-bounds/duplicate.stderr +++ /dev/null @@ -1,751 +0,0 @@ -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:6:36 - | -LL | struct SI1> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:10:36 - | -LL | struct SI2> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:14:39 - | -LL | struct SI3> { - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:20:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:27:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:34:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:40:34 - | -LL | enum EI1> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:44:34 - | -LL | enum EI2> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:48:37 - | -LL | enum EI3> { - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:54:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:61:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:68:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:74:35 - | -LL | union UI1> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:78:35 - | -LL | union UI2> { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:82:38 - | -LL | union UI3> { - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:88:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:95:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:102:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:108:32 - | -LL | fn FI1>() {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:110:32 - | -LL | fn FI2>() {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:112:35 - | -LL | fn FI3>() {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:116:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:122:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:128:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:133:42 - | -LL | fn FRPIT1() -> impl Iterator { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:139:42 - | -LL | fn FRPIT2() -> impl Iterator { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:145:45 - | -LL | fn FRPIT3() -> impl Iterator { - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:151:40 - | -LL | fn FAPIT1(_: impl Iterator) {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:153:40 - | -LL | fn FAPIT2(_: impl Iterator) {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:155:43 - | -LL | fn FAPIT3(_: impl Iterator) {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:158:35 - | -LL | type TAI1> = T; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:160:35 - | -LL | type TAI2> = T; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:162:38 - | -LL | type TAI3> = T; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:166:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:171:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:176:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:180:36 - | -LL | type ETAI1> = impl Copy; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:183:36 - | -LL | type ETAI2> = impl Copy; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:186:39 - | -LL | type ETAI3> = impl Copy; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:202:36 - | -LL | trait TRI1> {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:204:36 - | -LL | trait TRI2> {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:206:39 - | -LL | trait TRI3> {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:208:34 - | -LL | trait TRS1: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:208:34 - | -LL | trait TRS1: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:208:34 - | -LL | trait TRS1: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:212:34 - | -LL | trait TRS2: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:212:34 - | -LL | trait TRS2: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:212:34 - | -LL | trait TRS2: Iterator {} - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:216:37 - | -LL | trait TRS3: Iterator {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:216:37 - | -LL | trait TRS3: Iterator {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:216:37 - | -LL | trait TRS3: Iterator {} - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:222:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:228:29 - | -LL | T: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:234:32 - | -LL | T: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:240:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:240:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:240:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:248:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:248:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:248:32 - | -LL | Self: Iterator, - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:256:35 - | -LL | Self: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:256:35 - | -LL | Self: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:256:35 - | -LL | Self: Iterator, - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:263:34 - | -LL | type A: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:263:34 - | -LL | type A: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:268:34 - | -LL | type A: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:268:34 - | -LL | type A: Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:273:37 - | -LL | type A: Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:273:37 - | -LL | type A: Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:133:42 - | -LL | fn FRPIT1() -> impl Iterator { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0282]: type annotations needed - --> $DIR/duplicate.rs:136:5 - | -LL | iter::empty() - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` - | -help: consider specifying the generic argument - | -LL | iter::empty::() - | +++++ - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:139:42 - | -LL | fn FRPIT2() -> impl Iterator { - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0282]: type annotations needed - --> $DIR/duplicate.rs:142:5 - | -LL | iter::empty() - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` - | -help: consider specifying the generic argument - | -LL | iter::empty::() - | +++++ - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:145:45 - | -LL | fn FRPIT3() -> impl Iterator { - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0282]: type annotations needed - --> $DIR/duplicate.rs:148:5 - | -LL | iter::empty() - | ^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `empty` - | -help: consider specifying the generic argument - | -LL | iter::empty::() - | +++++ - -error: unconstrained opaque type - --> $DIR/duplicate.rs:180:51 - | -LL | type ETAI1> = impl Copy; - | ^^^^^^^^^ - | - = note: `ETAI1` must be used in combination with a concrete type within the same crate - -error: unconstrained opaque type - --> $DIR/duplicate.rs:183:51 - | -LL | type ETAI2> = impl Copy; - | ^^^^^^^^^ - | - = note: `ETAI2` must be used in combination with a concrete type within the same crate - -error: unconstrained opaque type - --> $DIR/duplicate.rs:186:57 - | -LL | type ETAI3> = impl Copy; - | ^^^^^^^^^ - | - = note: `ETAI3` must be used in combination with a concrete type within the same crate - -error: unconstrained opaque type - --> $DIR/duplicate.rs:189:14 - | -LL | type ETAI4 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `ETAI4` must be used in combination with a concrete type within the same crate - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:189:40 - | -LL | type ETAI4 = impl Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:189:40 - | -LL | type ETAI4 = impl Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: unconstrained opaque type - --> $DIR/duplicate.rs:193:14 - | -LL | type ETAI5 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `ETAI5` must be used in combination with a concrete type within the same crate - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:193:40 - | -LL | type ETAI5 = impl Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:193:40 - | -LL | type ETAI5 = impl Iterator; - | ---------- ^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: unconstrained opaque type - --> $DIR/duplicate.rs:197:14 - | -LL | type ETAI6 = impl Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `ETAI6` must be used in combination with a concrete type within the same crate - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:197:43 - | -LL | type ETAI6 = impl Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - -error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified - --> $DIR/duplicate.rs:197:43 - | -LL | type ETAI6 = impl Iterator; - | ------------- ^^^^^^^^^^^^^ re-bound here - | | - | `Item` bound here first - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 87 previous errors - -Some errors have detailed explanations: E0282, E0719. -For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/associated-consts/ambiguous-associated-type-error-78622.rs b/tests/ui/associated-types/ambiguous-associated-type-error-78622.rs similarity index 100% rename from tests/ui/associated-consts/ambiguous-associated-type-error-78622.rs rename to tests/ui/associated-types/ambiguous-associated-type-error-78622.rs diff --git a/tests/ui/associated-consts/ambiguous-associated-type-error-78622.stderr b/tests/ui/associated-types/ambiguous-associated-type-error-78622.stderr similarity index 100% rename from tests/ui/associated-consts/ambiguous-associated-type-error-78622.stderr rename to tests/ui/associated-types/ambiguous-associated-type-error-78622.stderr diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed index bce6148f9e199..ae4d0107aee52 100644 --- a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed +++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed @@ -8,7 +8,7 @@ trait Get { } trait Other { - fn uhoh(&self, foo: U, bar: ::Value) where Self: Sized, Self: Get, Self: Get {} + fn uhoh(&self, foo: U, bar: ::Value) where Self: Sized, Self: Get {} //~^ ERROR the trait bound `Self: Get` is not satisfied //~| ERROR the trait bound `Self: Get` is not satisfied } diff --git a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr index 71a4a2610aac4..e96a2446b6ce0 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding-2.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding-2.stderr @@ -1,4 +1,4 @@ -error: conflicting associated type bounds for `Item` when expanding trait alias +error: conflicting associated type bounds for `Item` --> $DIR/associated-types-overridden-binding-2.rs:6:13 | LL | trait I32Iterator = Iterator; diff --git a/tests/ui/associated-types/associated-types-overridden-binding.stderr b/tests/ui/associated-types/associated-types-overridden-binding.stderr index 3b20015dfcab3..08ab9b63ee9fd 100644 --- a/tests/ui/associated-types/associated-types-overridden-binding.stderr +++ b/tests/ui/associated-types/associated-types-overridden-binding.stderr @@ -22,7 +22,7 @@ note: required by a bound in `I32Iterator` LL | trait I32Iterator = Iterator; | ^^^^^^^^^^ required by this bound in `I32Iterator` -error: conflicting associated type bounds for `Item` when expanding trait alias +error: conflicting associated type bounds for `Item` --> $DIR/associated-types-overridden-binding.rs:10:13 | LL | trait I32Iterator = Iterator; diff --git a/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.rs b/tests/ui/associated-types/mismatched-types-in-associated-type-87490.rs similarity index 100% rename from tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.rs rename to tests/ui/associated-types/mismatched-types-in-associated-type-87490.rs diff --git a/tests/ui/associated-types/mismatched-types-in-associated-type-87490.stderr b/tests/ui/associated-types/mismatched-types-in-associated-type-87490.stderr new file mode 100644 index 0000000000000..0a2dbcdc27b75 --- /dev/null +++ b/tests/ui/associated-types/mismatched-types-in-associated-type-87490.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/mismatched-types-in-associated-type-87490.rs:10:5 + | +LL | fn follow(_: &str) -> <&str as StreamOnce>::Position { + | ------------------------------ expected `usize` because of return type +LL | String::new + | ^^^^^^^^^^^ expected `usize`, found fn item + | + = note: expected type `usize` + found fn item `fn() -> String {String::new}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.rs b/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.rs new file mode 100644 index 0000000000000..e762f5a748549 --- /dev/null +++ b/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.rs @@ -0,0 +1,12 @@ +// https://github.com/rust-lang/rust/issues/65230 +trait T0 {} +trait T1: T0 {} + +trait T2 {} + +impl<'a> T0 for &'a (dyn T2 + 'static) {} + +impl T1 for &dyn T2 {} +//~^ ERROR mismatched types + +fn main() {} diff --git a/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.stderr b/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.stderr new file mode 100644 index 0000000000000..c34685aacad5c --- /dev/null +++ b/tests/ui/associated-types/mismatched-types-in-trait-impl-65230.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/mismatched-types-in-trait-impl-65230.rs:9:13 + | +LL | impl T1 for &dyn T2 {} + | ^^^^^^^ lifetime mismatch + | + = note: expected trait `<&dyn T2 as T0>` + found trait `<&(dyn T2 + 'static) as T0>` +note: the anonymous lifetime as defined here... + --> $DIR/mismatched-types-in-trait-impl-65230.rs:9:13 + | +LL | impl T1 for &dyn T2 {} + | ^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/missing-default-associated-type-72076.rs b/tests/ui/associated-types/missing-default-associated-type-72076.rs new file mode 100644 index 0000000000000..c25bdff16fd2e --- /dev/null +++ b/tests/ui/associated-types/missing-default-associated-type-72076.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/72076 +trait X { + type S; + fn f() -> Self::S {} //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/missing-default-associated-type-72076.stderr b/tests/ui/associated-types/missing-default-associated-type-72076.stderr new file mode 100644 index 0000000000000..c91dbb6d5c858 --- /dev/null +++ b/tests/ui/associated-types/missing-default-associated-type-72076.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/missing-default-associated-type-72076.rs:4:23 + | +LL | fn f() -> Self::S {} + | ^^ expected associated type, found `()` + | + = note: expected associated type `::S` + found unit type `()` + = help: consider constraining the associated type `::S` to `()` or calling a method that returns `::S` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/projection-dyn-associated-type.rs b/tests/ui/associated-types/projection-dyn-associated-type.rs new file mode 100644 index 0000000000000..3b981e7987e0e --- /dev/null +++ b/tests/ui/associated-types/projection-dyn-associated-type.rs @@ -0,0 +1,28 @@ +// Regression test for the projection bug in +// +//@ compile-flags: -Zincremental-verify-ich=yes +//@ incremental + +pub trait A {} +pub trait B: A {} + +pub trait Mirror { + type Assoc: ?Sized; +} + +impl Mirror for A { + //~^ ERROR the type parameter `T` is not constrained by the impl trait, self type, or predicates [E0207] + //~| WARN trait objects without an explicit `dyn` are deprecated [bare_trait_objects] + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + type Assoc = T; +} + +pub fn foo<'a>( + x: &'a ::Assoc +) -> &'a ::Assoc { + //~^ ERROR the trait bound `(dyn B + 'static): Mirror` is not satisfied [E0277] + //~| ERROR the trait bound `(dyn B + 'static): Mirror` is not satisfied [E0277] + static +} //~ ERROR expected identifier, found `}` + +pub fn main() {} diff --git a/tests/ui/associated-types/projection-dyn-associated-type.stderr b/tests/ui/associated-types/projection-dyn-associated-type.stderr new file mode 100644 index 0000000000000..1ac2beb0414e2 --- /dev/null +++ b/tests/ui/associated-types/projection-dyn-associated-type.stderr @@ -0,0 +1,52 @@ +error: expected identifier, found `}` + --> $DIR/projection-dyn-associated-type.rs:26:1 + | +LL | } + | ^ expected identifier + +warning: trait objects without an explicit `dyn` are deprecated + --> $DIR/projection-dyn-associated-type.rs:13:28 + | +LL | impl Mirror for A { + | ^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see + = note: `#[warn(bare_trait_objects)]` (part of `#[warn(rust_2021_compatibility)]`) on by default +help: if this is a dyn-compatible trait, use `dyn` + | +LL | impl Mirror for dyn A { + | +++ +help: alternatively use a blanket implementation to implement `Mirror` for all types that also implement `A` + | +LL - impl Mirror for A { +LL + impl Mirror for U { + | + +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/projection-dyn-associated-type.rs:13:6 + | +LL | impl Mirror for A { + | ^ unconstrained type parameter + +error[E0277]: the trait bound `(dyn B + 'static): Mirror` is not satisfied + --> $DIR/projection-dyn-associated-type.rs:22:6 + | +LL | ) -> &'a ::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Mirror` is not implemented for `(dyn B + 'static)` + | + = help: the trait `Mirror` is implemented for `dyn A` + +error[E0277]: the trait bound `(dyn B + 'static): Mirror` is not satisfied + --> $DIR/projection-dyn-associated-type.rs:22:6 + | +LL | ) -> &'a ::Assoc { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Mirror` is not implemented for `(dyn B + 'static)` + | + = help: the trait `Mirror` is implemented for `dyn A` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0277. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.current.stderr b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.current.stderr new file mode 100644 index 0000000000000..f3938ff606f4d --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.current.stderr @@ -0,0 +1,21 @@ +error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:47:45: 47:67}>` + --> $DIR/post-mono-higher-ranked-hang.rs:47:21 + | +LL | / self.perm_pairs(l, &mut async move |left_pair| { +LL | | +LL | | self.perm_pairs(r, yield_chain).await +LL | | }) + | |______________________^ + | +note: `ToChain::<'env, 'db>::perm_pairs` defined here + --> $DIR/post-mono-higher-ranked-hang.rs:38:5 + | +LL | / fn perm_pairs<'l>( +LL | | &'l self, +LL | | perm: &'l SymPerm<'db>, +LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>), +LL | | ) -> Pin + 'l>> { + | |____________________________________________________________^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.next.stderr b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.next.stderr new file mode 100644 index 0000000000000..f3938ff606f4d --- /dev/null +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.next.stderr @@ -0,0 +1,21 @@ +error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:47:45: 47:67}>` + --> $DIR/post-mono-higher-ranked-hang.rs:47:21 + | +LL | / self.perm_pairs(l, &mut async move |left_pair| { +LL | | +LL | | self.perm_pairs(r, yield_chain).await +LL | | }) + | |______________________^ + | +note: `ToChain::<'env, 'db>::perm_pairs` defined here + --> $DIR/post-mono-higher-ranked-hang.rs:38:5 + | +LL | / fn perm_pairs<'l>( +LL | | &'l self, +LL | | perm: &'l SymPerm<'db>, +LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>), +LL | | ) -> Pin + 'l>> { + | |____________________________________________________________^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs index f6ebf787f81b9..55d7cc30ec964 100644 --- a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs +++ b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.rs @@ -2,6 +2,10 @@ //@ aux-build:block-on.rs //@ edition:2021 +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + // Regression test for . extern crate block_on; diff --git a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr b/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr deleted file mode 100644 index 486e5f9416550..0000000000000 --- a/tests/ui/async-await/async-closures/post-mono-higher-ranked-hang.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: reached the recursion limit while instantiating `ToChain::<'_, '_>::perm_pairs::<{async closure@$DIR/post-mono-higher-ranked-hang.rs:43:45: 43:67}>` - --> $DIR/post-mono-higher-ranked-hang.rs:43:21 - | -LL | / self.perm_pairs(l, &mut async move |left_pair| { -LL | | -LL | | self.perm_pairs(r, yield_chain).await -LL | | }) - | |______________________^ - | -note: `ToChain::<'env, 'db>::perm_pairs` defined here - --> $DIR/post-mono-higher-ranked-hang.rs:34:5 - | -LL | / fn perm_pairs<'l>( -LL | | &'l self, -LL | | perm: &'l SymPerm<'db>, -LL | | yield_chain: &'l mut impl AsyncFnMut(&SymPerm<'db>), -LL | | ) -> Pin + 'l>> { - | |____________________________________________________________^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs index 638fb67c3a465..d654906e8d4a1 100644 --- a/tests/ui/async-await/async-closures/precise-captures.rs +++ b/tests/ui/async-await/async-closures/precise-captures.rs @@ -10,6 +10,7 @@ // in . #![allow(unused_mut)] +#![allow(unused_assignments)] extern crate block_on; diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs index 19a31d1889b84..f97ec779b32cf 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs @@ -44,4 +44,18 @@ fn through_field_and_ref_move<'a>(x: &S<'a>) { outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` } +struct T; +impl T { + fn outlives<'a>(&'a self, _: impl Sized + 'a) {} +} +fn through_method<'a>(x: &'a i32) { + let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough + T.outlives::<'a>(c()); + T.outlives::<'a>(call_once(c)); + + let c = async move || { println!("{}", *x); }; + T.outlives::<'a>(c()); //~ ERROR `c` does not live long enough + T.outlives::<'a>(call_once(c)); +} + fn main() {} diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr index b7259074bf64b..4aae9807dd2e4 100644 --- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr +++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr @@ -28,6 +28,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that the value outlives `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:26:13 @@ -73,6 +79,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that the value outlives `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0505]: cannot move out of `c` because it is borrowed --> $DIR/without-precise-captures-we-are-powerless.rs:32:30 @@ -89,6 +101,12 @@ LL | outlives::<'a>(c()); | argument requires that `c` is borrowed for `'a` LL | outlives::<'a>(call_once(c)); | ^ move out of `c` occurs here + | +note: requirement that the value outlives `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0597]: `x` does not live long enough --> $DIR/without-precise-captures-we-are-powerless.rs:36:13 @@ -129,6 +147,12 @@ LL | outlives::<'a>(c()); LL | outlives::<'a>(call_once(c)); LL | } | - `c` dropped here while still borrowed + | +note: requirement that the value outlives `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:7:33 + | +LL | fn outlives<'a>(_: impl Sized + 'a) {} + | ^^ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/without-precise-captures-we-are-powerless.rs:44:5 @@ -141,7 +165,44 @@ help: add explicit lifetime `'a` to the type of `x` LL | fn through_field_and_ref_move<'a>(x: &'a S<'a>) { | ++ -error: aborting due to 10 previous errors +error[E0597]: `x` does not live long enough + --> $DIR/without-precise-captures-we-are-powerless.rs:52:13 + | +LL | fn through_method<'a>(x: &'a i32) { + | -- lifetime `'a` defined here +LL | let c = async || { println!("{}", *x); }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough +LL | T.outlives::<'a>(c()); +LL | T.outlives::<'a>(call_once(c)); + | ------------------------------ argument requires that `x` is borrowed for `'a` +... +LL | } + | - `x` dropped here while still borrowed + +error[E0597]: `c` does not live long enough + --> $DIR/without-precise-captures-we-are-powerless.rs:57:22 + | +LL | fn through_method<'a>(x: &'a i32) { + | -- lifetime `'a` defined here +... +LL | let c = async move || { println!("{}", *x); }; + | - binding `c` declared here +LL | T.outlives::<'a>(c()); + | -----------------^--- + | | | + | | borrowed value does not live long enough + | argument requires that `c` is borrowed for `'a` +LL | T.outlives::<'a>(call_once(c)); +LL | } + | - `c` dropped here while still borrowed + | +note: requirement that the value outlives `'a` introduced here + --> $DIR/without-precise-captures-we-are-powerless.rs:49:47 + | +LL | fn outlives<'a>(&'a self, _: impl Sized + 'a) {} + | ^^ + +error: aborting due to 12 previous errors Some errors have detailed explanations: E0505, E0597, E0621. For more information about an error, try `rustc --explain E0505`. diff --git a/tests/ui/async-await/async-drop/ex-ice1.stderr b/tests/ui/async-await/async-drop/ex-ice1.stderr index 68533edeb086c..a1fa89f2c4001 100644 --- a/tests/ui/async-await/async-drop/ex-ice1.stderr +++ b/tests/ui/async-await/async-drop/ex-ice1.stderr @@ -1,14 +1,14 @@ error[E0423]: expected function, found module `core::future::async_drop` --> $DIR/ex-ice1.rs:9:35 | -LL | let async_drop_fut = pin!(core::future::async_drop(async {})); - | ^^^^^^^^^^^^^^^^^^^^^^^^ not a function +LL | ... let async_drop_fut = pin!(core::future::async_drop(async {})); + | ^^^^^^^^^^^^^^^^^^^^^^^^ not a function error[E0603]: module `async_drop` is private --> $DIR/ex-ice1.rs:9:49 | -LL | let async_drop_fut = pin!(core::future::async_drop(async {})); - | ^^^^^^^^^^ private module +LL | ... let async_drop_fut = pin!(core::future::async_drop(async {})); + | ^^^^^^^^^^ private module | note: the module `async_drop` is defined here --> $SRC_DIR/core/src/future/mod.rs:LL:COL diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr deleted file mode 100644 index b47db2b19ffe2..0000000000000 --- a/tests/ui/async-await/higher-ranked-auto-trait-14.no_assumptions.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error: implementation of `FnOnce` is not general enough - --> $DIR/higher-ranked-auto-trait-14.rs:20:5 - | -LL | / async move { -LL | | let xs = unique_x.union(&cached) -LL | | // .copied() // works -LL | | .map(|x| *x) // error -LL | | ; -LL | | let blah = val.blah(xs.into_iter()).await; -LL | | } - | |_____^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`... - = note: ...but it actually implements `FnOnce<(&u32,)>` - -error: implementation of `FnOnce` is not general enough - --> $DIR/higher-ranked-auto-trait-14.rs:20:5 - | -LL | / async move { -LL | | let xs = unique_x.union(&cached) -LL | | // .copied() // works -LL | | .map(|x| *x) // error -LL | | ; -LL | | let blah = val.blah(xs.into_iter()).await; -LL | | } - | |_____^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'0 u32) -> u32` must implement `FnOnce<(&'1 u32,)>`, for any two lifetimes `'0` and `'1`... - = note: ...but it actually implements `FnOnce<(&u32,)>` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors - diff --git a/tests/ui/async-await/higher-ranked-auto-trait-14.rs b/tests/ui/async-await/higher-ranked-auto-trait-14.rs index 5ed12cd6e38cb..ed53d6306c602 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-14.rs +++ b/tests/ui/async-await/higher-ranked-auto-trait-14.rs @@ -1,9 +1,8 @@ // Repro for . +//@ check-pass //@ edition: 2021 //@ revisions: assumptions no_assumptions //@[assumptions] compile-flags: -Zhigher-ranked-assumptions -//@[assumptions] check-pass -//@[no_assumptions] known-bug: #110338 use std::collections::HashSet; use std::future::Future; diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr deleted file mode 100644 index 2fc44412b9dae..0000000000000 --- a/tests/ui/async-await/higher-ranked-auto-trait-2.no_assumptions.stderr +++ /dev/null @@ -1,49 +0,0 @@ -error: lifetime bound not satisfied - --> $DIR/higher-ranked-auto-trait-2.rs:16:9 - | -LL | / async move { -LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics -LL | | self.run(t).await; -LL | | } - | |_________^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) - -error: lifetime bound not satisfied - --> $DIR/higher-ranked-auto-trait-2.rs:16:9 - | -LL | / async move { -LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics -LL | | self.run(t).await; -LL | | } - | |_________^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: lifetime bound not satisfied - --> $DIR/higher-ranked-auto-trait-2.rs:16:9 - | -LL | / async move { -LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics -LL | | self.run(t).await; -LL | | } - | |_________^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: lifetime bound not satisfied - --> $DIR/higher-ranked-auto-trait-2.rs:16:9 - | -LL | / async move { -LL | | // asks for an unspecified lifetime to outlive itself? weird diagnostics -LL | | self.run(t).await; -LL | | } - | |_________^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 4 previous errors - diff --git a/tests/ui/async-await/higher-ranked-auto-trait-2.rs b/tests/ui/async-await/higher-ranked-auto-trait-2.rs index 6c75597265bc2..b09b4983de296 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-2.rs +++ b/tests/ui/async-await/higher-ranked-auto-trait-2.rs @@ -1,9 +1,8 @@ // Repro for . +//@ check-pass //@ edition: 2021 //@ revisions: assumptions no_assumptions //@[assumptions] compile-flags: -Zhigher-ranked-assumptions -//@[assumptions] check-pass -//@[no_assumptions] known-bug: #110338 use std::future::Future; diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr deleted file mode 100644 index c5c98ac807ea9..0000000000000 --- a/tests/ui/async-await/higher-ranked-auto-trait-3.no_assumptions.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error: lifetime bound not satisfied - --> $DIR/higher-ranked-auto-trait-3.rs:66:9 - | -LL | / async { -LL | | self.fi_2.get_iter(cx).await; -LL | | } - | |_________^ - | - = note: this is a known limitation that will be removed in the future (see issue #100013 for more information) - -error: aborting due to 1 previous error - diff --git a/tests/ui/async-await/higher-ranked-auto-trait-3.rs b/tests/ui/async-await/higher-ranked-auto-trait-3.rs index d42d423668051..2b7990d5f3f12 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-3.rs +++ b/tests/ui/async-await/higher-ranked-auto-trait-3.rs @@ -1,9 +1,8 @@ // Repro for . +//@ check-pass //@ edition: 2021 //@ revisions: assumptions no_assumptions //@[assumptions] compile-flags: -Zhigher-ranked-assumptions -//@[assumptions] check-pass -//@[no_assumptions] known-bug: #110338 #![feature(impl_trait_in_assoc_type)] diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr b/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr deleted file mode 100644 index dcb8075566e6d..0000000000000 --- a/tests/ui/async-await/higher-ranked-auto-trait-7.no_assumptions.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `S` does not live long enough - --> $DIR/higher-ranked-auto-trait-7.rs:26:5 - | -LL | future::<'a, S, _>(async move { - | ^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/async-await/higher-ranked-auto-trait-7.rs b/tests/ui/async-await/higher-ranked-auto-trait-7.rs index abded5a88d3ae..558bd6de44293 100644 --- a/tests/ui/async-await/higher-ranked-auto-trait-7.rs +++ b/tests/ui/async-await/higher-ranked-auto-trait-7.rs @@ -1,9 +1,8 @@ // Repro for . +//@ check-pass //@ edition: 2021 //@ revisions: assumptions no_assumptions //@[assumptions] compile-flags: -Zhigher-ranked-assumptions -//@[assumptions] check-pass -//@[no_assumptions] known-bug: #110338 #![allow(dropping_copy_types)] diff --git a/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs b/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs new file mode 100644 index 0000000000000..410d4e503b7c2 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-normalize-assumptions-2.rs @@ -0,0 +1,38 @@ +//@ revisions: stock hr +//@[hr] compile-flags: -Zhigher-ranked-assumptions +//@ edition: 2024 +//@ check-pass + +// Test that we don't normalize the higher-ranked assumptions of an auto trait goal +// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from +// this normalization may lead to higher-ranked lifetime errors when the flag is not +// enabled. + +// Regression test for . + +pub fn a() -> impl Future + Send { + async { + let queries = core::iter::empty().map(Thing::f); + b(queries).await; + } +} + +async fn b(queries: impl IntoIterator) { + c(queries).await; +} + +fn c<'a, I>(_queries: I) -> impl Future +where + I: IntoIterator, + I::IntoIter: 'a, +{ + async {} +} + +pub struct Thing<'a>(pub &'a ()); + +impl Thing<'_> { + fn f(_: &Self) {} +} + +fn main() {} diff --git a/tests/ui/async-await/higher-ranked-normalize-assumptions.rs b/tests/ui/async-await/higher-ranked-normalize-assumptions.rs new file mode 100644 index 0000000000000..ec9cf3a152214 --- /dev/null +++ b/tests/ui/async-await/higher-ranked-normalize-assumptions.rs @@ -0,0 +1,51 @@ +//@ revisions: stock hr +//@[hr] compile-flags: -Zhigher-ranked-assumptions +//@ edition: 2024 +//@ check-pass + +// Test that we don't normalize the higher-ranked assumptions of an auto trait goal +// unless we have `-Zhigher-ranked-assumptions`, since obligations that result from +// this normalization may lead to higher-ranked lifetime errors when the flag is not +// enabled. + +// Regression test for . + +pub trait Service { + type Response; +} + +impl Service for T +where + T: FnMut() -> R, + R: 'static, +{ + type Response = R; +} + +async fn serve(_: C) +where + C: Service, + C::Response: 'static, +{ + connect::().await; +} + +async fn connect() +where + C: Service, + C::Response: 'static, +{ +} + +fn repro() -> impl Send { + async { + let server = || do_something(); + serve(server).await; + } +} + +fn do_something() -> Box { + unimplemented!() +} + +fn main() {} diff --git a/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.rs b/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.rs new file mode 100644 index 0000000000000..923c2ad61164e --- /dev/null +++ b/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/66702 +// Breaks with values inside closures used to ICE (#66863) + +fn main() { + 'some_label: loop { + || break 'some_label (); + //~^ ERROR: use of unreachable label `'some_label` + //~| ERROR: `break` inside of a closure + } +} diff --git a/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.stderr b/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.stderr new file mode 100644 index 0000000000000..781e4e63913f4 --- /dev/null +++ b/tests/ui/async-await/labeled-break-in-async-fn-ice-66702.stderr @@ -0,0 +1,22 @@ +error[E0767]: use of unreachable label `'some_label` + --> $DIR/labeled-break-in-async-fn-ice-66702.rs:6:18 + | +LL | 'some_label: loop { + | ----------- unreachable label defined here +LL | || break 'some_label (); + | ^^^^^^^^^^^ unreachable label `'some_label` + | + = note: labels are unreachable through functions, closures, async blocks and modules + +error[E0267]: `break` inside of a closure + --> $DIR/labeled-break-in-async-fn-ice-66702.rs:6:12 + | +LL | || break 'some_label (); + | -- ^^^^^^^^^^^^^^^^^^^^ cannot `break` inside of a closure + | | + | enclosing closure + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0267, E0767. +For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/attributes/attr-mix-new.rs b/tests/ui/attributes/attr-mix-new.rs index bd249a0c198ab..c4f080eb8c302 100644 --- a/tests/ui/attributes/attr-mix-new.rs +++ b/tests/ui/attributes/attr-mix-new.rs @@ -5,6 +5,7 @@ #[rustc_dummy(bar)] mod foo { #![feature(globs)] + //~^ WARN crate-level attribute should be in the root module } fn main() {} diff --git a/tests/ui/attributes/attr-mix-new.stderr b/tests/ui/attributes/attr-mix-new.stderr new file mode 100644 index 0000000000000..c1bb8a550bcca --- /dev/null +++ b/tests/ui/attributes/attr-mix-new.stderr @@ -0,0 +1,10 @@ +warning: crate-level attribute should be in the root module + --> $DIR/attr-mix-new.rs:7:3 + | +LL | #![feature(globs)] + | ^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` + +warning: 1 warning emitted + diff --git a/tests/ui/attributes/attr-on-mac-call.stderr b/tests/ui/attributes/attr-on-mac-call.stderr index a08d305916856..1aeec463c71cf 100644 --- a/tests/ui/attributes/attr-on-mac-call.stderr +++ b/tests/ui/attributes/attr-on-mac-call.stderr @@ -55,7 +55,7 @@ LL | #[deprecated] | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to functions, data types, modules, unions, constants, statics, macro defs, type aliases, use statements, foreign statics, struct fields, traits, associated types, associated consts, enum variants, inherent impl blocks, and crates + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements warning: `#[inline]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:24:5 @@ -82,7 +82,7 @@ LL | #[link_section = "x"] | ^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[link_section]` can be applied to statics and functions + = help: `#[link_section]` can be applied to functions and statics warning: `#[link_ordinal]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:33:5 @@ -136,7 +136,7 @@ LL | #[deprecated] | ^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to functions, data types, modules, unions, constants, statics, macro defs, type aliases, use statements, foreign statics, struct fields, traits, associated types, associated consts, enum variants, inherent impl blocks, and crates + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements warning: `#[automatically_derived]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:51:5 @@ -154,7 +154,7 @@ LL | #[macro_use] | ^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[macro_use]` can be applied to modules, extern crates, and crates + = help: `#[macro_use]` can be applied to crates, extern crates, and modules warning: `#[must_use]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:57:5 @@ -163,7 +163,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions warning: `#[no_implicit_prelude]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:60:5 @@ -172,7 +172,7 @@ LL | #[no_implicit_prelude] | ^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[no_implicit_prelude]` can be applied to modules and crates + = help: `#[no_implicit_prelude]` can be applied to crates and modules warning: `#[path]` attribute cannot be used on macro calls --> $DIR/attr-on-mac-call.rs:63:5 diff --git a/tests/ui/attributes/crate-type-macro-empty.rs b/tests/ui/attributes/crate-type-macro-empty.rs index 217ff598f7a4c..cfc71e6b938f2 100644 --- a/tests/ui/attributes/crate-type-macro-empty.rs +++ b/tests/ui/attributes/crate-type-macro-empty.rs @@ -1,6 +1,7 @@ // Tests for the issue in #137589 #[crate_type = foo!()] //~^ ERROR cannot find macro `foo` in this scope +//~| WARN crate-level attribute should be an inner attribute macro_rules! foo {} //~ ERROR macros must contain at least one rule diff --git a/tests/ui/attributes/crate-type-macro-empty.stderr b/tests/ui/attributes/crate-type-macro-empty.stderr index 130fa454ca19e..0c2c4cf2a9b2d 100644 --- a/tests/ui/attributes/crate-type-macro-empty.stderr +++ b/tests/ui/attributes/crate-type-macro-empty.stderr @@ -1,5 +1,5 @@ error: macros must contain at least one rule - --> $DIR/crate-type-macro-empty.rs:5:1 + --> $DIR/crate-type-macro-empty.rs:6:1 | LL | macro_rules! foo {} | ^^^^^^^^^^^^^^^^^^^ @@ -11,10 +11,22 @@ LL | #[crate_type = foo!()] | ^^^ consider moving the definition of `foo` before this call | note: a macro with the same name exists, but it appears later - --> $DIR/crate-type-macro-empty.rs:5:14 + --> $DIR/crate-type-macro-empty.rs:6:14 | LL | macro_rules! foo {} | ^^^ -error: aborting due to 2 previous errors +warning: crate-level attribute should be an inner attribute + --> $DIR/crate-type-macro-empty.rs:2:1 + | +LL | #[crate_type = foo!()] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` +help: add a `!` + | +LL | #![crate_type = foo!()] + | + + +error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/attributes/crate-type-macro-not-found.rs b/tests/ui/attributes/crate-type-macro-not-found.rs index 824468c0e85b1..b9f05fa7caa13 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.rs +++ b/tests/ui/attributes/crate-type-macro-not-found.rs @@ -1,5 +1,6 @@ // Tests for the issue in #137589 #[crate_type = foo!()] //~ ERROR cannot find macro `foo` in this scope +//~| WARN crate-level attribute should be an inner attribute macro_rules! foo { ($x:expr) => {"rlib"} diff --git a/tests/ui/attributes/crate-type-macro-not-found.stderr b/tests/ui/attributes/crate-type-macro-not-found.stderr index a4967e4f12e93..7b8c6a8083497 100644 --- a/tests/ui/attributes/crate-type-macro-not-found.stderr +++ b/tests/ui/attributes/crate-type-macro-not-found.stderr @@ -5,10 +5,22 @@ LL | #[crate_type = foo!()] | ^^^ consider moving the definition of `foo` before this call | note: a macro with the same name exists, but it appears later - --> $DIR/crate-type-macro-not-found.rs:4:14 + --> $DIR/crate-type-macro-not-found.rs:5:14 | LL | macro_rules! foo { | ^^^ -error: aborting due to 1 previous error +warning: crate-level attribute should be an inner attribute + --> $DIR/crate-type-macro-not-found.rs:2:1 + | +LL | #[crate_type = foo!()] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` +help: add a `!` + | +LL | #![crate_type = foo!()] + | + + +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/attributes/empty-repr.stderr b/tests/ui/attributes/empty-repr.stderr index 92901fa170c25..6dfa2df75b737 100644 --- a/tests/ui/attributes/empty-repr.stderr +++ b/tests/ui/attributes/empty-repr.stderr @@ -4,6 +4,7 @@ error: unused attribute LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | + = note: using `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/empty-repr.rs:4:9 | diff --git a/tests/ui/attributes/fn-align-dyn.rs b/tests/ui/attributes/fn-align-dyn.rs index 3778c75a2caa7..91e2dab65a3cc 100644 --- a/tests/ui/attributes/fn-align-dyn.rs +++ b/tests/ui/attributes/fn-align-dyn.rs @@ -1,5 +1,6 @@ //@ run-pass //@ ignore-wasm32 aligning functions is not currently supported on wasm (#143368) +//@ ignore-backends: gcc // FIXME(#82232, #143834): temporarily renamed to mitigate `#[align]` nameres ambiguity #![feature(rustc_attrs)] diff --git a/tests/ui/attributes/inline/attr-usage-inline.rs b/tests/ui/attributes/inline/attr-usage-inline.rs index 8217b9834ff24..54f2f8020c4a9 100644 --- a/tests/ui/attributes/inline/attr-usage-inline.rs +++ b/tests/ui/attributes/inline/attr-usage-inline.rs @@ -9,16 +9,22 @@ struct S; struct I { #[inline] + //~^ WARN attribute cannot be used on + //~| WARN previously accepted i: u8, } #[macro_export] #[inline] +//~^ WARN attribute cannot be used on +//~| WARN previously accepted macro_rules! m_e { () => {}; } #[inline] //~ ERROR: attribute should be applied to function or closure +//~^ WARN attribute cannot be used on +//~| WARN previously accepted macro_rules! m { () => {}; } diff --git a/tests/ui/attributes/inline/attr-usage-inline.stderr b/tests/ui/attributes/inline/attr-usage-inline.stderr index 9fca17d90ca13..0a0af1a27b38d 100644 --- a/tests/ui/attributes/inline/attr-usage-inline.stderr +++ b/tests/ui/attributes/inline/attr-usage-inline.stderr @@ -7,11 +7,39 @@ LL | #[inline] = help: `#[inline]` can only be applied to functions error[E0518]: attribute should be applied to function or closure - --> $DIR/attr-usage-inline.rs:21:1 + --> $DIR/attr-usage-inline.rs:25:1 | LL | #[inline] | ^^^^^^^^^ not a function or closure -error: aborting due to 2 previous errors +warning: `#[inline]` attribute cannot be used on struct fields + --> $DIR/attr-usage-inline.rs:11:5 + | +LL | #[inline] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[inline]` can only be applied to functions + = note: requested on the command line with `-W unused-attributes` + +warning: `#[inline]` attribute cannot be used on macro defs + --> $DIR/attr-usage-inline.rs:18:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[inline]` can only be applied to functions + +warning: `#[inline]` attribute cannot be used on macro defs + --> $DIR/attr-usage-inline.rs:25:1 + | +LL | #[inline] + | ^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[inline]` can only be applied to functions + +error: aborting due to 2 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0518`. diff --git a/tests/ui/attributes/invalid_macro_export_argument.allow.stderr b/tests/ui/attributes/invalid_macro_export_argument.allow.stderr new file mode 100644 index 0000000000000..162b315b072a4 --- /dev/null +++ b/tests/ui/attributes/invalid_macro_export_argument.allow.stderr @@ -0,0 +1,40 @@ +Future incompatibility report: Future breakage diagnostic: +warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:7:1 + | +LL | #[macro_export(hello, world)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +Future breakage diagnostic: +warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:14:1 + | +LL | #[macro_export(not_local_inner_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +Future breakage diagnostic: +warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:31:1 + | +LL | #[macro_export()] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +Future breakage diagnostic: +warning: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:38:1 + | +LL | #[macro_export("blah")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + diff --git a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr b/tests/ui/attributes/invalid_macro_export_argument.deny.stderr index 9d44bd162c7b7..ad225ae187b11 100644 --- a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr +++ b/tests/ui/attributes/invalid_macro_export_argument.deny.stderr @@ -1,26 +1,103 @@ -error: `#[macro_export]` can only take 1 or 0 arguments +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` --> $DIR/invalid_macro_export_argument.rs:7:1 | LL | #[macro_export(hello, world)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 note: the lint level is defined here --> $DIR/invalid_macro_export_argument.rs:4:24 | LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: invalid `#[macro_export]` argument - --> $DIR/invalid_macro_export_argument.rs:13:16 +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:14:1 | LL | #[macro_export(not_local_inner_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:31:1 + | +LL | #[macro_export()] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 -error: invalid `#[macro_export]` argument - --> $DIR/invalid_macro_export_argument.rs:33:16 +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:38:1 | LL | #[macro_export("blah")] - | ^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + +error: aborting due to 4 previous errors + +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:7:1 + | +LL | #[macro_export(hello, world)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 +note: the lint level is defined here + --> $DIR/invalid_macro_export_argument.rs:4:24 + | +LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:14:1 + | +LL | #[macro_export(not_local_inner_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 +note: the lint level is defined here + --> $DIR/invalid_macro_export_argument.rs:4:24 + | +LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +Future breakage diagnostic: +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:31:1 + | +LL | #[macro_export()] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 +note: the lint level is defined here + --> $DIR/invalid_macro_export_argument.rs:4:24 + | +LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Future breakage diagnostic: +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/invalid_macro_export_argument.rs:38:1 + | +LL | #[macro_export("blah")] + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 +note: the lint level is defined here + --> $DIR/invalid_macro_export_argument.rs:4:24 + | +LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/invalid_macro_export_argument.rs b/tests/ui/attributes/invalid_macro_export_argument.rs index c5fe39d062a4e..05a40913434e8 100644 --- a/tests/ui/attributes/invalid_macro_export_argument.rs +++ b/tests/ui/attributes/invalid_macro_export_argument.rs @@ -5,13 +5,15 @@ #![cfg_attr(allow, allow(invalid_macro_export_arguments))] #[macro_export(hello, world)] -//[deny]~^ ERROR `#[macro_export]` can only take 1 or 0 arguments +//[deny]~^ ERROR valid forms for the attribute are +//[deny]~| WARN this was previously accepted macro_rules! a { () => () } #[macro_export(not_local_inner_macros)] -//[deny]~^ ERROR invalid `#[macro_export]` argument +//[deny]~^ ERROR valid forms for the attribute are +//[deny]~| WARN this was previously accepted macro_rules! b { () => () } @@ -20,18 +22,22 @@ macro_rules! b { macro_rules! c { () => () } + #[macro_export(local_inner_macros)] macro_rules! d { () => () } #[macro_export()] +//[deny]~^ ERROR valid forms for the attribute are +//[deny]~| WARN this was previously accepted macro_rules! e { () => () } #[macro_export("blah")] -//[deny]~^ ERROR invalid `#[macro_export]` argument +//[deny]~^ ERROR valid forms for the attribute are +//[deny]~| WARN this was previously accepted macro_rules! f { () => () } diff --git a/tests/ui/attributes/link-dl.allowed.stderr b/tests/ui/attributes/link-dl.allowed.stderr new file mode 100644 index 0000000000000..e0070d970595f --- /dev/null +++ b/tests/ui/attributes/link-dl.allowed.stderr @@ -0,0 +1,10 @@ +Future incompatibility report: Future breakage diagnostic: +warning: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]` + --> $DIR/link-dl.rs:14:1 + | +LL | #[link="dl"] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + diff --git a/tests/ui/attributes/link-dl.default_fcw.stderr b/tests/ui/attributes/link-dl.default_fcw.stderr new file mode 100644 index 0000000000000..249895fd17d00 --- /dev/null +++ b/tests/ui/attributes/link-dl.default_fcw.stderr @@ -0,0 +1,23 @@ +error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]` + --> $DIR/link-dl.rs:14:1 + | +LL | #[link="dl"] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 1 previous error + +Future incompatibility report: Future breakage diagnostic: +error: valid forms for the attribute are `#[link(name = "...")]`, `#[link(name = "...", import_name_type = "decorated|noprefix|undecorated")]`, `#[link(name = "...", kind = "dylib|static|...")]`, `#[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")]`, and `#[link(name = "...", wasm_import_module = "...")]` + --> $DIR/link-dl.rs:14:1 + | +LL | #[link="dl"] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default + diff --git a/tests/ui/attributes/link-dl.rs b/tests/ui/attributes/link-dl.rs new file mode 100644 index 0000000000000..b3b22c6bbc585 --- /dev/null +++ b/tests/ui/attributes/link-dl.rs @@ -0,0 +1,19 @@ +// Regression test for an issue discovered in https://github.com/rust-lang/rust/pull/143193/files and rediscovered in https://github.com/rust-lang/rust/issues/147254#event-20049906781 +// Malformed #[link] attribute was supposed to be deny-by-default report-in-deps FCW, +// but accidentally was landed as a hard error. +// +// revision `default_fcw` tests that with `ill_formed_attribute_input` (the default) denied, +// the attribute produces an FCW +// revision `allowed` tests that with `ill_formed_attribute_input` allowed the test passes + +//@ revisions: default_fcw allowed +//@[allowed] check-pass + +#![cfg_attr(allowed, allow(ill_formed_attribute_input))] + +#[link="dl"] +//[default_fcw]~^ ERROR valid forms for the attribute are +//[default_fcw]~| WARN previously accepted +extern "C" { } + +fn main() {} diff --git a/tests/ui/attributes/linkage.stderr b/tests/ui/attributes/linkage.stderr index d2aee3840582f..167cdb0243a79 100644 --- a/tests/ui/attributes/linkage.stderr +++ b/tests/ui/attributes/linkage.stderr @@ -4,7 +4,7 @@ error: `#[linkage]` attribute cannot be used on type aliases LL | #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to functions, statics, and foreign statics + = help: `#[linkage]` can be applied to foreign statics, functions, and statics error: `#[linkage]` attribute cannot be used on modules --> $DIR/linkage.rs:9:1 @@ -12,7 +12,7 @@ error: `#[linkage]` attribute cannot be used on modules LL | #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to functions, statics, and foreign statics + = help: `#[linkage]` can be applied to foreign statics, functions, and statics error: `#[linkage]` attribute cannot be used on structs --> $DIR/linkage.rs:12:1 @@ -20,7 +20,7 @@ error: `#[linkage]` attribute cannot be used on structs LL | #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to functions, statics, and foreign statics + = help: `#[linkage]` can be applied to foreign statics, functions, and statics error: `#[linkage]` attribute cannot be used on inherent impl blocks --> $DIR/linkage.rs:15:1 @@ -28,7 +28,7 @@ error: `#[linkage]` attribute cannot be used on inherent impl blocks LL | #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to functions, statics, and foreign statics + = help: `#[linkage]` can be applied to foreign statics, functions, and statics error: `#[linkage]` attribute cannot be used on expressions --> $DIR/linkage.rs:23:5 @@ -36,7 +36,7 @@ error: `#[linkage]` attribute cannot be used on expressions LL | #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to functions, statics, and foreign statics + = help: `#[linkage]` can be applied to foreign statics, functions, and statics error: `#[linkage]` attribute cannot be used on closures --> $DIR/linkage.rs:39:13 @@ -44,7 +44,7 @@ error: `#[linkage]` attribute cannot be used on closures LL | let _ = #[linkage = "weak"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[linkage]` can be applied to methods, functions, statics, foreign statics, and foreign functions + = help: `#[linkage]` can be applied to foreign functions, foreign statics, functions, methods, and statics error: aborting due to 6 previous errors diff --git a/tests/ui/attributes/main-removed-2/main.rs b/tests/ui/attributes/main-removed-2/main.rs index 53696d68ced07..21a05dc4b40be 100644 --- a/tests/ui/attributes/main-removed-2/main.rs +++ b/tests/ui/attributes/main-removed-2/main.rs @@ -2,6 +2,7 @@ //@ proc-macro: tokyo.rs //@ compile-flags:--extern tokyo //@ edition:2021 +//@ ignore-backends: gcc use tokyo::main; diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index 932aaf7a9e2fa..26ee89dd7b3be 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -73,6 +73,7 @@ //~| ERROR attribute cannot be used on #[crate_name] //~^ ERROR malformed +//~| WARN crate-level attribute should be an inner attribute #[doc] //~^ ERROR valid forms for the attribute are //~| WARN this was previously accepted by the compiler @@ -82,8 +83,12 @@ //~^ ERROR malformed #[link] //~^ ERROR malformed +//~| WARN attribute should be applied to an `extern` block with non-Rust ABI +//~| WARN previously accepted #[link_name] //~^ ERROR malformed +//~| WARN cannot be used on functions +//~| WARN previously accepted #[link_section] //~^ ERROR malformed #[coverage] @@ -95,6 +100,8 @@ //~| WARN this was previously accepted by the compiler #[no_implicit_prelude = 23] //~^ ERROR malformed +//~| WARN cannot be used on functions +//~| WARN previously accepted #[proc_macro = 18] //~^ ERROR malformed //~| ERROR the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type @@ -185,10 +192,11 @@ extern "C" { #[forbid] //~^ ERROR malformed #[debugger_visualizer] -//~^ ERROR invalid argument -//~| ERROR malformed `debugger_visualizer` attribute input +//~^ ERROR malformed `debugger_visualizer` attribute input #[automatically_derived = 18] //~^ ERROR malformed +//~| WARN cannot be used on modules +//~| WARN previously accepted mod yooo { } @@ -211,7 +219,7 @@ extern crate wloop; //~^ ERROR can't find crate for `wloop` [E0463] #[macro_export = 18] -//~^ ERROR malformed `macro_export` attribute input +//~^ ERROR valid forms for the attribute are #[allow_internal_unsafe = 1] //~^ ERROR malformed //~| ERROR allow_internal_unsafe side-steps the unsafe_code lint diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index b85864b401e37..c29bd0245bf04 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `cfg` attribute input - --> $DIR/malformed-attrs.rs:101:1 + --> $DIR/malformed-attrs.rs:108:1 | LL | #[cfg] | ^^^^^^ @@ -9,20 +9,19 @@ LL | #[cfg] | = note: for more information, visit -error: malformed `cfg_attr` attribute input - --> $DIR/malformed-attrs.rs:103:1 +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/malformed-attrs.rs:110:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit -help: missing condition and attribute - | -LL | #[cfg_attr(condition, attribute, other_attribute, ...)] - | ++++++++++++++++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:210:1 + --> $DIR/malformed-attrs.rs:218:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -42,7 +41,7 @@ LL | #![windows_subsystem = "windows"] | +++++++++++ error: malformed `instruction_set` attribute input - --> $DIR/malformed-attrs.rs:105:1 + --> $DIR/malformed-attrs.rs:112:1 | LL | #[instruction_set] | ^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[instruction_set(set)]` @@ -50,13 +49,13 @@ LL | #[instruction_set] = note: for more information, visit error: malformed `patchable_function_entry` attribute input - --> $DIR/malformed-attrs.rs:107:1 + --> $DIR/malformed-attrs.rs:114:1 | LL | #[patchable_function_entry] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` error: malformed `must_not_suspend` attribute input - --> $DIR/malformed-attrs.rs:131:1 + --> $DIR/malformed-attrs.rs:138:1 | LL | #[must_not_suspend()] | ^^^^^^^^^^^^^^^^^^^^^ @@ -71,13 +70,13 @@ LL + #[must_not_suspend] | error: malformed `cfi_encoding` attribute input - --> $DIR/malformed-attrs.rs:133:1 + --> $DIR/malformed-attrs.rs:140:1 | LL | #[cfi_encoding] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[cfi_encoding = "encoding"]` error: malformed `allow` attribute input - --> $DIR/malformed-attrs.rs:177:1 + --> $DIR/malformed-attrs.rs:184:1 | LL | #[allow] | ^^^^^^^^ @@ -93,7 +92,7 @@ LL | #[allow(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `expect` attribute input - --> $DIR/malformed-attrs.rs:179:1 + --> $DIR/malformed-attrs.rs:186:1 | LL | #[expect] | ^^^^^^^^^ @@ -109,7 +108,7 @@ LL | #[expect(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `warn` attribute input - --> $DIR/malformed-attrs.rs:181:1 + --> $DIR/malformed-attrs.rs:188:1 | LL | #[warn] | ^^^^^^^ @@ -125,7 +124,7 @@ LL | #[warn(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `deny` attribute input - --> $DIR/malformed-attrs.rs:183:1 + --> $DIR/malformed-attrs.rs:190:1 | LL | #[deny] | ^^^^^^^ @@ -141,7 +140,7 @@ LL | #[deny(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ error: malformed `forbid` attribute input - --> $DIR/malformed-attrs.rs:185:1 + --> $DIR/malformed-attrs.rs:192:1 | LL | #[forbid] | ^^^^^^^^^ @@ -156,64 +155,40 @@ LL | #[forbid(lint1, lint2, ...)] LL | #[forbid(lint1, lint2, lint3, reason = "...")] | +++++++++++++++++++++++++++++++++++++ -error: malformed `debugger_visualizer` attribute input - --> $DIR/malformed-attrs.rs:187:1 - | -LL | #[debugger_visualizer] - | ^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` - | - = note: for more information, visit - error: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:202:1 + --> $DIR/malformed-attrs.rs:210:1 | LL | #[thread_local()] | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[thread_local]` error: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:206:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | #[no_link()] | ^^^^^^^^^^^^ help: must be of the form: `#[no_link]` | = note: for more information, visit -error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:213:1 - | -LL | #[macro_export = 18] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, visit -help: the following are the possible correct uses - | -LL - #[macro_export = 18] -LL + #[macro_export(local_inner_macros)] - | -LL - #[macro_export = 18] -LL + #[macro_export] - | - error: the `#[proc_macro]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:105:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_attribute]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:129:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:223:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -233,7 +208,7 @@ LL | #[doc] = note: `#[deny(ill_formed_attribute_input)]` (part of `#[deny(future_incompatible)]`) on by default error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:76:1 + --> $DIR/malformed-attrs.rs:77:1 | LL | #[doc] | ^^^^^^ @@ -242,16 +217,6 @@ LL | #[doc] = note: for more information, see issue #57571 = note: for more information, visit -error: invalid argument - --> $DIR/malformed-attrs.rs:187:1 - | -LL | #[debugger_visualizer] - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: expected: `natvis_file = "..."` - = note: OR - = note: expected: `gdb_script_file = "..."` - error[E0539]: malformed `export_name` attribute input --> $DIR/malformed-attrs.rs:29:1 | @@ -467,7 +432,7 @@ LL | #[crate_name] | ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]` error[E0539]: malformed `target_feature` attribute input - --> $DIR/malformed-attrs.rs:79:1 + --> $DIR/malformed-attrs.rs:80:1 | LL | #[target_feature] | ^^^^^^^^^^^^^^^^^ @@ -476,7 +441,7 @@ LL | #[target_feature] | help: must be of the form: `#[target_feature(enable = "feat1, feat2")]` error[E0565]: malformed `export_stable` attribute input - --> $DIR/malformed-attrs.rs:81:1 + --> $DIR/malformed-attrs.rs:82:1 | LL | #[export_stable = 1] | ^^^^^^^^^^^^^^^^---^ @@ -485,7 +450,7 @@ LL | #[export_stable = 1] | help: must be of the form: `#[export_stable]` error[E0539]: malformed `link` attribute input - --> $DIR/malformed-attrs.rs:83:1 + --> $DIR/malformed-attrs.rs:84:1 | LL | #[link] | ^^^^^^^ expected this to be a list @@ -504,7 +469,7 @@ LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", = and 1 other candidate error[E0539]: malformed `link_name` attribute input - --> $DIR/malformed-attrs.rs:85:1 + --> $DIR/malformed-attrs.rs:88:1 | LL | #[link_name] | ^^^^^^^^^^^^ help: must be of the form: `#[link_name = "name"]` @@ -512,7 +477,7 @@ LL | #[link_name] = note: for more information, visit error[E0539]: malformed `link_section` attribute input - --> $DIR/malformed-attrs.rs:87:1 + --> $DIR/malformed-attrs.rs:92:1 | LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` @@ -520,7 +485,7 @@ LL | #[link_section] = note: for more information, visit error[E0539]: malformed `coverage` attribute input - --> $DIR/malformed-attrs.rs:89:1 + --> $DIR/malformed-attrs.rs:94:1 | LL | #[coverage] | ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument @@ -533,7 +498,7 @@ LL | #[coverage(on)] | ++++ error[E0539]: malformed `sanitize` attribute input - --> $DIR/malformed-attrs.rs:91:1 + --> $DIR/malformed-attrs.rs:96:1 | LL | #[sanitize] | ^^^^^^^^^^^ expected this to be a list @@ -551,7 +516,7 @@ LL | #[sanitize(kcfi = "on|off")] = and 5 other candidates error[E0565]: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:96:1 + --> $DIR/malformed-attrs.rs:101:1 | LL | #[no_implicit_prelude = 23] | ^^^^^^^^^^^^^^^^^^^^^^----^ @@ -560,7 +525,7 @@ LL | #[no_implicit_prelude = 23] | help: must be of the form: `#[no_implicit_prelude]` error[E0565]: malformed `proc_macro` attribute input - --> $DIR/malformed-attrs.rs:98:1 + --> $DIR/malformed-attrs.rs:105:1 | LL | #[proc_macro = 18] | ^^^^^^^^^^^^^----^ @@ -569,7 +534,7 @@ LL | #[proc_macro = 18] | help: must be of the form: `#[proc_macro]` error[E0565]: malformed `coroutine` attribute input - --> $DIR/malformed-attrs.rs:110:5 + --> $DIR/malformed-attrs.rs:117:5 | LL | #[coroutine = 63] || {} | ^^^^^^^^^^^^----^ @@ -578,7 +543,7 @@ LL | #[coroutine = 63] || {} | help: must be of the form: `#[coroutine]` error[E0565]: malformed `proc_macro_attribute` attribute input - --> $DIR/malformed-attrs.rs:115:1 + --> $DIR/malformed-attrs.rs:122:1 | LL | #[proc_macro_attribute = 19] | ^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -587,7 +552,7 @@ LL | #[proc_macro_attribute = 19] | help: must be of the form: `#[proc_macro_attribute]` error[E0539]: malformed `must_use` attribute input - --> $DIR/malformed-attrs.rs:118:1 + --> $DIR/malformed-attrs.rs:125:1 | LL | #[must_use = 1] | ^^^^^^^^^^^^^-^ @@ -605,7 +570,7 @@ LL + #[must_use] | error[E0539]: malformed `proc_macro_derive` attribute input - --> $DIR/malformed-attrs.rs:122:1 + --> $DIR/malformed-attrs.rs:129:1 | LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ expected this to be a list @@ -619,7 +584,7 @@ LL | #[proc_macro_derive(TraitName, attributes(name1, name2, ...))] | ++++++++++++++++++++++++++++++++++++++++++ error[E0539]: malformed `rustc_layout_scalar_valid_range_start` attribute input - --> $DIR/malformed-attrs.rs:127:1 + --> $DIR/malformed-attrs.rs:134:1 | LL | #[rustc_layout_scalar_valid_range_start] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -628,7 +593,7 @@ LL | #[rustc_layout_scalar_valid_range_start] | help: must be of the form: `#[rustc_layout_scalar_valid_range_start(start)]` error[E0539]: malformed `rustc_layout_scalar_valid_range_end` attribute input - --> $DIR/malformed-attrs.rs:129:1 + --> $DIR/malformed-attrs.rs:136:1 | LL | #[rustc_layout_scalar_valid_range_end] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -637,7 +602,7 @@ LL | #[rustc_layout_scalar_valid_range_end] | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` error[E0565]: malformed `marker` attribute input - --> $DIR/malformed-attrs.rs:154:1 + --> $DIR/malformed-attrs.rs:161:1 | LL | #[marker = 3] | ^^^^^^^^^---^ @@ -646,7 +611,7 @@ LL | #[marker = 3] | help: must be of the form: `#[marker]` error[E0565]: malformed `fundamental` attribute input - --> $DIR/malformed-attrs.rs:156:1 + --> $DIR/malformed-attrs.rs:163:1 | LL | #[fundamental()] | ^^^^^^^^^^^^^--^ @@ -655,7 +620,7 @@ LL | #[fundamental()] | help: must be of the form: `#[fundamental]` error[E0565]: malformed `ffi_pure` attribute input - --> $DIR/malformed-attrs.rs:164:5 + --> $DIR/malformed-attrs.rs:171:5 | LL | #[unsafe(ffi_pure = 1)] | ^^^^^^^^^^^^^^^^^^---^^ @@ -664,7 +629,7 @@ LL | #[unsafe(ffi_pure = 1)] | help: must be of the form: `#[ffi_pure]` error[E0539]: malformed `link_ordinal` attribute input - --> $DIR/malformed-attrs.rs:166:5 + --> $DIR/malformed-attrs.rs:173:5 | LL | #[link_ordinal] | ^^^^^^^^^^^^^^^ @@ -675,7 +640,7 @@ LL | #[link_ordinal] = note: for more information, visit error[E0565]: malformed `ffi_const` attribute input - --> $DIR/malformed-attrs.rs:170:5 + --> $DIR/malformed-attrs.rs:177:5 | LL | #[unsafe(ffi_const = 1)] | ^^^^^^^^^^^^^^^^^^^---^^ @@ -684,7 +649,7 @@ LL | #[unsafe(ffi_const = 1)] | help: must be of the form: `#[ffi_const]` error[E0539]: malformed `linkage` attribute input - --> $DIR/malformed-attrs.rs:172:5 + --> $DIR/malformed-attrs.rs:179:5 | LL | #[linkage] | ^^^^^^^^^^ expected this to be of the form `linkage = "..."` @@ -701,8 +666,19 @@ LL | #[linkage = "external"] | ++++++++++++ = and 5 other candidates +error[E0539]: malformed `debugger_visualizer` attribute input + --> $DIR/malformed-attrs.rs:194:1 + | +LL | #[debugger_visualizer] + | ^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` + | + = note: for more information, visit + error[E0565]: malformed `automatically_derived` attribute input - --> $DIR/malformed-attrs.rs:190:1 + --> $DIR/malformed-attrs.rs:196:1 | LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^----^ @@ -711,7 +687,7 @@ LL | #[automatically_derived = 18] | help: must be of the form: `#[automatically_derived]` error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:196:1 + --> $DIR/malformed-attrs.rs:204:1 | LL | #[non_exhaustive = 1] | ^^^^^^^^^^^^^^^^^---^ @@ -720,13 +696,19 @@ LL | #[non_exhaustive = 1] | help: must be of the form: `#[non_exhaustive]` error: valid forms for the attribute are `#[macro_use(name1, name2, ...)]` and `#[macro_use]` - --> $DIR/malformed-attrs.rs:208:1 + --> $DIR/malformed-attrs.rs:216:1 | LL | #[macro_use = 1] | ^^^^^^^^^^^^^^^^ +error: valid forms for the attribute are `#![macro_export(local_inner_macros)]` and `#![macro_export]` + --> $DIR/malformed-attrs.rs:221:1 + | +LL | #[macro_export = 18] + | ^^^^^^^^^^^^^^^^^^^^ + error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:215:1 + --> $DIR/malformed-attrs.rs:223:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^---^ @@ -735,7 +717,7 @@ LL | #[allow_internal_unsafe = 1] | help: must be of the form: `#[allow_internal_unsafe]` error[E0565]: malformed `type_const` attribute input - --> $DIR/malformed-attrs.rs:142:5 + --> $DIR/malformed-attrs.rs:149:5 | LL | #[type_const = 1] | ^^^^^^^^^^^^^---^ @@ -755,6 +737,21 @@ LL | | #[coroutine = 63] || {} LL | | } | |_- not a `const fn` +warning: attribute should be applied to an `extern` block with non-Rust ABI + --> $DIR/malformed-attrs.rs:84:1 + | +LL | #[link] + | ^^^^^^^ +... +LL | / fn test() { +LL | | #[coroutine = 63] || {} +... | +LL | | } + | |_- not an `extern` block + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: requested on the command line with `-W unused-attributes` + error: `#[repr(align(...))]` is not supported on functions --> $DIR/malformed-attrs.rs:47:1 | @@ -768,7 +765,7 @@ LL | #[repr] | ^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/malformed-attrs.rs:148:1 + --> $DIR/malformed-attrs.rs:155:1 | LL | #[diagnostic::do_not_recommend()] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -776,7 +773,7 @@ LL | #[diagnostic::do_not_recommend()] = note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default warning: missing options for `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:137:1 + --> $DIR/malformed-attrs.rs:144:1 | LL | #[diagnostic::on_unimplemented] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -784,7 +781,7 @@ LL | #[diagnostic::on_unimplemented] = help: at least one of the `message`, `note` and `label` options are expected warning: malformed `on_unimplemented` attribute - --> $DIR/malformed-attrs.rs:139:1 + --> $DIR/malformed-attrs.rs:146:1 | LL | #[diagnostic::on_unimplemented = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here @@ -800,8 +797,32 @@ LL | #[inline = 5] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 +warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![crate_name]` + --> $DIR/malformed-attrs.rs:74:1 + | +LL | #[crate_name] + | ^^^^^^^^^^^^^ + | +note: This attribute does not have an `!`, which means it is applied to this function + --> $DIR/malformed-attrs.rs:116:1 + | +LL | / fn test() { +LL | | #[coroutine = 63] || {} +... | +LL | | } + | |_^ + +warning: `#[link_name]` attribute cannot be used on functions + --> $DIR/malformed-attrs.rs:88:1 + | +LL | #[link_name] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_name]` can be applied to foreign functions and foreign statics + error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:93:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -809,8 +830,26 @@ LL | #[ignore()] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 +warning: `#[no_implicit_prelude]` attribute cannot be used on functions + --> $DIR/malformed-attrs.rs:101:1 + | +LL | #[no_implicit_prelude = 23] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_implicit_prelude]` can be applied to crates and modules + +warning: `#[automatically_derived]` attribute cannot be used on modules + --> $DIR/malformed-attrs.rs:196:1 + | +LL | #[automatically_derived = 18] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[automatically_derived]` can only be applied to trait impl blocks + error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:222:1 + --> $DIR/malformed-attrs.rs:230:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ @@ -819,7 +858,7 @@ LL | #[ignore = 1] = note: for more information, see issue #57571 error[E0308]: mismatched types - --> $DIR/malformed-attrs.rs:110:23 + --> $DIR/malformed-attrs.rs:117:23 | LL | fn test() { | - help: a return type might be missing here: `-> _` @@ -827,9 +866,9 @@ LL | #[coroutine = 63] || {} | ^^^^^ expected `()`, found coroutine | = note: expected unit type `()` - found coroutine `{coroutine@$DIR/malformed-attrs.rs:110:23: 110:25}` + found coroutine `{coroutine@$DIR/malformed-attrs.rs:117:23: 117:25}` -error: aborting due to 77 previous errors; 3 warnings emitted +error: aborting due to 76 previous errors; 8 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. @@ -847,7 +886,7 @@ LL | #[doc] Future breakage diagnostic: error: valid forms for the attribute are `#[doc(hidden)]`, `#[doc(inline)]`, and `#[doc = "string"]` - --> $DIR/malformed-attrs.rs:76:1 + --> $DIR/malformed-attrs.rs:77:1 | LL | #[doc] | ^^^^^^ @@ -870,7 +909,7 @@ LL | #[inline = 5] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:93:1 + --> $DIR/malformed-attrs.rs:98:1 | LL | #[ignore()] | ^^^^^^^^^^^ @@ -881,7 +920,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:222:1 + --> $DIR/malformed-attrs.rs:230:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ diff --git a/tests/ui/attributes/malformed-no-std.rs b/tests/ui/attributes/malformed-no-std.rs index 528ecb549b0e2..2e618a13d41fd 100644 --- a/tests/ui/attributes/malformed-no-std.rs +++ b/tests/ui/attributes/malformed-no-std.rs @@ -4,14 +4,18 @@ //~^ ERROR malformed `no_std` attribute input #![no_std("bar")] //~^ ERROR malformed `no_std` attribute input +//~| WARN unused attribute #![no_std(foo = "bar")] //~^ ERROR malformed `no_std` attribute input +//~| WARN unused attribute #![no_core = "foo"] //~^ ERROR malformed `no_core` attribute input #![no_core("bar")] //~^ ERROR malformed `no_core` attribute input +//~| WARN unused attribute #![no_core(foo = "bar")] //~^ ERROR malformed `no_core` attribute input +//~| WARN unused attribute #[deny(unused_attributes)] #[no_std] diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr index 322d5f03e41c4..89d7ee410d700 100644 --- a/tests/ui/attributes/malformed-no-std.stderr +++ b/tests/ui/attributes/malformed-no-std.stderr @@ -17,7 +17,7 @@ LL | #![no_std("bar")] | help: must be of the form: `#![no_std]` error[E0565]: malformed `no_std` attribute input - --> $DIR/malformed-no-std.rs:7:1 + --> $DIR/malformed-no-std.rs:8:1 | LL | #![no_std(foo = "bar")] | ^^^^^^^^^-------------^ @@ -26,7 +26,7 @@ LL | #![no_std(foo = "bar")] | help: must be of the form: `#![no_std]` error[E0565]: malformed `no_core` attribute input - --> $DIR/malformed-no-std.rs:9:1 + --> $DIR/malformed-no-std.rs:11:1 | LL | #![no_core = "foo"] | ^^^^^^^^^^^-------^ @@ -35,7 +35,7 @@ LL | #![no_core = "foo"] | help: must be of the form: `#![no_core]` error[E0565]: malformed `no_core` attribute input - --> $DIR/malformed-no-std.rs:11:1 + --> $DIR/malformed-no-std.rs:13:1 | LL | #![no_core("bar")] | ^^^^^^^^^^-------^ @@ -44,7 +44,7 @@ LL | #![no_core("bar")] | help: must be of the form: `#![no_core]` error[E0565]: malformed `no_core` attribute input - --> $DIR/malformed-no-std.rs:13:1 + --> $DIR/malformed-no-std.rs:16:1 | LL | #![no_core(foo = "bar")] | ^^^^^^^^^^-------------^ @@ -53,34 +53,83 @@ LL | #![no_core(foo = "bar")] | help: must be of the form: `#![no_core]` error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]` - --> $DIR/malformed-no-std.rs:17:1 + --> $DIR/malformed-no-std.rs:21:1 | LL | #[no_std] | ^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this extern crate - --> $DIR/malformed-no-std.rs:22:1 + --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ note: the lint level is defined here - --> $DIR/malformed-no-std.rs:16:8 + --> $DIR/malformed-no-std.rs:20:8 | LL | #[deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_core]` - --> $DIR/malformed-no-std.rs:19:1 + --> $DIR/malformed-no-std.rs:23:1 | LL | #[no_core] | ^^^^^^^^^^ | note: This attribute does not have an `!`, which means it is applied to this extern crate - --> $DIR/malformed-no-std.rs:22:1 + --> $DIR/malformed-no-std.rs:26:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +warning: unused attribute + --> $DIR/malformed-no-std.rs:5:1 + | +LL | #![no_std("bar")] + | ^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:3:1 + | +LL | #![no_std = "foo"] + | ^^^^^^^^^^^^^^^^^^ + = note: requested on the command line with `-W unused-attributes` + +warning: unused attribute + --> $DIR/malformed-no-std.rs:8:1 + | +LL | #![no_std(foo = "bar")] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:5:1 + | +LL | #![no_std("bar")] + | ^^^^^^^^^^^^^^^^^ + +warning: unused attribute + --> $DIR/malformed-no-std.rs:13:1 + | +LL | #![no_core("bar")] + | ^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:11:1 + | +LL | #![no_core = "foo"] + | ^^^^^^^^^^^^^^^^^^^ + +warning: unused attribute + --> $DIR/malformed-no-std.rs:16:1 + | +LL | #![no_core(foo = "bar")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/malformed-no-std.rs:13:1 + | +LL | #![no_core("bar")] + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors; 4 warnings emitted For more information about this error, try `rustc --explain E0565`. diff --git a/tests/ui/attributes/malformed-static-align.stderr b/tests/ui/attributes/malformed-static-align.stderr index 35f654d3990f2..e618ca8acd75b 100644 --- a/tests/ui/attributes/malformed-static-align.stderr +++ b/tests/ui/attributes/malformed-static-align.stderr @@ -25,7 +25,7 @@ error: `#[rustc_align_static]` attribute cannot be used on structs LL | #[rustc_align_static(16)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `#[rustc_align_static]` can be applied to statics and foreign statics + = help: `#[rustc_align_static]` can be applied to foreign statics and statics error: `#[repr(align(...))]` is not supported on statics --> $DIR/malformed-static-align.rs:13:8 diff --git a/tests/ui/attributes/no-mangle-closure.rs b/tests/ui/attributes/no-mangle-closure.rs index c76baa27f38a0..05dcbf8e5bed7 100644 --- a/tests/ui/attributes/no-mangle-closure.rs +++ b/tests/ui/attributes/no-mangle-closure.rs @@ -7,5 +7,5 @@ pub struct S([usize; 8]); pub fn outer_function(x: S, y: S) -> usize { (#[no_mangle] || y.0[0])() - //~^ ERROR `#[no_mangle]` cannot be used on a closure as it has no name + //~^ ERROR `#[no_mangle]` attribute cannot be used on closures } diff --git a/tests/ui/attributes/no-mangle-closure.stderr b/tests/ui/attributes/no-mangle-closure.stderr index c183783493bdb..f81e65d926752 100644 --- a/tests/ui/attributes/no-mangle-closure.stderr +++ b/tests/ui/attributes/no-mangle-closure.stderr @@ -1,8 +1,10 @@ -error: `#[no_mangle]` cannot be used on a closure as it has no name +error: `#[no_mangle]` attribute cannot be used on closures --> $DIR/no-mangle-closure.rs:9:6 | LL | (#[no_mangle] || y.0[0])() | ^^^^^^^^^^^^ + | + = help: `#[no_mangle]` can be applied to functions, methods, and statics error: aborting due to 1 previous error diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs index 894d1327da799..c0181d960539c 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.rs +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.rs @@ -1,7 +1,7 @@ #[unsafe(unsafe(no_mangle))] //~^ ERROR expected identifier, found keyword `unsafe` //~| ERROR cannot find attribute `r#unsafe` in this scope -//~| ERROR `r#unsafe` is not an unsafe attribute +//~| ERROR unnecessary `unsafe` fn a() {} fn main() {} diff --git a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr index 0825cf794083d..846800daa5465 100644 --- a/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr +++ b/tests/ui/attributes/unsafe/double-unsafe-attributes.stderr @@ -9,13 +9,11 @@ help: escape `unsafe` to use it as an identifier LL | #[unsafe(r#unsafe(no_mangle))] | ++ -error: `r#unsafe` is not an unsafe attribute +error: unnecessary `unsafe` on safe attribute --> $DIR/double-unsafe-attributes.rs:1:3 | LL | #[unsafe(unsafe(no_mangle))] - | ^^^^^^ this is not an unsafe attribute - | - = note: extraneous unsafe is not allowed in attributes + | ^^^^^^ error: cannot find attribute `r#unsafe` in this scope --> $DIR/double-unsafe-attributes.rs:1:10 diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs index 0f241cc439f34..d9054248a292c 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.rs @@ -1,4 +1,4 @@ -#[unsafe(diagnostic::on_unimplemented( //~ ERROR: is not an unsafe attribute +#[unsafe(diagnostic::on_unimplemented( //~ ERROR: unnecessary `unsafe` message = "testing", ))] trait Foo {} diff --git a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr index 3bc291db5acf8..a7662f5ee6c7d 100644 --- a/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr +++ b/tests/ui/attributes/unsafe/unsafe-safe-attribute_diagnostic.stderr @@ -1,10 +1,8 @@ -error: `diagnostic::on_unimplemented` is not an unsafe attribute +error: unnecessary `unsafe` on safe attribute --> $DIR/unsafe-safe-attribute_diagnostic.rs:1:3 | LL | #[unsafe(diagnostic::on_unimplemented( - | ^^^^^^ this is not an unsafe attribute - | - = note: extraneous unsafe is not allowed in attributes + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/autodiff/autodiff_illegal.rs b/tests/ui/autodiff/autodiff_illegal.rs index a53b6d5e58981..6bb384cc87e8d 100644 --- a/tests/ui/autodiff/autodiff_illegal.rs +++ b/tests/ui/autodiff/autodiff_illegal.rs @@ -110,15 +110,6 @@ fn f14(x: f32) -> Foo { type MyFloat = f32; -// We would like to support type alias to f32/f64 in argument type in the future, -// but that requires us to implement our checks at a later stage -// like THIR which has type information available. -#[autodiff_reverse(df15, Active, Active)] -fn f15(x: MyFloat) -> f32 { - //~^^ ERROR failed to resolve: use of undeclared type `MyFloat` [E0433] - unimplemented!() -} - // We would like to support type alias to f32/f64 in return type in the future #[autodiff_reverse(df16, Active, Active)] fn f16(x: f32) -> MyFloat { @@ -136,13 +127,6 @@ fn f17(x: f64) -> F64Trans { unimplemented!() } -// We would like to support `#[repr(transparent)]` f32/f64 wrapper in argument type in the future -#[autodiff_reverse(df18, Active, Active)] -fn f18(x: F64Trans) -> f64 { - //~^^ ERROR failed to resolve: use of undeclared type `F64Trans` [E0433] - unimplemented!() -} - // Invalid return activity #[autodiff_forward(df19, Dual, Active)] fn f19(x: f32) -> f32 { @@ -163,11 +147,4 @@ fn f21(x: f32) -> f32 { unimplemented!() } -struct DoesNotImplDefault; -#[autodiff_forward(df22, Dual)] -pub fn f22() -> DoesNotImplDefault { - //~^^ ERROR the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied - unimplemented!() -} - fn main() {} diff --git a/tests/ui/autodiff/autodiff_illegal.stderr b/tests/ui/autodiff/autodiff_illegal.stderr index ad6f10af46780..848ae1155e9c4 100644 --- a/tests/ui/autodiff/autodiff_illegal.stderr +++ b/tests/ui/autodiff/autodiff_illegal.stderr @@ -107,53 +107,24 @@ LL | #[autodiff_reverse(df13, Reverse)] | ^^^^^^^ error: invalid return activity Active in Forward Mode - --> $DIR/autodiff_illegal.rs:147:1 + --> $DIR/autodiff_illegal.rs:131:1 | LL | #[autodiff_forward(df19, Dual, Active)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid return activity Dual in Reverse Mode - --> $DIR/autodiff_illegal.rs:153:1 + --> $DIR/autodiff_illegal.rs:137:1 | LL | #[autodiff_reverse(df20, Active, Dual)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid return activity Duplicated in Reverse Mode - --> $DIR/autodiff_illegal.rs:160:1 + --> $DIR/autodiff_illegal.rs:144:1 | LL | #[autodiff_reverse(df21, Active, Duplicated)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0433]: failed to resolve: use of undeclared type `MyFloat` - --> $DIR/autodiff_illegal.rs:116:1 - | -LL | #[autodiff_reverse(df15, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `MyFloat` - -error[E0433]: failed to resolve: use of undeclared type `F64Trans` - --> $DIR/autodiff_illegal.rs:140:1 - | -LL | #[autodiff_reverse(df18, Active, Active)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type `F64Trans` - -error[E0599]: the function or associated item `default` exists for tuple `(DoesNotImplDefault, DoesNotImplDefault)`, but its trait bounds were not satisfied - --> $DIR/autodiff_illegal.rs:167:1 - | -LL | struct DoesNotImplDefault; - | ------------------------- doesn't satisfy `DoesNotImplDefault: Default` -LL | #[autodiff_forward(df22, Dual)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item cannot be called on `(DoesNotImplDefault, DoesNotImplDefault)` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `DoesNotImplDefault: Default` - which is required by `(DoesNotImplDefault, DoesNotImplDefault): Default` -help: consider annotating `DoesNotImplDefault` with `#[derive(Default)]` - | -LL + #[derive(Default)] -LL | struct DoesNotImplDefault; - | - -error: aborting due to 21 previous errors +error: aborting due to 18 previous errors -Some errors have detailed explanations: E0428, E0433, E0599, E0658. +Some errors have detailed explanations: E0428, E0658. For more information about an error, try `rustc --explain E0428`. diff --git a/tests/ui/autodiff/flag_nott.rs b/tests/ui/autodiff/flag_nott.rs new file mode 100644 index 0000000000000..faa9949fe8167 --- /dev/null +++ b/tests/ui/autodiff/flag_nott.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Zautodiff=Enable,NoTT +//@ needs-enzyme +//@ check-pass + +#![feature(autodiff)] + +use std::autodiff::autodiff_reverse; + +// Test that NoTT flag is accepted and doesn't cause compilation errors +#[autodiff_reverse(d_square, Duplicated, Active)] +fn square(x: &f64) -> f64 { + x * x +} + +fn main() { + let x = 2.0; + let mut dx = 0.0; + let result = d_square(&x, &mut dx, 1.0); +} diff --git a/tests/ui/autodiff/incremental.rs b/tests/ui/autodiff/incremental.rs new file mode 100644 index 0000000000000..a79059deaa778 --- /dev/null +++ b/tests/ui/autodiff/incremental.rs @@ -0,0 +1,41 @@ +//@ revisions: DEBUG RELEASE +//@[RELEASE] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=3 -Clto=fat +//@[DEBUG] compile-flags: -Zautodiff=Enable,NoTT -C opt-level=0 -Clto=fat -C debuginfo=2 +//@ needs-enzyme +//@ incremental +//@ no-prefer-dynamic +//@ build-pass +#![crate_type = "bin"] +#![feature(autodiff)] + +// We used to use llvm's metadata to instruct enzyme how to differentiate a function. +// In debug mode we would use incremental compilation which caused the metadata to be +// dropped. We now use globals instead and add this test to verify that incremental +// keeps working. Also testing debug mode while at it. + +use std::autodiff::autodiff_reverse; + +#[autodiff_reverse(bar, Duplicated, Duplicated)] +pub fn foo(r: &[f64; 10], res: &mut f64) { + let mut output = [0.0; 10]; + output[0] = r[0]; + output[1] = r[1] * r[2]; + output[2] = r[4] * r[5]; + output[3] = r[2] * r[6]; + output[4] = r[1] * r[7]; + output[5] = r[2] * r[8]; + output[6] = r[1] * r[9]; + output[7] = r[5] * r[6]; + output[8] = r[5] * r[7]; + output[9] = r[4] * r[8]; + *res = output.iter().sum(); +} +fn main() { + let inputs = Box::new([3.1; 10]); + let mut d_inputs = Box::new([0.0; 10]); + let mut res = Box::new(0.0); + let mut d_res = Box::new(1.0); + + bar(&inputs, &mut d_inputs, &mut res, &mut d_res); + dbg!(&d_inputs); +} diff --git a/tests/ui/autodiff/zst.rs b/tests/ui/autodiff/zst.rs new file mode 100644 index 0000000000000..7b9b5f5f20bdc --- /dev/null +++ b/tests/ui/autodiff/zst.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Zautodiff=Enable -C opt-level=3 -Clto=fat +//@ no-prefer-dynamic +//@ needs-enzyme +//@ build-pass + +// Check that differentiating functions with ZST args does not break + +#![feature(autodiff)] + +#[core::autodiff::autodiff_forward(fd_inner, Const, Dual)] +fn f(_zst: (), _x: &mut f64) {} + +fn fd(x: &mut f64, xd: &mut f64) { + fd_inner((), x, xd); +} + +fn main() {} diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr index 19c3c64181985..bad799b2550b9 100644 --- a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr +++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr @@ -5,7 +5,7 @@ LL | let var_fn = Value::wrap(); | ^^^^^^ ... LL | let _ = var_fn.clone(); - | ----- type must be known at this point + | ------ type must be known at this point | help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified | diff --git a/tests/ui/backtrace/apple-no-dsymutil.rs b/tests/ui/backtrace/apple-no-dsymutil.rs index e5aeced25ca35..00c8349d1293e 100644 --- a/tests/ui/backtrace/apple-no-dsymutil.rs +++ b/tests/ui/backtrace/apple-no-dsymutil.rs @@ -3,6 +3,7 @@ //@ compile-flags:-Cstrip=none //@ compile-flags:-g -Csplit-debuginfo=unpacked //@ only-apple +//@ ignore-remote needs the compiler-produced `.o` file to be copied to the device use std::process::Command; use std::str; diff --git a/tests/ui/backtrace/dylib-dep.rs b/tests/ui/backtrace/dylib-dep.rs index 05fdb9afef80d..cf420ec8d0697 100644 --- a/tests/ui/backtrace/dylib-dep.rs +++ b/tests/ui/backtrace/dylib-dep.rs @@ -7,6 +7,10 @@ //@ ignore-android FIXME #17520 //@ ignore-fuchsia Backtraces not symbolized //@ ignore-musl musl doesn't support dynamic libraries (at least when the original test was written). +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device //@ needs-unwind //@ ignore-backends: gcc //@ compile-flags: -g -Copt-level=0 -Cstrip=none -Cforce-frame-pointers=yes diff --git a/tests/ui/backtrace/line-tables-only.rs b/tests/ui/backtrace/line-tables-only.rs index 6624c71e184b0..5863cc1d17d46 100644 --- a/tests/ui/backtrace/line-tables-only.rs +++ b/tests/ui/backtrace/line-tables-only.rs @@ -11,6 +11,10 @@ //@ ignore-android FIXME #17520 //@ ignore-fuchsia Backtraces not symbolized //@ ignore-emscripten Requires custom symbolization code +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device //@ needs-unwind //@ aux-build: line-tables-only-helper.rs diff --git a/tests/ui/backtrace/synchronized-panic-handler.rs b/tests/ui/backtrace/synchronized-panic-handler.rs index 29431ae3c458a..ef7cc1faec8de 100644 --- a/tests/ui/backtrace/synchronized-panic-handler.rs +++ b/tests/ui/backtrace/synchronized-panic-handler.rs @@ -4,6 +4,7 @@ //@ exec-env:RUST_BACKTRACE=0 //@ needs-threads //@ needs-unwind +//@ ignore-backends: gcc use std::thread; const PANIC_MESSAGE: &str = "oops oh no woe is me"; diff --git a/tests/ui/backtrace/synchronized-panic-handler.run.stderr b/tests/ui/backtrace/synchronized-panic-handler.run.stderr index c604d49c193c5..5296a0d39ff30 100644 --- a/tests/ui/backtrace/synchronized-panic-handler.run.stderr +++ b/tests/ui/backtrace/synchronized-panic-handler.run.stderr @@ -1,7 +1,7 @@ -thread '' ($TID) panicked at $DIR/synchronized-panic-handler.rs:11:5: +thread '' ($TID) panicked at $DIR/synchronized-panic-handler.rs:12:5: oops oh no woe is me note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -thread '' ($TID) panicked at $DIR/synchronized-panic-handler.rs:11:5: +thread '' ($TID) panicked at $DIR/synchronized-panic-handler.rs:12:5: oops oh no woe is me diff --git a/tests/ui/binding/invalid-assignment-in-while-loop-77218.fixed b/tests/ui/binding/invalid-assignment-in-while-77218.fixed similarity index 100% rename from tests/ui/binding/invalid-assignment-in-while-loop-77218.fixed rename to tests/ui/binding/invalid-assignment-in-while-77218.fixed diff --git a/tests/ui/binding/invalid-assignment-in-while-loop-77218.rs b/tests/ui/binding/invalid-assignment-in-while-77218.rs similarity index 100% rename from tests/ui/binding/invalid-assignment-in-while-loop-77218.rs rename to tests/ui/binding/invalid-assignment-in-while-77218.rs diff --git a/tests/ui/binding/invalid-assignment-in-while-77218.stderr b/tests/ui/binding/invalid-assignment-in-while-77218.stderr new file mode 100644 index 0000000000000..0545a01309978 --- /dev/null +++ b/tests/ui/binding/invalid-assignment-in-while-77218.stderr @@ -0,0 +1,16 @@ +error[E0070]: invalid left-hand side of assignment + --> $DIR/invalid-assignment-in-while-77218.rs:5:19 + | +LL | while Some(0) = value.get(0) {} + | - ^ + | | + | cannot assign to this expression + | +help: you might have meant to use pattern destructuring + | +LL | while let Some(0) = value.get(0) {} + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0070`. diff --git a/tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr b/tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr deleted file mode 100644 index e6baf349d28ad..0000000000000 --- a/tests/ui/binding/invalid-assignment-in-while-loop-77218.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0070]: invalid left-hand side of assignment - --> $DIR/invalid-assignment-in-while-loop-77218.rs:5:19 - | -LL | while Some(0) = value.get(0) {} - | - ^ - | | - | cannot assign to this expression - | -help: you might have meant to use pattern destructuring - | -LL | while let Some(0) = value.get(0) {} - | +++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0070`. diff --git a/tests/ui/binop/binary-operation-error-on-function-70724.rs b/tests/ui/binop/binary-operation-error-on-function-70724.rs new file mode 100644 index 0000000000000..0bbf13761488d --- /dev/null +++ b/tests/ui/binop/binary-operation-error-on-function-70724.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/70724 +fn a() -> i32 { + 3 +} + +pub fn main() { + assert_eq!(a, 0); + //~^ ERROR binary operation `==` cannot + //~| ERROR mismatched types + //~| ERROR doesn't implement +} diff --git a/tests/ui/binop/binary-operation-error-on-function-70724.stderr b/tests/ui/binop/binary-operation-error-on-function-70724.stderr new file mode 100644 index 0000000000000..11b0e4ba19c58 --- /dev/null +++ b/tests/ui/binop/binary-operation-error-on-function-70724.stderr @@ -0,0 +1,37 @@ +error[E0369]: binary operation `==` cannot be applied to type `fn() -> i32 {a}` + --> $DIR/binary-operation-error-on-function-70724.rs:7:5 + | +LL | assert_eq!(a, 0); + | ^^^^^^^^^^^^^^^^ + | | + | fn() -> i32 {a} + | {integer} + | + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/binary-operation-error-on-function-70724.rs:7:5 + | +LL | assert_eq!(a, 0); + | ^^^^^^^^^^^^^^^^ expected fn item, found integer + | + = note: expected fn item `fn() -> i32 {a}` + found type `{integer}` + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `fn() -> i32 {a}` doesn't implement `Debug` + --> $DIR/binary-operation-error-on-function-70724.rs:7:5 + | +LL | fn a() -> i32 { + | - consider calling this function +... +LL | assert_eq!(a, 0); + | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn() -> i32 {a}` + | + = help: use parentheses to call this function: `a()` + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308, E0369. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/binop/let-chain-type-issue-147665.rs b/tests/ui/binop/let-chain-type-issue-147665.rs new file mode 100644 index 0000000000000..4a6b40c6f9877 --- /dev/null +++ b/tests/ui/binop/let-chain-type-issue-147665.rs @@ -0,0 +1,7 @@ +// Shouldn't highlight `let x = 1` as having type bool. +//@ edition:2024 + +fn main() { + if let x = 1 && 2 {} + //~^ ERROR mismatched types +} diff --git a/tests/ui/binop/let-chain-type-issue-147665.stderr b/tests/ui/binop/let-chain-type-issue-147665.stderr new file mode 100644 index 0000000000000..b2b82228eaebf --- /dev/null +++ b/tests/ui/binop/let-chain-type-issue-147665.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/let-chain-type-issue-147665.rs:5:21 + | +LL | if let x = 1 && 2 {} + | ^ expected `bool`, found integer + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.rs b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.rs new file mode 100644 index 0000000000000..d2e11b2dbffe9 --- /dev/null +++ b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.rs @@ -0,0 +1,8 @@ +// https://github.com/rust-lang/rust/issues/61108 +fn main() { + let mut bad_letters = vec!['e', 't', 'o', 'i']; + for l in bad_letters { + // something here + } + bad_letters.push('s'); //~ ERROR borrow of moved value: `bad_letters` +} diff --git a/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr new file mode 100644 index 0000000000000..4c3fa5e56dc9b --- /dev/null +++ b/tests/ui/borrowck/borrow-of-moved-value-in-for-loop-61108.stderr @@ -0,0 +1,21 @@ +error[E0382]: borrow of moved value: `bad_letters` + --> $DIR/borrow-of-moved-value-in-for-loop-61108.rs:7:5 + | +LL | let mut bad_letters = vec!['e', 't', 'o', 'i']; + | --------------- move occurs because `bad_letters` has type `Vec`, which does not implement the `Copy` trait +LL | for l in bad_letters { + | ----------- `bad_letters` moved due to this implicit call to `.into_iter()` +... +LL | bad_letters.push('s'); + | ^^^^^^^^^^^ value borrowed here after move + | +note: `into_iter` takes ownership of the receiver `self`, which moves `bad_letters` + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL +help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop + | +LL | for l in &bad_letters { + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/borrowck-assign-to-subfield.rs b/tests/ui/borrowck/borrowck-assign-to-subfield.rs index 27d9046e7b7cb..8e5192611ffd9 100644 --- a/tests/ui/borrowck/borrowck-assign-to-subfield.rs +++ b/tests/ui/borrowck/borrowck-assign-to-subfield.rs @@ -1,5 +1,6 @@ //@ run-pass +#[allow(unused)] pub fn main() { struct A { a: isize, diff --git a/tests/ui/borrowck/fn-item-check-type-params.stderr b/tests/ui/borrowck/fn-item-check-type-params.stderr index aafb7e66ef55f..7a0a7752a14b2 100644 --- a/tests/ui/borrowck/fn-item-check-type-params.stderr +++ b/tests/ui/borrowck/fn-item-check-type-params.stderr @@ -27,6 +27,12 @@ LL | want(&String::new(), extend_lt); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/fn-item-check-type-params.rs:47:33 + | +LL | fn want(_: I, _: impl Fn(I) -> O) {} + | ^^^^^^^^^^ error[E0716]: temporary value dropped while borrowed --> $DIR/fn-item-check-type-params.rs:54:26 @@ -36,6 +42,12 @@ LL | let val = extend_lt(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/fn-item-check-type-params.rs:22:21 + | +LL | (T, Option): Displayable, + | ^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/tests/ui/borrowck/format-args-temporary-scopes.e2024.stderr b/tests/ui/borrowck/format-args-temporary-scopes.e2024.stderr new file mode 100644 index 0000000000000..506fc6e0965f7 --- /dev/null +++ b/tests/ui/borrowck/format-args-temporary-scopes.e2024.stderr @@ -0,0 +1,27 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/format-args-temporary-scopes.rs:13:25 + | +LL | println!("{:?}", { &temp() }); + | ---^^^^^--- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary value which is freed while still in use + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/format-args-temporary-scopes.rs:19:29 + | +LL | println!("{:?}{:?}", { &temp() }, ()); + | ---^^^^^--- + | | | | + | | | temporary value is freed at the end of this statement + | | creates a temporary value which is freed while still in use + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/borrowck/format-args-temporary-scopes.rs b/tests/ui/borrowck/format-args-temporary-scopes.rs new file mode 100644 index 0000000000000..2641058accb31 --- /dev/null +++ b/tests/ui/borrowck/format-args-temporary-scopes.rs @@ -0,0 +1,21 @@ +//! Test for #145784 as it relates to format arguments: arguments to macros such as `println!` +//! should obey normal temporary scoping rules. +//@ revisions: e2021 e2024 +//@ [e2021] check-pass +//@ [e2021] edition: 2021 +//@ [e2024] edition: 2024 + +fn temp() {} + +fn main() { + // In Rust 2024, block tail expressions are temporary scopes, so the result of `temp()` is + // dropped after evaluating `&temp()`. + println!("{:?}", { &temp() }); + //[e2024]~^ ERROR: temporary value dropped while borrowed [E0716] + + // In Rust 1.89, `format_args!` extended the lifetime of all extending expressions in its + // arguments when provided with two or more arguments. This caused the result of `temp()` to + // outlive the result of the block, making this compile. + println!("{:?}{:?}", { &temp() }, ()); + //[e2024]~^ ERROR: temporary value dropped while borrowed [E0716] +} diff --git a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr index 5389226f7a7a4..7b840d54ed038 100644 --- a/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr +++ b/tests/ui/borrowck/implementation-not-general-enough-ice-133252.stderr @@ -22,6 +22,12 @@ LL | force_send(async_load(¬_static)); ... LL | } | - `not_static` dropped here while still borrowed + | +note: requirement that the value outlives `'1` introduced here + --> $DIR/implementation-not-general-enough-ice-133252.rs:16:18 + | +LL | fn force_send(_: T) {} + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/issue-17545.stderr b/tests/ui/borrowck/issue-17545.stderr index 45e977e39477e..63fd57cd2336f 100644 --- a/tests/ui/borrowck/issue-17545.stderr +++ b/tests/ui/borrowck/issue-17545.stderr @@ -10,6 +10,9 @@ LL | | )); | | -- temporary value is freed at the end of this statement | |______| | argument requires that borrow lasts for `'a` + | +note: requirement that the value outlives `'a` introduced here + --> $SRC_DIR/core/src/ops/function.rs:LL:COL error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.rs b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.rs new file mode 100644 index 0000000000000..c13f91c082a39 --- /dev/null +++ b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/64559 +fn main() { + let orig = vec![true]; + for _val in orig {} + let _closure = || orig; + //~^ ERROR use of moved value: `orig` +} diff --git a/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr new file mode 100644 index 0000000000000..09d4d04295c7c --- /dev/null +++ b/tests/ui/borrowck/moved-value-in-closure-suggestion-64559.stderr @@ -0,0 +1,22 @@ +error[E0382]: use of moved value: `orig` + --> $DIR/moved-value-in-closure-suggestion-64559.rs:5:20 + | +LL | let orig = vec![true]; + | ---- move occurs because `orig` has type `Vec`, which does not implement the `Copy` trait +LL | for _val in orig {} + | ---- `orig` moved due to this implicit call to `.into_iter()` +LL | let _closure = || orig; + | ^^ ---- use occurs due to use in closure + | | + | value used here after move + | +note: `into_iter` takes ownership of the receiver `self`, which moves `orig` + --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL +help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop + | +LL | for _val in &orig {} + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/borrowck/multiple-mutable-borrows-error-65131.rs b/tests/ui/borrowck/multiple-mutable-borrows-error-65131.rs new file mode 100644 index 0000000000000..ccf8b00a78a2d --- /dev/null +++ b/tests/ui/borrowck/multiple-mutable-borrows-error-65131.rs @@ -0,0 +1,19 @@ +// https://github.com/rust-lang/rust/issues/65131 +fn get_pair(_a: &mut u32, _b: &mut u32) {} + +macro_rules! x10 { + ($($t:tt)*) => { + $($t)* $($t)* $($t)* $($t)* $($t)* + $($t)* $($t)* $($t)* $($t)* $($t)* + } +} + +#[allow(unused_assignments)] +fn main() { + let mut x = 1; + + get_pair(&mut x, &mut x); + //~^ ERROR: cannot borrow `x` as mutable more than once at a time + + x10! { x10!{ x10!{ if x > 0 { x += 2 } else { x += 1 } } } } +} diff --git a/tests/ui/borrowck/multiple-mutable-borrows-error-65131.stderr b/tests/ui/borrowck/multiple-mutable-borrows-error-65131.stderr new file mode 100644 index 0000000000000..1d97403923f99 --- /dev/null +++ b/tests/ui/borrowck/multiple-mutable-borrows-error-65131.stderr @@ -0,0 +1,12 @@ +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/multiple-mutable-borrows-error-65131.rs:15:22 + | +LL | get_pair(&mut x, &mut x); + | -------- ------ ^^^^^^ second mutable borrow occurs here + | | | + | | first mutable borrow occurs here + | first borrow later used by call + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/borrowck/mutable-borrow-behind-reference-61623.rs b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.rs new file mode 100644 index 0000000000000..ae7bb1c0a76b4 --- /dev/null +++ b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/61623 +fn f1<'a>(_: &'a mut ()) {} + +fn f2

(_: P, _: ()) {} + +fn f3<'a>(x: &'a ((), &'a mut ())) { + f2(|| x.0, f1(x.1)) +//~^ ERROR cannot borrow `*x.1` as mutable, as it is behind a `&` reference +} + +fn main() {} diff --git a/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr new file mode 100644 index 0000000000000..cc7761acda9de --- /dev/null +++ b/tests/ui/borrowck/mutable-borrow-behind-reference-61623.stderr @@ -0,0 +1,14 @@ +error[E0596]: cannot borrow `*x.1` as mutable, as it is behind a `&` reference + --> $DIR/mutable-borrow-behind-reference-61623.rs:7:19 + | +LL | f2(|| x.0, f1(x.1)) + | ^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | +help: consider changing this to be a mutable reference + | +LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/borrowck/incorrect-use-after-storage-end-78192.rs b/tests/ui/borrowck/pointer-reassignment-after-deref-78192.rs similarity index 100% rename from tests/ui/borrowck/incorrect-use-after-storage-end-78192.rs rename to tests/ui/borrowck/pointer-reassignment-after-deref-78192.rs diff --git a/tests/ui/box/unit/unwind-unique.rs b/tests/ui/box/unit/unwind-unique.rs index 1da55c45ee969..ed549f50a740a 100644 --- a/tests/ui/box/unit/unwind-unique.rs +++ b/tests/ui/box/unit/unwind-unique.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc use std::thread; diff --git a/tests/ui/c-variadic/inherent-method.rs b/tests/ui/c-variadic/inherent-method.rs new file mode 100644 index 0000000000000..c5256aaa1fea3 --- /dev/null +++ b/tests/ui/c-variadic/inherent-method.rs @@ -0,0 +1,46 @@ +//@ run-pass +//@ ignore-backends: gcc +#![feature(c_variadic)] + +#[repr(transparent)] +struct S(i32); + +impl S { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method_owned(self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn method_ref(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn method_mut(&mut self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } + + unsafe extern "C" fn fat_pointer(self: Box, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } +} + +fn main() { + unsafe { + assert_eq!(S::associated_function(32), 32); + assert_eq!(S(100).method_owned(32), 132); + assert_eq!(S(100).method_ref(32), 132); + assert_eq!(S(100).method_mut(32), 132); + assert_eq!(S::fat_pointer(Box::new(S(100)), 32), 132); + + type Method = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((S::associated_function as unsafe extern "C" fn(...) -> i32)(32), 32); + assert_eq!((S::method_owned as Method<_>)(S(100), 32), 132); + assert_eq!((S::method_ref as Method<_>)(&S(100), 32), 132); + assert_eq!((S::method_mut as Method<_>)(&mut S(100), 32), 132); + assert_eq!((S::fat_pointer as Method<_>)(Box::new(S(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/no-closure.rs b/tests/ui/c-variadic/no-closure.rs index c0b77786e8b4a..830ed962a8c4a 100644 --- a/tests/ui/c-variadic/no-closure.rs +++ b/tests/ui/c-variadic/no-closure.rs @@ -4,14 +4,17 @@ // Check that `...` in closures is rejected. const F: extern "C" fn(...) = |_: ...| {}; -//~^ ERROR C-variadic type `...` may not be nested inside another type +//~^ ERROR: unexpected `...` +//~| NOTE: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list fn foo() { let f = |...| {}; - //~^ ERROR: `..` patterns are not allowed here - //~| ERROR: unexpected `...` + //~^ ERROR: unexpected `...` + //~| NOTE: not a valid pattern + //~| NOTE: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list let f = |_: ...| {}; - //~^ ERROR C-variadic type `...` may not be nested inside another type + //~^ ERROR: unexpected `...` + //~| NOTE: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list f(1i64) } diff --git a/tests/ui/c-variadic/no-closure.stderr b/tests/ui/c-variadic/no-closure.stderr index 77bd106bb9519..0946c4632e6e4 100644 --- a/tests/ui/c-variadic/no-closure.stderr +++ b/tests/ui/c-variadic/no-closure.stderr @@ -1,35 +1,26 @@ -error[E0743]: C-variadic type `...` may not be nested inside another type +error: unexpected `...` --> $DIR/no-closure.rs:6:35 | LL | const F: extern "C" fn(...) = |_: ...| {}; | ^^^ + | + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: unexpected `...` - --> $DIR/no-closure.rs:10:14 + --> $DIR/no-closure.rs:11:14 | LL | let f = |...| {}; | ^^^ not a valid pattern | -help: for a rest pattern, use `..` instead of `...` - | -LL - let f = |...| {}; -LL + let f = |..| {}; - | + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error[E0743]: C-variadic type `...` may not be nested inside another type - --> $DIR/no-closure.rs:14:17 +error: unexpected `...` + --> $DIR/no-closure.rs:16:17 | LL | let f = |_: ...| {}; | ^^^ - -error: `..` patterns are not allowed here - --> $DIR/no-closure.rs:10:14 - | -LL | let f = |...| {}; - | ^^^ | - = note: only allowed in tuple, tuple struct, and slice patterns + = note: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0743`. diff --git a/tests/ui/c-variadic/not-async.rs b/tests/ui/c-variadic/not-async.rs index 45a7e1f8972bf..bdb51a9a43232 100644 --- a/tests/ui/c-variadic/not-async.rs +++ b/tests/ui/c-variadic/not-async.rs @@ -2,6 +2,14 @@ #![feature(c_variadic)] #![crate_type = "lib"] -async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} +async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} //~^ ERROR functions cannot be both `async` and C-variadic //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds + +struct S; + +impl S { + async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + //~^ ERROR functions cannot be both `async` and C-variadic + //~| ERROR hidden type for `impl Future` captures lifetime that does not appear in bounds +} diff --git a/tests/ui/c-variadic/not-async.stderr b/tests/ui/c-variadic/not-async.stderr index b8caf0d8bd852..eab4c4f0822c4 100644 --- a/tests/ui/c-variadic/not-async.stderr +++ b/tests/ui/c-variadic/not-async.stderr @@ -1,19 +1,35 @@ error: functions cannot be both `async` and C-variadic --> $DIR/not-async.rs:5:1 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | ^^^^^ `async` because of this ^^^ C-variadic because of this +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this + +error: functions cannot be both `async` and C-variadic + --> $DIR/not-async.rs:12:5 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ^^^^^ `async` because of this ^^^ C-variadic because of this error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds - --> $DIR/not-async.rs:5:59 + --> $DIR/not-async.rs:5:62 | -LL | async unsafe extern "C" fn cannot_be_async(x: isize, ...) {} - | --------------------------------------------------------- ^^ +LL | async unsafe extern "C" fn fn_cannot_be_async(x: isize, ...) {} + | ------------------------------------------------------------ ^^ | | | opaque type defined here | - = note: hidden type `{async fn body of cannot_be_async()}` captures lifetime `'_` + = note: hidden type `{async fn body of fn_cannot_be_async()}` captures lifetime `'_` + +error[E0700]: hidden type for `impl Future` captures lifetime that does not appear in bounds + --> $DIR/not-async.rs:12:70 + | +LL | async unsafe extern "C" fn method_cannot_be_async(x: isize, ...) {} + | ---------------------------------------------------------------- ^^ + | | + | opaque type defined here + | + = note: hidden type `{async fn body of S::method_cannot_be_async()}` captures lifetime `'_` -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/c-variadic/not-dyn-compatible.rs b/tests/ui/c-variadic/not-dyn-compatible.rs new file mode 100644 index 0000000000000..b40a13e584762 --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.rs @@ -0,0 +1,35 @@ +// Traits where a method is c-variadic are not dyn compatible. +// +// Creating a function pointer from a method on an `&dyn T` value creates a ReifyShim. +// This shim cannot reliably forward C-variadic arguments. Thus the trait as a whole +// is dyn-incompatible to prevent invalid shims from being created. +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(u64); + +trait Trait { + fn get(&self) -> u64; + + unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + self.get() + unsafe { ap.arg::() } + } +} + +impl Trait for Struct { + fn get(&self) -> u64 { + self.0 + } +} + +fn main() { + unsafe { + let dyn_object: &dyn Trait = &Struct(64); + //~^ ERROR the trait `Trait` is not dyn compatible + assert_eq!(dyn_object.dyn_method_ref(100), 164); + assert_eq!( + (Trait::dyn_method_ref as unsafe extern "C" fn(_, ...) -> u64)(dyn_object, 100), + 164 + ); + } +} diff --git a/tests/ui/c-variadic/not-dyn-compatible.stderr b/tests/ui/c-variadic/not-dyn-compatible.stderr new file mode 100644 index 0000000000000..76630600c511f --- /dev/null +++ b/tests/ui/c-variadic/not-dyn-compatible.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `Trait` is not dyn compatible + --> $DIR/not-dyn-compatible.rs:27:30 + | +LL | let dyn_object: &dyn Trait = &Struct(64); + | ^^^^^ `Trait` is not dyn compatible + | +note: for a trait to be dyn compatible it needs to allow building a vtable + for more information, visit + --> $DIR/not-dyn-compatible.rs:14:26 + | +LL | trait Trait { + | ----- this trait is not dyn compatible... +... +LL | unsafe extern "C" fn dyn_method_ref(&self, mut ap: ...) -> u64 { + | ^^^^^^^^^^^^^^ ...because method `dyn_method_ref` is C-variadic + = help: consider moving `dyn_method_ref` to another trait + = help: only type `Struct` implements `Trait`; consider using it directly instead. + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/c-variadic/trait-method.rs b/tests/ui/c-variadic/trait-method.rs new file mode 100644 index 0000000000000..876a303f53ba5 --- /dev/null +++ b/tests/ui/c-variadic/trait-method.rs @@ -0,0 +1,74 @@ +//@ run-pass +//@ ignore-backends: gcc +#![feature(c_variadic)] + +#[repr(transparent)] +struct Struct(i32); + +impl Struct { + unsafe extern "C" fn associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn method(&self, mut ap: ...) -> i32 { + self.0 + unsafe { ap.arg::() } + } +} + +trait Trait: Sized { + fn get(&self) -> i32; + + unsafe extern "C" fn trait_associated_function(mut ap: ...) -> i32 { + unsafe { ap.arg() } + } + + unsafe extern "C" fn trait_method_owned(self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_method_ref(&self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_method_mut(&mut self, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } + + unsafe extern "C" fn trait_fat_pointer(self: Box, mut ap: ...) -> i32 { + self.get() + unsafe { ap.arg::() } + } +} + +impl Trait for Struct { + fn get(&self) -> i32 { + self.0 + } +} + +fn main() { + unsafe { + assert_eq!(Struct::associated_function(32), 32); + assert_eq!(Struct(100).method(32), 132); + + assert_eq!(Struct::trait_associated_function(32), 32); + assert_eq!(Struct(100).trait_method_owned(32), 132); + assert_eq!(Struct(100).trait_method_ref(32), 132); + assert_eq!(Struct(100).trait_method_mut(32), 132); + assert_eq!(Struct::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + assert_eq!(::trait_associated_function(32), 32); + assert_eq!(Trait::trait_method_owned(Struct(100), 32), 132); + assert_eq!(Trait::trait_method_ref(&Struct(100), 32), 132); + assert_eq!(Trait::trait_method_mut(&mut Struct(100), 32), 132); + assert_eq!(Trait::trait_fat_pointer(Box::new(Struct(100)), 32), 132); + + type Associated = unsafe extern "C" fn(...) -> i32; + type Method = unsafe extern "C" fn(T, ...) -> i32; + + assert_eq!((Struct::trait_associated_function as Associated)(32), 32); + assert_eq!((Struct::trait_method_owned as Method<_>)(Struct(100), 32), 132); + assert_eq!((Struct::trait_method_ref as Method<_>)(&Struct(100), 32), 132); + assert_eq!((Struct::trait_method_mut as Method<_>)(&mut Struct(100), 32), 132); + assert_eq!((Struct::trait_fat_pointer as Method<_>)(Box::new(Struct(100)), 32), 132); + } +} diff --git a/tests/ui/c-variadic/unsupported-abi.rs b/tests/ui/c-variadic/unsupported-abi.rs new file mode 100644 index 0000000000000..bed6b41d669ad --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.rs @@ -0,0 +1,124 @@ +//@ add-core-stubs +//@ needs-llvm-components: x86 +//@ compile-flags: --target=i686-pc-windows-gnu --crate-type=rlib +//@ ignore-backends: gcc +#![no_core] +#![feature(no_core, lang_items, c_variadic)] + +// Test that ABIs for which C-variadics are not supported report an error. + +extern crate minicore; +use minicore::*; + +#[rustfmt::skip] +mod foreign { + extern "Rust" { fn rust_foreign_explicit(_: ...); } + //~^ ERROR C-variadic functions with the "Rust" calling convention are not supported + extern "C" { fn c_foreign(_: ...); } + extern "C-unwind" { fn c_unwind_foreign(_: ...); } + extern "cdecl" { fn cdecl_foreign(_: ...); } + extern "cdecl-unwind" { fn cdecl_unwind_foreign(_: ...); } + extern "stdcall" { fn stdcall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall" calling convention are not supported + extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "stdcall-unwind" calling convention are not supported + extern "thiscall" { fn thiscall_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall" calling convention are not supported + extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + //~^ ERROR C-variadic functions with the "thiscall-unwind" calling convention are not supported +} + +#[lang = "va_list"] +struct VaList(*mut u8); + +unsafe fn rust_free(_: ...) {} +//~^ ERROR `...` is not supported for non-extern functions +unsafe extern "Rust" fn rust_free_explicit(_: ...) {} +//~^ ERROR `...` is not supported for `extern "Rust"` functions + +unsafe extern "C" fn c_free(_: ...) {} +unsafe extern "C-unwind" fn c_unwind_free(_: ...) {} + +unsafe extern "cdecl" fn cdecl_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl"` functions +unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions +unsafe extern "stdcall" fn stdcall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall"` functions +unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions +unsafe extern "thiscall" fn thiscall_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall"` functions +unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} +//~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions + +struct S; + +impl S { + unsafe fn rust_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +trait T { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} + +impl T for S { + unsafe fn rust_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for non-extern functions + unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + //~^ ERROR `...` is not supported for `extern "Rust"` functions + + unsafe extern "C" fn c_trait_method(_: ...) {} + unsafe extern "C-unwind" fn c_unwind_trait_method(_: ...) {} + + unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl"` functions + unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "cdecl-unwind"` functions + unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall"` functions + unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "stdcall-unwind"` functions + unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall"` functions + unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + //~^ ERROR `...` is not supported for `extern "thiscall-unwind"` functions +} diff --git a/tests/ui/c-variadic/unsupported-abi.stderr b/tests/ui/c-variadic/unsupported-abi.stderr new file mode 100644 index 0000000000000..ee1f5ece82ced --- /dev/null +++ b/tests/ui/c-variadic/unsupported-abi.stderr @@ -0,0 +1,345 @@ +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:34:21 + | +LL | unsafe fn rust_free(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:36:44 + | +LL | unsafe extern "Rust" fn rust_free_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:42:37 + | +LL | unsafe extern "cdecl" fn cdecl_free(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:44:51 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:46:41 + | +LL | unsafe extern "stdcall" fn stdcall_free(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:48:55 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:50:43 + | +LL | unsafe extern "thiscall" fn thiscall_free(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:52:57 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:58:27 + | +LL | unsafe fn rust_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:60:50 + | +LL | unsafe extern "Rust" fn rust_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:66:43 + | +LL | unsafe extern "cdecl" fn cdecl_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:68:57 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:70:47 + | +LL | unsafe extern "stdcall" fn stdcall_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:72:61 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:74:49 + | +LL | unsafe extern "thiscall" fn thiscall_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:76:63 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:81:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:83:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:89:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:91:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:93:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:95:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:97:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:99:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for non-extern functions + --> $DIR/unsupported-abi.rs:104:33 + | +LL | unsafe fn rust_trait_method(_: ...) {} + | ^^^^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "Rust"` functions + --> $DIR/unsupported-abi.rs:106:56 + | +LL | unsafe extern "Rust" fn rust_trait_method_explicit(_: ...) {} + | ------------- ^^^^^^ + | | + | `extern "Rust"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl"` functions + --> $DIR/unsupported-abi.rs:112:49 + | +LL | unsafe extern "cdecl" fn cdecl_trait_method(_: ...) {} + | -------------- ^^^^^^ + | | + | `extern "cdecl"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "cdecl-unwind"` functions + --> $DIR/unsupported-abi.rs:114:63 + | +LL | unsafe extern "cdecl-unwind" fn cdecl_unwind_trait_method(_: ...) {} + | --------------------- ^^^^^^ + | | + | `extern "cdecl-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall"` functions + --> $DIR/unsupported-abi.rs:116:53 + | +LL | unsafe extern "stdcall" fn stdcall_trait_method(_: ...) {} + | ---------------- ^^^^^^ + | | + | `extern "stdcall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "stdcall-unwind"` functions + --> $DIR/unsupported-abi.rs:118:67 + | +LL | unsafe extern "stdcall-unwind" fn stdcall_unwind_trait_method(_: ...) {} + | ----------------------- ^^^^^^ + | | + | `extern "stdcall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall"` functions + --> $DIR/unsupported-abi.rs:120:55 + | +LL | unsafe extern "thiscall" fn thiscall_trait_method(_: ...) {} + | ----------------- ^^^^^^ + | | + | `extern "thiscall"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: `...` is not supported for `extern "thiscall-unwind"` functions + --> $DIR/unsupported-abi.rs:122:69 + | +LL | unsafe extern "thiscall-unwind" fn thiscall_unwind_trait_method(_: ...) {} + | ------------------------ ^^^^^^ + | | + | `extern "thiscall-unwind"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error[E0045]: C-variadic functions with the "Rust" calling convention are not supported + --> $DIR/unsupported-abi.rs:15:22 + | +LL | extern "Rust" { fn rust_foreign_explicit(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall" calling convention are not supported + --> $DIR/unsupported-abi.rs:21:25 + | +LL | extern "stdcall" { fn stdcall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "stdcall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:23:32 + | +LL | extern "stdcall-unwind" { fn stdcall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall" calling convention are not supported + --> $DIR/unsupported-abi.rs:25:26 + | +LL | extern "thiscall" { fn thiscall_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error[E0045]: C-variadic functions with the "thiscall-unwind" calling convention are not supported + --> $DIR/unsupported-abi.rs:27:33 + | +LL | extern "thiscall-unwind" { fn thiscall_unwind_foreign(_: ...); } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention + +error: aborting due to 37 previous errors + +For more information about this error, try `rustc --explain E0045`. diff --git a/tests/ui/c-variadic/valid.rs b/tests/ui/c-variadic/valid.rs index 5a0b32026dc7a..8b42eb4932906 100644 --- a/tests/ui/c-variadic/valid.rs +++ b/tests/ui/c-variadic/valid.rs @@ -1,4 +1,5 @@ //@ run-pass +//@ ignore-backends: gcc #![feature(c_variadic)] // In rust (and C23 and above) `...` can be the only argument. diff --git a/tests/ui/c-variadic/variadic-ffi-1.rs b/tests/ui/c-variadic/variadic-ffi-1.rs index 2baa00a079a42..95cd34419676b 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.rs +++ b/tests/ui/c-variadic/variadic-ffi-1.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ needs-llvm-components: x86 //@ compile-flags: --target=i686-pc-windows-msvc --crate-type=rlib +//@ ignore-backends: gcc #![no_core] #![feature(no_core, lang_items)] diff --git a/tests/ui/c-variadic/variadic-ffi-1.stderr b/tests/ui/c-variadic/variadic-ffi-1.stderr index 981b021276d20..b7182887cfb78 100644 --- a/tests/ui/c-variadic/variadic-ffi-1.stderr +++ b/tests/ui/c-variadic/variadic-ffi-1.stderr @@ -1,23 +1,23 @@ error[E0045]: C-variadic functions with the "stdcall" calling convention are not supported - --> $DIR/variadic-ffi-1.rs:11:5 + --> $DIR/variadic-ffi-1.rs:12:5 | LL | fn printf(_: *const u8, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention error[E0045]: C-variadic functions with the "Rust" calling convention are not supported - --> $DIR/variadic-ffi-1.rs:15:11 + --> $DIR/variadic-ffi-1.rs:16:11 | LL | fn baz(f: extern "Rust" fn(usize, ...)) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention error[E0060]: this function takes at least 2 arguments but 0 arguments were supplied - --> $DIR/variadic-ffi-1.rs:28:9 + --> $DIR/variadic-ffi-1.rs:29:9 | LL | foo(); | ^^^-- two arguments of type `isize` and `u8` are missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:21:8 + --> $DIR/variadic-ffi-1.rs:22:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - - @@ -27,13 +27,13 @@ LL | foo(/* isize */, /* u8 */); | +++++++++++++++++++++ error[E0060]: this function takes at least 2 arguments but 1 argument was supplied - --> $DIR/variadic-ffi-1.rs:29:9 + --> $DIR/variadic-ffi-1.rs:30:9 | LL | foo(1); | ^^^--- argument #2 of type `u8` is missing | note: function defined here - --> $DIR/variadic-ffi-1.rs:21:8 + --> $DIR/variadic-ffi-1.rs:22:8 | LL | fn foo(f: isize, x: u8, ...); | ^^^ - @@ -43,7 +43,7 @@ LL | foo(1, /* u8 */); | ++++++++++ error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:31:56 + --> $DIR/variadic-ffi-1.rs:32:56 | LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; | ------------------------------------- ^^^ expected non-variadic fn, found variadic function @@ -54,7 +54,7 @@ LL | let x: unsafe extern "C" fn(f: isize, x: u8) = foo; found fn item `unsafe extern "C" fn(_, _, ...) {foo}` error[E0308]: mismatched types - --> $DIR/variadic-ffi-1.rs:32:54 + --> $DIR/variadic-ffi-1.rs:33:54 | LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; | ----------------------------------- ^^^ expected variadic fn, found non-variadic function @@ -65,7 +65,7 @@ LL | let y: extern "C" fn(f: isize, x: u8, ...) = bar; found fn item `extern "C" fn(_, _) {bar}` error[E0617]: can't pass `f32` to variadic function - --> $DIR/variadic-ffi-1.rs:34:19 + --> $DIR/variadic-ffi-1.rs:35:19 | LL | foo(1, 2, 3f32); | ^^^^ @@ -76,7 +76,7 @@ LL | foo(1, 2, 3f32 as c_double); | +++++++++++ error[E0617]: can't pass `bool` to variadic function - --> $DIR/variadic-ffi-1.rs:35:19 + --> $DIR/variadic-ffi-1.rs:36:19 | LL | foo(1, 2, true); | ^^^^ @@ -87,7 +87,7 @@ LL | foo(1, 2, true as c_int); | ++++++++ error[E0617]: can't pass `i8` to variadic function - --> $DIR/variadic-ffi-1.rs:36:19 + --> $DIR/variadic-ffi-1.rs:37:19 | LL | foo(1, 2, 1i8); | ^^^ @@ -98,7 +98,7 @@ LL | foo(1, 2, 1i8 as c_int); | ++++++++ error[E0617]: can't pass `u8` to variadic function - --> $DIR/variadic-ffi-1.rs:37:19 + --> $DIR/variadic-ffi-1.rs:38:19 | LL | foo(1, 2, 1u8); | ^^^ @@ -109,7 +109,7 @@ LL | foo(1, 2, 1u8 as c_uint); | +++++++++ error[E0617]: can't pass `i16` to variadic function - --> $DIR/variadic-ffi-1.rs:38:19 + --> $DIR/variadic-ffi-1.rs:39:19 | LL | foo(1, 2, 1i16); | ^^^^ @@ -120,7 +120,7 @@ LL | foo(1, 2, 1i16 as c_int); | ++++++++ error[E0617]: can't pass `u16` to variadic function - --> $DIR/variadic-ffi-1.rs:39:19 + --> $DIR/variadic-ffi-1.rs:40:19 | LL | foo(1, 2, 1u16); | ^^^^ diff --git a/tests/ui/cast/func-pointer-issue-140491.stderr b/tests/ui/cast/func-pointer-issue-140491.stderr index e1c07010e691c..0b777905da1f9 100644 --- a/tests/ui/cast/func-pointer-issue-140491.stderr +++ b/tests/ui/cast/func-pointer-issue-140491.stderr @@ -1,8 +1,8 @@ error[E0605]: non-primitive cast: `&for<'a, 'b> fn(&'a Event<'b>) {my_fn}` as `&for<'a, 'b> fn(&'a Event<'b>)` --> $DIR/func-pointer-issue-140491.rs:6:34 | -LL | ..._>) = &my_fn as _; - | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object +LL | ... = &my_fn as _; + | ^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object | = note: casting reference expression `&my_fn` because `&` binds tighter than `as` diff --git a/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs b/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs index cafb7389e29fa..2ca004d9a906d 100644 --- a/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs +++ b/tests/ui/cfg/assume-incomplete-release/assume-incomplete.rs @@ -2,6 +2,7 @@ //@ proc-macro: ver-cfg-rel.rs //@ revisions: assume no_assume //@ [assume]compile-flags: -Z assume-incomplete-release +//@ ignore-backends: gcc #![feature(cfg_version)] diff --git a/tests/ui/cfg/cfg-path-error.rs b/tests/ui/cfg/cfg-path-error.rs index 9db1f190bdc06..f22e6be32f3e1 100644 --- a/tests/ui/cfg/cfg-path-error.rs +++ b/tests/ui/cfg/cfg-path-error.rs @@ -3,19 +3,27 @@ #![allow(unexpected_cfgs)] // invalid cfgs #[cfg(any(foo, foo::bar))] -//~^ERROR `cfg` predicate key must be an identifier +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit fn foo1() {} #[cfg(any(foo::bar, foo))] -//~^ERROR `cfg` predicate key must be an identifier +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit fn foo2() {} #[cfg(all(foo, foo::bar))] -//~^ERROR `cfg` predicate key must be an identifier +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit fn foo3() {} #[cfg(all(foo::bar, foo))] -//~^ERROR `cfg` predicate key must be an identifier +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit fn foo4() {} fn main() {} diff --git a/tests/ui/cfg/cfg-path-error.stderr b/tests/ui/cfg/cfg-path-error.stderr index 4f68fa32a9ac2..bb9b7039c8a34 100644 --- a/tests/ui/cfg/cfg-path-error.stderr +++ b/tests/ui/cfg/cfg-path-error.stderr @@ -1,26 +1,47 @@ -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-path-error.rs:5:16 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-path-error.rs:5:1 | LL | #[cfg(any(foo, foo::bar))] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^--------^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-path-error.rs:9:11 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-path-error.rs:11:1 | LL | #[cfg(any(foo::bar, foo))] - | ^^^^^^^^ + | ^^^^^^^^^^--------^^^^^^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-path-error.rs:13:16 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-path-error.rs:17:1 | LL | #[cfg(all(foo, foo::bar))] - | ^^^^^^^^ + | ^^^^^^^^^^^^^^^--------^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-path-error.rs:17:11 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-path-error.rs:23:1 | LL | #[cfg(all(foo::bar, foo))] - | ^^^^^^^^ + | ^^^^^^^^^^--------^^^^^^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/cfg/cfg-target-compact-errors.rs b/tests/ui/cfg/cfg-target-compact-errors.rs index cfb19c58a197d..1ce68330c7623 100644 --- a/tests/ui/cfg/cfg-target-compact-errors.rs +++ b/tests/ui/cfg/cfg-target-compact-errors.rs @@ -19,7 +19,7 @@ fn three() {} fn four() {} #[cfg(target(clippy::os = "linux"))] -//~^ ERROR `cfg` predicate key must be an identifier +//~^ ERROR malformed `cfg` attribute input fn five() {} fn main() {} diff --git a/tests/ui/cfg/cfg-target-compact-errors.stderr b/tests/ui/cfg/cfg-target-compact-errors.stderr index cf61f94278a0b..3ca1b73e0c092 100644 --- a/tests/ui/cfg/cfg-target-compact-errors.stderr +++ b/tests/ui/cfg/cfg-target-compact-errors.stderr @@ -42,11 +42,16 @@ LL | #[cfg(target(true))] | = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-target-compact-errors.rs:21:14 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-target-compact-errors.rs:21:1 | LL | #[cfg(target(clippy::os = "linux"))] - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^----------^^^^^^^^^^^^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit error: aborting due to 5 previous errors diff --git a/tests/ui/check-cfg/cfg-crate-features.stderr b/tests/ui/check-cfg/cfg-crate-features.stderr index 6b2e628e12ea1..39fee52a909b6 100644 --- a/tests/ui/check-cfg/cfg-crate-features.stderr +++ b/tests/ui/check-cfg/cfg-crate-features.stderr @@ -24,7 +24,7 @@ warning: unexpected `cfg` condition value: `does_not_exist` LL | #![cfg(not(target(os = "does_not_exist")))] | ^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, and `tvos` and 11 more + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, and `trusty` and 12 more = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default diff --git a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr index 989a01f224412..4b5fc91c7eb91 100644 --- a/tests/ui/check-cfg/report-in-external-macros.cargo.stderr +++ b/tests/ui/check-cfg/report-in-external-macros.cargo.stderr @@ -18,7 +18,7 @@ warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE` LL | cfg_macro::my_lib_macro_value!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `panic` are: `abort` and `unwind` + = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind` = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg = help: the macro `cfg_macro::my_lib_macro_value` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro` diff --git a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr index 95d10e014f33b..0d99d061d28df 100644 --- a/tests/ui/check-cfg/report-in-external-macros.rustc.stderr +++ b/tests/ui/check-cfg/report-in-external-macros.rustc.stderr @@ -18,7 +18,7 @@ warning: unexpected `cfg` condition value: `UNEXPECTED_VALUE` LL | cfg_macro::my_lib_macro_value!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `panic` are: `abort` and `unwind` + = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind` = note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate = help: try referring to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg = note: see for more information about checking conditional configuration diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 6490fc63fd766..3f14c7b08eac6 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -80,7 +80,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `panic` are: `abort` and `unwind` + = note: expected values for `panic` are: `abort`, `immediate-abort`, and `unwind` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` + = note: expected values for `target_env` are: ``, `gnu`, `macabi`, `mlibc`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `p3`, `relibc`, `sgx`, `sim`, `uclibc`, and `v5` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `cygwin`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `lynxos178`, `macos`, `managarm`, `motor`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `vexos`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 28 warnings emitted diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs index c550af21f0753..641066b002273 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.rs @@ -13,13 +13,11 @@ struct Point { pub fn f() { let mut a = 1; - let mut c = Point{ x:1, y:0 }; + let mut c = Point { x: 1, y: 0 }; // Captured by value, but variable is dead on entry. (move || { - // This will not trigger a warning for unused variable as - // c.x will be treated as a Non-tracked place - c.x = 1; + c.x = 1; //~ WARN value captured by `c.x` is never read println!("{}", c.x); a = 1; //~ WARN value captured by `a` is never read println!("{}", a); @@ -27,10 +25,10 @@ pub fn f() { // Read and written to, but never actually used. (move || { - // This will not trigger a warning for unused variable as - // c.x will be treated as a Non-tracked place - c.x += 1; - a += 1; //~ WARN unused variable: `a` + c.x += 1; //~ WARN value captured by `c.x` is never read + //~| WARN value assigned to `c.x` is never read + a += 1; //~ WARN value captured by `a` is never read + //~| WARN value assigned to `a` is never read })(); (move || { @@ -45,10 +43,7 @@ pub fn f() { let b = Box::new(42); (move || { println!("{}", c.x); - // Never read because this is FnOnce closure. - // This will not trigger a warning for unused variable as - // c.x will be treated as a Non-tracked place - c.x += 1; + c.x += 1; //~ WARN value assigned to `c.x` is never read println!("{}", a); a += 1; //~ WARN value assigned to `a` is never read drop(b); @@ -56,35 +51,32 @@ pub fn f() { } #[derive(Debug)] -struct MyStruct<'a> { - x: Option<& 'a str>, +struct MyStruct<'a> { + x: Option<&'a str>, y: i32, } pub fn nested() { - let mut a : Option<& str>; + let mut a: Option<&str>; a = None; - let mut b : Option<& str>; + let mut b: Option<&str>; b = None; - let mut d = MyStruct{ x: None, y: 1}; - let mut e = MyStruct{ x: None, y: 1}; + let mut d = MyStruct { x: None, y: 1 }; + let mut e = MyStruct { x: None, y: 1 }; (|| { (|| { - // This will not trigger a warning for unused variable as - // d.x will be treated as a Non-tracked place - d.x = Some("d1"); + d.x = Some("d1"); //~ WARN value assigned to `d.x` is never read d.x = Some("d2"); a = Some("d1"); //~ WARN value assigned to `a` is never read a = Some("d2"); })(); (move || { - // This will not trigger a warning for unused variable as - //e.x will be treated as a Non-tracked place - e.x = Some("e1"); - e.x = Some("e2"); - b = Some("e1"); //~ WARN value assigned to `b` is never read - //~| WARN unused variable: `b` - b = Some("e2"); //~ WARN value assigned to `b` is never read + e.x = Some("e1"); //~ WARN value captured by `e.x` is never read + //~| WARN value assigned to `e.x` is never read + e.x = Some("e2"); //~ WARN value assigned to `e.x` is never read + b = Some("e1"); //~ WARN value captured by `b` is never read + //~| WARN value assigned to `b` is never read + b = Some("e2"); //~ WARN value assigned to `b` is never read })(); })(); } diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index cf414adc0b943..f697662d3ee93 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr @@ -1,10 +1,10 @@ -warning: value captured by `a` is never read - --> $DIR/liveness.rs:24:9 +warning: value assigned to `c.x` is never read + --> $DIR/liveness.rs:46:9 | -LL | a = 1; - | ^ +LL | c.x += 1; + | ^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness.rs:5:9 | @@ -12,54 +12,125 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` -warning: unused variable: `a` - --> $DIR/liveness.rs:33:9 +warning: value assigned to `a` is never read + --> $DIR/liveness.rs:48:9 + | +LL | a += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `c.x` is never read + --> $DIR/liveness.rs:28:9 + | +LL | c.x += 1; + | ^^^ + | + = help: did you mean to capture by reference instead? + +warning: value assigned to `c.x` is never read + --> $DIR/liveness.rs:28:9 + | +LL | c.x += 1; + | ^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `a` is never read + --> $DIR/liveness.rs:30:9 | LL | a += 1; | ^ | = help: did you mean to capture by reference instead? - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: value assigned to `a` is never read - --> $DIR/liveness.rs:53:9 + --> $DIR/liveness.rs:30:9 | LL | a += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `c.x` is never read + --> $DIR/liveness.rs:20:9 + | +LL | c.x = 1; + | ^^^ + | + = help: did you mean to capture by reference instead? + +warning: value captured by `a` is never read + --> $DIR/liveness.rs:22:9 + | +LL | a = 1; | ^ | + = help: did you mean to capture by reference instead? + +warning: value captured by `e.x` is never read + --> $DIR/liveness.rs:74:13 + | +LL | e.x = Some("e1"); + | ^^^ + | + = help: did you mean to capture by reference instead? + +warning: value assigned to `e.x` is never read + --> $DIR/liveness.rs:74:13 + | +LL | e.x = Some("e1"); + | ^^^^^^^^^^^^^^^^ + | = help: maybe it is overwritten before being read? -warning: value assigned to `a` is never read +warning: value assigned to `e.x` is never read + --> $DIR/liveness.rs:76:13 + | +LL | e.x = Some("e2"); + | ^^^^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `b` is never read --> $DIR/liveness.rs:77:13 | -LL | a = Some("d1"); +LL | b = Some("e1"); | ^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? warning: value assigned to `b` is never read - --> $DIR/liveness.rs:85:13 + --> $DIR/liveness.rs:77:13 | LL | b = Some("e1"); - | ^ + | ^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? warning: value assigned to `b` is never read - --> $DIR/liveness.rs:87:13 + --> $DIR/liveness.rs:79:13 | LL | b = Some("e2"); - | ^ + | ^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? -warning: unused variable: `b` - --> $DIR/liveness.rs:85:13 +warning: value assigned to `d.x` is never read + --> $DIR/liveness.rs:68:13 | -LL | b = Some("e1"); - | ^ +LL | d.x = Some("d1"); + | ^^^^^^^^^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? + +warning: value assigned to `a` is never read + --> $DIR/liveness.rs:70:13 + | +LL | a = Some("d1"); + | ^^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? -warning: 7 warnings emitted +warning: 16 warnings emitted diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs index bcd4d1090a411..2d4451d988ebc 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.rs @@ -12,14 +12,16 @@ struct MyStruct { pub fn unintentional_copy_one() { let mut a = 1; - let mut last = MyStruct{ a: 1, b: 1}; + //~^ WARN unused variable: `a` + let mut last = MyStruct { a: 1, b: 1 }; + //~^ WARN unused variable: `last` let mut f = move |s| { - // This will not trigger a warning for unused variable - // as last.a will be treated as a Non-tracked place last.a = s; + //~^ WARN value captured by `last.a` is never read + //~| WARN value assigned to `last.a` is never read a = s; - //~^ WARN value assigned to `a` is never read - //~| WARN unused variable: `a` + //~^ WARN value captured by `a` is never read + //~| WARN value assigned to `a` is never read }; f(2); f(3); @@ -28,12 +30,16 @@ pub fn unintentional_copy_one() { pub fn unintentional_copy_two() { let mut a = 1; - let mut sum = MyStruct{ a: 1, b: 0}; + //~^ WARN unused variable: `a` + let mut sum = MyStruct { a: 1, b: 0 }; + //~^ WARN unused variable: `sum` (1..10).for_each(move |x| { - // This will not trigger a warning for unused variable - // as sum.b will be treated as a Non-tracked place sum.b += x; - a += x; //~ WARN unused variable: `a` + //~^ WARN value captured by `sum.b` is never read + //~| WARN value assigned to `sum.b` is never read + a += x; + //~^ WARN value captured by `a` is never read + //~| WARN value assigned to `a` is never read }); } diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr index 0410de4c7982a..35b6d547eece0 100644 --- a/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr +++ b/tests/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr @@ -1,10 +1,10 @@ -warning: value assigned to `a` is never read - --> $DIR/liveness_unintentional_copy.rs:20:9 +warning: value captured by `last.a` is never read + --> $DIR/liveness_unintentional_copy.rs:19:9 | -LL | a = s; - | ^ +LL | last.a = s; + | ^^^^^^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? note: the lint level is defined here --> $DIR/liveness_unintentional_copy.rs:4:9 | @@ -12,22 +12,87 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` -warning: unused variable: `a` - --> $DIR/liveness_unintentional_copy.rs:20:9 +warning: value assigned to `last.a` is never read + --> $DIR/liveness_unintentional_copy.rs:19:9 + | +LL | last.a = s; + | ^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `a` is never read + --> $DIR/liveness_unintentional_copy.rs:22:9 | LL | a = s; | ^ | = help: did you mean to capture by reference instead? - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: value assigned to `a` is never read + --> $DIR/liveness_unintentional_copy.rs:22:9 + | +LL | a = s; + | ^^^^^ + | + = help: maybe it is overwritten before being read? warning: unused variable: `a` - --> $DIR/liveness_unintentional_copy.rs:36:9 + --> $DIR/liveness_unintentional_copy.rs:14:9 + | +LL | let mut a = 1; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_a` + | + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + +warning: unused variable: `last` + --> $DIR/liveness_unintentional_copy.rs:16:9 + | +LL | let mut last = MyStruct { a: 1, b: 1 }; + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_last` + +warning: value captured by `sum.b` is never read + --> $DIR/liveness_unintentional_copy.rs:37:9 + | +LL | sum.b += x; + | ^^^^^ + | + = help: did you mean to capture by reference instead? + +warning: value assigned to `sum.b` is never read + --> $DIR/liveness_unintentional_copy.rs:37:9 + | +LL | sum.b += x; + | ^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `a` is never read + --> $DIR/liveness_unintentional_copy.rs:40:9 | LL | a += x; | ^ | = help: did you mean to capture by reference instead? -warning: 3 warnings emitted +warning: value assigned to `a` is never read + --> $DIR/liveness_unintentional_copy.rs:40:9 + | +LL | a += x; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: unused variable: `a` + --> $DIR/liveness_unintentional_copy.rs:32:9 + | +LL | let mut a = 1; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_a` + +warning: unused variable: `sum` + --> $DIR/liveness_unintentional_copy.rs:34:9 + | +LL | let mut sum = MyStruct { a: 1, b: 0 }; + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_sum` + +warning: 12 warnings emitted diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr b/tests/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr index cf8bd7a0a2765..40274c88318c3 100644 --- a/tests/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr +++ b/tests/ui/closures/2229_closure_analysis/run_pass/destructure-pattern-closure-within-closure.stderr @@ -1,8 +1,8 @@ -warning: unused variable: `g2` - --> $DIR/destructure-pattern-closure-within-closure.rs:10:17 +warning: unused variable: `t2` + --> $DIR/destructure-pattern-closure-within-closure.rs:13:21 | -LL | let (_, g2) = g; - | ^^ help: if this is intentional, prefix it with an underscore: `_g2` +LL | let (_, t2) = t; + | ^^ help: if this is intentional, prefix it with an underscore: `_t2` | note: the lint level is defined here --> $DIR/destructure-pattern-closure-within-closure.rs:3:9 @@ -11,11 +11,11 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` -warning: unused variable: `t2` - --> $DIR/destructure-pattern-closure-within-closure.rs:13:21 +warning: unused variable: `g2` + --> $DIR/destructure-pattern-closure-within-closure.rs:10:17 | -LL | let (_, t2) = t; - | ^^ help: if this is intentional, prefix it with an underscore: `_t2` +LL | let (_, g2) = g; + | ^^ help: if this is intentional, prefix it with an underscore: `_g2` warning: 2 warnings emitted diff --git a/tests/ui/closures/impl-closure-147146.rs b/tests/ui/closures/impl-closure-147146.rs new file mode 100644 index 0000000000000..b709e577354e5 --- /dev/null +++ b/tests/ui/closures/impl-closure-147146.rs @@ -0,0 +1,7 @@ +impl typeof(|| {}) {} +//~^ ERROR `typeof` is a reserved keyword but unimplemented + +unsafe impl Send for typeof(|| {}) {} +//~^ ERROR `typeof` is a reserved keyword but unimplemented + +fn main() {} diff --git a/tests/ui/closures/impl-closure-147146.stderr b/tests/ui/closures/impl-closure-147146.stderr new file mode 100644 index 0000000000000..6da16b5d450fd --- /dev/null +++ b/tests/ui/closures/impl-closure-147146.stderr @@ -0,0 +1,15 @@ +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/impl-closure-147146.rs:1:6 + | +LL | impl typeof(|| {}) {} + | ^^^^^^^^^^^^^ reserved keyword + +error[E0516]: `typeof` is a reserved keyword but unimplemented + --> $DIR/impl-closure-147146.rs:4:22 + | +LL | unsafe impl Send for typeof(|| {}) {} + | ^^^^^^^^^^^^^ reserved keyword + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0516`. diff --git a/tests/ui/closures/labeled-break-inside-closure-62480.rs b/tests/ui/closures/labeled-break-inside-closure-62480.rs new file mode 100644 index 0000000000000..620f1e220fe42 --- /dev/null +++ b/tests/ui/closures/labeled-break-inside-closure-62480.rs @@ -0,0 +1,11 @@ +// https://github.com/rust-lang/rust/issues/62480 +fn main() { + // This used to ICE during liveness check because `target_id` passed to + // `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in + // `self.break_ln`. (#62480) + 'a: { + || break 'a + //~^ ERROR use of unreachable label `'a` + //~| ERROR `break` inside of a closure + } +} diff --git a/tests/ui/closures/labeled-break-inside-closure-62480.stderr b/tests/ui/closures/labeled-break-inside-closure-62480.stderr new file mode 100644 index 0000000000000..a4ca60bb97365 --- /dev/null +++ b/tests/ui/closures/labeled-break-inside-closure-62480.stderr @@ -0,0 +1,22 @@ +error[E0767]: use of unreachable label `'a` + --> $DIR/labeled-break-inside-closure-62480.rs:7:18 + | +LL | 'a: { + | -- unreachable label defined here +LL | || break 'a + | ^^ unreachable label `'a` + | + = note: labels are unreachable through functions, closures, async blocks and modules + +error[E0267]: `break` inside of a closure + --> $DIR/labeled-break-inside-closure-62480.rs:7:12 + | +LL | || break 'a + | -- ^^^^^^^^ cannot `break` inside of a closure + | | + | enclosing closure + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0267, E0767. +For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/closures/moved-upvar-mut-rebind-11958.rs b/tests/ui/closures/moved-upvar-mut-rebind-11958.rs index 701dc1a2cefd2..f308028bdd7b6 100644 --- a/tests/ui/closures/moved-upvar-mut-rebind-11958.rs +++ b/tests/ui/closures/moved-upvar-mut-rebind-11958.rs @@ -7,7 +7,8 @@ pub fn main() { let mut x = 1; + //~^ WARN unused variable: `x` let _thunk = Box::new(move|| { x = 2; }); - //~^ WARN value assigned to `x` is never read - //~| WARN unused variable: `x` + //~^ WARN value captured by `x` is never read + //~| WARN value assigned to `x` is never read } diff --git a/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr b/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr index 1bf8a8b23a1d0..e28db65392a4b 100644 --- a/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr +++ b/tests/ui/closures/moved-upvar-mut-rebind-11958.stderr @@ -1,20 +1,27 @@ -warning: value assigned to `x` is never read - --> $DIR/moved-upvar-mut-rebind-11958.rs:10:36 +warning: value captured by `x` is never read + --> $DIR/moved-upvar-mut-rebind-11958.rs:11:36 | LL | let _thunk = Box::new(move|| { x = 2; }); | ^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default -warning: unused variable: `x` - --> $DIR/moved-upvar-mut-rebind-11958.rs:10:36 +warning: value assigned to `x` is never read + --> $DIR/moved-upvar-mut-rebind-11958.rs:11:36 | LL | let _thunk = Box::new(move|| { x = 2; }); - | ^ + | ^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: unused variable: `x` + --> $DIR/moved-upvar-mut-rebind-11958.rs:9:9 + | +LL | let mut x = 1; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_x` | - = help: did you mean to capture by reference instead? = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default -warning: 2 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs index 796c2634b6237..2d937b69908eb 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/callback-as-argument.rs @@ -2,6 +2,7 @@ //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(abi_cmse_nonsecure_call, cmse_nonsecure_entry, no_core, lang_items, intrinsics)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs index 4ce5890a2da30..72efd05814325 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.rs @@ -14,10 +14,14 @@ struct Test { f1: extern "cmse-nonsecure-call" fn(U, u32, u32, u32) -> u64, //~^ ERROR cannot find type `U` in this scope //~| ERROR function pointer types may not have generic parameters - f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, + f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, //~^ ERROR `impl Trait` is not allowed in `fn` pointer parameters - f3: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, //~ ERROR [E0798] - f4: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, //~ ERROR [E0798] + //~| ERROR `impl Trait` is not allowed in `fn` pointer return types + f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), + //~^ ERROR `impl Trait` is not allowed in `fn` pointer parameters + //~| ERROR `impl Trait` is not allowed in `fn` pointer return types + f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, //~ ERROR [E0798] + f5: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, //~ ERROR [E0798] } type WithReference = extern "cmse-nonsecure-call" fn(&usize); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr index 156568535763b..75da78b0b75a9 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/generics.stderr @@ -25,25 +25,49 @@ LL | struct Test { error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters --> $DIR/generics.rs:17:41 | -LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> u64, +LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, | ^^^^^^^^^ | = note: `impl Trait` is only allowed in arguments and return types of functions and methods -error[E0798]: function pointers with the `"cmse-nonsecure-call"` ABI cannot contain generics in their type - --> $DIR/generics.rs:19:9 +error[E0562]: `impl Trait` is not allowed in `fn` pointer return types + --> $DIR/generics.rs:17:70 | -LL | f3: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | f2: extern "cmse-nonsecure-call" fn(impl Copy, u32, u32, u32) -> impl Copy, + | ^^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0562]: `impl Trait` is not allowed in `fn` pointer parameters + --> $DIR/generics.rs:20:42 + | +LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), + | ^^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0562]: `impl Trait` is not allowed in `fn` pointer return types + --> $DIR/generics.rs:20:78 + | +LL | f3: extern "cmse-nonsecure-call" fn((impl Copy, u32), u32, u32, u32) -> (impl Copy, u32), + | ^^^^^^^^^ + | + = note: `impl Trait` is only allowed in arguments and return types of functions and methods + +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures + --> $DIR/generics.rs:23:41 + | +LL | f4: extern "cmse-nonsecure-call" fn(T, u32, u32, u32) -> u64, + | ^ -error[E0798]: function pointers with the `"cmse-nonsecure-call"` ABI cannot contain generics in their type - --> $DIR/generics.rs:20:9 +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-call"` signatures + --> $DIR/generics.rs:24:41 | -LL | f4: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | f5: extern "cmse-nonsecure-call" fn(Wrapper, u32, u32, u32) -> u64, + | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:26:71 + --> $DIR/generics.rs:30:71 | LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn Trait; | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -52,7 +76,7 @@ LL | type WithTraitObject = extern "cmse-nonsecure-call" fn(&dyn Trait) -> &dyn = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:30:60 + --> $DIR/generics.rs:34:60 | LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Trait; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -61,7 +85,7 @@ LL | extern "cmse-nonsecure-call" fn(&'static dyn Trait) -> &'static dyn Tra = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/generics.rs:37:60 + --> $DIR/generics.rs:41:60 | LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTransparent; | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -70,12 +94,12 @@ LL | extern "cmse-nonsecure-call" fn(WrapperTransparent) -> WrapperTranspare = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0045]: C-variadic functions with the "cmse-nonsecure-call" calling convention are not supported - --> $DIR/generics.rs:40:20 + --> $DIR/generics.rs:44:20 | LL | type WithVarArgs = extern "cmse-nonsecure-call" fn(u32, ...); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention -error: aborting due to 9 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0045, E0412, E0562, E0798. For more information about an error, try `rustc --explain E0045`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr index 5d59405fbd1b2..5a059e4df7b10 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/params-via-stack.stderr @@ -1,42 +1,44 @@ error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers - --> $DIR/params-via-stack.rs:16:61 + --> $DIR/params-via-stack.rs:16:64 | LL | f1: extern "cmse-nonsecure-call" fn(u32, u32, u32, u32, x: u32, y: u32), - | ^^^^^^^^^^^^^^ these arguments don't fit in the available registers + | ^^^ ^^^ does not fit in the available registers + | | + | does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers --> $DIR/params-via-stack.rs:17:61 | LL | f2: extern "cmse-nonsecure-call" fn(u32, u32, u32, u16, u16), - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers --> $DIR/params-via-stack.rs:18:51 | LL | f3: extern "cmse-nonsecure-call" fn(u32, u64, u32), - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers --> $DIR/params-via-stack.rs:19:56 | LL | f4: extern "cmse-nonsecure-call" fn(AlignRelevant, u32), - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-call"` function too large to pass via registers --> $DIR/params-via-stack.rs:20:41 | LL | f5: extern "cmse-nonsecure-call" fn([u32; 5]), - | ^^^^^^^^ this argument doesn't fit in the available registers + | ^^^^^^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-call"` ABI must pass all their arguments via the 4 32-bit argument registers error: aborting due to 5 previous errors diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs new file mode 100644 index 0000000000000..0a0dca804ef35 --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.rs @@ -0,0 +1,21 @@ +//@ add-core-stubs +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ incremental (required to trigger the bug) +//@ needs-llvm-components: arm +#![feature(abi_cmse_nonsecure_call, no_core)] +#![no_core] + +extern crate minicore; +use minicore::*; + +// A regression test for https://github.com/rust-lang/rust/issues/131639. +// NOTE: `-Cincremental` was required for triggering the bug. + +fn foo() { + id::(PhantomData); + //~^ ERROR use of undeclared lifetime name `'a` +} + +fn id(x: PhantomData) -> PhantomData { + x +} diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr new file mode 100644 index 0000000000000..7300bdb72cdda --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/undeclared-lifetime.stderr @@ -0,0 +1,19 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/undeclared-lifetime.rs:15:43 + | +LL | id::(PhantomData); + | ^^ undeclared lifetime + | + = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html +help: consider making the type lifetime-generic with a new `'a` lifetime + | +LL | id:: extern "cmse-nonsecure-call" fn(&'a ())>(PhantomData); + | +++++++ +help: consider introducing lifetime `'a` here + | +LL | fn foo<'a>() { + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs new file mode 100644 index 0000000000000..9317ab5cd2756 --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.rs @@ -0,0 +1,69 @@ +//@ add-core-stubs +//@ edition: 2018 +//@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib +//@ needs-llvm-components: arm +#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] +#![no_core] + +extern crate minicore; +use minicore::*; + +#[lang = "va_list"] +struct VaList(*mut u8); + +unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions +} + +// A regression test for https://github.com/rust-lang/rust/issues/132142 +async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions + //~| ERROR functions cannot be both `async` and C-variadic +} + +// Below are the lang items that are required for a program that defines an `async` function. +// Without them, the ICE that is tested for here is not reached for this target. For now they are in +// this file, but they may be moved into `minicore` if/when other `#[no_core]` tests want to use +// them. + +// NOTE: in `core` this type uses `NonNull`. +#[lang = "ResumeTy"] +pub struct ResumeTy(*mut Context<'static>); + +#[lang = "future_trait"] +pub trait Future { + /// The type of value produced on completion. + #[lang = "future_output"] + type Output; + + // NOTE: misses the `poll` method. +} + +#[lang = "async_drop"] +pub trait AsyncDrop { + // NOTE: misses the `drop` method. +} + +#[lang = "Poll"] +pub enum Poll { + #[lang = "Ready"] + Ready(T), + + #[lang = "Pending"] + Pending, +} + +#[lang = "Context"] +pub struct Context<'a> { + // NOTE: misses a bunch of fields. + _marker: PhantomData &'a ()>, +} + +#[lang = "get_context"] +pub unsafe fn get_context<'a, 'b>(cx: ResumeTy) -> &'a mut Context<'b> { + // NOTE: the actual implementation looks different. + mem::transmute(cx.0) +} + +#[lang = "pin"] +pub struct Pin(T); diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr new file mode 100644 index 0000000000000..948f8f5747b0e --- /dev/null +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/c-variadic.stderr @@ -0,0 +1,28 @@ +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions + --> $DIR/c-variadic.rs:14:60 + | +LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: functions cannot be both `async` and C-variadic + --> $DIR/c-variadic.rs:19:1 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + | ^^^^^ `async` because of this ^^^^^^ C-variadic because of this + +error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions + --> $DIR/c-variadic.rs:19:68 + | +LL | async unsafe extern "cmse-nonsecure-entry" fn async_and_c_variadic(_: ...) { + | ----------------------------- ^^^^^^ + | | + | `extern "cmse-nonsecure-entry"` because of this + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list + +error: aborting due to 3 previous errors + diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs index eb6f4a323655b..d01934929d97f 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.rs @@ -1,7 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm -#![feature(cmse_nonsecure_entry, c_variadic, no_core, lang_items)] +#![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] extern crate minicore; @@ -17,8 +17,8 @@ impl Wrapper { } extern "cmse-nonsecure-entry" fn ambient_generic_nested( - //~^ ERROR [E0798] _: Wrapper, + //~^ ERROR [E0798] _: u32, _: u32, _: u32, @@ -28,8 +28,8 @@ impl Wrapper { } extern "cmse-nonsecure-entry" fn introduced_generic( - //~^ ERROR [E0798] _: U, + //~^ ERROR [E0798] _: u32, _: u32, _: u32, @@ -37,11 +37,6 @@ extern "cmse-nonsecure-entry" fn introduced_generic( 0 } -extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { - //~^ ERROR [E0798] - 0 -} - extern "cmse-nonsecure-entry" fn reference(x: &usize) -> usize { *x } @@ -66,7 +61,31 @@ extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> x } -unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - //~^ ERROR `...` is not supported for `extern "cmse-nonsecure-entry"` functions - //~| ERROR requires `va_list` lang_item +extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { + //~^ ERROR [E0798] + 0 +} + +extern "cmse-nonsecure-entry" fn return_impl_trait() -> impl Copy { + //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + 0u128 +} + +extern "cmse-nonsecure-entry" fn return_impl_trait_nested() -> (impl Copy, i32) { + //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + (0u128, 0i32) +} + +extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { + //~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + //~| ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + v +} + +extern "cmse-nonsecure-entry" fn identity_impl_trait_nested( + v: (impl Copy, i32), + //~^ ERROR generics are not allowed in `extern "cmse-nonsecure-entry"` signatures +) -> (impl Copy, i32) { + //~^ ERROR `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + v } diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr index 8937def9428cf..5ddd29883f867 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/generics.stderr @@ -1,51 +1,53 @@ -error: `...` is not supported for `extern "cmse-nonsecure-entry"` functions - --> $DIR/generics.rs:69:60 +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:31:8 | -LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ----------------------------- ^^^^^^ - | | - | `extern "cmse-nonsecure-entry"` because of this +LL | _: U, + | ^ + +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:64:48 + | +LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { + | ^^^^^^^^^ + +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:79:57 | - = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list +LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { + | ^^^^^^^^^ -error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:30:1 - | -LL | / extern "cmse-nonsecure-entry" fn introduced_generic( -LL | | -LL | | _: U, -LL | | _: u32, -LL | | _: u32, -LL | | _: u32, -LL | | ) -> u64 { - | |________^ +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:79:71 + | +LL | extern "cmse-nonsecure-entry" fn identity_impl_trait(v: impl Copy) -> impl Copy { + | ^^^^^^^^^ -error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:40:1 +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:86:8 | -LL | extern "cmse-nonsecure-entry" fn impl_trait(_: impl Copy, _: u32, _: u32, _: u32) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | v: (impl Copy, i32), + | ^^^^^^^^^^^^^^^^ -error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:14:5 +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:88:6 + | +LL | ) -> (impl Copy, i32) { + | ^^^^^^^^^^^^^^^^ + +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:14:57 | LL | extern "cmse-nonsecure-entry" fn ambient_generic(_: T, _: u32, _: u32, _: u32) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ -error[E0798]: functions with the `"cmse-nonsecure-entry"` ABI cannot contain generics in their type - --> $DIR/generics.rs:19:5 - | -LL | / extern "cmse-nonsecure-entry" fn ambient_generic_nested( -LL | | -LL | | _: Wrapper, -LL | | _: u32, -LL | | _: u32, -LL | | _: u32, -LL | | ) -> u64 { - | |____________^ +error[E0798]: generics are not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:20:12 + | +LL | _: Wrapper, + | ^^^^^^^^^^ error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:51:65 + --> $DIR/generics.rs:46:65 | LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait { | ^^^^^^^^^^ this type doesn't fit in the available registers @@ -54,7 +56,7 @@ LL | extern "cmse-nonsecure-entry" fn trait_object(x: &dyn Trait) -> &dyn Trait = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:56:80 + --> $DIR/generics.rs:51:80 | LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) -> &'static dyn Trait { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -63,7 +65,7 @@ LL | extern "cmse-nonsecure-entry" fn static_trait_object(x: &'static dyn Trait) = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size error[E0798]: return value of `"cmse-nonsecure-entry"` function too large to pass via registers - --> $DIR/generics.rs:64:81 + --> $DIR/generics.rs:59:81 | LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent) -> WrapperTransparent { | ^^^^^^^^^^^^^^^^^^ this type doesn't fit in the available registers @@ -71,12 +73,18 @@ LL | extern "cmse-nonsecure-entry" fn wrapped_trait_object(x: WrapperTransparent = note: functions with the `"cmse-nonsecure-entry"` ABI must pass their result via the available return registers = note: the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size -error: requires `va_list` lang_item - --> $DIR/generics.rs:69:60 +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:69:57 + | +LL | extern "cmse-nonsecure-entry" fn return_impl_trait() -> impl Copy { + | ^^^^^^^^^ + +error[E0798]: `impl Trait` is not allowed in `extern "cmse-nonsecure-entry"` signatures + --> $DIR/generics.rs:74:64 | -LL | unsafe extern "cmse-nonsecure-entry" fn c_variadic(_: u32, _: ...) { - | ^^^^^^ +LL | extern "cmse-nonsecure-entry" fn return_impl_trait_nested() -> (impl Copy, i32) { + | ^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0798`. diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr index f8b96bddc9479..3d523fc7be679 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/params-via-stack.stderr @@ -2,41 +2,43 @@ error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass --> $DIR/params-via-stack.rs:15:76 | LL | pub extern "cmse-nonsecure-entry" fn f1(_: u32, _: u32, _: u32, _: u32, _: u32, _: u32) {} - | ^^^^^^^^^^^ these arguments don't fit in the available registers + | ^^^ ^^^ does not fit in the available registers + | | + | does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers --> $DIR/params-via-stack.rs:17:76 | LL | pub extern "cmse-nonsecure-entry" fn f2(_: u32, _: u32, _: u32, _: u16, _: u16) {} - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers --> $DIR/params-via-stack.rs:19:60 | LL | pub extern "cmse-nonsecure-entry" fn f3(_: u32, _: u64, _: u32) {} - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers --> $DIR/params-via-stack.rs:21:62 | LL | pub extern "cmse-nonsecure-entry" fn f4(_: AlignRelevant, _: u32) {} - | ^^^ this argument doesn't fit in the available registers + | ^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error[E0798]: arguments for `"cmse-nonsecure-entry"` function too large to pass via registers --> $DIR/params-via-stack.rs:25:44 | LL | pub extern "cmse-nonsecure-entry" fn f5(_: [u32; 5]) {} - | ^^^^^^^^ this argument doesn't fit in the available registers + | ^^^^^^^^ does not fit in the available registers | - = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit available argument registers + = note: functions with the `"cmse-nonsecure-entry"` ABI must pass all their arguments via the 4 32-bit argument registers error: aborting due to 5 previous errors diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr index 3949eac15429f..b817610d73b77 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.aarch64.stderr @@ -1,5 +1,5 @@ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:17:12 + --> $DIR/trustzone-only.rs:18:12 | LL | pub extern "cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs index ff5d2ec0ab6c2..aff632fa28799 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.rs @@ -7,6 +7,7 @@ //@[aarch64] needs-llvm-components: aarch64 //@[thumb7] compile-flags: --target thumbv7em-none-eabi //@[thumb7] needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(no_core, lang_items, rustc_attrs, cmse_nonsecure_entry)] #![no_core] diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr index 3949eac15429f..b817610d73b77 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.thumb7.stderr @@ -1,5 +1,5 @@ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:17:12 + --> $DIR/trustzone-only.rs:18:12 | LL | pub extern "cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr index 3949eac15429f..b817610d73b77 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/trustzone-only.x86.stderr @@ -1,5 +1,5 @@ error[E0570]: "cmse-nonsecure-entry" is not a supported ABI for the current target - --> $DIR/trustzone-only.rs:17:12 + --> $DIR/trustzone-only.rs:18:12 | LL | pub extern "cmse-nonsecure-entry" fn entry_function(input: u32) -> u32 { | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs index 3437328812561..cc7e2199ca91a 100644 --- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs +++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/via-registers.rs @@ -2,6 +2,7 @@ //@ build-pass //@ compile-flags: --target thumbv8m.main-none-eabi --crate-type lib //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![feature(cmse_nonsecure_entry, no_core, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/codegen/emscripten-llvm-crash-regression-66308.rs b/tests/ui/codegen/emscripten-llvm-crash-regression-66308.rs new file mode 100644 index 0000000000000..c18d6761e8872 --- /dev/null +++ b/tests/ui/codegen/emscripten-llvm-crash-regression-66308.rs @@ -0,0 +1,9 @@ +// https://github.com/rust-lang/rust/issues/66308 +//@ build-pass +//@ compile-flags: --crate-type lib -C opt-level=0 + +// Regression test for LLVM crash affecting Emscripten targets + +pub fn foo() { + (0..0).rev().next(); +} diff --git a/tests/ui/codegen/issue-82833-slice-miscompile.rs b/tests/ui/codegen/issue-82833-slice-miscompile.rs index 32eac923a6361..e0cb871662967 100644 --- a/tests/ui/codegen/issue-82833-slice-miscompile.rs +++ b/tests/ui/codegen/issue-82833-slice-miscompile.rs @@ -1,5 +1,6 @@ //@ run-pass //@ compile-flags: -Ccodegen-units=1 -Cllvm-args=--inline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2 +//@ ignore-backends: gcc // Make sure LLVM does not miscompile this. diff --git a/tests/ui/codegen/llvm-args-invalid-flag.rs b/tests/ui/codegen/llvm-args-invalid-flag.rs index a8fa55a220a58..f88a7101abda1 100644 --- a/tests/ui/codegen/llvm-args-invalid-flag.rs +++ b/tests/ui/codegen/llvm-args-invalid-flag.rs @@ -1,6 +1,7 @@ //@ compile-flags: -Cllvm-args=-not-a-real-llvm-arg //@ normalize-stderr: "--help" -> "-help" //@ normalize-stderr: "\n(\n|.)*" -> "" +//@ ignore-backends: gcc // I'm seeing "--help" locally, but "-help" in CI, so I'm normalizing it to just "-help". diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs index ea1457148a52c..bf866c3b1c9d0 100644 --- a/tests/ui/codegen/mismatched-data-layouts.rs +++ b/tests/ui/codegen/mismatched-data-layouts.rs @@ -6,6 +6,7 @@ //@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`" //@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`" //@ normalize-stderr: "`mismatched-data-layout-\d+`" -> "`mismatched-data-layout-`" +//@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs new file mode 100644 index 0000000000000..98bbfd4420dc6 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.rs @@ -0,0 +1,28 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 + +pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + if n > 15 { + encode_num(n / 16, &mut writer)?; + //~^ ERROR: reached the recursion limit while instantiating + } + Ok(()) +} + +pub trait ExampleWriter { + type Error; +} + +impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { + type Error = T::Error; +} + +struct Error; + +impl ExampleWriter for Error { + type Error = (); +} + +fn main() { + encode_num(69, &mut Error).unwrap(); +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr new file mode 100644 index 0000000000000..94fba4621d0a0 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105275.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Error>` + --> $DIR/recursion-issue-105275.rs:6:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-105275.rs:4:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs new file mode 100644 index 0000000000000..98bbfd4420dc6 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.rs @@ -0,0 +1,28 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 + +pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + if n > 15 { + encode_num(n / 16, &mut writer)?; + //~^ ERROR: reached the recursion limit while instantiating + } + Ok(()) +} + +pub trait ExampleWriter { + type Error; +} + +impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { + type Error = T::Error; +} + +struct Error; + +impl ExampleWriter for Error { + type Error = (); +} + +fn main() { + encode_num(69, &mut Error).unwrap(); +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr new file mode 100644 index 0000000000000..64f33d251d5f0 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-105937.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Error>` + --> $DIR/recursion-issue-105937.rs:6:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-105937.rs:4:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.rs new file mode 100644 index 0000000000000..2109afbd84237 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.rs @@ -0,0 +1,30 @@ +//@ build-fail +fn main() { + let mut it = (Empty); + rec(&mut it); +} + +struct Empty; + +impl Iterator for Empty { + type Item = (); + fn next<'a>(&'a mut self) -> core::option::Option<()> { + None + } +} + +fn identity(x: T) -> T { + x +} + +fn rec(mut it: T) +where + T: Iterator, +{ + if () == () { + T::count(it); + //~^ ERROR: reached the recursion limit while instantiating + } else { + rec(identity(&mut it)) + } +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.stderr new file mode 100644 index 0000000000000..b261530c010d5 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-1.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut Empty as Iterator>::count` + --> $DIR/recursion-issue-117696-1.rs:25:9 + | +LL | T::count(it); + | ^^^^^^^^^^^^ + | +note: `count` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs new file mode 100644 index 0000000000000..0236e799bcb8b --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.rs @@ -0,0 +1,14 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 +fn main() { + rec(&mut None::<()>.into_iter()); +} + +fn rec(mut it: T) { + if true { + it.next(); + } else { + rec(&mut it); + //~^ ERROR: reached the recursion limit while instantiating + } +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr new file mode 100644 index 0000000000000..88cfb8904d2c7 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-117696-2.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut std::option::IntoIter<()>>` + --> $DIR/recursion-issue-117696-2.rs:11:9 + | +LL | rec(&mut it); + | ^^^^^^^^^^^^ + | +note: `rec` defined here + --> $DIR/recursion-issue-117696-2.rs:7:1 + | +LL | fn rec(mut it: T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs new file mode 100644 index 0000000000000..dba23d9d0bdd9 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.rs @@ -0,0 +1,12 @@ +//@ build-fail + +fn main() { + recurse(std::iter::empty::<()>()) +} + +fn recurse(nums: impl Iterator) { + if true { return } + + recurse(nums.skip(42).peekable()) + //~^ ERROR: reached the recursion limit while instantiating +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr new file mode 100644 index 0000000000000..bf07c19f70479 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-118590.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-118590.rs:10:13 + | +LL | recurse(nums.skip(42).peekable()) + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs new file mode 100644 index 0000000000000..9df8e7f28386f --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.rs @@ -0,0 +1,70 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 +// ignore-tidy-linelength + +use std::vec::Vec; +use std::iter::Peekable; + +pub fn main() { + let packet = decode(vec![1,0,1,0]); +} + +pub fn decode(bitstream: Vec) -> Packet { + let mut bitstream_itr = bitstream.into_iter().peekable(); + return match decode_packet(&mut bitstream_itr) { + Some(p) => p, + None => panic!("expected outer packet"), + } +} + +pub fn decode_packets>(itr: &mut Peekable) -> Vec { + let mut res = Vec::new(); + loop { + match decode_packet(itr) { + Some(p) => { res.push(p); }, + None => break + } + } + + return res; +} + +pub fn decode_packet>(itr: &mut Peekable) -> Option { + // get version digits + let version = extend_number(0, itr, 3)?; + let type_id = extend_number(0, itr, 3)?; + return operator_packet(version, type_id, itr); +} + +pub fn operator_packet>(version: u64, type_id: u64, itr: &mut Peekable) -> Option { + let p = OperatorPacket { + version: version, + type_id: type_id, + packets: decode_packets(&mut itr.take(0).peekable()), + //~^ ERROR: reached the recursion limit while instantiating + }; + + return Some(Packet::Operator(p)); +} + +pub fn extend_number>(num: u64, itr: &mut Peekable, take: u64) -> Option { + let mut value = num; + for _ in 0..take { + value *= 2; + value += itr.next()?; + } + + return Some(value); +} + +#[derive(Debug)] +pub enum Packet { + Operator(OperatorPacket), +} + +#[derive(Debug)] +pub struct OperatorPacket { + version: u64, + type_id: u64, + packets: Vec +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr new file mode 100644 index 0000000000000..7102298bcc6fc --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-122823.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-122823.rs:43:38 + | +LL | packets: decode_packets(&mut itr.take(0).peekable()), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs new file mode 100644 index 0000000000000..55a2c0647c2f4 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.rs @@ -0,0 +1,16 @@ +//@ build-fail + +fn main() { + let mut items = vec![1, 2, 3, 4, 5].into_iter(); + problem_thingy(&mut items); +} + +fn problem_thingy(items: &mut impl Iterator) { + let mut peeker = items.peekable(); + //~^ ERROR: reached the recursion limit while instantiating + match peeker.peek() { + Some(_) => (), + None => return (), + } + problem_thingy(&mut peeker); +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr new file mode 100644 index 0000000000000..fa313be0b8142 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-131342.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut Peekable<&mut std::vec::IntoIter>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-131342.rs:9:22 + | +LL | let mut peeker = items.peekable(); + | ^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs new file mode 100644 index 0000000000000..30f97dba6ee58 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.rs @@ -0,0 +1,30 @@ +//@ build-fail +//@compile-flags: -Cdebuginfo=2 -Copt-level=0 --crate-type lib +//~^^ ERROR: reached the recursion limit while instantiating +trait Trait { + type Output; +} + +impl O> Trait for F { + type Output = O; +} + +struct Wrap

(P); +struct WrapOutput(O); + +impl Trait for Wrap

{ + type Output = WrapOutput; +} + +fn wrap(x: P) -> impl Trait { + Wrap(x) +} + +fn consume(_: P) -> P::Output { + unimplemented!() +} + +pub fn recurse() -> impl Sized { + consume(wrap(recurse)) +} +pub fn main() {} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr new file mode 100644 index 0000000000000..5e1e4fe18f842 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-139659.stderr @@ -0,0 +1,10 @@ +error: reached the recursion limit while instantiating `recurse` + | +note: `recurse` defined here + --> $DIR/recursion-issue-139659.rs:27:1 + | +LL | pub fn recurse() -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs new file mode 100644 index 0000000000000..949359cfa4238 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.rs @@ -0,0 +1,71 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 +//@ edition:2021 +// ignore-tidy-linelength + +use std::vec::Vec; +use std::iter::Peekable; + +pub fn main() { + let packet = decode(vec![1,0,1,0]); +} + +pub fn decode(bitstream: Vec) -> Packet { + let mut bitstream_itr = bitstream.into_iter().peekable(); + return match decode_packet(&mut bitstream_itr) { + Some(p) => p, + None => panic!("expected outer packet"), + } +} + +pub fn decode_packets>(itr: &mut Peekable) -> Vec { + let mut res = Vec::new(); + loop { + match decode_packet(itr) { + Some(p) => { res.push(p); }, + None => break + } + } + + return res; +} + +pub fn decode_packet>(itr: &mut Peekable) -> Option { + // get version digits + let version = extend_number(0, itr, 3)?; + let type_id = extend_number(0, itr, 3)?; + return operator_packet(version, type_id, itr); +} + +pub fn operator_packet>(version: u64, type_id: u64, itr: &mut Peekable) -> Option { + let p = OperatorPacket { + version: version, + type_id: type_id, + packets: decode_packets(&mut itr.take(0).peekable()), + //~^ ERROR: reached the recursion limit while instantiating + }; + + return Some(Packet::Operator(p)); +} + +pub fn extend_number>(num: u64, itr: &mut Peekable, take: u64) -> Option { + let mut value = num; + for _ in 0..take { + value *= 2; + value += itr.next()?; + } + + return Some(value); +} + +#[derive(Debug)] +pub enum Packet { + Operator(OperatorPacket), +} + +#[derive(Debug)] +pub struct OperatorPacket { + version: u64, + type_id: u64, + packets: Vec +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr new file mode 100644 index 0000000000000..e6f14b995a82e --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92004.stderr @@ -0,0 +1,11 @@ +error: reached the recursion limit while instantiating `>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> as Iterator>::peekable` + --> $DIR/recursion-issue-92004.rs:44:38 + | +LL | packets: decode_packets(&mut itr.take(0).peekable()), + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: `peekable` defined here + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs new file mode 100644 index 0000000000000..cd024d75897e1 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.rs @@ -0,0 +1,33 @@ +//@ build-fail +fn main() { + encode(&mut EncoderImpl); +} + +pub trait Encoder { + type W; + + fn writer(&self) -> Self::W; +} + +fn encode(mut encoder: E) { +//~^ WARN: function cannot return without recursing + encoder.writer(); + encode(&mut encoder); + //~^ ERROR: reached the recursion limit while instantiating +} + +struct EncoderImpl; + +impl Encoder for EncoderImpl { + type W = (); + + fn writer(&self) {} +} + +impl<'a, T: Encoder> Encoder for &'a mut T { + type W = T::W; + + fn writer(&self) -> Self::W { + panic!() + } +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr new file mode 100644 index 0000000000000..1775a99928853 --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-92470.stderr @@ -0,0 +1,26 @@ +warning: function cannot return without recursing + --> $DIR/recursion-issue-92470.rs:12:1 + | +LL | fn encode(mut encoder: E) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +... +LL | encode(&mut encoder); + | -------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error: reached the recursion limit while instantiating `encode::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut EncoderImpl>` + --> $DIR/recursion-issue-92470.rs:15:5 + | +LL | encode(&mut encoder); + | ^^^^^^^^^^^^^^^^^^^^ + | +note: `encode` defined here + --> $DIR/recursion-issue-92470.rs:12:1 + | +LL | fn encode(mut encoder: E) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs new file mode 100644 index 0000000000000..bbeeeeda6090a --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.rs @@ -0,0 +1,28 @@ +//@ build-fail +//@ compile-flags: -Copt-level=0 + +pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + if n > 15 { + encode_num(n / 16, &mut writer)?; + //~^ ERROR: reached the recursion limit while instantiating + } + Ok(()) +} + +pub trait ExampleWriter { + type Error; +} + +impl<'a, T: ExampleWriter> ExampleWriter for &'a mut T { + type Error = T::Error; +} + +struct EmptyWriter; + +impl ExampleWriter for EmptyWriter { + type Error = (); +} + +fn main() { + encode_num(69, &mut EmptyWriter).unwrap(); +} diff --git a/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr new file mode 100644 index 0000000000000..0c49e0010f54c --- /dev/null +++ b/tests/ui/codegen/normalization-overflow/recursion-issue-95134.stderr @@ -0,0 +1,14 @@ +error: reached the recursion limit while instantiating `encode_num::<&mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut &mut EmptyWriter>` + --> $DIR/recursion-issue-95134.rs:6:9 + | +LL | encode_num(n / 16, &mut writer)?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: `encode_num` defined here + --> $DIR/recursion-issue-95134.rs:4:1 + | +LL | pub fn encode_num(n: u32, mut writer: Writer) -> Result<(), Writer::Error> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/codegen/remark-flag-functionality.rs b/tests/ui/codegen/remark-flag-functionality.rs index 797c55ba830c1..4cfc5f5c8ec19 100644 --- a/tests/ui/codegen/remark-flag-functionality.rs +++ b/tests/ui/codegen/remark-flag-functionality.rs @@ -17,6 +17,7 @@ //@ dont-check-compiler-stderr //@ dont-require-annotations: NOTE +//@ ignore-backends: gcc #[no_mangle] #[inline(never)] diff --git a/tests/ui/codegen/target-cpus.rs b/tests/ui/codegen/target-cpus.rs index f26203171f330..8fa06a8ecfe1a 100644 --- a/tests/ui/codegen/target-cpus.rs +++ b/tests/ui/codegen/target-cpus.rs @@ -7,3 +7,4 @@ // versions currently used by default. // FIXME(#133919): Once Rust upgrades to LLVM 20, remove this. //@ normalize-stdout: "(?m)^ *lime1\n" -> "" +//@ ignore-backends: gcc diff --git a/tests/ui/codegen/virtual-function-elimination.rs b/tests/ui/codegen/virtual-function-elimination.rs index 3cbeb1293e50a..90fc86f95c5c6 100644 --- a/tests/ui/codegen/virtual-function-elimination.rs +++ b/tests/ui/codegen/virtual-function-elimination.rs @@ -2,6 +2,7 @@ //@ compile-flags: -Zvirtual-function-elimination=true -Clto=true //@ only-x86_64 //@ no-prefer-dynamic +//@ ignore-backends: gcc // issue #123955 pub fn test0() { diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg index 1cedbf75e4bf6..9a7d10f6d6d37 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg +++ b/tests/ui/codemap_tests/huge_multispan_highlight.ascii.svg @@ -1,9 +1,9 @@ - + , U: ?Sized> CoerceUnsized> for X<'a, T> where + &'a T: CoerceUnsized<&'a U> +{ +} + +const Y: X<'static, i32> = X { f: &0 }; + +fn main() { + let _: [X<'static, dyn Display>; 0] = [Y; 0]; + coercion_on_weak_in_const(); + coercion_on_weak_as_cast(); +} + +fn coercion_on_weak_in_const() { + const X: Weak = Weak::new(); + const Y: [Weak; 0] = [X; 0]; + let _ = Y; +} + +fn coercion_on_weak_as_cast() { + const Y: X<'static, i32> = X { f: &0 }; + // What happens in the following code is that + // a constant is explicitly coerced into + let _a: [X<'static, dyn Display>; 0] = [Y as X<'static, dyn Display>; 0]; +} diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr index 22673cef64079..c92854b92f9d3 100644 --- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr +++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr @@ -12,7 +12,7 @@ LL | impl Trait for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>` | = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>` - = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<_>` + = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box< as WithAssoc<'a>>::Assoc>` error: aborting due to 1 previous error diff --git a/tests/ui/command/command-current-dir.rs b/tests/ui/command/command-current-dir.rs index e264cbe4d7045..a6b51df5f176c 100644 --- a/tests/ui/command/command-current-dir.rs +++ b/tests/ui/command/command-current-dir.rs @@ -2,6 +2,8 @@ //@ no-prefer-dynamic We move the binary around, so do not depend dynamically on libstd //@ needs-subprocess //@ ignore-fuchsia Needs directory creation privilege +//@ ignore-tvos `Command::current_dir` requires fork, which is prohibited +//@ ignore-watchos `Command::current_dir` requires fork, which is prohibited use std::env; use std::fs; diff --git a/tests/ui/command/command-exec.rs b/tests/ui/command/command-exec.rs index 77336377e8899..870f8b047b9a2 100644 --- a/tests/ui/command/command-exec.rs +++ b/tests/ui/command/command-exec.rs @@ -3,6 +3,8 @@ //@ only-unix (this is a unix-specific test) //@ needs-subprocess //@ ignore-fuchsia no execvp syscall provided +//@ ignore-tvos execvp is prohibited +//@ ignore-watchos execvp is prohibited use std::env; use std::os::unix::process::CommandExt; diff --git a/tests/ui/command/command-pre-exec.rs b/tests/ui/command/command-pre-exec.rs index 7299f357bd078..a62ab0b5ed6a7 100644 --- a/tests/ui/command/command-pre-exec.rs +++ b/tests/ui/command/command-pre-exec.rs @@ -2,6 +2,8 @@ //@ only-unix (this is a unix-specific test) //@ needs-subprocess //@ ignore-fuchsia no execvp syscall +//@ ignore-tvos execvp is prohibited +//@ ignore-watchos execvp is prohibited #![feature(rustc_private)] diff --git a/tests/ui/command/command-uid-gid.rs b/tests/ui/command/command-uid-gid.rs index f54a0f50708ba..ef0653eb2cb4e 100644 --- a/tests/ui/command/command-uid-gid.rs +++ b/tests/ui/command/command-uid-gid.rs @@ -1,6 +1,8 @@ //@ run-pass //@ ignore-android //@ ignore-fuchsia no '/bin/sh', '/bin/ls' +//@ ignore-tvos `Command::uid/gid` requires fork, which is prohibited +//@ ignore-watchos `Command::uid/gid` requires fork, which is prohibited //@ needs-subprocess #![feature(rustc_private)] diff --git a/tests/ui/compiletest-self-test/compile-flags-incremental.rs b/tests/ui/compiletest-self-test/compile-flags-incremental.rs new file mode 100644 index 0000000000000..62a1ad84d8f7d --- /dev/null +++ b/tests/ui/compiletest-self-test/compile-flags-incremental.rs @@ -0,0 +1,17 @@ +//@ revisions: good bad bad-space +//@ check-pass + +//@[bad] compile-flags: -Cincremental=true +//@[bad] should-fail + +//@[bad-space] compile-flags: -C incremental=dir +//@[bad-space] should-fail + +fn main() {} + +// Tests should not try to manually enable incremental compilation with +// `-Cincremental`, because that typically results in stray directories being +// created in the repository root. +// +// Instead, use the `//@ incremental` directive, which instructs compiletest +// to handle the details of passing `-Cincremental` with a fresh directory. diff --git a/tests/ui/compiletest-self-test/test-aux-bin.rs b/tests/ui/compiletest-self-test/test-aux-bin.rs index c1c28e12b3b5a..9ac17e6e14619 100644 --- a/tests/ui/compiletest-self-test/test-aux-bin.rs +++ b/tests/ui/compiletest-self-test/test-aux-bin.rs @@ -1,4 +1,5 @@ //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ aux-bin: print-it-works.rs //@ run-pass diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.rs b/tests/ui/conditional-compilation/cfg-attr-parse.rs index 8ca31c118369c..b8aaad2685ef6 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.rs +++ b/tests/ui/conditional-compilation/cfg-attr-parse.rs @@ -9,7 +9,8 @@ struct NoConfigurationPredicate; struct A0C0; // Zero attributes, one trailing comma -#[cfg_attr(all(),)] // Ok +#[cfg_attr(all(),)] +//~^ WARN `#[cfg_attr]` does not expand to any attributes struct A0C1; // Zero attributes, two trailing commas diff --git a/tests/ui/conditional-compilation/cfg-attr-parse.stderr b/tests/ui/conditional-compilation/cfg-attr-parse.stderr index 76f199caace37..4d4769b05cdaf 100644 --- a/tests/ui/conditional-compilation/cfg-attr-parse.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-parse.stderr @@ -1,53 +1,60 @@ -error: malformed `cfg_attr` attribute input +error[E0539]: malformed `cfg_attr` attribute input --> $DIR/cfg-attr-parse.rs:4:1 | LL | #[cfg_attr()] - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^--^ + | | | + | | expected at least 1 argument here + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit -help: missing condition and attribute - | -LL | #[cfg_attr(condition, attribute, other_attribute, ...)] - | ++++++++++++++++++++++++++++++++++++++++++ error: expected `,`, found end of `cfg_attr` input --> $DIR/cfg-attr-parse.rs:8:17 | LL | #[cfg_attr(all())] - | ^ expected `,` + | ----------------^- + | | | + | | expected `,` + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:16:18 + --> $DIR/cfg-attr-parse.rs:17:18 | LL | #[cfg_attr(all(),,)] - | ^ expected identifier + | -----------------^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:28:28 + --> $DIR/cfg-attr-parse.rs:29:28 | LL | #[cfg_attr(all(), must_use,,)] - | ^ expected identifier + | ---------------------------^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:40:40 + --> $DIR/cfg-attr-parse.rs:41:40 | LL | #[cfg_attr(all(), must_use, deprecated,,)] - | ^ expected identifier + | ---------------------------------------^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: wrong `cfg_attr` delimiters - --> $DIR/cfg-attr-parse.rs:44:11 + --> $DIR/cfg-attr-parse.rs:45:11 | LL | #[cfg_attr[all(),,]] | ^^^^^^^^^ @@ -59,16 +66,18 @@ LL + #[cfg_attr(all(),,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:44:18 + --> $DIR/cfg-attr-parse.rs:45:18 | LL | #[cfg_attr[all(),,]] - | ^ expected identifier + | -----------------^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: wrong `cfg_attr` delimiters - --> $DIR/cfg-attr-parse.rs:50:11 + --> $DIR/cfg-attr-parse.rs:51:11 | LL | #[cfg_attr{all(),,}] | ^^^^^^^^^ @@ -80,13 +89,24 @@ LL + #[cfg_attr(all(),,)] | error: expected identifier, found `,` - --> $DIR/cfg-attr-parse.rs:50:18 + --> $DIR/cfg-attr-parse.rs:51:18 | LL | #[cfg_attr{all(),,}] - | ^ expected identifier + | -----------------^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit -error: aborting due to 9 previous errors +warning: `#[cfg_attr]` does not expand to any attributes + --> $DIR/cfg-attr-parse.rs:12:1 + | +LL | #[cfg_attr(all(),)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` + +error: aborting due to 9 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs index 2c84a966f904d..7d4fd206c6b52 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.rs @@ -22,10 +22,16 @@ struct S3; //~| NOTE for more information, visit struct S4; -#[cfg("str")] //~ ERROR `cfg` predicate key must be an identifier +#[cfg("str")] +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit struct S5; -#[cfg(a::b)] //~ ERROR `cfg` predicate key must be an identifier +#[cfg(a::b)] +//~^ ERROR malformed `cfg` attribute input +//~| NOTE expected a valid identifier here +//~| NOTE for more information, visit struct S6; #[cfg(a())] //~ ERROR invalid predicate `a` diff --git a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr index 59ff611e0661e..e73b20f2d5d31 100644 --- a/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr +++ b/tests/ui/conditional-compilation/cfg-attr-syntax-validation.stderr @@ -42,26 +42,36 @@ LL | #[cfg(a, b)] | = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-attr-syntax-validation.rs:25:7 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-attr-syntax-validation.rs:25:1 | LL | #[cfg("str")] - | ^^^^^ + | ^^^^^^-----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit -error: `cfg` predicate key must be an identifier - --> $DIR/cfg-attr-syntax-validation.rs:28:7 +error[E0539]: malformed `cfg` attribute input + --> $DIR/cfg-attr-syntax-validation.rs:31:1 | LL | #[cfg(a::b)] - | ^^^^ + | ^^^^^^----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg(predicate)]` + | + = note: for more information, visit error[E0537]: invalid predicate `a` - --> $DIR/cfg-attr-syntax-validation.rs:31:7 + --> $DIR/cfg-attr-syntax-validation.rs:37:7 | LL | #[cfg(a())] | ^^^ error[E0539]: malformed `cfg` attribute input - --> $DIR/cfg-attr-syntax-validation.rs:34:1 + --> $DIR/cfg-attr-syntax-validation.rs:40:1 | LL | #[cfg(a = 10)] | ^^^^^^^^^^--^^ @@ -72,7 +82,7 @@ LL | #[cfg(a = 10)] = note: for more information, visit error[E0539]: malformed `cfg` attribute input - --> $DIR/cfg-attr-syntax-validation.rs:39:1 + --> $DIR/cfg-attr-syntax-validation.rs:45:1 | LL | #[cfg(a = b"hi")] | ^^^^^^^^^^-^^^^^^ @@ -82,7 +92,7 @@ LL | #[cfg(a = b"hi")] = note: expected a normal string literal, not a byte string literal error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable - --> $DIR/cfg-attr-syntax-validation.rs:45:25 + --> $DIR/cfg-attr-syntax-validation.rs:51:25 | LL | #[cfg(feature = $expr)] | ^^^^^ diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs new file mode 100644 index 0000000000000..a0f86e3e771fd --- /dev/null +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.rs @@ -0,0 +1,52 @@ +#[cfg_attr] +//~^ ERROR malformed `cfg_attr` attribute +struct S1; + +#[cfg_attr = 10] +//~^ ERROR malformed `cfg_attr` attribute +struct S2; + +#[cfg_attr()] +//~^ ERROR malformed `cfg_attr` attribute +struct S3; + +#[cfg_attr("str")] //~ ERROR malformed `cfg_attr` attribute input +struct S5; + +#[cfg_attr(a::b)] //~ ERROR malformed `cfg_attr` attribute input +struct S6; + +#[cfg_attr(a())] //~ ERROR invalid predicate `a` +struct S7; + +#[cfg_attr(a = 10)] //~ ERROR malformed `cfg_attr` attribute input +struct S8; + +#[cfg_attr(a = b"hi")] //~ ERROR malformed `cfg_attr` attribute input +struct S9; + +macro_rules! generate_s10 { + ($expr: expr) => { + #[cfg_attr(feature = $expr)] + //~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable + struct S10; + } +} + +generate_s10!(concat!("nonexistent")); + +#[cfg_attr(true)] //~ ERROR expected `,`, found end of `cfg_attr` input +struct S11; + +#[cfg_attr(true, unknown_attribute)] //~ ERROR cannot find attribute `unknown_attribute` in this scope +struct S12; + +#[cfg_attr(true, link_section)] //~ ERROR malformed `link_section` attribute input +//~^ WARN attribute cannot be used on +//~| WARN previously accepted +struct S13; + +#[cfg_attr(true, inline())] //~ ERROR malformed `inline` attribute input +fn f1() {} + +fn main() {} diff --git a/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr new file mode 100644 index 0000000000000..2b7a7da3e33da --- /dev/null +++ b/tests/ui/conditional-compilation/cfg_attr-attr-syntax-validation.stderr @@ -0,0 +1,154 @@ +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:1:1 + | +LL | #[cfg_attr] + | ^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:5:1 + | +LL | #[cfg_attr = 10] + | ^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:9:1 + | +LL | #[cfg_attr()] + | ^^^^^^^^^^--^ + | | | + | | expected at least 1 argument here + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:13:1 + | +LL | #[cfg_attr("str")] + | ^^^^^^^^^^^-----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:16:1 + | +LL | #[cfg_attr(a::b)] + | ^^^^^^^^^^^----^^ + | | | + | | expected a valid identifier here + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0537]: invalid predicate `a` + --> $DIR/cfg_attr-attr-syntax-validation.rs:19:12 + | +LL | #[cfg_attr(a())] + | ^^^ + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:22:1 + | +LL | #[cfg_attr(a = 10)] + | ^^^^^^^^^^^^^^^--^^ + | | | + | | expected a string literal here + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error[E0539]: malformed `cfg_attr` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:25:1 + | +LL | #[cfg_attr(a = b"hi")] + | ^^^^^^^^^^^^^^^-^^^^^^ + | | + | help: consider removing the prefix + | + = note: expected a normal string literal, not a byte string literal + +error: expected `,`, found end of `cfg_attr` input + --> $DIR/cfg_attr-attr-syntax-validation.rs:38:16 + | +LL | #[cfg_attr(true)] + | ---------------^- + | | | + | | expected `,` + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` + | + = note: for more information, visit + +error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable + --> $DIR/cfg_attr-attr-syntax-validation.rs:30:30 + | +LL | #[cfg_attr(feature = $expr)] + | ---------------------^^^^^-- help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` +... +LL | generate_s10!(concat!("nonexistent")); + | ------------------------------------- in this macro invocation + | + = note: for more information, visit + = note: this error originates in the macro `generate_s10` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: cannot find attribute `unknown_attribute` in this scope + --> $DIR/cfg_attr-attr-syntax-validation.rs:41:18 + | +LL | #[cfg_attr(true, unknown_attribute)] + | ^^^^^^^^^^^^^^^^^ + +error[E0539]: malformed `link_section` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:44:18 + | +LL | #[cfg_attr(true, link_section)] + | ^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` + | + = note: for more information, visit + +error[E0805]: malformed `inline` attribute input + --> $DIR/cfg_attr-attr-syntax-validation.rs:49:18 + | +LL | #[cfg_attr(true, inline())] + | ^^^^^^-- + | | + | expected a single argument here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[cfg_attr(true, inline())] +LL + #[cfg_attr(true, #[inline(always)])] + | +LL - #[cfg_attr(true, inline())] +LL + #[cfg_attr(true, #[inline(never)])] + | +LL - #[cfg_attr(true, inline())] +LL + #[cfg_attr(true, #[inline])] + | + +warning: `#[link_section]` attribute cannot be used on structs + --> $DIR/cfg_attr-attr-syntax-validation.rs:44:18 + | +LL | #[cfg_attr(true, link_section)] + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[link_section]` can be applied to functions and statics + = note: requested on the command line with `-W unused-attributes` + +error: aborting due to 13 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0537, E0539, E0805. +For more information about an error, try `rustc --explain E0537`. diff --git a/tests/ui/const-generics/adt_const_params/auxiliary/unsized_const_param.rs b/tests/ui/const-generics/adt_const_params/auxiliary/unsized_const_param.rs index e2ba459f8dd33..1bfd7c3465613 100644 --- a/tests/ui/const-generics/adt_const_params/auxiliary/unsized_const_param.rs +++ b/tests/ui/const-generics/adt_const_params/auxiliary/unsized_const_param.rs @@ -1,6 +1,6 @@ #![feature(adt_const_params, unsized_const_params)] -#[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)] +#[derive(std::marker::ConstParamTy, Eq, PartialEq)] pub struct Foo([u8]); #[derive(std::marker::ConstParamTy, Eq, PartialEq)] diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs index 35539193a2787..d482e7fad06d2 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.rs @@ -1,7 +1,7 @@ #![allow(incomplete_features)] #![feature(adt_const_params, unsized_const_params)] -fn check(_: impl std::marker::UnsizedConstParamTy) {} +fn check(_: impl std::marker::ConstParamTy_) {} fn main() { check(main); //~ error: `fn() {main}` can't be used as a const parameter type diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index c05584ef909ac..ff514f5608f19 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -2,15 +2,15 @@ error[E0277]: `fn() {main}` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:7:11 | LL | check(main); - | ----- ^^^^ the trait `UnsizedConstParamTy` is not implemented for fn item `fn() {main}` + | ----- ^^^^ the trait `ConstParamTy_` is not implemented for fn item `fn() {main}` | | | required by a bound introduced by this call | note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` help: use parentheses to call this function | LL | check(main()); @@ -24,12 +24,12 @@ LL | check(|| {}); | | | required by a bound introduced by this call | - = help: the trait `UnsizedConstParamTy` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` + = help: the trait `ConstParamTy_` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` help: use parentheses to call this closure | LL - check(|| {}); @@ -40,15 +40,15 @@ error[E0277]: `fn()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:9:11 | LL | check(main as fn()); - | ----- ^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `fn()` + | ----- ^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `fn()` | | | required by a bound introduced by this call | note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` help: use parentheses to call this function pointer | LL | check(main as fn()()); @@ -58,16 +58,16 @@ error[E0277]: `&mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:10:11 | LL | check(&mut ()); - | ----- ^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `&mut ()` + | ----- ^^^^^^^ the trait `ConstParamTy_` is not implemented for `&mut ()` | | | required by a bound introduced by this call | - = note: `UnsizedConstParamTy` is implemented for `&()`, but not for `&mut ()` + = note: `ConstParamTy_` is implemented for `&()`, but not for `&mut ()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` help: consider removing the leading `&`-reference | LL - check(&mut ()); @@ -78,31 +78,31 @@ error[E0277]: `*mut ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:11:11 | LL | check(&mut () as *mut ()); - | ----- ^^^^^^^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `*mut ()` + | ----- ^^^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*mut ()` | | | required by a bound introduced by this call | - = help: the trait `UnsizedConstParamTy` is implemented for `()` + = help: the trait `ConstParamTy_` is implemented for `()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: `*const ()` can't be used as a const parameter type --> $DIR/const_param_ty_bad.rs:12:11 | LL | check(&() as *const ()); - | ----- ^^^^^^^^^^^^^^^^ the trait `UnsizedConstParamTy` is not implemented for `*const ()` + | ----- ^^^^^^^^^^^^^^^^ the trait `ConstParamTy_` is not implemented for `*const ()` | | | required by a bound introduced by this call | - = help: the trait `UnsizedConstParamTy` is implemented for `()` + = help: the trait `ConstParamTy_` is implemented for `()` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | -LL | fn check(_: impl std::marker::UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check(_: impl std::marker::ConstParamTy_) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` error: aborting due to 6 previous errors diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.rs index 6a553c2e08540..2fcf872c99aaf 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.rs @@ -1,12 +1,9 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::{ConstParamTy_, UnsizedConstParamTy}; +use std::marker::ConstParamTy_; fn foo(a: &dyn ConstParamTy_) {} //~^ ERROR: the trait `ConstParamTy_` -fn bar(a: &dyn UnsizedConstParamTy) {} -//~^ ERROR: the trait `UnsizedConstParamTy` - fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr index c71ec24dda330..ce695ff66d58c 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_dyn_compatibility.stderr @@ -15,23 +15,6 @@ LL - fn foo(a: &dyn ConstParamTy_) {} LL + fn foo(a: &impl ConstParamTy_) {} | -error[E0038]: the trait `UnsizedConstParamTy` is not dyn compatible - --> $DIR/const_param_ty_dyn_compatibility.rs:9:16 - | -LL | fn bar(a: &dyn UnsizedConstParamTy) {} - | ^^^^^^^^^^^^^^^^^^^ `UnsizedConstParamTy` is not dyn compatible - | -note: for a trait to be dyn compatible it needs to allow building a vtable - for more information, visit - --> $SRC_DIR/core/src/cmp.rs:LL:COL - | - = note: the trait is not dyn compatible because it uses `Self` as a type parameter -help: consider using an opaque type instead - | -LL - fn bar(a: &dyn UnsizedConstParamTy) {} -LL + fn bar(a: &impl UnsizedConstParamTy) {} - | - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs index 7ffdafa33e938..a86d74275de8a 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.rs @@ -4,7 +4,7 @@ #[derive(PartialEq, Eq)] struct NotParam; -fn check() {} +fn check() {} fn main() { check::<&NotParam>(); //~ error: `NotParam` can't be used as a const parameter type diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr index 158e76630f3a3..ca2aa3adcb7a6 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_generic_bounds_do_not_hold.stderr @@ -4,17 +4,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<&NotParam>(); | ^^^^^^^^^ unsatisfied trait bound | -help: the trait `UnsizedConstParamTy` is not implemented for `NotParam` +help: the trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; | ^^^^^^^^^^^^^^^ - = note: required for `&NotParam` to implement `UnsizedConstParamTy` + = note: required for `&NotParam` to implement `ConstParamTy_` note: required by a bound in `check` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 | -LL | fn check() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: `NotParam` can't be used as a const parameter type --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:11:13 @@ -22,17 +22,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<[NotParam]>(); | ^^^^^^^^^^ unsatisfied trait bound | -help: the trait `UnsizedConstParamTy` is not implemented for `NotParam` +help: the trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; | ^^^^^^^^^^^^^^^ - = note: required for `[NotParam]` to implement `UnsizedConstParamTy` + = note: required for `[NotParam]` to implement `ConstParamTy_` note: required by a bound in `check` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 | -LL | fn check() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: `NotParam` can't be used as a const parameter type --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:12:13 @@ -40,17 +40,17 @@ error[E0277]: `NotParam` can't be used as a const parameter type LL | check::<[NotParam; 17]>(); | ^^^^^^^^^^^^^^ unsatisfied trait bound | -help: the trait `UnsizedConstParamTy` is not implemented for `NotParam` +help: the trait `ConstParamTy_` is not implemented for `NotParam` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:5:1 | LL | struct NotParam; | ^^^^^^^^^^^^^^^ - = note: required for `[NotParam; 17]` to implement `UnsizedConstParamTy` + = note: required for `[NotParam; 17]` to implement `ConstParamTy_` note: required by a bound in `check` --> $DIR/const_param_ty_generic_bounds_do_not_hold.rs:7:13 | -LL | fn check() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` +LL | fn check() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check` error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs index 98a8eb6ee950d..24bbc5a9a2389 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -3,7 +3,7 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::UnsizedConstParamTy; +use std::marker::{ConstParamTy, ConstParamTy_}; #[derive(PartialEq, Eq)] struct S { @@ -11,15 +11,15 @@ struct S { gen: T, } -impl UnsizedConstParamTy for S {} +impl ConstParamTy_ for S {} -#[derive(PartialEq, Eq, UnsizedConstParamTy)] +#[derive(PartialEq, Eq, ConstParamTy)] struct D { field: u8, gen: T, } -fn check() {} +fn check() {} fn main() { check::(); diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs index 8b3d0546010dc..0614ea97b1add 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -7,10 +7,10 @@ struct NotParam; #[derive(PartialEq, Eq)] struct CantParam(NotParam); -impl std::marker::UnsizedConstParamTy for CantParam {} +impl std::marker::ConstParamTy_ for CantParam {} //~^ error: the trait `ConstParamTy_` cannot be implemented for this type -#[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)] +#[derive(std::marker::ConstParamTy, Eq, PartialEq)] //~^ error: the trait `ConstParamTy_` cannot be implemented for this type struct CantParamDerive(NotParam); diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr index a4e5736d83429..fd1836802c4ae 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -1,17 +1,17 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/const_param_ty_impl_bad_field.rs:10:43 + --> $DIR/const_param_ty_impl_bad_field.rs:10:37 | LL | struct CantParam(NotParam); | -------- this field does not implement `ConstParamTy_` LL | -LL | impl std::marker::UnsizedConstParamTy for CantParam {} - | ^^^^^^^^^ +LL | impl std::marker::ConstParamTy_ for CantParam {} + | ^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type --> $DIR/const_param_ty_impl_bad_field.rs:13:10 | -LL | #[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ LL | LL | struct CantParamDerive(NotParam); | -------- this field does not implement `ConstParamTy_` diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index e743b78fd134b..a1c8eccfb095f 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -3,20 +3,20 @@ #[derive(PartialEq, Eq)] struct ImplementsConstParamTy; -impl std::marker::UnsizedConstParamTy for ImplementsConstParamTy {} +impl std::marker::ConstParamTy_ for ImplementsConstParamTy {} struct CantParam(ImplementsConstParamTy); -impl std::marker::UnsizedConstParamTy for CantParam {} +impl std::marker::ConstParamTy_ for CantParam {} //~^ error: the type `CantParam` does not `#[derive(PartialEq)]` //~| ERROR the trait bound `CantParam: Eq` is not satisfied -#[derive(std::marker::UnsizedConstParamTy)] +#[derive(std::marker::ConstParamTy)] //~^ error: the type `CantParamDerive` does not `#[derive(PartialEq)]` //~| ERROR the trait bound `CantParamDerive: Eq` is not satisfied struct CantParamDerive(ImplementsConstParamTy); -fn check() {} +fn check() {} fn main() { check::(); diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index d3141381db8cf..c6b791ed9674a 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `CantParam: Eq` is not satisfied - --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:43 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:37 | -LL | impl std::marker::UnsizedConstParamTy for CantParam {} - | ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam` +LL | impl std::marker::ConstParamTy_ for CantParam {} + | ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam` | -note: required by a bound in `UnsizedConstParamTy` +note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL help: consider annotating `CantParam` with `#[derive(Eq)]` | @@ -13,26 +13,26 @@ LL | struct CantParam(ImplementsConstParamTy); | error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:43 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:37 | -LL | impl std::marker::UnsizedConstParamTy for CantParam {} - | ^^^^^^^^^ unsatisfied trait bound +LL | impl std::marker::ConstParamTy_ for CantParam {} + | ^^^^^^^^^ unsatisfied trait bound | help: the trait `StructuralPartialEq` is not implemented for `CantParam` --> $DIR/const_param_ty_impl_no_structural_eq.rs:8:1 | LL | struct CantParam(ImplementsConstParamTy); | ^^^^^^^^^^^^^^^^ -note: required by a bound in `UnsizedConstParamTy` +note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 | -LL | #[derive(std::marker::UnsizedConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` | -note: required by a bound in `UnsizedConstParamTy` +note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL help: consider annotating `CantParamDerive` with `#[derive(Eq)]` | @@ -43,15 +43,15 @@ LL | struct CantParamDerive(ImplementsConstParamTy); error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]` --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 | -LL | #[derive(std::marker::UnsizedConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | help: the trait `StructuralPartialEq` is not implemented for `CantParamDerive` --> $DIR/const_param_ty_impl_no_structural_eq.rs:17:1 | LL | struct CantParamDerive(ImplementsConstParamTy); | ^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `UnsizedConstParamTy` +note: required by a bound in `ConstParamTy_` --> $SRC_DIR/core/src/marker.rs:LL:COL error: aborting due to 4 previous errors diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs index 236b3bc162aaa..0c9b12805f757 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs @@ -12,10 +12,10 @@ impl PartialEq for Union { } impl Eq for Union {} -impl std::marker::UnsizedConstParamTy for Union {} +impl std::marker::ConstParamTy_ for Union {} //~^ ERROR the trait `ConstParamTy` may not be implemented for this type -#[derive(std::marker::UnsizedConstParamTy)] +#[derive(std::marker::ConstParamTy)] //~^ ERROR this trait cannot be derived for unions union UnionDerive { a: u8, diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr index 837c289c9248f..cc2147b49aea5 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr @@ -1,14 +1,14 @@ error: this trait cannot be derived for unions --> $DIR/const_param_ty_impl_union.rs:18:10 | -LL | #[derive(std::marker::UnsizedConstParamTy)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the trait `ConstParamTy` may not be implemented for this type - --> $DIR/const_param_ty_impl_union.rs:15:43 + --> $DIR/const_param_ty_impl_union.rs:15:37 | -LL | impl std::marker::UnsizedConstParamTy for Union {} - | ^^^^^ type is not a structure or enumeration +LL | impl std::marker::ConstParamTy_ for Union {} + | ^^^^^ type is not a structure or enumeration error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs index 34ea143d25462..d42ef90e1b180 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.rs @@ -5,17 +5,14 @@ use std::marker::ConstParamTy; #[derive(ConstParamTy)] //~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty -//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo([*const u8; 1]); #[derive(ConstParamTy)] //~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty -//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo2([*mut u8; 1]); #[derive(ConstParamTy)] //~^ ERROR the trait `ConstParamTy_` cannot be implemented for this ty -//~| ERROR the trait `ConstParamTy_` cannot be implemented for this ty struct Foo3([fn(); 1]); fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr index 6b8d2394a8618..442ec6b96cefa 100644 --- a/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr +++ b/tests/ui/const-generics/adt_const_params/nested_bad_const_param_ty.stderr @@ -3,91 +3,46 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type | LL | #[derive(ConstParamTy)] | ^^^^^^^^^^^^ -... +LL | LL | struct Foo([*const u8; 1]); | -------------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:9:12 + --> $DIR/nested_bad_const_param_ty.rs:8:12 | LL | struct Foo([*const u8; 1]); | ^^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:11:10 + --> $DIR/nested_bad_const_param_ty.rs:10:10 | LL | #[derive(ConstParamTy)] | ^^^^^^^^^^^^ -... +LL | LL | struct Foo2([*mut u8; 1]); | ------------ this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:14:13 + --> $DIR/nested_bad_const_param_ty.rs:12:13 | LL | struct Foo2([*mut u8; 1]); | ^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:16:10 + --> $DIR/nested_bad_const_param_ty.rs:14:10 | LL | #[derive(ConstParamTy)] | ^^^^^^^^^^^^ -... +LL | LL | struct Foo3([fn(); 1]); | --------- this field does not implement `ConstParamTy_` | note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): ConstParamTy_` - --> $DIR/nested_bad_const_param_ty.rs:19:13 + --> $DIR/nested_bad_const_param_ty.rs:16:13 | LL | struct Foo3([fn(); 1]); | ^^^^^^^^^ -error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:6:10 - | -LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -... -LL | struct Foo([*const u8; 1]); - | -------------- this field does not implement `ConstParamTy_` - | -note: the `ConstParamTy_` impl for `[*const u8; 1]` requires that `*const u8: UnsizedConstParamTy` - --> $DIR/nested_bad_const_param_ty.rs:9:12 - | -LL | struct Foo([*const u8; 1]); - | ^^^^^^^^^^^^^^ - -error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:11:10 - | -LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -... -LL | struct Foo2([*mut u8; 1]); - | ------------ this field does not implement `ConstParamTy_` - | -note: the `ConstParamTy_` impl for `[*mut u8; 1]` requires that `*mut u8: UnsizedConstParamTy` - --> $DIR/nested_bad_const_param_ty.rs:14:13 - | -LL | struct Foo2([*mut u8; 1]); - | ^^^^^^^^^^^^ - -error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/nested_bad_const_param_ty.rs:16:10 - | -LL | #[derive(ConstParamTy)] - | ^^^^^^^^^^^^ -... -LL | struct Foo3([fn(); 1]); - | --------- this field does not implement `ConstParamTy_` - | -note: the `ConstParamTy_` impl for `[fn(); 1]` requires that `fn(): UnsizedConstParamTy` - --> $DIR/nested_bad_const_param_ty.rs:19:13 - | -LL | struct Foo3([fn(); 1]); - | ^^^^^^^^^ - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr index b13f76eabadbc..72dfda50ea5ca 100644 --- a/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr +++ b/tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr @@ -9,11 +9,13 @@ help: you might be missing a const parameter LL | impl Wrapper<{ bar() }> { | +++++++++++++++++++++++ -error[E0741]: using function pointers as const generic parameters is forbidden +error: using function pointers as const generic parameters is forbidden --> $DIR/non_valtreeable_const_arg-2.rs:8:25 | LL | struct Wrapper; | ^^^^ + | + = note: the only supported types are integers, `bool`, and `char` error[E0599]: the function or associated item `call` exists for struct `Wrapper`, but its trait bounds were not satisfied --> $DIR/non_valtreeable_const_arg-2.rs:17:26 @@ -35,5 +37,5 @@ note: the trait `Fn` must be implemented error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0599, E0741. +Some errors have detailed explanations: E0425, E0599. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.rs b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.rs index a1ee1c4cdd585..937acf2e6bb63 100644 --- a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.rs +++ b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.rs @@ -1,11 +1,11 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::UnsizedConstParamTy; +use std::marker::ConstParamTy_; struct Foo; -impl UnsizedConstParamTy for &'static Foo {} +impl ConstParamTy_ for &'static Foo {} //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.stderr b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.stderr index 5ca8e6c75167f..b977cf5d44e09 100644 --- a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.stderr +++ b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-1.stderr @@ -1,8 +1,8 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/reference_pointee_is_const_param-1.rs:8:30 + --> $DIR/reference_pointee_is_const_param-1.rs:8:24 | -LL | impl UnsizedConstParamTy for &'static Foo {} - | ^^^^^^^^^^^^ this field does not implement `ConstParamTy_` +LL | impl ConstParamTy_ for &'static Foo {} + | ^^^^^^^^^^^^ this field does not implement `ConstParamTy_` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.rs b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.rs index ac1b522f469e1..605fed26c9c3c 100644 --- a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.rs +++ b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.rs @@ -3,12 +3,12 @@ // Regression test for #119299 -use std::marker::UnsizedConstParamTy; +use std::marker::ConstParamTy_; #[derive(Eq, PartialEq)] struct ConstStrU(*const u8, usize); -impl UnsizedConstParamTy for &'static ConstStrU {} +impl ConstParamTy_ for &'static ConstStrU {} //~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type impl ConstStrU { diff --git a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.stderr b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.stderr index 5e5f6cc642d33..0fe92f253a05e 100644 --- a/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.stderr +++ b/tests/ui/const-generics/adt_const_params/reference_pointee_is_const_param-2.stderr @@ -1,8 +1,8 @@ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/reference_pointee_is_const_param-2.rs:11:30 + --> $DIR/reference_pointee_is_const_param-2.rs:11:24 | -LL | impl UnsizedConstParamTy for &'static ConstStrU {} - | ^^^^^^^^^^^^^^^^^^ this field does not implement `ConstParamTy_` +LL | impl ConstParamTy_ for &'static ConstStrU {} + | ^^^^^^^^^^^^^^^^^^ this field does not implement `ConstParamTy_` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.rs b/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.rs index b0934508399d5..0fe86adb291dd 100644 --- a/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.rs +++ b/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.rs @@ -1,11 +1,11 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::UnsizedConstParamTy; +use std::marker::ConstParamTy_; trait Trait {} -impl UnsizedConstParamTy for dyn Trait {} +impl ConstParamTy_ for dyn Trait {} //~^ ERROR: the trait `ConstParamTy` may not be implemented for this type fn foo() {} diff --git a/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.stderr b/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.stderr index 9933ba6e335b7..67c6314e2975b 100644 --- a/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.stderr +++ b/tests/ui/const-generics/adt_const_params/trait_objects_as_a_const_generic.stderr @@ -1,8 +1,8 @@ error: the trait `ConstParamTy` may not be implemented for this type - --> $DIR/trait_objects_as_a_const_generic.rs:8:30 + --> $DIR/trait_objects_as_a_const_generic.rs:8:24 | -LL | impl UnsizedConstParamTy for dyn Trait {} - | ^^^^^^^^^ type is not a structure or enumeration +LL | impl ConstParamTy_ for dyn Trait {} + | ^^^^^^^^^ type is not a structure or enumeration error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs index f6e5bd6e355da..5db031cb900fc 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.rs +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.rs @@ -14,7 +14,10 @@ struct A([u8]); struct B(&'static [u8]); #[derive(ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type struct C(unsized_const_param::Foo); +#[derive(std::marker::ConstParamTy, Eq, PartialEq)] +//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type +struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); + fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr index 3089b30bd76d1..134dbba0d63ab 100644 --- a/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr +++ b/tests/ui/const-generics/adt_const_params/unsized_field-1.stderr @@ -6,6 +6,12 @@ LL | #[derive(ConstParamTy, Eq, PartialEq)] LL | LL | struct A([u8]); | ---- this field does not implement `ConstParamTy_` + | +note: the `ConstParamTy_` impl for `[u8]` requires that `feature(unsized_const_params) is enabled` + --> $DIR/unsized_field-1.rs:10:10 + | +LL | struct A([u8]); + | ^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type --> $DIR/unsized_field-1.rs:12:10 @@ -15,15 +21,27 @@ LL | #[derive(ConstParamTy, Eq, PartialEq)] LL | LL | struct B(&'static [u8]); | ------------- this field does not implement `ConstParamTy_` + | +note: the `ConstParamTy_` impl for `&'static [u8]` requires that `feature(unsized_const_params) is enabled` + --> $DIR/unsized_field-1.rs:14:10 + | +LL | struct B(&'static [u8]); + | ^^^^^^^^^^^^^ error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-1.rs:16:10 + --> $DIR/unsized_field-1.rs:19:10 | -LL | #[derive(ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^ +LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ LL | -LL | struct C(unsized_const_param::Foo); - | ------------------------ this field does not implement `ConstParamTy_` +LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); + | ---------------------------------------------------------- this field does not implement `ConstParamTy_` + | +note: the `ConstParamTy_` impl for `GenericNotUnsizedParam<&'static [u8]>` requires that `feature(unsized_const_params) is enabled` + --> $DIR/unsized_field-1.rs:21:10 + | +LL | struct D(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-2.rs b/tests/ui/const-generics/adt_const_params/unsized_field-2.rs deleted file mode 100644 index e4a3a481b4e37..0000000000000 --- a/tests/ui/const-generics/adt_const_params/unsized_field-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ aux-build:unsized_const_param.rs -#![feature(adt_const_params, unsized_const_params)] -//~^ WARN: the feature `unsized_const_params` is incomplete - -extern crate unsized_const_param; - -#[derive(std::marker::ConstParamTy, Eq, PartialEq)] -//~^ ERROR: the trait `ConstParamTy_` cannot be implemented for this type -struct A(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - -#[derive(std::marker::UnsizedConstParamTy, Eq, PartialEq)] -struct B(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - -fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsized_field-2.stderr b/tests/ui/const-generics/adt_const_params/unsized_field-2.stderr deleted file mode 100644 index cef70ca0463bd..0000000000000 --- a/tests/ui/const-generics/adt_const_params/unsized_field-2.stderr +++ /dev/null @@ -1,27 +0,0 @@ -warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/unsized_field-2.rs:2:30 - | -LL | #![feature(adt_const_params, unsized_const_params)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #95174 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsized_field-2.rs:7:10 - | -LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | struct A(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - | ---------------------------------------------------------- this field does not implement `ConstParamTy_` - | -note: the `ConstParamTy_` impl for `GenericNotUnsizedParam<&'static [u8]>` requires that `&'static [u8]: ConstParamTy_` - --> $DIR/unsized_field-2.rs:9:10 - | -LL | struct A(unsized_const_param::GenericNotUnsizedParam<&'static [u8]>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error; 1 warning emitted - -For more information about this error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs index 311f507d3c7f4..500e8e22b0e3d 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs @@ -7,7 +7,6 @@ use std::marker::ConstParamTy; #[derive(Debug, PartialEq, Eq, ConstParamTy)] //~^ ERROR the trait `ConstParamTy_` -//~| ERROR the trait `ConstParamTy_` struct Foo { nested: &'static Bar, //~^ ERROR the size for values diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr index 992a27c1c0e90..d4aeb91999c6b 100644 --- a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -1,17 +1,17 @@ error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:13 | LL | nested: &'static Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: required by an implicit `Sized` bound in `Bar` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ - ...if indirection were used here: `Box` @@ -26,34 +26,25 @@ LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] ... LL | nested: &'static Bar, | ----------------------------------------- this field does not implement `ConstParamTy_` - -error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type - --> $DIR/unsizing-wfcheck-issue-126272.rs:8:32 | -LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] - | ^^^^^^^^^^^^ -... -LL | nested: &'static Bar, - | ----------------------------------------- this field does not implement `ConstParamTy_` - | -note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Eq` - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): ConstParamTy_` + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:13 | LL | nested: &'static Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Sized` - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Eq` + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:13 | LL | nested: &'static Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): UnsizedConstParamTy` - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Sized` + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:13 | LL | nested: &'static Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:5 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ----- in this derive macro expansion @@ -64,7 +55,7 @@ LL | nested: &'static Bar, = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` = help: the trait `Debug` is implemented for `Bar` note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` - --> $DIR/unsizing-wfcheck-issue-126272.rs:20:10 + --> $DIR/unsizing-wfcheck-issue-126272.rs:19:10 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^^^^ @@ -75,7 +66,7 @@ LL | struct Bar(T); = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` error[E0369]: binary operation `==` cannot be applied to type `&Bar` - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:5 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | --------- in this derive macro expansion @@ -84,7 +75,7 @@ LL | nested: &'static Bar, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `dyn Debug: Eq` is not satisfied - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:5 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | -- in this derive macro expansion @@ -94,7 +85,7 @@ LL | nested: &'static Bar, | = help: the trait `Eq` is implemented for `Bar` note: required for `Bar` to implement `Eq` - --> $DIR/unsizing-wfcheck-issue-126272.rs:20:28 + --> $DIR/unsizing-wfcheck-issue-126272.rs:19:28 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | ^^ unsatisfied trait bound introduced in this `derive` macro @@ -104,7 +95,7 @@ note: required by a bound in `AssertParamIsEq` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time - --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + --> $DIR/unsizing-wfcheck-issue-126272.rs:11:5 | LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] | -- in this derive macro expansion @@ -114,12 +105,12 @@ LL | nested: &'static Bar, | = help: the trait `Sized` is not implemented for `dyn Debug` note: required by an implicit `Sized` bound in `Bar` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ - ...if indirection were used here: `Box` @@ -127,26 +118,26 @@ LL | struct Bar(T); | this could be changed to `T: ?Sized`... error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/unsizing-wfcheck-issue-126272.rs:26:33 + --> $DIR/unsizing-wfcheck-issue-126272.rs:25:33 | LL | let x: Test<{ Foo { nested: &Bar(4) } }> = Test; | ^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: required by an implicit `Sized` bound in `Bar` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:12 | LL | struct Bar(T); | ^ - ...if indirection were used here: `Box` | | | this could be changed to `T: ?Sized`... -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0204, E0277, E0369. For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/const-param-with-additional-obligations.rs b/tests/ui/const-generics/const-param-with-additional-obligations.rs index 98097e86c7dfe..5110f95d5bf9a 100644 --- a/tests/ui/const-generics/const-param-with-additional-obligations.rs +++ b/tests/ui/const-generics/const-param-with-additional-obligations.rs @@ -1,14 +1,14 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::UnsizedConstParamTy; +use std::marker::ConstParamTy_; #[derive(Eq, PartialEq)] struct Foo(T); trait Other {} -impl UnsizedConstParamTy for Foo where T: Other + UnsizedConstParamTy {} +impl ConstParamTy_ for Foo where T: Other + ConstParamTy_ {} fn foo>() {} //~^ ERROR `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter diff --git a/tests/ui/const-generics/defaults/trait_object_lt_defaults.rs b/tests/ui/const-generics/defaults/trait_object_lt_defaults.rs index 39dd6cb031f79..da25c0146c543 100644 --- a/tests/ui/const-generics/defaults/trait_object_lt_defaults.rs +++ b/tests/ui/const-generics/defaults/trait_object_lt_defaults.rs @@ -1,6 +1,6 @@ //@ aux-build:trait_object_lt_defaults_lib.rs //@ run-pass -#![allow(dead_code)] +#![allow(dead_code, unused)] extern crate trait_object_lt_defaults_lib; // Tests that `A<'a, 3, dyn Test>` is short for `A<'a, 3, dyn Test + 'a>` diff --git a/tests/ui/const-generics/forbid-non-structural_match-types.stderr b/tests/ui/const-generics/forbid-non-structural_match-types.stderr index 8ef629329f103..94afded9469e8 100644 --- a/tests/ui/const-generics/forbid-non-structural_match-types.stderr +++ b/tests/ui/const-generics/forbid-non-structural_match-types.stderr @@ -6,8 +6,8 @@ LL | struct D; | help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct | -LL - struct C; LL + #[derive(ConstParamTy, PartialEq, Eq)] +LL | struct C; | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/generic-const-array-pattern-ice-139815.rs b/tests/ui/const-generics/generic-const-array-pattern-ice-139815.rs new file mode 100644 index 0000000000000..52f4b246d069f --- /dev/null +++ b/tests/ui/const-generics/generic-const-array-pattern-ice-139815.rs @@ -0,0 +1,16 @@ +//@ compile-flags: --crate-type=lib +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +fn is_123( + x: [u32; { + //~^ ERROR overly complex generic constant + N + 1; + 5 + }], +) -> bool { + match x { + [1, 2] => true, + _ => false, + } +} diff --git a/tests/ui/const-generics/generic-const-array-pattern-ice-139815.stderr b/tests/ui/const-generics/generic-const-array-pattern-ice-139815.stderr new file mode 100644 index 0000000000000..9da973ef3a04e --- /dev/null +++ b/tests/ui/const-generics/generic-const-array-pattern-ice-139815.stderr @@ -0,0 +1,16 @@ +error: overly complex generic constant + --> $DIR/generic-const-array-pattern-ice-139815.rs:6:14 + | +LL | x: [u32; { + | ______________^ +LL | | +LL | | N + 1; +LL | | 5 +LL | | }], + | |_____^ blocks are not supported in generic constants + | + = help: consider moving this anonymous constant into a `const` function + = note: this operation may be supported in the future + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr index b6f2662a93932..d7a7ab52c83de 100644 --- a/tests/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/tests/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -2,29 +2,39 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/in-signature.rs:6:21 | LL | fn arr_fn() -> [u8; _] { - | -----^- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `[u8; 3]` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn arr_fn() -> [u8; _] { +LL + fn arr_fn() -> [u8; 3] { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/in-signature.rs:11:24 | LL | fn ty_fn() -> Bar { - | ---------^- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn ty_fn() -> Bar { +LL + fn ty_fn() -> Bar { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/in-signature.rs:16:25 | LL | fn ty_fn_mixed() -> Bar<_, _> { - | ----^--^- - | | | | - | | | not allowed in type signatures - | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn ty_fn_mixed() -> Bar<_, _> { +LL + fn ty_fn_mixed() -> Bar { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:21:20 diff --git a/tests/ui/const-generics/generic_arg_infer/paren_infer.rs b/tests/ui/const-generics/generic_arg_infer/paren_infer.rs new file mode 100644 index 0000000000000..869683b705669 --- /dev/null +++ b/tests/ui/const-generics/generic_arg_infer/paren_infer.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ reference: items.generics.const.inferred + +struct Foo; + +fn main() { + // AST Types preserve parens for pretty printing reasons. This means + // that this is parsed as a `TyKind::Paren(TyKind::Infer)`. Generic + // arg lowering therefore needs to take into account not just `TyKind::Infer` + // but `TyKind::Infer` wrapped in arbitrarily many `TyKind::Paren`. + let a: Vec<(_)> = vec![1_u8]; + let a: Vec<(((((_)))))> = vec![1_u8]; + + // AST Exprs similarly preserve parens for pretty printing reasons. + #[rustfmt::skip] + let b: [u8; (_)] = [1; (((((_)))))]; + let b: [u8; 2] = b; + + // This is the same case as AST types as the parser doesn't distinguish between const + // and type args when they share syntax + let c: Foo<_> = Foo::<1>; + let c: Foo<(_)> = Foo::<1>; + let c: Foo<(((_)))> = Foo::<1>; +} diff --git a/tests/ui/const-generics/generic_arg_infer/parend_infer.rs b/tests/ui/const-generics/generic_arg_infer/parend_infer.rs deleted file mode 100644 index 9d7df8016cb1e..0000000000000 --- a/tests/ui/const-generics/generic_arg_infer/parend_infer.rs +++ /dev/null @@ -1,23 +0,0 @@ -//@ check-pass - -struct Foo; - -fn main() { - // AST Types preserve parens for pretty printing reasons. This means - // that this is parsed as a `TyKind::Paren(TyKind::Infer)`. Generic - // arg lowering therefore needs to take into account not just `TyKind::Infer` - // but `TyKind::Infer` wrapped in arbitrarily many `TyKind::Paren`. - let a: Vec<(_)> = vec![1_u8]; - let a: Vec<(((((_)))))> = vec![1_u8]; - - // AST Exprs similarly preserve parens for pretty printing reasons. - #[rustfmt::skip] - let b: [u8; (_)] = [1; (((((_)))))]; - let b: [u8; 2] = b; - - // This is the same case as AST types as the parser doesn't distinguish between const - // and type args when they share syntax - let c: Foo<_> = Foo::<1>; - let c: Foo<(_)> = Foo::<1>; - let c: Foo<(((_)))> = Foo::<1>; -} diff --git a/tests/ui/const-generics/generic_const_exprs/negative-coherence-ice-140609.rs b/tests/ui/const-generics/generic_const_exprs/negative-coherence-ice-140609.rs new file mode 100644 index 0000000000000..1b02b874ed898 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/negative-coherence-ice-140609.rs @@ -0,0 +1,14 @@ +//@ check-pass +#![feature(with_negative_coherence)] +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] +#![crate_type = "lib"] +trait Trait {} +struct A; + +trait C {} + +impl Trait for E where A<{ D <= 2 }>: FnOnce(&isize) {} +struct E; + +impl Trait for E where A<{ D <= 2 }>: C {} diff --git a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr index 4ea323f4a5c85..1eacc28b2625e 100644 --- a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr +++ b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr @@ -4,7 +4,7 @@ error[E0741]: `[T; N]` can't be used as a const parameter type LL | struct UsesType(PhantomData); | ^^^^^^ | - = note: `T` must implement `UnsizedConstParamTy`, but it does not + = note: `T` must implement `ConstParamTy_`, but it does not error: aborting due to 1 previous error diff --git a/tests/ui/attributes/invalid-attributes-on-const-params-78957.rs b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.rs similarity index 100% rename from tests/ui/attributes/invalid-attributes-on-const-params-78957.rs rename to tests/ui/const-generics/invalid-attributes-on-const-params-78957.rs diff --git a/tests/ui/attributes/invalid-attributes-on-const-params-78957.stderr b/tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr similarity index 100% rename from tests/ui/attributes/invalid-attributes-on-const-params-78957.stderr rename to tests/ui/const-generics/invalid-attributes-on-const-params-78957.stderr diff --git a/tests/ui/const-generics/issue-66451.rs b/tests/ui/const-generics/issue-66451.rs index 0b8693e0e675d..9ce7658586ad1 100644 --- a/tests/ui/const-generics/issue-66451.rs +++ b/tests/ui/const-generics/issue-66451.rs @@ -1,15 +1,15 @@ #![feature(adt_const_params, unsized_const_params)] #![allow(incomplete_features)] -use std::marker::UnsizedConstParamTy; +use std::marker::ConstParamTy; -#[derive(Debug, PartialEq, Eq, UnsizedConstParamTy)] +#[derive(Debug, PartialEq, Eq, ConstParamTy)] struct Foo { value: i32, nested: &'static Bar, } -#[derive(Debug, PartialEq, Eq, UnsizedConstParamTy)] +#[derive(Debug, PartialEq, Eq, ConstParamTy)] struct Bar(T); struct Test; diff --git a/tests/ui/const-generics/issue-80471.stderr b/tests/ui/const-generics/issue-80471.stderr index 8cf3d68e5d691..fff2eb53cf126 100644 --- a/tests/ui/const-generics/issue-80471.stderr +++ b/tests/ui/const-generics/issue-80471.stderr @@ -4,10 +4,10 @@ error[E0741]: `Nat` must implement `ConstParamTy` to be used as the type of a co LL | fn foo() {} | ^^^ | -help: add `#[derive(ConstParamTy)]` to the struct +help: add `#[derive(ConstParamTy)]` to the enum | -LL - enum Nat { LL + #[derive(ConstParamTy)] +LL | enum Nat { | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr index 8ea96428deb3b..1301ca92f015c 100644 --- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr +++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr @@ -4,7 +4,7 @@ error[E0741]: `&'static (dyn A + 'static)` can't be used as a const parameter ty LL | fn test() { | ^^^^^^^^^^^^^^ | - = note: `(dyn A + 'static)` must implement `UnsizedConstParamTy`, but it does not + = note: `(dyn A + 'static)` must implement `ConstParamTy_`, but it does not error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/issues/issue-97278.stderr b/tests/ui/const-generics/issues/issue-97278.stderr index 4894ddb7b8db8..21a5fc94032c0 100644 --- a/tests/ui/const-generics/issues/issue-97278.stderr +++ b/tests/ui/const-generics/issues/issue-97278.stderr @@ -4,10 +4,10 @@ error[E0741]: `Bar` must implement `ConstParamTy` to be used as the type of a co LL | fn test() {} | ^^^ | -help: add `#[derive(ConstParamTy)]` to the struct +help: add `#[derive(ConstParamTy)]` to the enum | -LL - enum Bar { LL + #[derive(ConstParamTy)] +LL | enum Bar { | error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/slice-const-param-mismatch.adt_const_params.stderr b/tests/ui/const-generics/slice-const-param-mismatch.adt_const_params.stderr index bcb2bd255dab9..d970b12df6a1d 100644 --- a/tests/ui/const-generics/slice-const-param-mismatch.adt_const_params.stderr +++ b/tests/ui/const-generics/slice-const-param-mismatch.adt_const_params.stderr @@ -1,14 +1,22 @@ -error[E0741]: `&'static str` can't be used as a const parameter type - --> $DIR/slice-const-param-mismatch.rs:8:29 +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/slice-const-param-mismatch.rs:8:20 | LL | struct ConstString; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `&'static str` to implement `ConstParamTy_` -error[E0741]: `&'static [u8]` can't be used as a const parameter type - --> $DIR/slice-const-param-mismatch.rs:11:28 +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/slice-const-param-mismatch.rs:11:19 | LL | struct ConstBytes; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `&'static [u8]` to implement `ConstParamTy_` error[E0308]: mismatched types --> $DIR/slice-const-param-mismatch.rs:17:35 @@ -45,5 +53,5 @@ LL | let _: ConstBytes = ConstBytes::; error: aborting due to 5 previous errors -Some errors have detailed explanations: E0308, E0741. +Some errors have detailed explanations: E0308, E0658. For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/const-generics/slice-const-param.rs b/tests/ui/const-generics/slice-const-param.rs index 1c5088b528355..8b5e934149e42 100644 --- a/tests/ui/const-generics/slice-const-param.rs +++ b/tests/ui/const-generics/slice-const-param.rs @@ -12,7 +12,7 @@ pub fn function_with_bytes() -> &'static [u8] { } // Also check the codepaths for custom DST -#[derive(std::marker::UnsizedConstParamTy, PartialEq, Eq)] +#[derive(std::marker::ConstParamTy, PartialEq, Eq)] struct MyStr(str); fn function_with_my_str() -> &'static MyStr { diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.adt_const_params.stderr b/tests/ui/const-generics/transmute-const-param-static-reference.adt_const_params.stderr index 7a936ced0305a..c2351c707d7bf 100644 --- a/tests/ui/const-generics/transmute-const-param-static-reference.adt_const_params.stderr +++ b/tests/ui/const-generics/transmute-const-param-static-reference.adt_const_params.stderr @@ -1,9 +1,13 @@ -error[E0741]: `&'static ()` can't be used as a const parameter type - --> $DIR/transmute-const-param-static-reference.rs:9:23 +error[E0658]: use of unstable library feature `unsized_const_params` + --> $DIR/transmute-const-param-static-reference.rs:9:14 | LL | struct Const; - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unsized_const_params)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: required for `&'static ()` to implement `ConstParamTy_` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0741`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.rs b/tests/ui/const-generics/transmute-const-param-static-reference.rs index 0b47fd31eaf69..bf164bdadb0e0 100644 --- a/tests/ui/const-generics/transmute-const-param-static-reference.rs +++ b/tests/ui/const-generics/transmute-const-param-static-reference.rs @@ -8,7 +8,7 @@ struct Const; //[min]~^ ERROR `&'static ()` is forbidden as the type of a const generic parameter -//[adt_const_params]~^^ ERROR `&'static ()` can't be used as a const parameter type +//[adt_const_params]~^^ ERROR use of unstable library feature `unsized_const_params` fn main() { const A: &'static () = unsafe { std::mem::transmute(10 as *const ()) }; diff --git a/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs b/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs index 359126f125167..429c401af1f55 100644 --- a/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs +++ b/tests/ui/const-generics/unsized_const_params/symbol_mangling_v0_str.rs @@ -1,13 +1,13 @@ //@ check-pass //@ compile-flags: -Csymbol-mangling-version=v0 #![allow(incomplete_features)] -#![feature(unsized_const_params)] +#![feature(adt_const_params, unsized_const_params)] // Regression test for #116303 #[derive(PartialEq, Eq)] struct MyStr(str); -impl std::marker::UnsizedConstParamTy for MyStr {} +impl std::marker::ConstParamTy_ for MyStr {} fn function_with_my_str() -> &'static MyStr { S diff --git a/tests/ui/consts/closure-type-error-during-const-eval-66706.rs b/tests/ui/consts/closure-type-error-during-const-eval-66706.rs new file mode 100644 index 0000000000000..d88aa30615861 --- /dev/null +++ b/tests/ui/consts/closure-type-error-during-const-eval-66706.rs @@ -0,0 +1,24 @@ +// https://github.com/rust-lang/rust/issues/66706 +fn a() { + [0; [|_: _ &_| ()].len()] + //~^ ERROR expected one of `,` or `|`, found `&` + //~| ERROR type annotations needed +} + +fn b() { + [0; [|f @ &ref _| {} ; 0 ].len() ]; + //~^ ERROR expected identifier, found reserved identifier `_` +} + +fn c() { + [0; [|&_: _ &_| {}; 0 ].len()] + //~^ ERROR expected one of `,` or `|`, found `&` + //~| ERROR type annotations needed +} + +fn d() { + [0; match [|f @ &ref _| () ] {} ] + //~^ ERROR expected identifier, found reserved identifier `_` +} + +fn main() {} diff --git a/tests/ui/consts/closure-type-error-during-const-eval-66706.stderr b/tests/ui/consts/closure-type-error-during-const-eval-66706.stderr new file mode 100644 index 0000000000000..e774b1adf1187 --- /dev/null +++ b/tests/ui/consts/closure-type-error-during-const-eval-66706.stderr @@ -0,0 +1,45 @@ +error: expected one of `,` or `|`, found `&` + --> $DIR/closure-type-error-during-const-eval-66706.rs:3:16 + | +LL | [0; [|_: _ &_| ()].len()] + | -^ expected one of `,` or `|` + | | + | help: missing `,` + +error: expected identifier, found reserved identifier `_` + --> $DIR/closure-type-error-during-const-eval-66706.rs:9:20 + | +LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; + | ^ expected identifier, found reserved identifier + +error: expected one of `,` or `|`, found `&` + --> $DIR/closure-type-error-during-const-eval-66706.rs:14:17 + | +LL | [0; [|&_: _ &_| {}; 0 ].len()] + | -^ expected one of `,` or `|` + | | + | help: missing `,` + +error: expected identifier, found reserved identifier `_` + --> $DIR/closure-type-error-during-const-eval-66706.rs:20:26 + | +LL | [0; match [|f @ &ref _| () ] {} ] + | ----- ^ expected identifier, found reserved identifier + | | + | while parsing this `match` expression + +error[E0282]: type annotations needed + --> $DIR/closure-type-error-during-const-eval-66706.rs:3:14 + | +LL | [0; [|_: _ &_| ()].len()] + | ^ cannot infer type + +error[E0282]: type annotations needed + --> $DIR/closure-type-error-during-const-eval-66706.rs:14:11 + | +LL | [0; [|&_: _ &_| {}; 0 ].len()] + | ^^^^^ cannot infer type + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs index 9164684262480..851f3996cd104 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.rs +++ b/tests/ui/consts/const-eval/ub-nonnull.rs @@ -57,4 +57,8 @@ const NULL_FAT_PTR: NonNull = unsafe { mem::transmute((0_usize, meta)) }; +static S: u32 = 0; // just a static to construct a maybe-null pointer off of +const MAYBE_NULL_PTR: NonNull<()> = unsafe { mem::transmute((&raw const S).wrapping_add(4)) }; +//~^ ERROR invalid value + fn main() {} diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr index 91c82efbc5ed1..e4486e3c500b9 100644 --- a/tests/ui/consts/const-eval/ub-nonnull.stderr +++ b/tests/ui/consts/const-eval/ub-nonnull.stderr @@ -9,7 +9,7 @@ LL | const NULL_PTR: NonNull = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 255 bytes, but got ALLOC1 which is only 1 byte from the end of the allocation +error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 255 bytes, but got ALLOC2 which is only 1 byte from the end of the allocation --> $DIR/ub-nonnull.rs:22:29 | LL | let out_of_bounds_ptr = &ptr[255]; @@ -37,7 +37,7 @@ LL | const NULL_USIZE: NonZero = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC2[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory +error[E0080]: reading memory at ALLOC3[0x0..0x1], but memory is uninitialized at [0x0..0x1], and this operation requires initialized memory --> $DIR/ub-nonnull.rs:36:38 | LL | const UNINIT: NonZero = unsafe { MaybeUninit { uninit: () }.init }; @@ -80,6 +80,17 @@ LL | const NULL_FAT_PTR: NonNull = unsafe { HEX_DUMP } -error: aborting due to 8 previous errors +error[E0080]: constructing invalid value: encountered a maybe-null pointer, but expected something that is definitely non-zero + --> $DIR/ub-nonnull.rs:61:1 + | +LL | const MAYBE_NULL_PTR: NonNull<()> = unsafe { mem::transmute((&raw const S).wrapping_add(4)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs index d8e5102fcbe78..a5fdde1f9a4e9 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.rs +++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs @@ -4,7 +4,7 @@ //@ normalize-stderr: "([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" //@ dont-require-annotations: NOTE //@ normalize-stderr: "0x[0-9](\.\.|\])" -> "0x%$1" - +#![feature(rustc_attrs)] #![allow(invalid_value)] use std::mem; @@ -27,6 +27,11 @@ const NULL: &u16 = unsafe { mem::transmute(0usize) }; const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; //~^ ERROR invalid value +const MAYBE_NULL_BOX: Box<()> = unsafe { mem::transmute({ +//~^ ERROR maybe-null + let ref_ = &0u8; + (ref_ as *const u8).wrapping_add(10) +}) }; // It is very important that we reject this: We do promote `&(4 * REF_AS_USIZE)`, // but that would fail to compile; so we ended up breaking user code that would @@ -57,7 +62,12 @@ const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; //~^ ERROR invalid value const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; //~^ ERROR invalid value - +const MAYBE_NULL_FN_PTR: fn() = unsafe { mem::transmute({ +//~^ ERROR invalid value + fn fun() {} + let ptr = fun as fn(); + (ptr as *const u8).wrapping_add(10) +}) }; const UNALIGNED_READ: () = unsafe { let x = &[0u8; 4]; @@ -65,5 +75,14 @@ const UNALIGNED_READ: () = unsafe { ptr.read(); //~ ERROR accessing memory }; +// Check the general case of a pointer value not falling into the scalar valid range. +#[rustc_layout_scalar_valid_range_start(1000)] +pub struct High { + pointer: *const (), +} +static S: u32 = 0; // just a static to construct a pointer with unknown absolute address +const INVALID_VALUE_PTR: High = unsafe { mem::transmute(&S) }; +//~^ ERROR invalid value + fn main() {} diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr index c45f66c29259c..349a98f11be42 100644 --- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr @@ -42,8 +42,19 @@ LL | const NULL_BOX: Box = unsafe { mem::transmute(0usize) }; HEX_DUMP } +error[E0080]: constructing invalid value: encountered a maybe-null box + --> $DIR/ub-ref-ptr.rs:30:1 + | +LL | const MAYBE_NULL_BOX: Box<()> = unsafe { mem::transmute({ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:34:1 + --> $DIR/ub-ref-ptr.rs:39:1 | LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE` failed here @@ -52,7 +63,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:37:39 + --> $DIR/ub-ref-ptr.rs:42:39 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_SLICE` failed here @@ -61,13 +72,13 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:37:38 + --> $DIR/ub-ref-ptr.rs:42:38 | LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0080]: unable to turn pointer into integer - --> $DIR/ub-ref-ptr.rs:40:86 + --> $DIR/ub-ref-ptr.rs:45:86 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^ evaluation of `REF_AS_USIZE_BOX_SLICE` failed here @@ -76,13 +87,13 @@ LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[us = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported note: erroneous constant encountered - --> $DIR/ub-ref-ptr.rs:40:85 + --> $DIR/ub-ref-ptr.rs:45:85 | LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ^^^^^^^^^^^^^^^^^^^^^ error[E0080]: constructing invalid value: encountered a dangling reference (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:43:1 + --> $DIR/ub-ref-ptr.rs:48:1 | LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -93,7 +104,7 @@ LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) }; } error[E0080]: constructing invalid value: encountered a dangling box (0x539[noalloc] has no provenance) - --> $DIR/ub-ref-ptr.rs:46:1 + --> $DIR/ub-ref-ptr.rs:51:1 | LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -103,8 +114,8 @@ LL | const USIZE_AS_BOX: Box = unsafe { mem::transmute(1337usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC3[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:49:41 +error[E0080]: reading memory at ALLOC6[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:54:41 | LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_PTR` failed here @@ -114,7 +125,7 @@ LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: constructing invalid value: encountered null pointer, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:52:1 + --> $DIR/ub-ref-ptr.rs:57:1 | LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -124,8 +135,8 @@ LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) }; HEX_DUMP } -error[E0080]: reading memory at ALLOC4[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory - --> $DIR/ub-ref-ptr.rs:54:38 +error[E0080]: reading memory at ALLOC7[0x%..0x%], but memory is uninitialized at [0x%..0x%], and this operation requires initialized memory + --> $DIR/ub-ref-ptr.rs:59:38 | LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINIT_FN_PTR` failed here @@ -135,7 +146,7 @@ LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init }; } error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected a function pointer - --> $DIR/ub-ref-ptr.rs:56:1 + --> $DIR/ub-ref-ptr.rs:61:1 | LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -145,8 +156,8 @@ LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) }; HEX_DUMP } -error[E0080]: constructing invalid value: encountered ALLOC2, but expected a function pointer - --> $DIR/ub-ref-ptr.rs:58:1 +error[E0080]: constructing invalid value: encountered ALLOC3, but expected a function pointer + --> $DIR/ub-ref-ptr.rs:63:1 | LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value @@ -156,12 +167,34 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; HEX_DUMP } +error[E0080]: constructing invalid value: encountered ALLOC4+0xa, but expected a function pointer + --> $DIR/ub-ref-ptr.rs:65:1 + | +LL | const MAYBE_NULL_FN_PTR: fn() = unsafe { mem::transmute({ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + error[E0080]: accessing memory based on pointer with alignment 1, but alignment 4 is required - --> $DIR/ub-ref-ptr.rs:65:5 + --> $DIR/ub-ref-ptr.rs:75:5 | LL | ptr.read(); | ^^^^^^^^^^ evaluation of `UNALIGNED_READ` failed here -error: aborting due to 15 previous errors +error[E0080]: constructing invalid value: encountered a pointer with unknown absolute address, but expected something that is definitely greater or equal to 1000 + --> $DIR/ub-ref-ptr.rs:84:1 + | +LL | const INVALID_VALUE_PTR: High = unsafe { mem::transmute(&S) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs index fd3ed8f18265e..55d430a08aadb 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.rs @@ -8,8 +8,8 @@ extern "C" { } const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; -//~^ ERROR `extern type` does not have known layout +//~^ ERROR: the size for values of type `Opaque` cannot be known const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; -//~^ ERROR `extern type` does not have known layout +//~^ ERROR: the size for values of type `Opaque` cannot be known fn main() {} diff --git a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index 23f7aaf538edc..825b9e941584c 100644 --- a/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/tests/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -1,15 +1,39 @@ -error[E0080]: `extern type` does not have known layout - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:31 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:10:43 | LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_SIZE` failed here + | ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` + | | + | required by a bound introduced by this call + | + = note: the trait bound `Opaque: MetaSized` is not satisfied +note: required by a bound in `std::intrinsics::size_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _SIZE: usize = unsafe { size_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _SIZE: usize = unsafe { size_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + -error[E0080]: `extern type` does not have known layout - --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:32 +error[E0277]: the size for values of type `Opaque` cannot be known + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:12:45 | LL | const _ALIGN: usize = unsafe { align_of_val(&4 as *const i32 as *const Opaque) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `_ALIGN` failed here + | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MetaSized` is not implemented for `Opaque` + | | + | required by a bound introduced by this call + | + = note: the trait bound `Opaque: MetaSized` is not satisfied +note: required by a bound in `std::intrinsics::align_of_val` + --> $SRC_DIR/core/src/intrinsics/mod.rs:LL:COL +help: consider borrowing here + | +LL | const _ALIGN: usize = unsafe { align_of_val(&(&4 as *const i32 as *const Opaque)) }; + | ++ + +LL | const _ALIGN: usize = unsafe { align_of_val(&mut (&4 as *const i32 as *const Opaque)) }; + | ++++++ + error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const_refs_to_static_fail.stderr b/tests/ui/consts/const_refs_to_static_fail.stderr index c567b3e0ce1f4..2bb6d2b8fef7c 100644 --- a/tests/ui/consts/const_refs_to_static_fail.stderr +++ b/tests/ui/consts/const_refs_to_static_fail.stderr @@ -16,7 +16,7 @@ error: constant BAD_PATTERN cannot be used as pattern LL | BAD_PATTERN => {}, | ^^^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr index f9088c318a621..226a9de285dc3 100644 --- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr +++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr @@ -15,7 +15,7 @@ error: constant extern_::C cannot be used as pattern LL | C => {} | ^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant mutable::C cannot be used as pattern --> $DIR/const_refs_to_static_fail_invalid.rs:42:9 @@ -23,7 +23,7 @@ error: constant mutable::C cannot be used as pattern LL | C => {} | ^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 3 previous errors diff --git a/tests/ui/consts/const_transmute_type_id7.rs b/tests/ui/consts/const_transmute_type_id7.rs new file mode 100644 index 0000000000000..73b8187a8007a --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id7.rs @@ -0,0 +1,16 @@ +//! Ensure a decent error message for maybe-null references. +//! (see ) + +// Strip out raw byte dumps to make comparison platform-independent: +//@ normalize-stderr: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" +//@ normalize-stderr: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?()?─*╼ )+ *│.*" -> "HEX_DUMP" + +#![feature(const_trait_impl, const_cmp)] + +use std::any::TypeId; +use std::mem::transmute; + +const A: [&(); 16 / size_of::<*const ()>()] = unsafe { transmute(TypeId::of::()) }; +//~^ERROR: maybe-null + +fn main() {} diff --git a/tests/ui/consts/const_transmute_type_id7.stderr b/tests/ui/consts/const_transmute_type_id7.stderr new file mode 100644 index 0000000000000..664975831f402 --- /dev/null +++ b/tests/ui/consts/const_transmute_type_id7.stderr @@ -0,0 +1,14 @@ +error[E0080]: constructing invalid value at [0]: encountered a maybe-null reference + --> $DIR/const_transmute_type_id7.rs:13:1 + | +LL | const A: [&(); 16 / size_of::<*const ()>()] = unsafe { transmute(TypeId::of::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value + | + = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { + HEX_DUMP + } + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs new file mode 100644 index 0000000000000..465b54e69d1b4 --- /dev/null +++ b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs @@ -0,0 +1,14 @@ +// The test confirms ICE-125323 is fixed. +// +// This warning tests there is no warning about dead code +// when there is a constant evaluation error. +#![warn(unused)] +fn should_not_be_dead() {} + +fn main() { + for _ in 0..0 { + [(); loop {}]; //~ ERROR constant evaluation is taking a long time + } + + should_not_be_dead(); +} diff --git a/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr new file mode 100644 index 0000000000000..32a18469ab9e5 --- /dev/null +++ b/tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr @@ -0,0 +1,17 @@ +error: constant evaluation is taking a long time + --> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14 + | +LL | [(); loop {}]; + | ^^^^^^^ + | + = note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval. + If your compilation actually takes a long time, you can safely allow the lint. +help: the constant being evaluated + --> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14 + | +LL | [(); loop {}]; + | ^^^^^^^ + = note: `#[deny(long_running_const_eval)]` on by default + +error: aborting due to 1 previous error + diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs index e17bac603b415..60086acc3707e 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.rs +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.rs @@ -52,6 +52,16 @@ const UNALIGNED_PTR: () = unsafe { //[with_flag]~^ ERROR: invalid value }; +// A function pointer offset to be maybe-null. +const MAYBE_NULL_FN_PTR: () = unsafe { + let _x: fn() = transmute({ + //[with_flag]~^ ERROR: invalid value + fn fun() {} + let ptr = fun as fn(); + (ptr as *const u8).wrapping_add(10) + }); +}; + const UNINHABITED_VARIANT: () = unsafe { let data = [1u8]; // Not using transmute, we want to hit the ImmTy code path. diff --git a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 6af72868045ac..96c1666a2d2eb 100644 --- a/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/tests/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -37,14 +37,26 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re LL | let _x: &u32 = transmute(&[0u8; 4]); | ^^^^^^^^^^^^^^^^^^^^ evaluation of `UNALIGNED_PTR` failed here +error[E0080]: constructing invalid value: encountered a maybe-null function pointer + --> $DIR/detect-extra-ub.rs:57:20 + | +LL | let _x: fn() = transmute({ + | ____________________^ +LL | | +LL | | fn fun() {} +LL | | let ptr = fun as fn(); +LL | | (ptr as *const u8).wrapping_add(10) +LL | | }); + | |______^ evaluation of `MAYBE_NULL_FN_PTR` failed here + error[E0080]: constructing invalid value at .: encountered an uninhabited enum variant - --> $DIR/detect-extra-ub.rs:58:13 + --> $DIR/detect-extra-ub.rs:68:13 | LL | let v = *addr_of!(data).cast::(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `UNINHABITED_VARIANT` failed here error[E0080]: constructing invalid value at [0]: encountered a partial pointer or a mix of pointers - --> $DIR/detect-extra-ub.rs:77:16 + --> $DIR/detect-extra-ub.rs:87:16 | LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `PARTIAL_POINTER` failed here @@ -53,11 +65,11 @@ LL | let _val = *(&mem as *const Align as *const [*const u8; 2]); = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported error[E0080]: constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object - --> $DIR/detect-extra-ub.rs:91:16 + --> $DIR/detect-extra-ub.rs:101:16 | LL | let _val = &*slice; | ^^^^^^^ evaluation of `OVERSIZED_REF` failed here -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr index 6b70a211a72cc..5b8797c511627 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -22,7 +22,7 @@ error: constant REF_INTERIOR_MUT cannot be used as pattern LL | REF_INTERIOR_MUT => {}, | ^^^^^^^^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns warning: skipping const checks | diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr index d753506cc94e3..c2b730375f2c2 100644 --- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr +++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.stderr @@ -10,7 +10,7 @@ error: constant SLICE_MUT cannot be used as pattern LL | SLICE_MUT => true, | ^^^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant U8_MUT cannot be used as pattern --> $DIR/const_refers_to_static_cross_crate.rs:44:9 @@ -18,7 +18,7 @@ error: constant U8_MUT cannot be used as pattern LL | U8_MUT => true, | ^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: constant U8_MUT2 cannot be used as pattern --> $DIR/const_refers_to_static_cross_crate.rs:53:9 @@ -26,7 +26,7 @@ error: constant U8_MUT2 cannot be used as pattern LL | U8_MUT2 => true, | ^^^^^^^ | - = note: constants that reference mutable or external memory cannot be used as pattern + = note: constants that reference mutable or external memory cannot be used as patterns error: aborting due to 4 previous errors diff --git a/tests/ui/consts/offset_ub.stderr b/tests/ui/consts/offset_ub.stderr index d92ca09223de7..f40d342758360 100644 --- a/tests/ui/consts/offset_ub.stderr +++ b/tests/ui/consts/offset_ub.stderr @@ -43,8 +43,8 @@ LL | pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).of error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by -$BYTES bytes, but got ALLOC3-0x2 which points to before the beginning of the allocation --> $DIR/offset_ub.rs:16:49 | -LL | ...*const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEGATIVE_OFFSET` failed here +LL | ...nst u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `NEGATIVE_OFFSET` failed here error[E0080]: in-bounds pointer arithmetic failed: attempting to offset pointer by 1 byte, but got ALLOC4 which is at or beyond the end of the allocation of size $BYTES bytes --> $DIR/offset_ub.rs:18:50 diff --git a/tests/ui/consts/precise-drop-nested-deref-ice.rs b/tests/ui/consts/precise-drop-nested-deref-ice.rs new file mode 100644 index 0000000000000..3ac5bea6266a6 --- /dev/null +++ b/tests/ui/consts/precise-drop-nested-deref-ice.rs @@ -0,0 +1,15 @@ +//! Tests that multiple derefs in a projection does not cause an ICE +//! when checking const precise drops. +//! +//! Regression test for + +#![feature(const_precise_live_drops)] +struct Foo(u32); +impl Foo { + const fn get(self: Box<&Self>, f: &u32) -> u32 { + //~^ ERROR destructor of `Box<&Foo>` cannot be evaluated at compile-time + self.0 + } +} + +fn main() {} diff --git a/tests/ui/consts/precise-drop-nested-deref-ice.stderr b/tests/ui/consts/precise-drop-nested-deref-ice.stderr new file mode 100644 index 0000000000000..4e5af100f1dbe --- /dev/null +++ b/tests/ui/consts/precise-drop-nested-deref-ice.stderr @@ -0,0 +1,12 @@ +error[E0493]: destructor of `Box<&Foo>` cannot be evaluated at compile-time + --> $DIR/precise-drop-nested-deref-ice.rs:9:18 + | +LL | const fn get(self: Box<&Self>, f: &u32) -> u32 { + | ^^^^ the destructor for this type cannot be evaluated in constant functions +... +LL | } + | - value is dropped here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0493`. diff --git a/tests/ui/consts/promoted_const_call2.rs b/tests/ui/consts/promoted_const_call2.rs index f332cd18cea37..62391f098e5d1 100644 --- a/tests/ui/consts/promoted_const_call2.rs +++ b/tests/ui/consts/promoted_const_call2.rs @@ -4,7 +4,6 @@ pub const C: () = { let _: &'static _ = &id(&String::new()); //~^ ERROR: temporary value dropped while borrowed //~| ERROR: temporary value dropped while borrowed - //~| ERROR: destructor of `String` cannot be evaluated at compile-time }; fn main() { diff --git a/tests/ui/consts/promoted_const_call2.stderr b/tests/ui/consts/promoted_const_call2.stderr index bdb43385d2032..e62458d1a6ae4 100644 --- a/tests/ui/consts/promoted_const_call2.stderr +++ b/tests/ui/consts/promoted_const_call2.stderr @@ -18,16 +18,8 @@ LL | let _: &'static _ = &id(&String::new()); | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` -error[E0493]: destructor of `String` cannot be evaluated at compile-time - --> $DIR/promoted_const_call2.rs:4:30 - | -LL | let _: &'static _ = &id(&String::new()); - | ^^^^^^^^^^^^^ - value is dropped here - | | - | the destructor for this type cannot be evaluated in constants - error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call2.rs:11:26 + --> $DIR/promoted_const_call2.rs:10:26 | LL | let _: &'static _ = &id(&String::new()); | ---------- ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -38,7 +30,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call2.rs:11:30 + --> $DIR/promoted_const_call2.rs:10:30 | LL | let _: &'static _ = &id(&String::new()); | ---------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement @@ -46,7 +38,6 @@ LL | let _: &'static _ = &id(&String::new()); | | creates a temporary value which is freed while still in use | type annotation requires that borrow lasts for `'static` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0493, E0716. -For more information about an error, try `rustc --explain E0493`. +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr index 65e4dc22c2887..62c5c52764115 100644 --- a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr +++ b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr @@ -15,8 +15,8 @@ LL | struct Foo; | help: add `#[derive(ConstParamTy)]` to the struct | -LL - struct CompileTimeSettings { LL + #[derive(ConstParamTy)] +LL | struct CompileTimeSettings { | error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter @@ -27,8 +27,8 @@ LL | impl Foo { | help: add `#[derive(ConstParamTy)]` to the struct | -LL - struct CompileTimeSettings { LL + #[derive(ConstParamTy)] +LL | struct CompileTimeSettings { | error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr index c1ae42b3939dc..9f65e4f91be95 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.noopt.stderr @@ -1,17 +1,17 @@ error[E0080]: evaluation panicked: explicit panic - --> $DIR/collect-in-promoted-const.rs:11:19 + --> $DIR/collect-in-promoted-const.rs:9:19 | LL | const C: () = panic!(); | ^^^^^^^^ evaluation of `Fail::::C` failed here note: erroneous constant encountered - --> $DIR/collect-in-promoted-const.rs:22:21 + --> $DIR/collect-in-promoted-const.rs:17:21 | LL | let _val = &Fail::::C; | ^^^^^^^^^^^^ note: the above error was encountered while instantiating `fn f::` - --> $DIR/collect-in-promoted-const.rs:27:5 + --> $DIR/collect-in-promoted-const.rs:22:5 | LL | f::(); | ^^^^^^^^^^ diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr index 0d7ac48172c8c..9f65e4f91be95 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.opt.stderr @@ -1,35 +1,21 @@ error[E0080]: evaluation panicked: explicit panic - --> $DIR/collect-in-promoted-const.rs:11:19 - | -LL | const C: () = panic!(); - | ^^^^^^^^ evaluation of `Fail::::C` failed here - -note: erroneous constant encountered - --> $DIR/collect-in-promoted-const.rs:22:21 - | -LL | let _val = &Fail::::C; - | ^^^^^^^^^^^^ - -error[E0080]: evaluation panicked: explicit panic - --> $DIR/collect-in-promoted-const.rs:11:19 + --> $DIR/collect-in-promoted-const.rs:9:19 | LL | const C: () = panic!(); | ^^^^^^^^ evaluation of `Fail::::C` failed here note: erroneous constant encountered - --> $DIR/collect-in-promoted-const.rs:22:21 + --> $DIR/collect-in-promoted-const.rs:17:21 | LL | let _val = &Fail::::C; | ^^^^^^^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn f::` - --> $DIR/collect-in-promoted-const.rs:27:5 + --> $DIR/collect-in-promoted-const.rs:22:5 | LL | f::(); | ^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/required-consts/collect-in-promoted-const.rs b/tests/ui/consts/required-consts/collect-in-promoted-const.rs index 498328abe2160..c475720938697 100644 --- a/tests/ui/consts/required-consts/collect-in-promoted-const.rs +++ b/tests/ui/consts/required-consts/collect-in-promoted-const.rs @@ -1,17 +1,12 @@ //@revisions: noopt opt //@ build-fail //@[noopt] compile-flags: -Copt-level=0 -// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo=0 -//@[opt] compile-flags: -C debuginfo=0 //@[opt] compile-flags: -O //! Make sure we error on erroneous consts even if they get promoted. struct Fail(T); impl Fail { const C: () = panic!(); //~ERROR evaluation panicked: explicit panic - //[opt]~^ ERROR evaluation panicked: explicit panic - // (Not sure why optimizations lead to this being emitted twice, but as long as compilation - // fails either way it's fine.) } #[inline(never)] diff --git a/tests/ui/consts/std/conjure_zst.rs b/tests/ui/consts/std/conjure_zst.rs new file mode 100644 index 0000000000000..c04deae502b0f --- /dev/null +++ b/tests/ui/consts/std/conjure_zst.rs @@ -0,0 +1,10 @@ +#![feature(mem_conjure_zst)] + +use std::{convert::Infallible, mem}; + +const INVALID: Infallible = unsafe { mem::conjure_zst() }; +//~^ ERROR attempted to instantiate uninhabited type + +const VALID: () = unsafe { mem::conjure_zst() }; + +fn main() {} diff --git a/tests/ui/consts/std/conjure_zst.stderr b/tests/ui/consts/std/conjure_zst.stderr new file mode 100644 index 0000000000000..0c4a978b81ee6 --- /dev/null +++ b/tests/ui/consts/std/conjure_zst.stderr @@ -0,0 +1,12 @@ +error[E0080]: evaluation panicked: aborted execution: attempted to instantiate uninhabited type `Infallible` + --> $DIR/conjure_zst.rs:5:38 + | +LL | const INVALID: Infallible = unsafe { mem::conjure_zst() }; + | ^^^^^^^^^^^^^^^^^^ evaluation of `INVALID` failed inside this call + | +note: inside `conjure_zst::` + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/consts/zst_no_llvm_alloc.rs b/tests/ui/consts/zst_no_llvm_alloc.rs index 1e92e3bbd4c1b..ec5600ade16f1 100644 --- a/tests/ui/consts/zst_no_llvm_alloc.rs +++ b/tests/ui/consts/zst_no_llvm_alloc.rs @@ -1,10 +1,21 @@ //@ run-pass +// We need some non-1 alignment to test we use the alignment of the type in the compiler. #[repr(align(4))] struct Foo; static FOO: Foo = Foo; +// This tests for regression of https://github.com/rust-lang/rust/issues/147516 +// +// The compiler will codegen `&Zst` without creating a real allocation, just a properly aligned +// `usize` (i.e., ptr::dangling). However, code can add an arbitrary offset from that base +// allocation. We confirm here that we correctly codegen that offset combined with the necessary +// alignment of the base &() as a 1-ZST and &Foo as a 4-ZST. +const A: *const () = (&() as *const ()).wrapping_byte_add(2); +const B: *const () = (&Foo as *const _ as *const ()).wrapping_byte_add(usize::MAX); +const C: *const () = (&Foo as *const _ as *const ()).wrapping_byte_add(2); + fn main() { // There's no stable guarantee that these are true. // However, we want them to be true so that our LLVM IR and runtime are a bit faster: @@ -15,6 +26,13 @@ fn main() { let x: &'static Foo = &Foo; assert_eq!(x as *const Foo as usize, 4); + // * A 1-aligned ZST (1-ZST) is placed at 0x1. Then offsetting that by 2 results in 3. + // * Foo is a 4-aligned ZST, so is placed at 0x4. +2 = 6 + // * Foo is a 4-aligned ZST, so is placed at 0x4. +usize::MAX = -1 (same bit pattern) = 3 + assert_eq!(A.addr(), 3); + assert_eq!(B.addr(), 3); + assert_eq!(C.addr(), 6); + // The exact addresses returned by these library functions are not necessarily stable guarantees // but for now we assert that we're still matching. #[allow(dangling_pointers_from_temporaries)] diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.rs b/tests/ui/contracts/async-fn-contract-ice-145333.rs new file mode 100644 index 0000000000000..a6de8a786af96 --- /dev/null +++ b/tests/ui/contracts/async-fn-contract-ice-145333.rs @@ -0,0 +1,10 @@ +//@ compile-flags: --crate-type=lib +//@ edition: 2021 +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete + +#[core::contracts::ensures(|ret| *ret)] +//~^ ERROR contract annotations are not yet supported on async or gen functions +async fn _always_true(b: bool) -> bool { + b +} diff --git a/tests/ui/contracts/async-fn-contract-ice-145333.stderr b/tests/ui/contracts/async-fn-contract-ice-145333.stderr new file mode 100644 index 0000000000000..77f5379e6fb54 --- /dev/null +++ b/tests/ui/contracts/async-fn-contract-ice-145333.stderr @@ -0,0 +1,17 @@ +error: contract annotations are not yet supported on async or gen functions + --> $DIR/async-fn-contract-ice-145333.rs:6:1 + | +LL | #[core::contracts::ensures(|ret| *ret)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/async-fn-contract-ice-145333.rs:3:12 + | +LL | #![feature(contracts)] + | ^^^^^^^^^ + | + = note: see issue #128044 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs new file mode 100644 index 0000000000000..d234acb8268a1 --- /dev/null +++ b/tests/ui/contracts/contracts-disabled-side-effect-ensures.rs @@ -0,0 +1,17 @@ +//@ run-pass +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] + +extern crate core; +use core::contracts::ensures; + +#[ensures({*x = 0; |_ret| true})] +fn buggy_add(x: &mut u32, y: u32) { + *x = *x + y; +} + +fn main() { + let mut x = 10; + buggy_add(&mut x, 100); + assert_eq!(x, 110); +} diff --git a/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr b/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr new file mode 100644 index 0000000000000..dd9ebe9bd3556 --- /dev/null +++ b/tests/ui/contracts/contracts-disabled-side-effect-ensures.stderr @@ -0,0 +1,11 @@ +warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/contracts-disabled-side-effect-ensures.rs:2:12 + | +LL | #![feature(contracts)] + | ^^^^^^^^^ + | + = note: see issue #128044 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/contracts/cross-crate-checks/auxiliary/id.rs b/tests/ui/contracts/cross-crate-checks/auxiliary/id.rs new file mode 100644 index 0000000000000..c6210375a8482 --- /dev/null +++ b/tests/ui/contracts/cross-crate-checks/auxiliary/id.rs @@ -0,0 +1,16 @@ +//@ [unchk_pass] compile-flags: -Zcontract-checks=no +//@ [unchk_fail] compile-flags: -Zcontract-checks=yes +//@ [chk_pass] compile-flags: -Zcontract-checks=no +//@ [chk_fail] compile-flags: -Zcontract-checks=yes + +#![crate_type = "lib"] +#![feature(contracts)] + +extern crate core; +use core::contracts::requires; + +/// Example function with a spec to be called across a crate boundary. +#[requires(x > 0)] +pub fn id_if_positive(x: u32) -> u32 { + x +} diff --git a/tests/ui/contracts/cross-crate-checks/cross-crate.rs b/tests/ui/contracts/cross-crate-checks/cross-crate.rs new file mode 100644 index 0000000000000..43f81fe0d807a --- /dev/null +++ b/tests/ui/contracts/cross-crate-checks/cross-crate.rs @@ -0,0 +1,26 @@ +//@ aux-build:id.rs +//@ revisions: unchk_pass unchk_fail chk_pass chk_fail +// +// The dependency crate `id` can be compiled with runtime contract checking +// enabled independently of whether this crate is compiled with contract checks +// or not. +// +// chk/unchk indicates whether this crate is compiled with contracts or not +// and pass/fail indicates whether the `id` crate is compiled with contract checks. +// +//@ [unchk_pass] run-pass +//@ [unchk_fail] run-crash +//@ [chk_pass] run-pass +//@ [chk_fail] run-crash +// +// +//@ [unchk_pass] compile-flags: -Zcontract-checks=no +//@ [unchk_fail] compile-flags: -Zcontract-checks=no +//@ [chk_pass] compile-flags: -Zcontract-checks=yes +//@ [chk_fail] compile-flags: -Zcontract-checks=yes + +extern crate id; + +fn main() { + id::id_if_positive(0); +} diff --git a/tests/ui/contracts/empty-ensures.rs b/tests/ui/contracts/empty-ensures.rs new file mode 100644 index 0000000000000..d897f27bf6c94 --- /dev/null +++ b/tests/ui/contracts/empty-ensures.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -Zcontract-checks=yes +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] + +extern crate core; +use core::contracts::ensures; + +#[ensures()] +//~^ ERROR expected a `Fn(&_)` closure, found `()` [E0277] +fn foo(x: u32) -> u32 { + x * 2 +} + +fn main() { + foo(1); +} diff --git a/tests/ui/contracts/empty-ensures.stderr b/tests/ui/contracts/empty-ensures.stderr new file mode 100644 index 0000000000000..407a253bd8565 --- /dev/null +++ b/tests/ui/contracts/empty-ensures.stderr @@ -0,0 +1,25 @@ +warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/empty-ensures.rs:2:12 + | +LL | #![feature(contracts)] + | ^^^^^^^^^ + | + = note: see issue #128044 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: expected a `Fn(&_)` closure, found `()` + --> $DIR/empty-ensures.rs:8:1 + | +LL | #[ensures()] + | ^^^^^^^^^^^^ + | | + | expected an `Fn(&_)` closure, found `()` + | required by a bound introduced by this call + | + = help: the trait `for<'a> Fn(&'a _)` is not implemented for `()` +note: required by a bound in `build_check_ensures` + --> $SRC_DIR/core/src/contracts.rs:LL:COL + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/contracts/empty-requires.rs b/tests/ui/contracts/empty-requires.rs new file mode 100644 index 0000000000000..e3c72dcd66a17 --- /dev/null +++ b/tests/ui/contracts/empty-requires.rs @@ -0,0 +1,18 @@ +//@ dont-require-annotations: NOTE +//@ compile-flags: -Zcontract-checks=yes +#![feature(contracts)] +//~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] + +extern crate core; +use core::contracts::requires; + +#[requires()] +//~^ ERROR mismatched types [E0308] +//~| NOTE expected `bool`, found `()` +fn foo(x: u32) -> u32 { + x * 2 +} + +fn main() { + foo(1); +} diff --git a/tests/ui/contracts/empty-requires.stderr b/tests/ui/contracts/empty-requires.stderr new file mode 100644 index 0000000000000..b48e547b8cda7 --- /dev/null +++ b/tests/ui/contracts/empty-requires.stderr @@ -0,0 +1,18 @@ +warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/empty-requires.rs:3:12 + | +LL | #![feature(contracts)] + | ^^^^^^^^^ + | + = note: see issue #128044 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0308]: mismatched types + --> $DIR/empty-requires.rs:9:1 + | +LL | #[requires()] + | ^^^^^^^^^^^^^ expected `bool`, found `()` + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs index 6e613b53fc9b1..9dd5167c9e117 100644 --- a/tests/ui/contracts/internal_machinery/contract-intrinsics.rs +++ b/tests/ui/contracts/internal_machinery/contract-intrinsics.rs @@ -1,36 +1,23 @@ -//@ revisions: default unchk_pass chk_pass chk_fail_ensures chk_fail_requires +//@ revisions: default chk_fail_ensures chk_fail_requires // //@ [default] run-pass -//@ [unchk_pass] run-pass -//@ [chk_pass] run-pass //@ [chk_fail_requires] run-crash //@ [chk_fail_ensures] run-crash -// -//@ [unchk_pass] compile-flags: -Zcontract-checks=no -//@ [chk_pass] compile-flags: -Zcontract-checks=yes -//@ [chk_fail_requires] compile-flags: -Zcontract-checks=yes -//@ [chk_fail_ensures] compile-flags: -Zcontract-checks=yes -#![feature(cfg_contract_checks, contracts_internals, core_intrinsics)] +#![feature(contracts_internals, core_intrinsics)] fn main() { - #[cfg(any(default, unchk_pass))] // default: disabled - assert_eq!(core::intrinsics::contract_checks(), false); - - #[cfg(chk_pass)] // explicitly enabled - assert_eq!(core::intrinsics::contract_checks(), true); - // always pass core::intrinsics::contract_check_requires(|| true); - // fail if enabled - #[cfg(any(default, unchk_pass, chk_fail_requires))] + // always fail + #[cfg(chk_fail_requires)] core::intrinsics::contract_check_requires(|| false); let doubles_to_two = { let old = 2; move |ret: &u32 | ret + ret == old }; // Always pass - core::intrinsics::contract_check_ensures(doubles_to_two, 1); + core::intrinsics::contract_check_ensures(Some(doubles_to_two), 1); - // Fail if enabled - #[cfg(any(default, unchk_pass, chk_fail_ensures))] - core::intrinsics::contract_check_ensures(doubles_to_two, 2); + // always fail + #[cfg(chk_fail_ensures)] + core::intrinsics::contract_check_ensures(Some(doubles_to_two), 2); } diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr index a60ce1602659b..acce6b1fbc729 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_fail_post.stderr @@ -1,5 +1,5 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:15:12 + --> $DIR/contract-lang-items.rs:8:12 | LL | #![feature(contracts)] // to access core::contracts | ^^^^^^^^^ diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr index a60ce1602659b..acce6b1fbc729 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.chk_pass.stderr @@ -1,5 +1,5 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:15:12 + --> $DIR/contract-lang-items.rs:8:12 | LL | #![feature(contracts)] // to access core::contracts | ^^^^^^^^^ diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.rs b/tests/ui/contracts/internal_machinery/contract-lang-items.rs index ac72d233bf6b4..ad88ebfe22e3b 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.rs +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.rs @@ -1,25 +1,16 @@ -//@ revisions: unchk_pass unchk_fail_post chk_pass chk_fail_post +//@ revisions: unchk_pass chk_pass chk_fail_post // //@ [unchk_pass] run-pass -//@ [unchk_fail_post] run-pass //@ [chk_pass] run-pass // //@ [chk_fail_post] run-crash -// -//@ [unchk_pass] compile-flags: -Zcontract-checks=no -//@ [unchk_fail_post] compile-flags: -Zcontract-checks=no -// -//@ [chk_pass] compile-flags: -Zcontract-checks=yes -//@ [chk_fail_post] compile-flags: -Zcontract-checks=yes #![feature(contracts)] // to access core::contracts //~^ WARN the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes [incomplete_features] #![feature(contracts_internals)] // to access check_requires lang item #![feature(core_intrinsics)] fn foo(x: Baz) -> i32 { - let injected_checker = { - core::contracts::build_check_ensures(|ret| *ret > 100) - }; + let injected_checker = Some(core::contracts::build_check_ensures(|ret| *ret > 100)); let ret = x.baz + 50; core::intrinsics::contract_check_ensures(injected_checker, ret) @@ -29,11 +20,11 @@ struct Baz { baz: i32 } const BAZ_PASS_PRE_POST: Baz = Baz { baz: 100 }; -#[cfg(any(unchk_fail_post, chk_fail_post))] +#[cfg(chk_fail_post)] const BAZ_FAIL_POST: Baz = Baz { baz: 10 }; fn main() { assert_eq!(foo(BAZ_PASS_PRE_POST), 150); - #[cfg(any(unchk_fail_post, chk_fail_post))] + #[cfg(chk_fail_post)] foo(BAZ_FAIL_POST); } diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr deleted file mode 100644 index a60ce1602659b..0000000000000 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_fail_post.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:15:12 - | -LL | #![feature(contracts)] // to access core::contracts - | ^^^^^^^^^ - | - = note: see issue #128044 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr index a60ce1602659b..acce6b1fbc729 100644 --- a/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr +++ b/tests/ui/contracts/internal_machinery/contract-lang-items.unchk_pass.stderr @@ -1,5 +1,5 @@ warning: the feature `contracts` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/contract-lang-items.rs:15:12 + --> $DIR/contract-lang-items.rs:8:12 | LL | #![feature(contracts)] // to access core::contracts | ^^^^^^^^^ diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.rs b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs index 6e5a7a3f95005..48bd376594f22 100644 --- a/tests/ui/contracts/internal_machinery/internal-feature-gating.rs +++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.rs @@ -2,11 +2,9 @@ fn main() { // intrinsics are guarded by contracts_internals feature gate. - core::intrinsics::contract_checks(); - //~^ ERROR use of unstable library feature `contracts_internals` core::intrinsics::contract_check_requires(|| true); //~^ ERROR use of unstable library feature `contracts_internals` - core::intrinsics::contract_check_ensures( |_|true, &1); + core::intrinsics::contract_check_ensures(Some(|_: &&u32| true), &1); //~^ ERROR use of unstable library feature `contracts_internals` core::contracts::build_check_ensures(|_: &()| true); diff --git a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr index 1e39bd62e245b..c1318fc15a78d 100644 --- a/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr +++ b/tests/ui/contracts/internal_machinery/internal-feature-gating.stderr @@ -1,5 +1,5 @@ error[E0658]: contract internal machinery is for internal use only - --> $DIR/internal-feature-gating.rs:16:28 + --> $DIR/internal-feature-gating.rs:14:28 | LL | fn identity_1() -> i32 contract_requires(|| true) { 10 } | ^^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | fn identity_1() -> i32 contract_requires(|| true) { 10 } = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: contract internal machinery is for internal use only - --> $DIR/internal-feature-gating.rs:18:28 + --> $DIR/internal-feature-gating.rs:16:28 | LL | fn identity_2() -> i32 contract_ensures(|_| true) { 10 } | ^^^^^^^^^^^^^^^^ @@ -21,16 +21,6 @@ LL | fn identity_2() -> i32 contract_ensures(|_| true) { 10 } error[E0658]: use of unstable library feature `contracts_internals` --> $DIR/internal-feature-gating.rs:5:5 | -LL | core::intrinsics::contract_checks(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #128044 for more information - = help: add `#![feature(contracts_internals)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: use of unstable library feature `contracts_internals` - --> $DIR/internal-feature-gating.rs:7:5 - | LL | core::intrinsics::contract_check_requires(|| true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | @@ -39,9 +29,9 @@ LL | core::intrinsics::contract_check_requires(|| true); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `contracts_internals` - --> $DIR/internal-feature-gating.rs:9:5 + --> $DIR/internal-feature-gating.rs:7:5 | -LL | core::intrinsics::contract_check_ensures( |_|true, &1); +LL | core::intrinsics::contract_check_ensures(Some(|_: &&u32| true), &1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #128044 for more information @@ -49,7 +39,7 @@ LL | core::intrinsics::contract_check_ensures( |_|true, &1); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `contracts_internals` - --> $DIR/internal-feature-gating.rs:12:5 + --> $DIR/internal-feature-gating.rs:10:5 | LL | core::contracts::build_check_ensures(|_: &()| true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -58,6 +48,6 @@ LL | core::contracts::build_check_ensures(|_: &()| true); = help: add `#![feature(contracts_internals)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/coroutine/copy-fast-path-query-cycle.rs b/tests/ui/coroutine/copy-fast-path-query-cycle.rs new file mode 100644 index 0000000000000..644cba0d47af2 --- /dev/null +++ b/tests/ui/coroutine/copy-fast-path-query-cycle.rs @@ -0,0 +1,40 @@ +//@ edition: 2024 +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// Regression test for #146813. We previously used a pseudo-canonical +// query during HIR typeck which caused a query cycle when looking at the +// witness of a coroutine. + +use std::future::Future; + +trait ConnectMiddleware {} + +trait ConnectHandler: Sized { + fn with(self, _: M) -> impl ConnectHandler + where + M: ConnectMiddleware, + { + LayeredConnectHandler + } +} + +struct LayeredConnectHandler; +impl ConnectHandler for LayeredConnectHandler {} +impl ConnectHandler for F where F: FnOnce() {} + +impl ConnectMiddleware for F +where + F: FnOnce() -> Fut, + Fut: Future + Send, +{ +} + +pub async fn fails() { + { || {} } + .with(async || ()) + .with(async || ()) + .with(async || ()); +} +fn main() {} diff --git a/tests/ui/coroutine/gen_block_panic.rs b/tests/ui/coroutine/gen_block_panic.rs index b6362d5046a3b..5417ed583e8ca 100644 --- a/tests/ui/coroutine/gen_block_panic.rs +++ b/tests/ui/coroutine/gen_block_panic.rs @@ -1,6 +1,7 @@ //@ edition: 2024 //@ run-pass //@ needs-unwind +//@ ignore-backends: gcc #![feature(gen_blocks)] fn main() { diff --git a/tests/ui/coroutine/gen_block_panic.stderr b/tests/ui/coroutine/gen_block_panic.stderr index a43c9e03691a5..d0a146e7baf9a 100644 --- a/tests/ui/coroutine/gen_block_panic.stderr +++ b/tests/ui/coroutine/gen_block_panic.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/gen_block_panic.rs:10:9 + --> $DIR/gen_block_panic.rs:11:9 | LL | panic!("foo"); | ------------- any code following this expression is unreachable diff --git a/tests/ui/coroutine/handle_opaques_before_coroutines.rs b/tests/ui/coroutine/handle_opaques_before_coroutines.rs new file mode 100644 index 0000000000000..2771c77429cac --- /dev/null +++ b/tests/ui/coroutine/handle_opaques_before_coroutines.rs @@ -0,0 +1,15 @@ +// test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/239 +//@edition: 2024 +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +fn foo<'a>() -> impl Send { + if false { + foo(); + } + async {} +} + +fn main() {} diff --git a/tests/ui/coroutine/moved-twice.rs b/tests/ui/coroutine/moved-twice.rs new file mode 100644 index 0000000000000..72b83e274c929 --- /dev/null +++ b/tests/ui/coroutine/moved-twice.rs @@ -0,0 +1,27 @@ +//! Regression test for #122630 +//@ compile-flags: -Zvalidate-mir + +#![feature(coroutines, coroutine_trait, yield_expr)] + +use std::ops::Coroutine; + +const FOO_SIZE: usize = 1024; +struct Foo([u8; FOO_SIZE]); + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn overlap_move_points() -> impl Coroutine { + #[coroutine] static || { + let first = Foo([0; FOO_SIZE]); + yield; + let second = first; + yield; + let second = first; + //~^ ERROR: use of moved value: `first` [E0382] + yield; + } +} + +fn main() {} diff --git a/tests/ui/coroutine/moved-twice.stderr b/tests/ui/coroutine/moved-twice.stderr new file mode 100644 index 0000000000000..2b21f6c59f0bc --- /dev/null +++ b/tests/ui/coroutine/moved-twice.stderr @@ -0,0 +1,24 @@ +error[E0382]: use of moved value: `first` + --> $DIR/moved-twice.rs:21:22 + | +LL | let first = Foo([0; FOO_SIZE]); + | ----- move occurs because `first` has type `Foo`, which does not implement the `Copy` trait +LL | yield; +LL | let second = first; + | ----- value moved here +LL | yield; +LL | let second = first; + | ^^^^^ value used here after move + | +note: if `Foo` implemented `Clone`, you could clone the value + --> $DIR/moved-twice.rs:9:1 + | +LL | struct Foo([u8; FOO_SIZE]); + | ^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let second = first; + | ----- you could clone this value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/coverage-attr/allowed-positions.stderr b/tests/ui/coverage-attr/allowed-positions.stderr index 1690d089a8c5c..09d6bac497d21 100644 --- a/tests/ui/coverage-attr/allowed-positions.stderr +++ b/tests/ui/coverage-attr/allowed-positions.stderr @@ -14,7 +14,7 @@ error: `#[coverage]` attribute cannot be used on type aliases LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on traits --> $DIR/allowed-positions.rs:17:1 @@ -22,7 +22,7 @@ error: `#[coverage]` attribute cannot be used on traits LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on associated consts --> $DIR/allowed-positions.rs:19:5 @@ -30,7 +30,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on associated types --> $DIR/allowed-positions.rs:22:5 @@ -38,7 +38,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on required trait methods --> $DIR/allowed-positions.rs:25:5 @@ -46,7 +46,7 @@ error: `#[coverage]` attribute cannot be used on required trait methods LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to impl blocks, functions, closures, provided trait methods, trait methods in impl blocks, inherent methods, modules, and crates + = help: `#[coverage]` can be applied to closures, crates, functions, impl blocks, inherent methods, modules, provided trait methods, and trait methods in impl blocks error: `#[coverage]` attribute cannot be used on required trait methods --> $DIR/allowed-positions.rs:31:5 @@ -54,7 +54,7 @@ error: `#[coverage]` attribute cannot be used on required trait methods LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to impl blocks, functions, closures, provided trait methods, trait methods in impl blocks, inherent methods, modules, and crates + = help: `#[coverage]` can be applied to closures, crates, functions, impl blocks, inherent methods, modules, provided trait methods, and trait methods in impl blocks error: `#[coverage]` attribute cannot be used on associated types --> $DIR/allowed-positions.rs:39:5 @@ -62,7 +62,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on associated types --> $DIR/allowed-positions.rs:56:5 @@ -70,7 +70,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on structs --> $DIR/allowed-positions.rs:61:1 @@ -78,7 +78,7 @@ error: `#[coverage]` attribute cannot be used on structs LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on struct fields --> $DIR/allowed-positions.rs:63:5 @@ -86,7 +86,7 @@ error: `#[coverage]` attribute cannot be used on struct fields LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on foreign statics --> $DIR/allowed-positions.rs:76:5 @@ -94,7 +94,7 @@ error: `#[coverage]` attribute cannot be used on foreign statics LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on foreign types --> $DIR/allowed-positions.rs:79:5 @@ -102,7 +102,7 @@ error: `#[coverage]` attribute cannot be used on foreign types LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on foreign functions --> $DIR/allowed-positions.rs:82:5 @@ -110,7 +110,7 @@ error: `#[coverage]` attribute cannot be used on foreign functions LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to methods, impl blocks, functions, closures, modules, and crates + = help: `#[coverage]` can be applied to closures, crates, functions, impl blocks, methods, and modules error: `#[coverage]` attribute cannot be used on statements --> $DIR/allowed-positions.rs:88:5 @@ -118,7 +118,7 @@ error: `#[coverage]` attribute cannot be used on statements LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on statements --> $DIR/allowed-positions.rs:94:5 @@ -126,7 +126,7 @@ error: `#[coverage]` attribute cannot be used on statements LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on match arms --> $DIR/allowed-positions.rs:110:9 @@ -134,7 +134,7 @@ error: `#[coverage]` attribute cannot be used on match arms LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: `#[coverage]` attribute cannot be used on expressions --> $DIR/allowed-positions.rs:114:5 @@ -142,7 +142,7 @@ error: `#[coverage]` attribute cannot be used on expressions LL | #[coverage(off)] | ^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error: aborting due to 18 previous errors diff --git a/tests/ui/coverage-attr/name-value.stderr b/tests/ui/coverage-attr/name-value.stderr index 77abaa42e311f..06e59e5a8646a 100644 --- a/tests/ui/coverage-attr/name-value.stderr +++ b/tests/ui/coverage-attr/name-value.stderr @@ -49,7 +49,7 @@ error: `#[coverage]` attribute cannot be used on structs LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:26:1 @@ -87,7 +87,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:35:1 @@ -110,7 +110,7 @@ error: `#[coverage]` attribute cannot be used on traits LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:39:5 @@ -133,7 +133,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:44:5 @@ -156,7 +156,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:50:1 @@ -194,7 +194,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:58:5 @@ -217,7 +217,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage = "off"] | ^^^^^^^^^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/name-value.rs:64:1 diff --git a/tests/ui/coverage-attr/word-only.stderr b/tests/ui/coverage-attr/word-only.stderr index 5fcffacc7fa7f..05478695256f9 100644 --- a/tests/ui/coverage-attr/word-only.stderr +++ b/tests/ui/coverage-attr/word-only.stderr @@ -43,7 +43,7 @@ error: `#[coverage]` attribute cannot be used on structs LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:26:1 @@ -77,7 +77,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:35:1 @@ -98,7 +98,7 @@ error: `#[coverage]` attribute cannot be used on traits LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:39:5 @@ -119,7 +119,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:44:5 @@ -140,7 +140,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:50:1 @@ -174,7 +174,7 @@ error: `#[coverage]` attribute cannot be used on associated consts LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:58:5 @@ -195,7 +195,7 @@ error: `#[coverage]` attribute cannot be used on associated types LL | #[coverage] | ^^^^^^^^^^^ | - = help: `#[coverage]` can be applied to functions, impl blocks, modules, and crates + = help: `#[coverage]` can be applied to crates, functions, impl blocks, and modules error[E0539]: malformed `coverage` attribute input --> $DIR/word-only.rs:64:1 diff --git a/tests/ui/crate-loading/missing-std.rs b/tests/ui/crate-loading/missing-std.rs index aed8b0c530a69..0fb45b4cfe987 100644 --- a/tests/ui/crate-loading/missing-std.rs +++ b/tests/ui/crate-loading/missing-std.rs @@ -1,6 +1,7 @@ //@ compile-flags: --target x86_64-unknown-uefi //@ needs-llvm-components: x86 //@ rustc-env:CARGO_CRATE_NAME=foo +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] extern crate core; diff --git a/tests/ui/crate-loading/missing-std.stderr b/tests/ui/crate-loading/missing-std.stderr index 3eb6c2946d354..67ed73a2ec6f6 100644 --- a/tests/ui/crate-loading/missing-std.stderr +++ b/tests/ui/crate-loading/missing-std.stderr @@ -1,5 +1,5 @@ error[E0463]: can't find crate for `core` - --> $DIR/missing-std.rs:6:1 + --> $DIR/missing-std.rs:7:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ can't find crate diff --git a/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs b/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs index 86d637b579dc6..c6cfae1e5452c 100644 --- a/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs +++ b/tests/ui/cross-crate/exporting-impl-from-root-causes-ice-2472.rs @@ -1,6 +1,9 @@ //@ run-pass //@ aux-build:exporting-impl-from-root-causes-ice-2472-b.rs - +//@ ignore-ios FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-tvos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-watchos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? +//@ ignore-visionos FIXME(madsmtm): For some reason the necessary dylib isn't copied to the remote? extern crate exporting_impl_from_root_causes_ice_2472_b as lib; diff --git a/tests/ui/cross/cross-file-errors/main.stderr b/tests/ui/cross/cross-file-errors/main.stderr index c7dea801acfbd..db7b3a84fc8b3 100644 --- a/tests/ui/cross/cross-file-errors/main.stderr +++ b/tests/ui/cross/cross-file-errors/main.stderr @@ -1,5 +1,5 @@ error: in expressions, `_` can only be used on the left-hand side of an assignment - --> $DIR/underscore.rs:6:9 + --> $DIR/underscore.rs:5:9 | LL | _ | ^ `_` not allowed here diff --git a/tests/ui/cross/cross-file-errors/underscore.rs b/tests/ui/cross/cross-file-errors/underscore.rs index 73eb36cec24cb..9bad2268b98e9 100644 --- a/tests/ui/cross/cross-file-errors/underscore.rs +++ b/tests/ui/cross/cross-file-errors/underscore.rs @@ -1,5 +1,4 @@ //@ ignore-auxiliary (used by `./main.rs`) -#![crate_type = "lib"] macro_rules! underscore { () => ( diff --git a/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.rs b/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.rs new file mode 100644 index 0000000000000..f0260d090820c --- /dev/null +++ b/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.rs @@ -0,0 +1,20 @@ +// https://github.com/rust-lang/rust/issues/66667 +fn first() { + second == 1 //~ ERROR binary operation + //~^ ERROR mismatched types + //~| ERROR mismatched types +} + +fn second() { + first == 1 //~ ERROR binary operation + //~^ ERROR mismatched types + //~| ERROR mismatched types +} + +fn bar() { + bar == 1 //~ ERROR binary operation + //~^ ERROR mismatched types + //~| ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.stderr b/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.stderr new file mode 100644 index 0000000000000..6d9f8d85a9cbe --- /dev/null +++ b/tests/ui/cycle-trait/cycle-error-comparing-function-inside-itself-66667.stderr @@ -0,0 +1,79 @@ +error[E0369]: binary operation `==` cannot be applied to type `fn() {second}` + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:3:12 + | +LL | second == 1 + | ------ ^^ - {integer} + | | + | fn() {second} + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:3:15 + | +LL | second == 1 + | ^ expected fn item, found integer + | + = note: expected fn item `fn() {second}` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:3:5 + | +LL | fn first() { + | - help: try adding a return type: `-> bool` +LL | second == 1 + | ^^^^^^^^^^^ expected `()`, found `bool` + +error[E0369]: binary operation `==` cannot be applied to type `fn() {first}` + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:9:11 + | +LL | first == 1 + | ----- ^^ - {integer} + | | + | fn() {first} + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:9:14 + | +LL | first == 1 + | ^ expected fn item, found integer + | + = note: expected fn item `fn() {first}` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:9:5 + | +LL | fn second() { + | - help: try adding a return type: `-> bool` +LL | first == 1 + | ^^^^^^^^^^ expected `()`, found `bool` + +error[E0369]: binary operation `==` cannot be applied to type `fn() {bar}` + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:15:9 + | +LL | bar == 1 + | --- ^^ - {integer} + | | + | fn() {bar} + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:15:12 + | +LL | bar == 1 + | ^ expected fn item, found integer + | + = note: expected fn item `fn() {bar}` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/cycle-error-comparing-function-inside-itself-66667.rs:15:5 + | +LL | fn bar() { + | - help: try adding a return type: `-> bool` +LL | bar == 1 + | ^^^^^^^^ expected `()`, found `bool` + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0308, E0369. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/darwin-objc/darwin-objc-bad-arg.rs b/tests/ui/darwin-objc/darwin-objc-bad-arg.rs new file mode 100644 index 0000000000000..70eb83aa052d1 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-arg.rs @@ -0,0 +1,36 @@ +// Test that `objc::class!` and `objc::selector!` only take string literals. + +//@ edition: 2024 +//@ only-apple + +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +pub fn main() { + let s = "NSObject"; + objc::class!(s); + //~^ ERROR attribute value must be a literal + + objc::class!(NSObject); + //~^ ERROR attribute value must be a literal + + objc::class!(123); + //~^ ERROR `objc::class!` expected a string literal + + objc::class!("NSObject\0"); + //~^ ERROR `objc::class!` may not contain null characters + + let s = "alloc"; + objc::selector!(s); + //~^ ERROR attribute value must be a literal + + objc::selector!(alloc); + //~^ ERROR attribute value must be a literal + + objc::selector!(123); + //~^ ERROR `objc::selector!` expected a string literal + + objc::selector!("alloc\0"); + //~^ ERROR `objc::selector!` may not contain null characters +} diff --git a/tests/ui/darwin-objc/darwin-objc-bad-arg.stderr b/tests/ui/darwin-objc/darwin-objc-bad-arg.stderr new file mode 100644 index 0000000000000..99eeb27e30c1b --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-arg.stderr @@ -0,0 +1,50 @@ +error: attribute value must be a literal + --> $DIR/darwin-objc-bad-arg.rs:12:18 + | +LL | objc::class!(s); + | ^ + +error: attribute value must be a literal + --> $DIR/darwin-objc-bad-arg.rs:15:18 + | +LL | objc::class!(NSObject); + | ^^^^^^^^ + +error: `objc::class!` expected a string literal + --> $DIR/darwin-objc-bad-arg.rs:18:18 + | +LL | objc::class!(123); + | ^^^ + +error: `objc::class!` may not contain null characters + --> $DIR/darwin-objc-bad-arg.rs:21:18 + | +LL | objc::class!("NSObject\0"); + | ^^^^^^^^^^^^ + +error: attribute value must be a literal + --> $DIR/darwin-objc-bad-arg.rs:25:21 + | +LL | objc::selector!(s); + | ^ + +error: attribute value must be a literal + --> $DIR/darwin-objc-bad-arg.rs:28:21 + | +LL | objc::selector!(alloc); + | ^^^^^ + +error: `objc::selector!` expected a string literal + --> $DIR/darwin-objc-bad-arg.rs:31:21 + | +LL | objc::selector!(123); + | ^^^ + +error: `objc::selector!` may not contain null characters + --> $DIR/darwin-objc-bad-arg.rs:34:21 + | +LL | objc::selector!("alloc\0"); + | ^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/darwin-objc/darwin-objc-bad-const.rs b/tests/ui/darwin-objc/darwin-objc-bad-const.rs new file mode 100644 index 0000000000000..ccf28697b482a --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-const.rs @@ -0,0 +1,17 @@ +// Test that `objc::class!` and `objc::selector!` aren't `const` expressions. +// The system gives them their final values at dynamic load time. + +//@ edition: 2024 +//@ only-apple + +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +pub const CLASS: objc::Class = objc::class!("NSObject"); +//~^ ERROR cannot access extern static `CLASS::VAL` [E0080] + +pub const SELECTOR: objc::SEL = objc::selector!("alloc"); +//~^ ERROR cannot access extern static `SELECTOR::VAL` [E0080] + +pub fn main() {} diff --git a/tests/ui/darwin-objc/darwin-objc-bad-const.stderr b/tests/ui/darwin-objc/darwin-objc-bad-const.stderr new file mode 100644 index 0000000000000..43d0b7d761f17 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-const.stderr @@ -0,0 +1,19 @@ +error[E0080]: cannot access extern static `CLASS::VAL` + --> $DIR/darwin-objc-bad-const.rs:11:32 + | +LL | pub const CLASS: objc::Class = objc::class!("NSObject"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `CLASS` failed here + | + = note: this error originates in the macro `objc::class` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: cannot access extern static `SELECTOR::VAL` + --> $DIR/darwin-objc-bad-const.rs:14:33 + | +LL | pub const SELECTOR: objc::SEL = objc::selector!("alloc"); + | ^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `SELECTOR` failed here + | + = note: this error originates in the macro `objc::selector` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/tests/ui/darwin-objc/darwin-objc-bad-ref.rs b/tests/ui/darwin-objc/darwin-objc-bad-ref.rs new file mode 100644 index 0000000000000..fb1437366dd43 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-ref.rs @@ -0,0 +1,31 @@ +// Test that `objc::class!` and `objc::selector!` can't be returned by reference. +// A single instance may have multiple addresses (e.g. across dylib boundaries). + +//@ edition: 2024 +//@ only-apple + +#![feature(darwin_objc)] + +use std::os::darwin::objc; + +pub fn class_ref<'a>() -> &'a objc::Class { + &objc::class!("NSObject") + //~^ ERROR cannot return reference to temporary value [E0515] +} + +pub fn class_ref_static() -> &'static objc::Class { + &objc::class!("NSObject") + //~^ ERROR cannot return reference to temporary value [E0515] +} + +pub fn selector_ref<'a>() -> &'a objc::SEL { + &objc::selector!("alloc") + //~^ ERROR cannot return reference to temporary value [E0515] +} + +pub fn selector_ref_static() -> &'static objc::SEL { + &objc::selector!("alloc") + //~^ ERROR cannot return reference to temporary value [E0515] +} + +pub fn main() {} diff --git a/tests/ui/darwin-objc/darwin-objc-bad-ref.stderr b/tests/ui/darwin-objc/darwin-objc-bad-ref.stderr new file mode 100644 index 0000000000000..b09e6a75c844d --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-bad-ref.stderr @@ -0,0 +1,39 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/darwin-objc-bad-ref.rs:12:5 + | +LL | &objc::class!("NSObject") + | ^------------------------ + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/darwin-objc-bad-ref.rs:17:5 + | +LL | &objc::class!("NSObject") + | ^------------------------ + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/darwin-objc-bad-ref.rs:22:5 + | +LL | &objc::selector!("alloc") + | ^------------------------ + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error[E0515]: cannot return reference to temporary value + --> $DIR/darwin-objc-bad-ref.rs:27:5 + | +LL | &objc::selector!("alloc") + | ^------------------------ + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/darwin-objc/darwin-objc-class-selector.rs b/tests/ui/darwin-objc/darwin-objc-class-selector.rs new file mode 100644 index 0000000000000..b9a2fc3634f46 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-class-selector.rs @@ -0,0 +1,31 @@ +// Call `[NSObject class]` using `objc::class!` and `objc::selector!`. + +//@ edition: 2024 +//@ only-apple +//@ run-pass + +#![feature(darwin_objc)] + +use std::mem::transmute; +use std::os::darwin::objc; + +#[link(name = "Foundation", kind = "framework")] +unsafe extern "C" {} + +#[link(name = "objc", kind = "dylib")] +unsafe extern "C" { + unsafe fn objc_msgSend(); +} + +fn main() { + let msg_send_fn = unsafe { + transmute::< + unsafe extern "C" fn(), + unsafe extern "C" fn(objc::Class, objc::SEL) -> objc::Class, + >(objc_msgSend) + }; + let static_sel = objc::selector!("class"); + let static_class = objc::class!("NSObject"); + let runtime_class = unsafe { msg_send_fn(static_class, static_sel) }; + assert_eq!(static_class, runtime_class); +} diff --git a/tests/ui/darwin-objc/darwin-objc-class.rs b/tests/ui/darwin-objc/darwin-objc-class.rs new file mode 100644 index 0000000000000..851149d872683 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-class.rs @@ -0,0 +1,39 @@ +// Test that `objc::class!` returns the same thing as `objc_lookUpClass`. + +//@ edition: 2024 +//@ only-apple +//@ run-pass + +#![feature(darwin_objc)] + +use std::ffi::c_char; +use std::os::darwin::objc; + +#[link(name = "Foundation", kind = "framework")] +unsafe extern "C" {} + +#[link(name = "objc")] +unsafe extern "C" { + fn objc_lookUpClass(methname: *const c_char) -> objc::Class; +} + +fn get_object_class() -> objc::Class { + objc::class!("NSObject") +} + +fn lookup_object_class() -> objc::Class { + unsafe { objc_lookUpClass(c"NSObject".as_ptr()) } +} + +fn get_string_class() -> objc::Class { + objc::class!("NSString") +} + +fn lookup_string_class() -> objc::Class { + unsafe { objc_lookUpClass(c"NSString".as_ptr()) } +} + +fn main() { + assert_eq!(get_object_class(), lookup_object_class()); + assert_eq!(get_string_class(), lookup_string_class()); +} diff --git a/tests/ui/darwin-objc/darwin-objc-selector.rs b/tests/ui/darwin-objc/darwin-objc-selector.rs new file mode 100644 index 0000000000000..008ae4c4ca457 --- /dev/null +++ b/tests/ui/darwin-objc/darwin-objc-selector.rs @@ -0,0 +1,36 @@ +// Test that `objc::selector!` returns the same thing as `sel_registerName`. + +//@ edition: 2024 +//@ only-apple +//@ run-pass + +#![feature(darwin_objc)] + +use std::ffi::c_char; +use std::os::darwin::objc; + +#[link(name = "objc")] +unsafe extern "C" { + fn sel_registerName(methname: *const c_char) -> objc::SEL; +} + +fn get_alloc_selector() -> objc::SEL { + objc::selector!("alloc") +} + +fn register_alloc_selector() -> objc::SEL { + unsafe { sel_registerName(c"alloc".as_ptr()) } +} + +fn get_init_selector() -> objc::SEL { + objc::selector!("initWithCString:encoding:") +} + +fn register_init_selector() -> objc::SEL { + unsafe { sel_registerName(c"initWithCString:encoding:".as_ptr()) } +} + +fn main() { + assert_eq!(get_alloc_selector(), register_alloc_selector()); + assert_eq!(get_init_selector(), register_init_selector()); +} diff --git a/tests/ui/debuginfo/dest_prop_debuginfo-147485.rs b/tests/ui/debuginfo/dest_prop_debuginfo-147485.rs new file mode 100644 index 0000000000000..652660d473b15 --- /dev/null +++ b/tests/ui/debuginfo/dest_prop_debuginfo-147485.rs @@ -0,0 +1,18 @@ +//@ build-pass +//@ compile-flags: -g -O + +// Regression test for #147485. + +#![crate_type = "lib"] + +pub fn foo(a: bool, b: bool) -> bool { + let mut c = &a; + if false { + return *c; + } + let d = b && a; + if d { + c = &b; + } + b +} diff --git a/tests/ui/debuginfo/ref_prop_debuginfo-147485.rs b/tests/ui/debuginfo/ref_prop_debuginfo-147485.rs new file mode 100644 index 0000000000000..15899626aff7b --- /dev/null +++ b/tests/ui/debuginfo/ref_prop_debuginfo-147485.rs @@ -0,0 +1,16 @@ +//@ build-pass +//@ compile-flags: -g -O + +// Regression test for #147485. + +#![crate_type = "lib"] + +pub fn f(x: *const usize) -> &'static usize { + let mut a = unsafe { &*x }; + a = unsafe { &*x }; + a +} + +pub fn g() { + f(&0); +} diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs index 3a8d9c998cf74..e0d0f9cff324d 100644 --- a/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs +++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_off.rs @@ -22,6 +22,7 @@ //@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu //@[x86_64_uwp_g] needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core)] diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs index 75b8141cc385f..e6f830ea73eb4 100644 --- a/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs +++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_packed.rs @@ -21,6 +21,7 @@ //@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu //@[x86_64_uwp_g] needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core)] diff --git a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs index 3f4da555aadf1..e8edbc669b5cc 100644 --- a/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs +++ b/tests/ui/debuginfo/windows_gnu_split_debuginfo_unpacked.rs @@ -21,6 +21,7 @@ //@[x86_64_uwp_g] compile-flags: --target x86_64-uwp-windows-gnu //@[x86_64_uwp_g] needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core)] diff --git a/tests/ui/delegation/fn-header-variadic.rs b/tests/ui/delegation/fn-header-variadic.rs index 2c83d64d0b3ff..346c49f08e5d3 100644 --- a/tests/ui/delegation/fn-header-variadic.rs +++ b/tests/ui/delegation/fn-header-variadic.rs @@ -1,4 +1,5 @@ //@ aux-crate:fn_header_aux=fn-header-aux.rs +//@ ignore-backends: gcc #![feature(c_variadic)] #![feature(fn_delegation)] diff --git a/tests/ui/delegation/fn-header-variadic.stderr b/tests/ui/delegation/fn-header-variadic.stderr index 688a965fb4d5c..c2d7672939fcc 100644 --- a/tests/ui/delegation/fn-header-variadic.stderr +++ b/tests/ui/delegation/fn-header-variadic.stderr @@ -1,5 +1,5 @@ error: delegation to C-variadic functions is not allowed - --> $DIR/fn-header-variadic.rs:11:17 + --> $DIR/fn-header-variadic.rs:12:17 | LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {} | ------------------------------------------------------------- callee defined here @@ -8,7 +8,7 @@ LL | reuse to_reuse::variadic_fn; | ^^^^^^^^^^^ error: delegation to C-variadic functions is not allowed - --> $DIR/fn-header-variadic.rs:13:22 + --> $DIR/fn-header-variadic.rs:14:22 | LL | reuse fn_header_aux::variadic_fn_extern; | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/delegation/unsupported.current.stderr b/tests/ui/delegation/unsupported.current.stderr new file mode 100644 index 0000000000000..55564e8f231f7 --- /dev/null +++ b/tests/ui/delegation/unsupported.current.stderr @@ -0,0 +1,59 @@ +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` + --> $DIR/unsupported.rs:30:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + | +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/unsupported.rs:30:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle +note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition + --> $DIR/unsupported.rs:30:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` + --> $DIR/unsupported.rs:33:24 + | +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + | +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/unsupported.rs:33:24 + | +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle +note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition + --> $DIR/unsupported.rs:33:24 + | +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: recursive delegation is not supported yet + --> $DIR/unsupported.rs:46:22 + | +LL | pub reuse to_reuse2::foo; + | --- callee defined here +... +LL | reuse to_reuse1::foo; + | ^^^ + +error[E0283]: type annotations needed + --> $DIR/unsupported.rs:56:18 + | +LL | reuse Trait::foo; + | ^^^ cannot infer type + | + = note: cannot satisfy `_: effects::Trait` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0283, E0391. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.next.stderr b/tests/ui/delegation/unsupported.next.stderr new file mode 100644 index 0000000000000..606a25d4269a1 --- /dev/null +++ b/tests/ui/delegation/unsupported.next.stderr @@ -0,0 +1,51 @@ +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` + --> $DIR/unsupported.rs:30:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + | +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/unsupported.rs:30:25 + | +LL | reuse to_reuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle + = note: cycle used when computing implied outlives bounds for `::opaque_ret::{anon_assoc#0}` (hack disabled = false) + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` + --> $DIR/unsupported.rs:33:24 + | +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + | +note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... + --> $DIR/unsupported.rs:33:24 + | +LL | reuse ToReuse::opaque_ret; + | ^^^^^^^^^^ + = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle + = note: cycle used when computing implied outlives bounds for `::opaque_ret::{anon_assoc#0}` (hack disabled = false) + = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information + +error: recursive delegation is not supported yet + --> $DIR/unsupported.rs:46:22 + | +LL | pub reuse to_reuse2::foo; + | --- callee defined here +... +LL | reuse to_reuse1::foo; + | ^^^ + +error[E0283]: type annotations needed + --> $DIR/unsupported.rs:56:18 + | +LL | reuse Trait::foo; + | ^^^ cannot infer type + | + = note: cannot satisfy `_: effects::Trait` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0283, E0391. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs index af1c20976d7ad..79bab342da091 100644 --- a/tests/ui/delegation/unsupported.rs +++ b/tests/ui/delegation/unsupported.rs @@ -1,3 +1,11 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-fail + +// Next solver revision included because of trait-system-refactor-initiative#234. +// If we end up in a query cycle, it should be okay as long as results are the same. + #![feature(const_trait_impl)] #![feature(c_variadic)] #![feature(fn_delegation)] diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr deleted file mode 100644 index f69be60133e2b..0000000000000 --- a/tests/ui/delegation/unsupported.stderr +++ /dev/null @@ -1,59 +0,0 @@ -error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` - --> $DIR/unsupported.rs:22:25 - | -LL | reuse to_reuse::opaque_ret; - | ^^^^^^^^^^ - | -note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... - --> $DIR/unsupported.rs:22:25 - | -LL | reuse to_reuse::opaque_ret; - | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle -note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition - --> $DIR/unsupported.rs:22:25 - | -LL | reuse to_reuse::opaque_ret; - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error[E0391]: cycle detected when computing type of `opaque::::opaque_ret::{anon_assoc#0}` - --> $DIR/unsupported.rs:25:24 - | -LL | reuse ToReuse::opaque_ret; - | ^^^^^^^^^^ - | -note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process... - --> $DIR/unsupported.rs:25:24 - | -LL | reuse ToReuse::opaque_ret; - | ^^^^^^^^^^ - = note: ...which again requires computing type of `opaque::::opaque_ret::{anon_assoc#0}`, completing the cycle -note: cycle used when checking assoc item `opaque::::opaque_ret` is compatible with trait definition - --> $DIR/unsupported.rs:25:24 - | -LL | reuse ToReuse::opaque_ret; - | ^^^^^^^^^^ - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: recursive delegation is not supported yet - --> $DIR/unsupported.rs:38:22 - | -LL | pub reuse to_reuse2::foo; - | --- callee defined here -... -LL | reuse to_reuse1::foo; - | ^^^ - -error[E0283]: type annotations needed - --> $DIR/unsupported.rs:48:18 - | -LL | reuse Trait::foo; - | ^^^ cannot infer type - | - = note: cannot satisfy `_: effects::Trait` - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0283, E0391. -For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/deprecation/deprecated-expr-precedence.rs b/tests/ui/deprecation/deprecated-expr-precedence.rs index 9636b46df2013..08a741e11c0de 100644 --- a/tests/ui/deprecation/deprecated-expr-precedence.rs +++ b/tests/ui/deprecation/deprecated-expr-precedence.rs @@ -5,4 +5,6 @@ pub fn public() { #[deprecated] 0 //~^ ERROR mismatched types + //~| WARN attribute cannot be used on expressions + //~| WARN previously accepted } diff --git a/tests/ui/deprecation/deprecated-expr-precedence.stderr b/tests/ui/deprecation/deprecated-expr-precedence.stderr index 3275f2e790aeb..c3124cf86ef49 100644 --- a/tests/ui/deprecation/deprecated-expr-precedence.stderr +++ b/tests/ui/deprecation/deprecated-expr-precedence.stderr @@ -1,3 +1,13 @@ +warning: `#[deprecated]` attribute cannot be used on expressions + --> $DIR/deprecated-expr-precedence.rs:6:5 + | +LL | #[deprecated] 0 + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements + = note: requested on the command line with `-W unused-attributes` + error[E0308]: mismatched types --> $DIR/deprecated-expr-precedence.rs:6:19 | @@ -6,6 +16,6 @@ LL | pub fn public() { LL | #[deprecated] 0 | ^ expected `()`, found integer -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 95ae1b04d8611..5a39b0cf31516 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -73,8 +73,8 @@ LL | let _ = nested::DeprecatedStruct { error: use of deprecated unit struct `deprecation_lint::nested::DeprecatedUnitStruct`: text --> $DIR/deprecation-lint.rs:48:25 | -LL | let _ = nested::DeprecatedUnitStruct; - | ^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = nested::DeprecatedUnitStruct; + | ^^^^^^^^^^^^^^^^^^^^ error: use of deprecated unit variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text --> $DIR/deprecation-lint.rs:50:31 @@ -97,8 +97,8 @@ LL | macro_test_arg!(deprecated_text()); error: use of deprecated function `deprecation_lint::deprecated_text`: text --> $DIR/deprecation-lint.rs:60:41 | -LL | macro_test_arg!(macro_test_arg!(deprecated_text())); - | ^^^^^^^^^^^^^^^ +LL | ... macro_test_arg!(macro_test_arg!(deprecated_text())); + | ^^^^^^^^^^^^^^^ error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:65:16 @@ -211,8 +211,8 @@ LL | Trait::trait_deprecated_text(&foo); error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:261:25 | -LL | ::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated_future`: text --> $DIR/deprecation-lint.rs:264:9 @@ -295,8 +295,8 @@ LL | Trait::trait_deprecated_text(&foo); error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:299:25 | -LL | ::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar` --> $DIR/deprecation-lint.rs:317:13 @@ -391,8 +391,8 @@ LL | foo.method_deprecated_text(); error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:27:14 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:28:16 @@ -589,8 +589,8 @@ LL | Foo::method_deprecated_text(&foo); error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:257:16 | -LL | ::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:258:13 diff --git a/tests/ui/deprecation/deprecation-sanity.stderr b/tests/ui/deprecation/deprecation-sanity.stderr index ea021b71e1485..48d08b18f8bda 100644 --- a/tests/ui/deprecation/deprecation-sanity.stderr +++ b/tests/ui/deprecation/deprecation-sanity.stderr @@ -177,7 +177,7 @@ LL | #[deprecated = "hello"] | ^^^^^^^^^^^^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[deprecated]` can be applied to functions, data types, modules, unions, constants, statics, macro defs, type aliases, use statements, foreign statics, struct fields, traits, associated types, associated consts, enum variants, inherent impl blocks, and crates + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements = note: `#[deny(useless_deprecated)]` on by default error: aborting due to 10 previous errors diff --git a/tests/ui/deref/pin-impl-deref.rs b/tests/ui/deref/pin-impl-deref.rs index b1dc8dea3f248..ccd8d0dfc72ae 100644 --- a/tests/ui/deref/pin-impl-deref.rs +++ b/tests/ui/deref/pin-impl-deref.rs @@ -22,7 +22,7 @@ impl MyPinType { fn impl_deref_mut(_: impl DerefMut) {} fn unpin_impl_ref(r_unpin: Pin<&MyUnpinType>) { impl_deref_mut(r_unpin) - //~^ ERROR: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied + //~^ ERROR: the trait bound `&MyUnpinType: DerefMut` is not satisfied } fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) { impl_deref_mut(r_unpin) @@ -30,7 +30,7 @@ fn unpin_impl_mut(r_unpin: Pin<&mut MyUnpinType>) { fn pin_impl_ref(r_pin: Pin<&MyPinType>) { impl_deref_mut(r_pin) //~^ ERROR: `PhantomPinned` cannot be unpinned - //~| ERROR: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied + //~| ERROR: the trait bound `&MyPinType: DerefMut` is not satisfied } fn pin_impl_mut(r_pin: Pin<&mut MyPinType>) { impl_deref_mut(r_pin) diff --git a/tests/ui/deref/pin-impl-deref.stderr b/tests/ui/deref/pin-impl-deref.stderr index 106654641a117..4143d66f42723 100644 --- a/tests/ui/deref/pin-impl-deref.stderr +++ b/tests/ui/deref/pin-impl-deref.stderr @@ -1,40 +1,34 @@ -error[E0277]: the trait bound `Pin<&MyUnpinType>: DerefMut` is not satisfied +error[E0277]: the trait bound `&MyUnpinType: DerefMut` is not satisfied --> $DIR/pin-impl-deref.rs:24:20 | LL | impl_deref_mut(r_unpin) - | -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyUnpinType>` + | -------------- ^^^^^^^ the trait `DerefMut` is not implemented for `&MyUnpinType` | | | required by a bound introduced by this call | + = note: `DerefMut` is implemented for `&mut MyUnpinType`, but not for `&MyUnpinType` = note: required for `Pin<&MyUnpinType>` to implement `DerefMut` note: required by a bound in `impl_deref_mut` --> $DIR/pin-impl-deref.rs:22:27 | LL | fn impl_deref_mut(_: impl DerefMut) {} | ^^^^^^^^ required by this bound in `impl_deref_mut` -help: consider mutably borrowing here - | -LL | impl_deref_mut(&mut r_unpin) - | ++++ -error[E0277]: the trait bound `Pin<&MyPinType>: DerefMut` is not satisfied +error[E0277]: the trait bound `&MyPinType: DerefMut` is not satisfied --> $DIR/pin-impl-deref.rs:31:20 | LL | impl_deref_mut(r_pin) - | -------------- ^^^^^ the trait `DerefMut` is not implemented for `Pin<&MyPinType>` + | -------------- ^^^^^ the trait `DerefMut` is not implemented for `&MyPinType` | | | required by a bound introduced by this call | + = note: `DerefMut` is implemented for `&mut MyPinType`, but not for `&MyPinType` = note: required for `Pin<&MyPinType>` to implement `DerefMut` note: required by a bound in `impl_deref_mut` --> $DIR/pin-impl-deref.rs:22:27 | LL | fn impl_deref_mut(_: impl DerefMut) {} | ^^^^^^^^ required by this bound in `impl_deref_mut` -help: consider mutably borrowing here - | -LL | impl_deref_mut(&mut r_pin) - | ++++ error[E0277]: `PhantomPinned` cannot be unpinned --> $DIR/pin-impl-deref.rs:31:20 diff --git a/tests/ui/diagnostic-flags/colored-session-opt-error.svg b/tests/ui/diagnostic-flags/colored-session-opt-error.svg index 69f452f29f31f..136c6fa562807 100644 --- a/tests/ui/diagnostic-flags/colored-session-opt-error.svg +++ b/tests/ui/diagnostic-flags/colored-session-opt-error.svg @@ -1,7 +1,7 @@ - + (x: U) -> S2 { + Self(x) + //~^ ERROR mismatched types + //~| ERROR mismatched types + } +} diff --git a/tests/ui/generics/generic-struct-self-unconstrained-inference-vars-69306.stderr b/tests/ui/generics/generic-struct-self-unconstrained-inference-vars-69306.stderr new file mode 100644 index 0000000000000..f2fd4340a5804 --- /dev/null +++ b/tests/ui/generics/generic-struct-self-unconstrained-inference-vars-69306.stderr @@ -0,0 +1,138 @@ +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:6:28 + | +LL | impl S0 { + | - expected this type parameter +LL | const C: S0 = Self(0); + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect + | + = note: expected type parameter `T` + found type `{integer}` +note: tuple struct defined here + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:4:8 + | +LL | struct S0(T); + | ^^ + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:6:23 + | +LL | impl S0 { + | - found this type parameter +LL | const C: S0 = Self(0); + | ^^^^^^^ expected `S0`, found `S0` + | + = note: expected struct `S0` + found struct `S0` + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:11:14 + | +LL | impl S0 { + | - expected this type parameter +... +LL | Self(0); + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect + | + = note: expected type parameter `T` + found type `{integer}` +note: tuple struct defined here + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:4:8 + | +LL | struct S0(T); + | ^^ + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:28:14 + | +LL | impl Foo for as Fun>::Out { + | - expected this type parameter +LL | fn foo() { +LL | Self(0); + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect + | + = note: expected type parameter `T` + found type `{integer}` +note: tuple struct defined here + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:4:8 + | +LL | struct S0(T); + | ^^ + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:34:32 + | +LL | impl S1 { + | - expected this type parameter +LL | const C: S1 = Self(0, 1); + | ---- ^ expected type parameter `T`, found integer + | | + | arguments to this function are incorrect + | + = note: expected type parameter `T` + found type `{integer}` +note: tuple struct defined here + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:32:8 + | +LL | struct S1(T, U); + | ^^ + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:34:27 + | +LL | impl S1 { + | - found this type parameter +LL | const C: S1 = Self(0, 1); + | ^^^^^^^^^^ expected `S1`, found `S1` + | + = note: expected struct `S1` + found struct `S1` + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:42:14 + | +LL | impl S2 { + | - expected type parameter +LL | fn map(x: U) -> S2 { + | - found type parameter +LL | Self(x) + | ---- ^ expected type parameter `T`, found type parameter `U` + | | + | arguments to this function are incorrect + | + = note: expected type parameter `T` + found type parameter `U` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters +note: tuple struct defined here + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:39:8 + | +LL | struct S2(T); + | ^^ + +error[E0308]: mismatched types + --> $DIR/generic-struct-self-unconstrained-inference-vars-69306.rs:42:9 + | +LL | impl S2 { + | - found type parameter +LL | fn map(x: U) -> S2 { + | - ----- expected `S2` because of return type + | | + | expected type parameter +LL | Self(x) + | ^^^^^^^ expected `S2`, found `S2` + | + = note: expected struct `S2` + found struct `S2` + = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound + = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr index 5cd98faa8abb2..d1b672c14904a 100644 --- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr +++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr @@ -8,7 +8,7 @@ LL | 0..5+1 => errors_only.push(x), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 5+1; -LL ~ match x as i32 { +LL | match x as i32 { LL ~ 0..VAL => errors_only.push(x), | diff --git a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs b/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs new file mode 100644 index 0000000000000..d1a4e09243ecf --- /dev/null +++ b/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.rs @@ -0,0 +1,20 @@ +// https://github.com/rust-lang/rust/issues/60218 +// Regression test for #60218 +// +// This was reported to cause ICEs. + +use std::iter::Map; + +pub trait Foo {} + +pub fn trigger_error(iterable: I, functor: F) +where + for<'t> &'t I: IntoIterator, +for<'t> Map<<&'t I as IntoIterator>::IntoIter, F>: Iterator, +for<'t> ::IntoIter, F> as Iterator>::Item: Foo, +{ +} + +fn main() { + trigger_error(vec![], |x: &u32| x) //~ ERROR E0277 +} diff --git a/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr b/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr new file mode 100644 index 0000000000000..4c403bcbd601f --- /dev/null +++ b/tests/ui/higher-ranked-trait-bounds/higher-trait-bounds-ice-60218.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `&u32: Foo` is not satisfied + --> $DIR/higher-trait-bounds-ice-60218.rs:19:19 + | +LL | trigger_error(vec![], |x: &u32| x) + | ------------- ^^^^^^ the trait `Foo` is not implemented for `&u32` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/higher-trait-bounds-ice-60218.rs:8:1 + | +LL | pub trait Foo {} + | ^^^^^^^^^^^^^ +note: required by a bound in `trigger_error` + --> $DIR/higher-trait-bounds-ice-60218.rs:14:72 + | +LL | pub fn trigger_error(iterable: I, functor: F) + | ------------- required by a bound in this function +... +LL | for<'t> ::IntoIter, F> as Iterator>::Item: Foo, + | ^^^ required by this bound in `trigger_error` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs new file mode 100644 index 0000000000000..dfdb816652c44 --- /dev/null +++ b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.rs @@ -0,0 +1,12 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +// Regression test for #146467. +trait Trait { type Assoc; } + +impl Trait for fn(&()) { type Assoc = (); } + +fn f(_: for<'a> fn(::Assoc)) {} +//~^ ERROR implementation of `Trait` is not general enough +//~| ERROR higher-ranked subtype error + +fn main() {} diff --git a/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr new file mode 100644 index 0000000000000..c75a063e45fa0 --- /dev/null +++ b/tests/ui/higher-ranked/do-not-blame-outlives-static-ice.stderr @@ -0,0 +1,17 @@ +error: implementation of `Trait` is not general enough + --> $DIR/do-not-blame-outlives-static-ice.rs:8:9 + | +LL | fn f(_: for<'a> fn(::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough + | + = note: `for<'a> fn(&'a ())` must implement `Trait`, for any lifetime `'0`... + = note: ...but `Trait` is actually implemented for the type `for<'a> fn(&'a ())` + +error: higher-ranked subtype error + --> $DIR/do-not-blame-outlives-static-ice.rs:8:1 + | +LL | fn f(_: for<'a> fn(::Assoc)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr deleted file mode 100644 index 90391b7b86b5c..0000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.next.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0277]: the trait bound `for<'a> &'a &T: Trait` is not satisfied - --> $DIR/candidate-from-env-universe-err-1.rs:27:16 - | -LL | hr_bound::<&T>(); - | ^^ the trait `for<'a> Trait` is not implemented for `&'a &T` - | -note: required by a bound in `hr_bound` - --> $DIR/candidate-from-env-universe-err-1.rs:14:20 - | -LL | fn hr_bound() - | -------- required by a bound in this function -LL | where -LL | for<'a> &'a T: Trait, - | ^^^^^ required by this bound in `hr_bound` -help: consider removing the leading `&`-reference - | -LL - hr_bound::<&T>(); -LL + hr_bound::(); - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs index bd251216162db..5f560e60c8c88 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs @@ -1,6 +1,7 @@ //@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[old] check-pass +//@ check-pass // cc #119820 @@ -24,8 +25,11 @@ where // but are able to successfully use the impl candidate. Without // the leak check both candidates may apply and we prefer the // `param_env` candidate in winnowing. + // + // By doing the leak check for each candidate, we discard the `param_env` + // candidate and use the impl candidate instead, allowing this to + // compile. hr_bound::<&T>(); - //[next]~^ ERROR the trait bound `for<'a> &'a &T: Trait` is not satisfied } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr deleted file mode 100644 index 0f5a9de7ab854..0000000000000 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied - --> $DIR/candidate-from-env-universe-err-2.rs:15:15 - | -LL | impl_hr::(); - | ^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T` - | -note: required by a bound in `impl_hr` - --> $DIR/candidate-from-env-universe-err-2.rs:12:19 - | -LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} - | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs index 0132b7db60574..96c6f95329aff 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs @@ -1,6 +1,7 @@ //@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[current] check-pass +//@ check-pass // cc #119820 @@ -13,7 +14,6 @@ fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {} fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() { impl_hr::(); - //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied } fn main() {} diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr index c8394575e71de..395dd068e2371 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr @@ -7,7 +7,7 @@ LL | projection_bound::(); = note: expected associated type `>::Assoc` found associated type `>::Assoc` note: the lifetime requirement is introduced here - --> $DIR/candidate-from-env-universe-err-project.rs:18:42 + --> $DIR/candidate-from-env-universe-err-project.rs:19:42 | LL | fn projection_bound Trait<'a, Assoc = usize>>() {} | ^^^^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr index 468dc3b082e5c..ddfc94da1354c 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr @@ -1,26 +1,14 @@ -error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied - --> $DIR/candidate-from-env-universe-err-project.rs:28:19 - | -LL | trait_bound::(); - | ^ the trait `for<'a> Trait<'a>` is not implemented for `T` - | -note: required by a bound in `trait_bound` - --> $DIR/candidate-from-env-universe-err-project.rs:17:19 - | -LL | fn trait_bound Trait<'a>>() {} - | ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound` - -error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied +error[E0271]: type mismatch resolving `>::Assoc == usize` --> $DIR/candidate-from-env-universe-err-project.rs:38:24 | LL | projection_bound::(); - | ^ the trait `for<'a> Trait<'a>` is not implemented for `T` + | ^ types differ | note: required by a bound in `projection_bound` - --> $DIR/candidate-from-env-universe-err-project.rs:18:24 + --> $DIR/candidate-from-env-universe-err-project.rs:19:42 | LL | fn projection_bound Trait<'a, Assoc = usize>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound` + | ^^^^^^^^^^^^^ required by this bound in `projection_bound` error: higher-ranked subtype error --> $DIR/candidate-from-env-universe-err-project.rs:52:30 @@ -36,6 +24,6 @@ LL | let _higher_ranked_norm: for<'a> fn(>::Assoc) = |_| (); | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs index d70e392238218..dd6da62a47272 100644 --- a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs +++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs @@ -1,4 +1,5 @@ //@ revisions: next current +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver // cc #119820 the behavior is inconsistent as we discard the where-bound @@ -20,13 +21,12 @@ fn projection_bound Trait<'a, Assoc = usize>>() {} // We use a function with a trivial where-bound which is more // restrictive than the impl. fn function1>() { - // err + // ok // // Proving `for<'a> T: Trait<'a>` using the where-bound does not // result in a leak check failure even though it does not apply. // We prefer env candidates over impl candidatescausing this to succeed. trait_bound::(); - //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied } fn function2>() { @@ -36,7 +36,7 @@ fn function2>() { // does not use the leak check when trying the where-bound, causing us // to prefer it over the impl, resulting in a placeholder error. projection_bound::(); - //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied + //[next]~^ ERROR type mismatch resolving `>::Assoc == usize` //[current]~^^ ERROR mismatched types } diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr deleted file mode 100644 index cb97bc4b8fc6e..0000000000000 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-2.rs:17:5 - | -LL | impls_trait::<(), _>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` - | -note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found - --> $DIR/leak-check-in-selection-2.rs:10:1 - | -LL | impl<'a> Trait<&'a str, &'a str> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | -LL | impl<'a> Trait<&'a str, String> for () {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-2.rs:14:19 - | -LL | fn impls_trait Trait<&'a str, U>, U>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs index 24e38ec45a2c4..365d743528448 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs @@ -1,6 +1,7 @@ //@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@[old] check-pass +//@ check-pass // cc #119820 @@ -15,5 +16,4 @@ fn impls_trait Trait<&'a str, U>, U>() {} fn main() { impls_trait::<(), _>(); - //[next]~^ ERROR type annotations needed } diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr index 5be683cd3191b..622df3b00e595 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr @@ -1,22 +1,3 @@ -error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-3.rs:18:5 - | -LL | impls_leak::>(); - | ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak` - | -note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found - --> $DIR/leak-check-in-selection-3.rs:9:1 - | -LL | impl Leak<'_> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -LL | impl Leak<'static> for Box {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `impls_leak` - --> $DIR/leak-check-in-selection-3.rs:12:18 - | -LL | fn impls_leak Leak<'a>>() {} - | ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak` - error[E0283]: type annotations needed --> $DIR/leak-check-in-selection-3.rs:35:5 | @@ -24,7 +5,7 @@ LL | impls_indirect_leak::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak` | note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found - --> $DIR/leak-check-in-selection-3.rs:9:1 + --> $DIR/leak-check-in-selection-3.rs:10:1 | LL | impl Leak<'_> for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,6 +24,6 @@ note: required by a bound in `impls_indirect_leak` LL | fn impls_indirect_leak IndirectLeak<'a>>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak` -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr index 194571dd4a85b..a193ddd891691 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr @@ -5,7 +5,7 @@ LL | impls_indirect_leak::>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak` | note: multiple `impl`s satisfying `Box<_>: Leak<'_>` found - --> $DIR/leak-check-in-selection-3.rs:9:1 + --> $DIR/leak-check-in-selection-3.rs:10:1 | LL | impl Leak<'_> for Box {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs index 9aa1be57a4fb2..191528a15e659 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs @@ -1,4 +1,5 @@ //@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver // cc #119820, the behavior here is inconsistent, @@ -16,7 +17,6 @@ fn direct() { // The `Box` impls fails the leak check, // meaning that we apply the `Box` impl. impls_leak::>(); - //[next]~^ ERROR type annotations needed } trait IndirectLeak<'a> {} diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr index a12e3312230af..77dec93d0617a 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.next.stderr @@ -1,18 +1,18 @@ error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:5 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:32:5 | LL | impls_trait::<(), _, _>() | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` | note: multiple `impl`s satisfying `(): Trait<_, _>` found - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:26:1 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:1 | -LL | impl Trait for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:19 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | LL | fn impls_trait, U: Id, V>() {} | ^^^^^^^^^^^ required by this bound in `impls_trait` diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr index a12e3312230af..77dec93d0617a 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.old.stderr @@ -1,18 +1,18 @@ error[E0283]: type annotations needed - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:5 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:32:5 | LL | impls_trait::<(), _, _>() | ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait` | note: multiple `impl`s satisfying `(): Trait<_, _>` found - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:26:1 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:1 | -LL | impl Trait for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `impls_trait` - --> $DIR/leak-check-in-selection-6-ambig-unify.rs:28:19 + --> $DIR/leak-check-in-selection-6-ambig-unify.rs:30:19 | LL | fn impls_trait, U: Id, V>() {} | ^^^^^^^^^^^ required by this bound in `impls_trait` diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs index 592d581695e52..2a286b2dd7bd2 100644 --- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-6-ambig-unify.rs @@ -1,4 +1,5 @@ //@ revisions: old next +//@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver // The new trait solver does not return region constraints if the goal @@ -21,9 +22,10 @@ impl Id for u16 {} trait LeakCheckFailure<'a, 'b, V: ?Sized> {} impl<'a, 'b: 'a, V: ?Sized + Ambig> LeakCheckFailure<'a, 'b, V> for () {} +impl<'a, 'b, V: ?Sized, T: LeakCheckFailure<'a, 'b, V>> LeakCheckFailure<'a, 'b, V> for (T,) {} trait Trait {} -impl Trait for () where for<'b> (): LeakCheckFailure<'static, 'b, V> {} +impl Trait for () where for<'b> ((),): LeakCheckFailure<'static, 'b, V> {} impl Trait for () {} fn impls_trait, U: Id, V>() {} fn main() { diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-7-coherence.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-7-coherence.rs new file mode 100644 index 0000000000000..97837515ccbf9 --- /dev/null +++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-7-coherence.rs @@ -0,0 +1,20 @@ +//@ check-pass + +// cc #119820 +struct W(T, U); + +trait Trait {} +// using this impl results in a higher-ranked region error. +impl<'a> Trait> for () {} +impl<'a> Trait> for () {} + +trait NotString {} +impl NotString for &str {} +impl NotString for u32 {} + + +trait Overlap {} +impl Trait>, U> Overlap for T {} +impl Overlap for () {} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr index a26c617dc931d..f8f64dcc545bc 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -37,7 +37,7 @@ error: higher-ranked lifetime error LL | v.t(|| {}); | ^^^^^ | - = note: could not prove `for<'a> &'a V: 'b` + = note: could not prove `for<'a> &'a V: '_` error: aborting due to 3 previous errors diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr new file mode 100644 index 0000000000000..723dd097f9b97 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `>::Out<_>` + --> $DIR/norm-before-method-resolution-opaque-type.rs:25:9 + | +LL | let x = *x; + | ^ + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: <_ as Trait<'static>>::Out<_> = *x; + | +++++++++++++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index 79ded34d9cd9e..d8b94fd4f7d1b 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,5 +1,5 @@ error[E0507]: cannot move out of `*x` which is behind a shared reference - --> $DIR/norm-before-method-resolution-opaque-type.rs:22:13 + --> $DIR/norm-before-method-resolution-opaque-type.rs:25:13 | LL | let x = *x; | ^^ move occurs because `*x` has type `>::Out`, which does not implement the `Copy` trait diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index f881fcb779fa8..55e99171ea633 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -1,6 +1,9 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver -//@[next] check-pass + +// In the next solver, the opaque was previously defined by using the where-bound when checking +// whether the alias is `Sized`, constraining the opaque. Instead, the alias-bound is now used, +// which means the opaque is never constrained. #![feature(type_alias_impl_trait)] trait Trait<'a> { @@ -20,6 +23,7 @@ where for<'a> >::Out<()>: Copy, { let x = *x; //[old]~ ERROR: cannot move out of `*x` + //[next]~^ ERROR: type annotations needed todo!(); } diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr index 9e0d7e4b7be09..a04c6d770d73e 100644 --- a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr @@ -4,7 +4,7 @@ error: higher-ranked lifetime error LL | || {}; | ^^^^^ | - = note: could not prove `for<'a> &'a (): 'b` + = note: could not prove `for<'a> &'a (): '_` error: aborting due to 1 previous error diff --git a/tests/ui/hygiene/issue-77523-def-site-async-await.rs b/tests/ui/hygiene/issue-77523-def-site-async-await.rs index ad6bd5e0b78bc..0a279682b71bb 100644 --- a/tests/ui/hygiene/issue-77523-def-site-async-await.rs +++ b/tests/ui/hygiene/issue-77523-def-site-async-await.rs @@ -1,5 +1,6 @@ //@ build-pass //@ aux-build:def-site-async-await.rs +//@ ignore-backends: gcc // Regression test for issue #77523 // Tests that we don't ICE when an unusual combination diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr index d28ab86418345..bd74e96fd8cc7 100644 --- a/tests/ui/hygiene/panic-location.run.stderr +++ b/tests/ui/hygiene/panic-location.run.stderr @@ -1,4 +1,4 @@ -thread 'main' ($TID) panicked at $DIR/panic-location.rs:LL:CC: +thread 'main' ($TID) panicked at library/alloc/src/raw_vec/mod.rs:LL:CC: capacity overflow note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/tests/ui/impl-trait/associated-type-fn-bound-issue-72207.rs b/tests/ui/impl-trait/associated-type-fn-bound-issue-72207.rs new file mode 100644 index 0000000000000..67e4ed9f4c87a --- /dev/null +++ b/tests/ui/impl-trait/associated-type-fn-bound-issue-72207.rs @@ -0,0 +1,57 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib + +#![allow(dead_code)] + +use std::marker::PhantomData; + +pub struct XImpl +where + F2: Fn(E), +{ + f1: F1, + f2: F2, + _ghost: PhantomData<(T, E)>, +} + +pub trait X: Sized { + type F1; + type F2: Fn(Self::E); + type E; + + fn and(self, f: NewF1Generator) -> XImpl + where + NewF1Generator: FnOnce(Self::F1) -> NewF1; +} + +impl X for XImpl +where + F2: Fn(E), +{ + type E = E; + type F2 = F2; + type F1 = F1; + + fn and(self, f: NewF1Generator) -> XImpl + where + NewF1Generator: FnOnce(F1) -> NewF1, + { + XImpl { + f1: f(self.f1), + f2: self.f2, + _ghost: PhantomData, + } + } +} + +fn f() -> impl X<(), E = ()> { + XImpl { + f1: || (), + f2: |()| (), + _ghost: PhantomData, + } +} + +fn f2() -> impl X<(), E = ()> { + f().and(|rb| rb) +} diff --git a/tests/ui/impl-trait/call_method_ambiguous.next.stderr b/tests/ui/impl-trait/call_method_ambiguous.next.stderr deleted file mode 100644 index 5251555f57421..0000000000000 --- a/tests/ui/impl-trait/call_method_ambiguous.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/call_method_ambiguous.rs:26:13 - | -LL | let mut iter = foo(n - 1, m); - | ^^^^^^^^ -LL | -LL | assert_eq!(iter.get(), 1); - | ---- type must be known at this point - | -help: consider giving `iter` an explicit type - | -LL | let mut iter: /* Type */ = foo(n - 1, m); - | ++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_ambiguous.rs b/tests/ui/impl-trait/call_method_ambiguous.rs index 6bcafc8ce1494..021d6c22f79dd 100644 --- a/tests/ui/impl-trait/call_method_ambiguous.rs +++ b/tests/ui/impl-trait/call_method_ambiguous.rs @@ -1,6 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[current] run-pass +//@ run-pass trait Get { fn get(&mut self) -> u32; @@ -24,7 +24,6 @@ where fn foo(n: usize, m: &mut ()) -> impl Get + use<'_> { if n > 0 { let mut iter = foo(n - 1, m); - //[next]~^ ERROR type annotations needed assert_eq!(iter.get(), 1); } m diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr deleted file mode 100644 index 271051f120abc..0000000000000 --- a/tests/ui/impl-trait/call_method_on_inherent_impl.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/call_method_on_inherent_impl.rs:18:13 - | -LL | let x = my_foo(); - | ^ -LL | -LL | x.my_debug(); - | - type must be known at this point - | -help: consider giving `x` an explicit type - | -LL | let x: /* Type */ = my_foo(); - | ++++++++++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl.rs b/tests/ui/impl-trait/call_method_on_inherent_impl.rs index 0e333c3260a2f..1dd38bc671730 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl.rs +++ b/tests/ui/impl-trait/call_method_on_inherent_impl.rs @@ -1,6 +1,6 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[current] check-pass +//@ check-pass trait MyDebug { fn my_debug(&self); @@ -16,7 +16,6 @@ where fn my_foo() -> impl std::fmt::Debug { if false { let x = my_foo(); - //[next]~^ ERROR type annotations needed x.my_debug(); } () diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr index 6ecb2b05fc56b..e710466447043 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.current.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `my_debug` found for reference `&impl Debug` in the current scope - --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:16:11 + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:15:11 | LL | x.my_debug(); | ^^^^^^^^ method not found in `&impl Debug` diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr index 5fb0b8f1d14b2..de808259d40dc 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.next.stderr @@ -1,17 +1,15 @@ -error[E0282]: type annotations needed for `&_` - --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:14:13 +error[E0599]: no method named `my_debug` found for reference `&_` in the current scope + --> $DIR/call_method_on_inherent_impl_on_rigid_type.rs:15:11 | -LL | let x = &my_foo(); - | ^ -LL | LL | x.my_debug(); - | -------- type must be known at this point + | ^^^^^^^^ method not found in `&_` | -help: consider giving `x` an explicit type, where the placeholders `_` are specified + = help: items from traits can only be used if the trait is implemented and in scope +help: trait `MyDebug` which provides `my_debug` is implemented but not in scope; perhaps you want to import it + | +LL + use MyDebug; | -LL | let x: &_ = &my_foo(); - | ++++ error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs index 7fb2ff3b2bcc6..0c9909efa1ba1 100644 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_on_rigid_type.rs @@ -12,9 +12,8 @@ impl MyDebug for &() { fn my_foo() -> impl std::fmt::Debug { if false { let x = &my_foo(); - //[next]~^ ERROR: type annotations needed x.my_debug(); - //[current]~^ ERROR: no method named `my_debug` + //~^ ERROR: no method named `my_debug` } () } diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.current.stderr new file mode 100644 index 0000000000000..71acbd1497d93 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.current.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope + --> $DIR/call_method_on_inherent_impl_ref-err.rs:18:11 + | +LL | fn my_debug(&self); + | -------- the method is available for `&impl Debug` here +... +LL | x.my_debug(); + | ^^^^^^^^ method not found in `impl Debug` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it + --> $DIR/call_method_on_inherent_impl_ref-err.rs:4:1 + | +LL | trait MyDebug { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.next.stderr new file mode 100644 index 0000000000000..523505e980221 --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.next.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `my_debug` found for type `_` in the current scope + --> $DIR/call_method_on_inherent_impl_ref-err.rs:18:11 + | +LL | fn my_debug(&self); + | -------- the method is available for `&_` here +... +LL | x.my_debug(); + | ^^^^^^^^ method not found in `_` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it + --> $DIR/call_method_on_inherent_impl_ref-err.rs:4:1 + | +LL | trait MyDebug { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.rs new file mode 100644 index 0000000000000..0ed09bc76a41e --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-err.rs @@ -0,0 +1,24 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +trait MyDebug { + fn my_debug(&self); +} + +impl MyDebug for &T +where + T: std::fmt::Debug, +{ + fn my_debug(&self) {} +} + +fn my_foo() -> impl std::fmt::Debug { + if false { + let x = my_foo(); + x.my_debug(); + //~^ ERROR no method named `my_debug` found + } + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref-ok.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-ok.rs new file mode 100644 index 0000000000000..40739d6a0ce4b --- /dev/null +++ b/tests/ui/impl-trait/call_method_on_inherent_impl_ref-ok.rs @@ -0,0 +1,24 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ check-pass + +trait MyDebug { + fn my_debug(&self); +} + +impl MyDebug for &T +where + T: std::fmt::Debug, +{ + fn my_debug(&self) {} +} + +fn my_bar() -> impl std::fmt::Debug { + if false { + let x = &my_bar(); + x.my_debug(); + } + () +} + +fn main() {} diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr deleted file mode 100644 index fb51bb7b4173b..0000000000000 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.current.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0599]: no method named `my_debug` found for opaque type `impl Debug` in the current scope - --> $DIR/call_method_on_inherent_impl_ref.rs:19:11 - | -LL | fn my_debug(&self); - | -------- the method is available for `&impl Debug` here -... -LL | x.my_debug(); - | ^^^^^^^^ method not found in `impl Debug` - | - = help: items from traits can only be used if the trait is implemented and in scope -note: `MyDebug` defines an item `my_debug`, perhaps you need to implement it - --> $DIR/call_method_on_inherent_impl_ref.rs:4:1 - | -LL | trait MyDebug { - | ^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr deleted file mode 100644 index 7202cb6f90a6f..0000000000000 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.next.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/call_method_on_inherent_impl_ref.rs:17:13 - | -LL | let x = my_foo(); - | ^ -LL | -LL | x.my_debug(); - | - type must be known at this point - | -help: consider giving `x` an explicit type - | -LL | let x: /* Type */ = my_foo(); - | ++++++++++++ - -error[E0282]: type annotations needed for `&_` - --> $DIR/call_method_on_inherent_impl_ref.rs:27:13 - | -LL | let x = &my_bar(); - | ^ -LL | -LL | x.my_debug(); - | -------- type must be known at this point - | -help: consider giving `x` an explicit type, where the placeholders `_` are specified - | -LL | let x: &_ = &my_bar(); - | ++++ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs b/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs deleted file mode 100644 index 4e4098b37f93b..0000000000000 --- a/tests/ui/impl-trait/call_method_on_inherent_impl_ref.rs +++ /dev/null @@ -1,34 +0,0 @@ -//@ revisions: current next -//@[next] compile-flags: -Znext-solver - -trait MyDebug { - fn my_debug(&self); -} - -impl MyDebug for &T -where - T: std::fmt::Debug, -{ - fn my_debug(&self) {} -} - -fn my_foo() -> impl std::fmt::Debug { - if false { - let x = my_foo(); - //[next]~^ ERROR type annotations needed - x.my_debug(); - //[current]~^ ERROR no method named `my_debug` found - } - () -} - -fn my_bar() -> impl std::fmt::Debug { - if false { - let x = &my_bar(); - //[next]~^ ERROR type annotations needed - x.my_debug(); - } - () -} - -fn main() {} diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg index 73acb072ac52a..8c2713c5ecb05 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg @@ -1,10 +1,10 @@ - + Deref for Foo { + type Target = U; + fn deref(&self) -> &Self::Target { + &self.1 + } +} + +impl Foo { + fn method(&self) {} +} +fn inherent_method() -> impl Sized { + if false { + let x = Foo(Default::default(), inherent_method()); + x.method(); + let _: Foo = x; // Test that we did not apply the deref step + } + 1i32 +} + +trait Trait { + fn trait_method(&self) {} +} +impl Trait for Foo {} +impl Trait for i32 {} +fn trait_method() -> impl Trait { + if false { + let x = Foo(Default::default(), trait_method()); + x.trait_method(); + let _: Foo = x; // Test that we did not apply the deref step + //[current]~^ ERROR mismatched types + } + 1i32 +} + +fn main() {} diff --git a/tests/ui/impl-trait/method-resolution.rs b/tests/ui/impl-trait/method/method-resolution.rs similarity index 100% rename from tests/ui/impl-trait/method-resolution.rs rename to tests/ui/impl-trait/method/method-resolution.rs diff --git a/tests/ui/impl-trait/method-resolution2.next.stderr b/tests/ui/impl-trait/method/method-resolution2.next.stderr similarity index 100% rename from tests/ui/impl-trait/method-resolution2.next.stderr rename to tests/ui/impl-trait/method/method-resolution2.next.stderr diff --git a/tests/ui/impl-trait/method-resolution2.rs b/tests/ui/impl-trait/method/method-resolution2.rs similarity index 100% rename from tests/ui/impl-trait/method-resolution2.rs rename to tests/ui/impl-trait/method/method-resolution2.rs diff --git a/tests/ui/impl-trait/method-resolution3.current.stderr b/tests/ui/impl-trait/method/method-resolution3.current.stderr similarity index 100% rename from tests/ui/impl-trait/method-resolution3.current.stderr rename to tests/ui/impl-trait/method/method-resolution3.current.stderr diff --git a/tests/ui/impl-trait/method-resolution3.next.stderr b/tests/ui/impl-trait/method/method-resolution3.next.stderr similarity index 100% rename from tests/ui/impl-trait/method-resolution3.next.stderr rename to tests/ui/impl-trait/method/method-resolution3.next.stderr diff --git a/tests/ui/impl-trait/method-resolution3.rs b/tests/ui/impl-trait/method/method-resolution3.rs similarity index 100% rename from tests/ui/impl-trait/method-resolution3.rs rename to tests/ui/impl-trait/method/method-resolution3.rs diff --git a/tests/ui/impl-trait/method-resolution4.rs b/tests/ui/impl-trait/method/method-resolution4.rs similarity index 87% rename from tests/ui/impl-trait/method-resolution4.rs rename to tests/ui/impl-trait/method/method-resolution4.rs index 90e7850cad51e..f90a9309cdab8 100644 --- a/tests/ui/impl-trait/method-resolution4.rs +++ b/tests/ui/impl-trait/method/method-resolution4.rs @@ -6,12 +6,11 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[current] check-pass +//@ check-pass fn foo(b: bool) -> impl Iterator { if b { foo(false).next().unwrap(); - //[next]~^ ERROR type annotations needed } std::iter::empty() } diff --git a/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.current.stderr b/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.current.stderr new file mode 100644 index 0000000000000..08578de426ade --- /dev/null +++ b/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.current.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/method-resolution5-deref-no-constrain.rs:20:5 + | +LL | fn via_deref() -> impl Deref { + | --- expected `&Foo` because of return type +... +LL | Box::new(Foo) + | ^^^^^^^^^^^^^ expected `&Foo`, found `Box` + | + = note: expected reference `&Foo` + found struct `Box` +help: consider borrowing here + | +LL | &Box::new(Foo) + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.rs b/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.rs new file mode 100644 index 0000000000000..2c41f62b9fda5 --- /dev/null +++ b/tests/ui/impl-trait/method/method-resolution5-deref-no-constrain.rs @@ -0,0 +1,23 @@ +//! The recursive method call yields the opaque type. We want +//! to use the impl candidate for `Foo` here without constraining +//! the opaque to `&Foo`. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@[next] check-pass + +use std::ops::Deref; +struct Foo; +impl Foo { + fn method(&self) {} +} +fn via_deref() -> impl Deref { + // Currently errors on stable, but should not + if false { + via_deref().method(); + } + + Box::new(Foo) + //[current]~^ ERROR mismatched types +} +fn main() {} diff --git a/tests/ui/impl-trait/method/method-resolution5-deref.rs b/tests/ui/impl-trait/method/method-resolution5-deref.rs new file mode 100644 index 0000000000000..6133a8efe244d --- /dev/null +++ b/tests/ui/impl-trait/method/method-resolution5-deref.rs @@ -0,0 +1,30 @@ +//! The recursive method call yields the opaque type. We want +//! to use the trait candidate for `impl Foo` here while not +//! applying it for the `impl Deref`. + +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ check-pass + +use std::ops::Deref; +trait Foo { + fn method(&self) {} +} +impl Foo for u32 {} +fn via_deref() -> impl Deref { + if false { + via_deref().method(); + } + + Box::new(1u32) +} + +fn via_deref_nested() -> Box> { + if false { + via_deref_nested().method(); + } + + Box::new(Box::new(1u32)) +} + +fn main() {} diff --git a/tests/ui/impl-trait/method/would-constrain-opaque.current.stderr b/tests/ui/impl-trait/method/would-constrain-opaque.current.stderr new file mode 100644 index 0000000000000..60533a39c536f --- /dev/null +++ b/tests/ui/impl-trait/method/would-constrain-opaque.current.stderr @@ -0,0 +1,29 @@ +error[E0599]: no method named `method` found for reference `&impl Sized` in the current scope + --> $DIR/would-constrain-opaque.rs:28:11 + | +LL | x.method(); + | ^^^^^^ method not found in `&impl Sized` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Trait` defines an item `method`, perhaps you need to implement it + --> $DIR/would-constrain-opaque.rs:15:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `method` found for reference `&impl Sized` in the current scope + --> $DIR/would-constrain-opaque.rs:30:11 + | +LL | x.method(); + | ^^^^^^ method not found in `&impl Sized` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Trait` defines an item `method`, perhaps you need to implement it + --> $DIR/would-constrain-opaque.rs:15:1 + | +LL | trait Trait: Sized { + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/method/would-constrain-opaque.next.stderr b/tests/ui/impl-trait/method/would-constrain-opaque.next.stderr new file mode 100644 index 0000000000000..23a4ceb826a6e --- /dev/null +++ b/tests/ui/impl-trait/method/would-constrain-opaque.next.stderr @@ -0,0 +1,27 @@ +error[E0599]: no method named `method` found for reference `&_` in the current scope + --> $DIR/would-constrain-opaque.rs:28:11 + | +LL | x.method(); + | ^^^^^^ method not found in `&_` + | + = help: items from traits can only be used if the trait is implemented and in scope +help: trait `Trait` which provides `method` is implemented but not in scope; perhaps you want to import it + | +LL + use Trait; + | + +error[E0599]: no method named `method` found for reference `&_` in the current scope + --> $DIR/would-constrain-opaque.rs:30:11 + | +LL | x.method(); + | ^^^^^^ method not found in `&_` + | + = help: items from traits can only be used if the trait is implemented and in scope +help: trait `Trait` which provides `method` is implemented but not in scope; perhaps you want to import it + | +LL + use Trait; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/method/would-constrain-opaque.rs b/tests/ui/impl-trait/method/would-constrain-opaque.rs new file mode 100644 index 0000000000000..8dd322825296b --- /dev/null +++ b/tests/ui/impl-trait/method/would-constrain-opaque.rs @@ -0,0 +1,39 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver + +// If we don't treat `impl Sized` as rigid, the first call would +// resolve to the trait method, constraining the opaque, while the +// second call would resolve to the inherent method. +// +// We avoid cases like this by rejecting candidates which constrain +// opaque types encountered in the autoderef chain. +// +// FIXME(-Znext-solver): ideally we would note that the inference variable +// is an opaque type in the error message and change this to a type annotations +// needed error. + +trait Trait: Sized { + fn method(self) {} +} +impl Trait for &Foo {} + +struct Foo; +impl Foo { + fn method(&self) {} +} + +fn define_opaque(b: bool) -> impl Sized { + if b { + let x = &define_opaque(false); + x.method(); + //~^ ERROR no method named `method` found for reference + x.method(); + //~^ ERROR no method named `method` found for reference + } + + Foo +} + +fn main() { + define_opaque(true); +} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index f4ff13d6c20f9..11d79bcff7371 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -48,7 +48,6 @@ fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = im // This should resolve. fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} //~^ ERROR implementation of `Bar` is not general enough -//~| ERROR lifetime may not live long enough // This should resolve. fn two_htrb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Qux<'b>> {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 93cd7bd788f45..2e95ef370c7fd 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:57:77 + --> $DIR/nested-rpit-hrtb.rs:56:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:65:82 + --> $DIR/nested-rpit-hrtb.rs:64:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -87,12 +87,6 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc but trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` -error: lifetime may not live long enough - --> $DIR/nested-rpit-hrtb.rs:49:93 - | -LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} - | -- lifetime `'b` defined here ^^ opaque type requires that `'b` must outlive `'static` - error: implementation of `Bar` is not general enough --> $DIR/nested-rpit-hrtb.rs:49:93 | @@ -103,7 +97,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:61:64 + --> $DIR/nested-rpit-hrtb.rs:60:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -112,7 +106,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> but trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` -error: aborting due to 10 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0261, E0277, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr new file mode 100644 index 0000000000000..c54c1bba028cb --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.current.stderr @@ -0,0 +1,62 @@ +error[E0369]: cannot add `{integer}` to `impl Sized` + --> $DIR/ambiguous-ops.rs:17:15 + | +LL | add() + 1 + | ----- ^ - {integer} + | | + | impl Sized + +error[E0368]: binary assignment operation `*=` cannot be applied to type `impl Sized` + --> $DIR/ambiguous-ops.rs:31:9 + | +LL | temp *= 2; + | ----^^^^^ + | | + | cannot use `*=` on type `impl Sized` + +error[E0614]: type `DerefWrapper` cannot be dereferenced + --> $DIR/ambiguous-ops.rs:57:22 + | +LL | let _rarw = &*explicit_deref(); + | ^^^^^^^^^^^^^^^^^ can't be dereferenced + +error[E0614]: type `DerefWrapper` cannot be dereferenced + --> $DIR/ambiguous-ops.rs:69:9 + | +LL | *explicit_deref_mut() = 1; + | ^^^^^^^^^^^^^^^^^^^^^ can't be dereferenced + +error[E0277]: the type `impl Sized` cannot be indexed by `_` + --> $DIR/ambiguous-ops.rs:94:18 + | +LL | let _y = explicit_index()[0]; + | ^^^^^^^^^^^^^^^^ `impl Sized` cannot be indexed by `_` + | + = help: the trait `Index<_>` is not implemented for `impl Sized` +note: required for `IndexWrapper` to implement `Index<_>` + --> $DIR/ambiguous-ops.rs:81:22 + | +LL | impl, U> Index for IndexWrapper { + | -------- ^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here + +error[E0277]: the type `impl Sized` cannot be indexed by `_` + --> $DIR/ambiguous-ops.rs:106:9 + | +LL | explicit_index_mut()[0] = 1; + | ^^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be indexed by `_` + | + = help: the trait `Index<_>` is not implemented for `impl Sized` +note: required for `IndexWrapper` to implement `Index<_>` + --> $DIR/ambiguous-ops.rs:81:22 + | +LL | impl, U> Index for IndexWrapper { + | -------- ^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0277, E0368, E0369, E0614. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs new file mode 100644 index 0000000000000..0aa5715339dc2 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/ambiguous-ops.rs @@ -0,0 +1,117 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] check-pass + +// Make sure we support non-call operations for opaque types even if +// its not part of its item bounds. + +use std::ops::{Deref, DerefMut, Index, IndexMut}; + +fn mk() -> T { + todo!() +} + +fn add() -> impl Sized { + let unconstrained = if false { + add() + 1 + //[current]~^ ERROR cannot add `{integer}` to `impl Sized + } else { + let with_infer = mk(); + let _ = with_infer + 1; + with_infer + }; + let _: u32 = unconstrained; + 1u32 +} + +fn mul_assign() -> impl Sized { + if false { + let mut temp = mul_assign(); + temp *= 2; + //[current]~^ ERROR binary assignment operation `*=` cannot be applied to type `impl Sized` + } + + let mut with_infer = mk(); + with_infer *= 2; + let _: u32 = with_infer; + + 1u32 +} + +struct DerefWrapper(T); +impl Deref for DerefWrapper { + type Target = T::Target; + fn deref(&self) -> &Self::Target { + &*self.0 + } +} +impl DerefMut for DerefWrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut *self.0 + } +} + +fn explicit_deref() -> DerefWrapper { + if false { + let _rarw = &*explicit_deref(); + //[current]~^ ERROR type `DerefWrapper` cannot be dereferenced + + let mut with_infer = DerefWrapper(mk()); + let _rarw = &*with_infer; + with_infer + } else { + DerefWrapper(&1u32) + } +} +fn explicit_deref_mut() -> DerefWrapper { + if false { + *explicit_deref_mut() = 1; + //[current]~^ ERROR type `DerefWrapper` cannot be dereferenced + + let mut with_infer = DerefWrapper(Default::default()); + *with_infer = 1; + with_infer + } else { + DerefWrapper(Box::new(1u32)) + } +} + +struct IndexWrapper(T); +impl, U> Index for IndexWrapper { + type Output = T::Output; + fn index(&self, index: U) -> &Self::Output { + &self.0[index] + } +} +impl, U> IndexMut for IndexWrapper { + fn index_mut(&mut self, index: U) -> &mut Self::Output { + &mut self.0[index] + } +} +fn explicit_index() -> IndexWrapper { + if false { + let _y = explicit_index()[0]; + //[current]~^ ERROR the type `impl Sized` cannot be indexed by `_` + + let with_infer = IndexWrapper(Default::default()); + let _y = with_infer[0]; + with_infer + } else { + IndexWrapper([1u32]) + } +} +fn explicit_index_mut() -> IndexWrapper { + if false { + explicit_index_mut()[0] = 1; + //[current]~^ ERROR the type `impl Sized` cannot be indexed by `_` + + let mut with_infer = IndexWrapper(Default::default()); + with_infer[0] = 1; + with_infer + } else { + IndexWrapper([1u32]) + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.current.stderr b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.current.stderr new file mode 100644 index 0000000000000..e213dab5d9618 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.current.stderr @@ -0,0 +1,53 @@ +error[E0382]: use of moved value: `var` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:14:9 + | +LL | let mut var = item_bound_is_too_weak(); + | ------- move occurs because `var` has type `impl FnOnce()`, which does not implement the `Copy` trait +LL | var(); + | ----- `var` moved due to this call +LL | var(); + | ^^^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:13:9 + | +LL | var(); + | ^^^ + +error[E0618]: expected function, found `impl Sized` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:24:9 + | +LL | fn opaque_type_no_impl_fn() -> impl Sized { + | ----------------------------------------- `opaque_type_no_impl_fn` defined here returns `impl Sized` +LL | if false { +LL | opaque_type_no_impl_fn()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0618]: expected function, found `impl Sized` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:34:9 + | +LL | fn opaque_type_no_impl_fn_incorrect() -> impl Sized { + | --------------------------------------------------- `opaque_type_no_impl_fn_incorrect` defined here returns `impl Sized` +LL | if false { +LL | opaque_type_no_impl_fn_incorrect()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0618]: expected function, found `impl Deref` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:44:9 + | +LL | fn opaque_type_deref_no_impl_fn() -> impl Deref { + | -------------------------------------------------------------------- `opaque_type_deref_no_impl_fn` defined here returns `impl Deref` +LL | if false { +LL | opaque_type_deref_no_impl_fn()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0382, E0618. +For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.next.stderr b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.next.stderr new file mode 100644 index 0000000000000..5678349cad32d --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.next.stderr @@ -0,0 +1,57 @@ +error[E0382]: use of moved value: `var` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:14:9 + | +LL | let mut var = item_bound_is_too_weak(); + | ------- move occurs because `var` has type `{closure@$DIR/call-expr-incorrect-choice-diagnostics.rs:19:5: 19:12}`, which does not implement the `Copy` trait +LL | var(); + | ----- `var` moved due to this call +LL | var(); + | ^^^ value used here after move + | +note: this value implements `FnOnce`, which causes it to be moved when called + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:13:9 + | +LL | var(); + | ^^^ +help: consider cloning the value if the performance cost is acceptable + | +LL | var.clone()(); + | ++++++++ + +error[E0618]: expected function, found `_` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:24:9 + | +LL | fn opaque_type_no_impl_fn() -> impl Sized { + | ----------------------------------------- `opaque_type_no_impl_fn` defined here returns `_` +LL | if false { +LL | opaque_type_no_impl_fn()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0618]: expected function, found `_` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:34:9 + | +LL | fn opaque_type_no_impl_fn_incorrect() -> impl Sized { + | --------------------------------------------------- `opaque_type_no_impl_fn_incorrect` defined here returns `_` +LL | if false { +LL | opaque_type_no_impl_fn_incorrect()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error[E0618]: expected function, found `_` + --> $DIR/call-expr-incorrect-choice-diagnostics.rs:44:9 + | +LL | fn opaque_type_deref_no_impl_fn() -> impl Deref { + | -------------------------------------------------------------------- `opaque_type_deref_no_impl_fn` defined here returns `_` +LL | if false { +LL | opaque_type_deref_no_impl_fn()(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- + | | + | call expression requires function + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0382, E0618. +For more information about an error, try `rustc --explain E0382`. diff --git a/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.rs b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.rs new file mode 100644 index 0000000000000..1d73985f78a12 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/call-expr-incorrect-choice-diagnostics.rs @@ -0,0 +1,52 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) + +// Testing the errors in case we've made a wrong choice when +// calling an opaque. + +use std::ops::Deref; + +fn item_bound_is_too_weak() -> impl FnOnce() { + if false { + let mut var = item_bound_is_too_weak(); + var(); + var(); + //~^ ERROR use of moved value: `var` + } + + let mut state = String::new(); + move || state.push('a') +} + +fn opaque_type_no_impl_fn() -> impl Sized { + if false { + opaque_type_no_impl_fn()(); + //[current]~^ ERROR expected function, found `impl Sized` + //[next]~^^ ERROR expected function, found `_` + } + + 1 +} + +fn opaque_type_no_impl_fn_incorrect() -> impl Sized { + if false { + opaque_type_no_impl_fn_incorrect()(); + //[current]~^ ERROR expected function, found `impl Sized` + //[next]~^^ ERROR expected function, found `_` + } + + || () +} + +fn opaque_type_deref_no_impl_fn() -> impl Deref { + if false { + opaque_type_deref_no_impl_fn()(); + //[current]~^ ERROR expected function, found `impl Deref` + //[next]~^^ ERROR expected function, found `_` + } + + &1 +} + +fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.current.stderr b/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.current.stderr new file mode 100644 index 0000000000000..bbe90e5873d04 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.current.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `len` found for struct `Wrapper` in the current scope + --> $DIR/deref-constrains-self-ty.rs:22:32 + | +LL | struct Wrapper(T); + | ----------------- method `len` not found for this struct +... +LL | let _ = Wrapper(foo()).len(); + | ^^^ method not found in `Wrapper` + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `len`, perhaps you need to implement it: + candidate #1: `ExactSizeIterator` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.rs b/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.rs new file mode 100644 index 0000000000000..d143878bc7466 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/deref-constrains-self-ty.rs @@ -0,0 +1,28 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] check-pass + +// A test which shows that autoderef can constrain opaque types even +// though it's supposed to treat not-yet-defined opaque types as +// mostly rigid. I don't think this should necessarily compile :shrug: +use std::ops::Deref; + +struct Wrapper(T); + +impl Deref for Wrapper> { + type Target = Vec; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +fn foo() -> impl Sized { + if false { + let _ = Wrapper(foo()).len(); + //[current]~^ ERROR no method named `len` found for struct `Wrapper` in the current scope + } + + std::iter::once(1).collect() +} +fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.current.stderr b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.current.stderr index 30424ec58f913..bac5b3e0cf441 100644 --- a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.current.stderr +++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.current.stderr @@ -1,5 +1,5 @@ error[E0792]: expected generic type parameter, found `impl Foo` - --> $DIR/double-wrap-with-defining-use.rs:12:26 + --> $DIR/double-wrap-with-defining-use.rs:11:26 | LL | fn a(x: T) -> impl Foo { | - this generic parameter must be used with a generic type parameter @@ -7,7 +7,7 @@ LL | if true { x } else { a(a(x)) } | ^^^^^^^ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/double-wrap-with-defining-use.rs:12:26 + --> $DIR/double-wrap-with-defining-use.rs:11:26 | LL | if true { x } else { a(a(x)) } | ^^^^^^^ diff --git a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs index 734b1920772f7..39b327eff18ed 100644 --- a/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs +++ b/tests/ui/impl-trait/non-defining-uses/double-wrap-with-defining-use.rs @@ -1,7 +1,6 @@ // Regression test for ICE from issue #140545 // The error message is confusing and wrong, but that's a different problem (#139350) -//@ edition:2018 //@ revisions: current next //@[next] compile-flags: -Znext-solver //@ ignore-compare-mode-next-solver (explicit revisions) diff --git a/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs b/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs new file mode 100644 index 0000000000000..9b9156ee4c716 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/function-call-on-infer.rs @@ -0,0 +1,73 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for trait-system-refactor-initiative#181. Make sure calling +// opaque types works. + +fn fn_trait() -> impl Fn() { + if false { + let f = fn_trait(); + f(); + } + + || () +} + +fn fn_trait_ref() -> impl Fn() { + if false { + let f = &fn_trait(); + f(); + } + || () +} + +fn fn_mut() -> impl FnMut() -> usize { + if false { + let mut f = fn_mut(); + f(); + } + + let mut state = 0; + move || { + state += 1; + state + } +} + +fn fn_mut_ref() -> impl FnMut() -> usize { + if false { + let mut f = &mut fn_mut(); + f(); + } + + let mut state = 0; + move || { + state += 1; + state + } +} + + +fn fn_once() -> impl FnOnce() { + if false { + let mut f = fn_once(); + f(); + } + + let string = String::new(); + move || drop(string) +} + +fn fn_once_ref() -> impl FnOnce() { + if false { + let mut f = Box::new(fn_once_ref()); + f(); + } + + let string = String::new(); + move || drop(string) +} + +fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr index ccbe2d3593c66..5dc66f454652a 100644 --- a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr +++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.current.stderr @@ -5,7 +5,7 @@ LL | fn create_complex_future() -> impl Future { | ^^^^^^^^^^^^^^^^ the trait `ReturnsSend` is not implemented for `()` | help: this trait has no implementations, consider adding one - --> $DIR/ice-issue-146191.rs:14:1 + --> $DIR/ice-issue-146191.rs:13:1 | LL | trait ReturnsSend {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr index e8b551c65fc0c..4a88359ca9679 100644 --- a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr +++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.next.stderr @@ -4,14 +4,6 @@ error[E0282]: type annotations needed LL | async { create_complex_future().await } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type -error[E0282]: type annotations needed - --> $DIR/ice-issue-146191.rs:8:5 - | -LL | async { create_complex_future().await } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs index 356f7d01eb9b7..84f139da4e32a 100644 --- a/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs +++ b/tests/ui/impl-trait/non-defining-uses/ice-issue-146191.rs @@ -8,7 +8,6 @@ fn create_complex_future() -> impl Future { async { create_complex_future().await } //[current]~^ ERROR recursion in an async block requires //[next]~^^ ERROR type annotations needed - //[next]~| ERROR type annotations needed } trait ReturnsSend {} diff --git a/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs b/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs new file mode 100644 index 0000000000000..5ff0dae55cc35 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/impl-deref-function-call.rs @@ -0,0 +1,56 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for trait-system-refactor-initiative#181. We want to +// be able to step through `impl Deref` in its defining scope. +use std::ops::{Deref, DerefMut}; +fn impl_deref_fn() -> impl Deref usize)> { + if false { + let func = impl_deref_fn(); + func(|s| s.len()); + } + + &((|_| ()) as fn(_)) +} + +fn impl_deref_impl_fn() -> impl Deref { + if false { + let func = impl_deref_impl_fn(); + func(); + } + + &|| () +} + +fn impl_deref_impl_deref_impl_fn() -> impl Deref> { + if false { + let func = impl_deref_impl_deref_impl_fn(); + func(); + } + + &&|| () +} + + +fn impl_deref_mut_impl_fn() -> impl DerefMut { + if false { + let func = impl_deref_impl_fn(); + func(); + } + + Box::new(|| ()) +} + + +fn impl_deref_mut_impl_fn_mut() -> impl DerefMut { + if false { + let mut func = impl_deref_mut_impl_fn_mut(); + func(); + } + + let mut state = 0; + Box::new(move || state += 1) +} +fn main() {} diff --git a/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs b/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs new file mode 100644 index 0000000000000..aa1b51d6906e4 --- /dev/null +++ b/tests/ui/impl-trait/non-defining-uses/shex_compat-regression-test.rs @@ -0,0 +1,19 @@ +//@ revisions: current next +//@[next] compile-flags: -Znext-solver +//@ ignore-compare-mode-next-solver (explicit revisions) +//@ check-pass + +// Regression test for trait-system-refactor-initiative#181. + +struct ShExCompactPrinter; + +struct TripleExpr; + +impl ShExCompactPrinter { + fn pp_triple_expr(&self) -> impl Fn(&TripleExpr, &ShExCompactPrinter) + '_ { + move |te, printer| { + printer.pp_triple_expr()(te, printer); + } + } +} +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/external-macro.rs b/tests/ui/impl-trait/precise-capturing/external-macro.rs index 9d4d8a1bb119a..1342ecd58dcf2 100644 --- a/tests/ui/impl-trait/precise-capturing/external-macro.rs +++ b/tests/ui/impl-trait/precise-capturing/external-macro.rs @@ -6,6 +6,7 @@ //@ aux-crate: no_use_macro=no-use-macro.rs //@ edition: 2024 //@ check-pass +//@ ignore-backends: gcc no_use_pm::pm_rpit!{} diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.rs b/tests/ui/impl-trait/precise-capturing/migration-note.rs index 7587e89409aaa..412d8af98845e 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.rs +++ b/tests/ui/impl-trait/precise-capturing/migration-note.rs @@ -32,6 +32,7 @@ fn needs_static() { //~| NOTE borrowed value does not live long enoug fn needs_static(_: impl Sized + 'static) {} + //~^ NOTE requirement that the value outlives `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } @@ -79,6 +80,7 @@ fn needs_static_mut() { //~| NOTE borrowed value does not live long enough fn needs_static(_: impl Sized + 'static) {} + //~^ NOTE requirement that the value outlives `'static` introduced here needs_static(a); //~^ NOTE argument requires that `x` is borrowed for `'static` } diff --git a/tests/ui/impl-trait/precise-capturing/migration-note.stderr b/tests/ui/impl-trait/precise-capturing/migration-note.stderr index aa0f640009158..880e7878477af 100644 --- a/tests/ui/impl-trait/precise-capturing/migration-note.stderr +++ b/tests/ui/impl-trait/precise-capturing/migration-note.stderr @@ -1,5 +1,5 @@ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:182:17 + --> $DIR/migration-note.rs:184:17 | LL | let x = vec![0]; | - binding `x` declared here @@ -50,6 +50,11 @@ LL | LL | } | - `x` dropped here while still borrowed | +note: requirement that the value outlives `'static` introduced here + --> $DIR/migration-note.rs:34:37 + | +LL | fn needs_static(_: impl Sized + 'static) {} + | ^^^^^^^ note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules --> $DIR/migration-note.rs:29:13 | @@ -61,7 +66,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:48:8 + --> $DIR/migration-note.rs:49:8 | LL | let x = vec![1]; | - binding `x` declared here @@ -76,7 +81,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:43:13 + --> $DIR/migration-note.rs:44:13 | LL | let a = display_len(&x); | ^^^^^^^^^^^^^^^ @@ -90,7 +95,7 @@ LL | let a = display_len(&x.clone()); | ++++++++ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/migration-note.rs:66:5 + --> $DIR/migration-note.rs:67:5 | LL | let a = display_len_mut(&mut x); | ------ first mutable borrow occurs here @@ -102,7 +107,7 @@ LL | println!("{a}"); | - first borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:63:13 + --> $DIR/migration-note.rs:64:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -112,7 +117,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0597]: `x` does not live long enough - --> $DIR/migration-note.rs:76:29 + --> $DIR/migration-note.rs:77:29 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -126,8 +131,13 @@ LL | LL | } | - `x` dropped here while still borrowed | +note: requirement that the value outlives `'static` introduced here + --> $DIR/migration-note.rs:82:37 + | +LL | fn needs_static(_: impl Sized + 'static) {} + | ^^^^^^^ note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:76:13 + --> $DIR/migration-note.rs:77:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +147,7 @@ LL | fn display_len_mut(x: &mut Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:95:8 + --> $DIR/migration-note.rs:97:8 | LL | let mut x = vec![1]; | ----- binding `x` declared here @@ -152,7 +162,7 @@ LL | } | - borrow might be used here, when `a` is dropped and runs the destructor for type `impl std::fmt::Display` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:90:13 + --> $DIR/migration-note.rs:92:13 | LL | let a = display_len_mut(&mut x); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +176,7 @@ LL | let a = display_len_mut(&mut x.clone()); | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:115:5 + --> $DIR/migration-note.rs:117:5 | LL | let a = display_field(&s.f); | ---- `s.f` is borrowed here @@ -178,7 +188,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:112:13 + --> $DIR/migration-note.rs:114:13 | LL | let a = display_field(&s.f); | ^^^^^^^^^^^^^^^^^^^ @@ -188,7 +198,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0506]: cannot assign to `s.f` because it is borrowed - --> $DIR/migration-note.rs:131:5 + --> $DIR/migration-note.rs:133:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -200,7 +210,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:128:13 + --> $DIR/migration-note.rs:130:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -210,7 +220,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0503]: cannot use `s.f` because it was mutably borrowed - --> $DIR/migration-note.rs:143:5 + --> $DIR/migration-note.rs:145:5 | LL | let a = display_field(&mut s.f); | -------- `s.f` is borrowed here @@ -222,7 +232,7 @@ LL | println!("{a}"); | - borrow later used here | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:140:13 + --> $DIR/migration-note.rs:142:13 | LL | let a = display_field(&mut s.f); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -232,7 +242,7 @@ LL | fn display_field(t: &T) -> impl Display + use { | ++++++++ error[E0597]: `z.f` does not live long enough - --> $DIR/migration-note.rs:159:25 + --> $DIR/migration-note.rs:161:25 | LL | let z = Z { f: vec![1] }; | - binding `z` declared here @@ -248,7 +258,7 @@ LL | } | = note: values in a scope are dropped in the opposite order they are defined note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:159:13 + --> $DIR/migration-note.rs:161:13 | LL | x = display_len(&z.f); | ^^^^^^^^^^^^^^^^^ @@ -258,7 +268,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0716]: temporary value dropped while borrowed - --> $DIR/migration-note.rs:170:40 + --> $DIR/migration-note.rs:172:40 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^ - - borrow later used here @@ -268,7 +278,7 @@ LL | let x = { let x = display_len(&mut vec![0]); x }; | = note: consider using a `let` binding to create a longer lived value note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:170:23 + --> $DIR/migration-note.rs:172:23 | LL | let x = { let x = display_len(&mut vec![0]); x }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,7 +289,7 @@ LL | fn display_len(x: &Vec) -> impl Display + use { | ++++++++ error[E0505]: cannot move out of `x` because it is borrowed - --> $DIR/migration-note.rs:198:10 + --> $DIR/migration-note.rs:200:10 | LL | let x = String::new(); | - binding `x` declared here @@ -294,12 +304,12 @@ LL | } | - borrow might be used here, when `y` is dropped and runs the destructor for type `impl Sized` | note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules - --> $DIR/migration-note.rs:195:13 + --> $DIR/migration-note.rs:197:13 | LL | let y = capture_apit(&x); | ^^^^^^^^^^^^^^^^ note: you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable - --> $DIR/migration-note.rs:189:21 + --> $DIR/migration-note.rs:191:21 | LL | fn capture_apit(x: &impl Sized) -> impl Sized {} | ^^^^^^^^^^ diff --git a/tests/ui/impl-trait/recursive-bound-eval.next.stderr b/tests/ui/impl-trait/recursive-bound-eval.next.stderr deleted file mode 100644 index 4bab290d71c3c..0000000000000 --- a/tests/ui/impl-trait/recursive-bound-eval.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/recursive-bound-eval.rs:20:13 - | -LL | move || recursive_fn().parse() - | ^^^^^^^^^^^^^^ cannot infer type - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs index 7859c8983fc89..058b12e5651e3 100644 --- a/tests/ui/impl-trait/recursive-bound-eval.rs +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -1,10 +1,9 @@ //! Test that we can evaluate nested obligations when invoking methods on recursive calls on //! an RPIT. -//@revisions: next current +//@ revisions: next current //@[next] compile-flags: -Znext-solver - -//@[current] check-pass +//@ check-pass pub trait Parser { fn parse(&self) -> E; @@ -18,7 +17,6 @@ impl E> Parser for T { pub fn recursive_fn() -> impl Parser { move || recursive_fn().parse() - //[next]~^ ERROR: type annotations needed } fn main() {} diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr deleted file mode 100644 index 5ce6eb0fc3989..0000000000000 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/recursive-coroutine-boxed.rs:11:23 - | -LL | let mut gen = Box::pin(foo()); - | ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box` -LL | -LL | let mut r = gen.as_mut().resume(()); - | ------ type must be known at this point - | -help: consider specifying the generic argument - | -LL | let mut gen = Box::::pin(foo()); - | +++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs index 306edc3591e98..932023d103dc4 100644 --- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs +++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs @@ -1,7 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-pass //@[next] compile-flags: -Znext-solver +//@ check-pass #![feature(coroutines, coroutine_trait)] use std::ops::{Coroutine, CoroutineState}; @@ -9,7 +9,6 @@ use std::ops::{Coroutine, CoroutineState}; fn foo() -> impl Coroutine { #[coroutine] || { let mut gen = Box::pin(foo()); - //[next]~^ ERROR type annotations needed let mut r = gen.as_mut().resume(()); while let CoroutineState::Yielded(v) = r { yield v; diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr index 785e5fdeb6433..9b18a9715f21f 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr @@ -4,12 +4,6 @@ error[E0282]: type annotations needed LL | fn muh(x: A) -> B { | ^ cannot infer type -error[E0282]: type annotations needed - --> $DIR/two_tait_defining_each_other2.rs:14:5 - | -LL | x // B's hidden type is A (opaquely) - | ^ cannot infer type - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs index 99262f4bc4b38..ec2963249f9da 100644 --- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs +++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs @@ -12,8 +12,7 @@ trait Foo {} fn muh(x: A) -> B { //[next]~^ ERROR: type annotations needed x // B's hidden type is A (opaquely) - //[next]~^ ERROR: type annotations needed - //[current]~^^ ERROR opaque type's hidden type cannot be another opaque type + //[current]~^ ERROR opaque type's hidden type cannot be another opaque type } struct Bar; diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 08caff326c470..4d8f23bf7ca64 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -387,6 +387,8 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani where A: Tuple, F: Fn, F: ?Sized; - impl Fn for Box where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + - impl Fn for Exclusive + where F: Sync, F: Fn, Args: Tuple; error[E0118]: no nominal type found for inherent implementation --> $DIR/where-allowed.rs:240:1 diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs index 6548c03d1b00c..e2750bcf957ea 100644 --- a/tests/ui/implied-bounds/bevy_world_query.rs +++ b/tests/ui/implied-bounds/bevy_world_query.rs @@ -1,6 +1,8 @@ -#![crate_name = "bevy_ecs"] - //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +#![crate_name = "bevy_ecs"] // We currently special case bevy from erroring on incorrect implied bounds // from normalization (issue #109628). diff --git a/tests/ui/imports/auxiliary/same-res-ambigious-extern-fail.rs b/tests/ui/imports/auxiliary/same-res-ambigious-extern-fail.rs new file mode 100644 index 0000000000000..61a8d8f0054a8 --- /dev/null +++ b/tests/ui/imports/auxiliary/same-res-ambigious-extern-fail.rs @@ -0,0 +1,16 @@ +//@ edition:2018 +//@ proc-macro: same-res-ambigious-extern-macro.rs + +macro_rules! globbing{ + () => { + pub use same_res_ambigious_extern_macro::*; + } +} + +#[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility +extern crate same_res_ambigious_extern_macro; +globbing! {} // this imports the same `RustEmbed` macro with `pub` visibility + +pub trait RustEmbed {} + +pub use RustEmbed as Embed; diff --git a/tests/ui/imports/auxiliary/same-res-ambigious-extern-macro.rs b/tests/ui/imports/auxiliary/same-res-ambigious-extern-macro.rs new file mode 100644 index 0000000000000..4e9b8427092f5 --- /dev/null +++ b/tests/ui/imports/auxiliary/same-res-ambigious-extern-macro.rs @@ -0,0 +1,8 @@ +//@ edition: 2018 +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_derive(RustEmbed)] +pub fn rust_embed_derive(_input: TokenStream) -> TokenStream { + TokenStream::new() +} diff --git a/tests/ui/imports/auxiliary/same-res-ambigious-extern.rs b/tests/ui/imports/auxiliary/same-res-ambigious-extern.rs new file mode 100644 index 0000000000000..5269dcd0b17a2 --- /dev/null +++ b/tests/ui/imports/auxiliary/same-res-ambigious-extern.rs @@ -0,0 +1,11 @@ +//@ edition:2018 +//@ proc-macro: same-res-ambigious-extern-macro.rs + +#[macro_use] // this imports the `RustEmbed` macro with `pub(crate)` visibility +extern crate same_res_ambigious_extern_macro; +// this imports the same `RustEmbed` macro with `pub` visibility +pub use same_res_ambigious_extern_macro::*; + +pub trait RustEmbed {} + +pub use RustEmbed as Embed; diff --git a/tests/ui/imports/same-res-ambigious.fail.stderr b/tests/ui/imports/same-res-ambigious.fail.stderr new file mode 100644 index 0000000000000..dfd7c5a5f94e0 --- /dev/null +++ b/tests/ui/imports/same-res-ambigious.fail.stderr @@ -0,0 +1,20 @@ +error[E0603]: derive macro `Embed` is private + --> $DIR/same-res-ambigious.rs:8:28 + | +LL | #[derive(ambigious_extern::Embed)] + | ^^^^^ private derive macro + | +note: the derive macro `Embed` is defined here + --> $DIR/auxiliary/same-res-ambigious-extern-fail.rs:16:9 + | +LL | pub use RustEmbed as Embed; + | ^^^^^^^^^ +help: import `Embed` directly + | +LL - #[derive(ambigious_extern::Embed)] +LL + #[derive(same_res_ambigious_extern_macro::RustEmbed)] + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/same-res-ambigious.nightly-fail.stderr b/tests/ui/imports/same-res-ambigious.nightly-fail.stderr new file mode 100644 index 0000000000000..dfd7c5a5f94e0 --- /dev/null +++ b/tests/ui/imports/same-res-ambigious.nightly-fail.stderr @@ -0,0 +1,20 @@ +error[E0603]: derive macro `Embed` is private + --> $DIR/same-res-ambigious.rs:8:28 + | +LL | #[derive(ambigious_extern::Embed)] + | ^^^^^ private derive macro + | +note: the derive macro `Embed` is defined here + --> $DIR/auxiliary/same-res-ambigious-extern-fail.rs:16:9 + | +LL | pub use RustEmbed as Embed; + | ^^^^^^^^^ +help: import `Embed` directly + | +LL - #[derive(ambigious_extern::Embed)] +LL + #[derive(same_res_ambigious_extern_macro::RustEmbed)] + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/tests/ui/imports/same-res-ambigious.rs b/tests/ui/imports/same-res-ambigious.rs new file mode 100644 index 0000000000000..b5c13a15b7c9c --- /dev/null +++ b/tests/ui/imports/same-res-ambigious.rs @@ -0,0 +1,11 @@ +//@ edition: 2018 +//@ revisions: fail pass +//@[pass] check-pass +//@[pass] aux-crate: ambigious_extern=same-res-ambigious-extern.rs +//@[fail] aux-crate: ambigious_extern=same-res-ambigious-extern-fail.rs +// see https://github.com/rust-lang/rust/pull/147196 + +#[derive(ambigious_extern::Embed)] //[fail]~ ERROR: derive macro `Embed` is private +struct Foo{} + +fn main(){} diff --git a/tests/ui/indexing/ambiguity-after-deref-step.rs b/tests/ui/indexing/ambiguity-after-deref-step.rs new file mode 100644 index 0000000000000..2dd95eed097ca --- /dev/null +++ b/tests/ui/indexing/ambiguity-after-deref-step.rs @@ -0,0 +1,9 @@ +// Regression test making sure that indexing fails with an ambiguity +// error if one of the deref-steps encounters an inference variable. + +fn main() { + let x = &Default::default(); + //~^ ERROR type annotations needed for `&_` + x[1]; + let _: &Vec<()> = x; +} diff --git a/tests/ui/indexing/ambiguity-after-deref-step.stderr b/tests/ui/indexing/ambiguity-after-deref-step.stderr new file mode 100644 index 0000000000000..c7ddd4731c7cb --- /dev/null +++ b/tests/ui/indexing/ambiguity-after-deref-step.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `&_` + --> $DIR/ambiguity-after-deref-step.rs:5:9 + | +LL | let x = &Default::default(); + | ^ +LL | +LL | x[1]; + | - type must be known at this point + | +help: consider giving `x` an explicit type, where the placeholders `_` are specified + | +LL | let x: &_ = &Default::default(); + | ++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/indexing/index_message.stderr b/tests/ui/indexing/index_message.stderr index 6affb1ed96252..b6f61379f2af5 100644 --- a/tests/ui/indexing/index_message.stderr +++ b/tests/ui/indexing/index_message.stderr @@ -2,7 +2,9 @@ error[E0608]: cannot index into a value of type `({integer},)` --> $DIR/index_message.rs:3:14 | LL | let _ = z[0]; - | ^^^ help: to access tuple elements, use: `.0` + | ^^^ help: to access tuple element `0`, use: `.0` + | + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error: aborting due to 1 previous error diff --git a/tests/ui/inference/ambiguous-numeric-in-closure-ref.fixed b/tests/ui/inference/ambiguous-numeric-in-closure-ref.fixed new file mode 100644 index 0000000000000..683d581d034b1 --- /dev/null +++ b/tests/ui/inference/ambiguous-numeric-in-closure-ref.fixed @@ -0,0 +1,14 @@ +// Test for better error message when numeric type is ambiguous in closure parameter with reference + +//@ run-rustfix + +fn main() { + let _ = (0..10).filter(|&v: &i32| v.pow(2) > 0); + //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}` + //~| SUGGESTION &i32 + + let v = vec![0, 1, 2]; + let _ = v.iter().filter(|&&v: &&i32| v.pow(2) > 0); + //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}` + //~| SUGGESTION &&i32 +} diff --git a/tests/ui/inference/ambiguous-numeric-in-closure-ref.rs b/tests/ui/inference/ambiguous-numeric-in-closure-ref.rs new file mode 100644 index 0000000000000..eab309c701d69 --- /dev/null +++ b/tests/ui/inference/ambiguous-numeric-in-closure-ref.rs @@ -0,0 +1,14 @@ +// Test for better error message when numeric type is ambiguous in closure parameter with reference + +//@ run-rustfix + +fn main() { + let _ = (0..10).filter(|&v| v.pow(2) > 0); + //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}` + //~| SUGGESTION &i32 + + let v = vec![0, 1, 2]; + let _ = v.iter().filter(|&&v| v.pow(2) > 0); + //~^ ERROR can't call method `pow` on ambiguous numeric type `{integer}` + //~| SUGGESTION &&i32 +} diff --git a/tests/ui/inference/ambiguous-numeric-in-closure-ref.stderr b/tests/ui/inference/ambiguous-numeric-in-closure-ref.stderr new file mode 100644 index 0000000000000..0789581abea80 --- /dev/null +++ b/tests/ui/inference/ambiguous-numeric-in-closure-ref.stderr @@ -0,0 +1,29 @@ +error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}` + --> $DIR/ambiguous-numeric-in-closure-ref.rs:6:35 + | +LL | let _ = (0..10).filter(|&v| v.pow(2) > 0); + | - ^^^ + | | + | you must specify a type for this binding + | +help: specify the type in the closure argument list + | +LL | let _ = (0..10).filter(|&v: &i32| v.pow(2) > 0); + | ++++++ + +error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}` + --> $DIR/ambiguous-numeric-in-closure-ref.rs:11:37 + | +LL | let _ = v.iter().filter(|&&v| v.pow(2) > 0); + | - ^^^ + | | + | you must specify a type for this binding + | +help: specify the type in the closure argument list + | +LL | let _ = v.iter().filter(|&&v: &&i32| v.pow(2) > 0); + | +++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0689`. diff --git a/tests/ui/inference/bitwise-integer-inference-68951.rs b/tests/ui/inference/bitwise-integer-inference-68951.rs new file mode 100644 index 0000000000000..4904af3e1f3b0 --- /dev/null +++ b/tests/ui/inference/bitwise-integer-inference-68951.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/68951 +//@ check-pass + +fn main() { + let array = [0x42u8; 10]; + for b in &array { + let lo = b & 0xf; + let hi = (b >> 4) & 0xf; + } +} diff --git a/tests/ui/inference/issue-72616.rs b/tests/ui/inference/issue-72616.rs index 71e095cc6fc02..ba18575a57156 100644 --- a/tests/ui/inference/issue-72616.rs +++ b/tests/ui/inference/issue-72616.rs @@ -21,7 +21,6 @@ pub fn main() { { if String::from("a") == "a".try_into().unwrap() {} //~^ ERROR type annotations needed - //~| ERROR type annotations needed } { let _: String = match "_".try_into() { diff --git a/tests/ui/inference/issue-72616.stderr b/tests/ui/inference/issue-72616.stderr index a271639996fd2..6b47d56881134 100644 --- a/tests/ui/inference/issue-72616.stderr +++ b/tests/ui/inference/issue-72616.stderr @@ -16,23 +16,6 @@ LL - if String::from("a") == "a".try_into().unwrap() {} LL + if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} | -error[E0283]: type annotations needed - --> $DIR/issue-72616.rs:22:37 - | -LL | if String::from("a") == "a".try_into().unwrap() {} - | ^^^^^^^^ - | - = note: multiple `impl`s satisfying `_: TryFrom<&str>` found in the following crates: `core`, `std`: - - impl TryFrom<&str> for std::sys::net::connection::socket::LookupHost; - - impl TryFrom for T - where U: Into; - = note: required for `&str` to implement `TryInto<_>` -help: try using a fully qualified path to specify the expected types - | -LL - if String::from("a") == "a".try_into().unwrap() {} -LL + if String::from("a") == <&str as TryInto>::try_into("a").unwrap() {} - | - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/inference/return-block-type-inference-15965.stderr b/tests/ui/inference/return-block-type-inference-15965.stderr index fc4f2defe7ffa..bfee904192204 100644 --- a/tests/ui/inference/return-block-type-inference-15965.stderr +++ b/tests/ui/inference/return-block-type-inference-15965.stderr @@ -1,10 +1,8 @@ error[E0282]: type annotations needed --> $DIR/return-block-type-inference-15965.rs:5:9 | -LL | / { return () } -LL | | -LL | | () - | |______^ cannot infer type +LL | { return () } + | ^^^^^^^^^^^^^ cannot infer type error: aborting due to 1 previous error diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs index f7117368ece7b..b8ea353df9385 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs @@ -1,4 +1,17 @@ -//~ ERROR reached the recursion limit while instantiating `` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `SomeData<256>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` +//~| ERROR reached the recursion limit while instantiating ` as MyTrait>::virtualize` + //@ build-fail //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes @@ -72,16 +85,3 @@ fn main() { let test = SomeData([0; 256]); test.virtualize(); } - -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `[u8; 256]` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `SomeData<256>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` -//~? ERROR reached the recursion limit finding the struct tail for `VirtualWrapper, 0>` diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr index faf9cbe2318c4..deccc88e64fa5 100644 --- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr +++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr @@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -46,7 +46,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` note: the above error was encountered while instantiating `fn virtualize_my_trait::>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper>` - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:18 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:38:18 | LL | unsafe { virtualize_my_trait(L, self) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | unsafe { virtualize_my_trait(L, self) } error: reached the recursion limit while instantiating ` as MyTrait>::virtualize` | note: ` as MyTrait>::virtualize` defined here - --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:24:5 + --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:37:5 | LL | fn virtualize(&self) -> &dyn MyTrait { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/infinite/infinite-struct.rs b/tests/ui/infinite/infinite-struct.rs index fd47a4ec9cc6a..d784455824604 100644 --- a/tests/ui/infinite/infinite-struct.rs +++ b/tests/ui/infinite/infinite-struct.rs @@ -1,6 +1,7 @@ struct Take(Take); //~^ ERROR has infinite size //~| ERROR cycle +//~| ERROR reached the recursion limit finding the struct tail for `Take` // check that we don't hang trying to find the tail of a recursive struct (#79437) fn foo() -> Take { @@ -15,5 +16,3 @@ struct Foo { //~ ERROR has infinite size struct Bar([T; 1]); fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `Take` diff --git a/tests/ui/infinite/infinite-struct.stderr b/tests/ui/infinite/infinite-struct.stderr index 5896aec399dc4..0d1ec4989aa53 100644 --- a/tests/ui/infinite/infinite-struct.stderr +++ b/tests/ui/infinite/infinite-struct.stderr @@ -10,7 +10,7 @@ LL | struct Take(Box); | ++++ + error[E0072]: recursive type `Foo` has infinite size - --> $DIR/infinite-struct.rs:11:1 + --> $DIR/infinite-struct.rs:12:1 | LL | struct Foo { | ^^^^^^^^^^ @@ -23,6 +23,10 @@ LL | x: Bar>, | ++++ + error: reached the recursion limit finding the struct tail for `Take` + --> $DIR/infinite-struct.rs:1:1 + | +LL | struct Take(Take); + | ^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` diff --git a/tests/ui/instrument-coverage/link-regex-crate-with-instrument-coverage-85461.rs b/tests/ui/instrument-coverage/msvc-link-dead-code-inline-always-85461.rs similarity index 100% rename from tests/ui/instrument-coverage/link-regex-crate-with-instrument-coverage-85461.rs rename to tests/ui/instrument-coverage/msvc-link-dead-code-inline-always-85461.rs diff --git a/tests/ui/instrument-xray/platform-support.rs b/tests/ui/instrument-xray/platform-support.rs index 238018b348dee..68b0e4f5c9821 100644 --- a/tests/ui/instrument-xray/platform-support.rs +++ b/tests/ui/instrument-xray/platform-support.rs @@ -19,6 +19,7 @@ //@[aarch64-darwin] needs-llvm-components: aarch64 //@[aarch64-darwin] compile-flags: -Z instrument-xray --target=aarch64-apple-darwin //@[aarch64-darwin] check-pass +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr index 5a959d14c8a91..b307d608a1fd9 100644 --- a/tests/ui/interior-mutability/interior-mutability.stderr +++ b/tests/ui/interior-mutability/interior-mutability.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/interior-mutability.rs:6:18 | LL | catch_unwind(|| { x.set(23); }); - | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ------------ ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | | | required by a bound introduced by this call | diff --git a/tests/ui/internal/internal-unstable.rs b/tests/ui/internal/internal-unstable.rs index 381c1337148c9..5564852e98888 100644 --- a/tests/ui/internal/internal-unstable.rs +++ b/tests/ui/internal/internal-unstable.rs @@ -8,6 +8,8 @@ extern crate internal_unstable; struct Baz { #[allow_internal_unstable] //~ ERROR `allow_internal_unstable` expects a list of feature names + //~^ WARN cannot be used on + //~| WARN previously accepted baz: u8, } @@ -57,6 +59,8 @@ fn main() { match true { #[allow_internal_unstable] //~ ERROR `allow_internal_unstable` expects a list of feature names + //~^ WARN cannot be used on + //~| WARN previously accepted _ => {} } diff --git a/tests/ui/internal/internal-unstable.stderr b/tests/ui/internal/internal-unstable.stderr index bbf589d3f9268..192ecdfd08916 100644 --- a/tests/ui/internal/internal-unstable.stderr +++ b/tests/ui/internal/internal-unstable.stderr @@ -5,13 +5,13 @@ LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `allow_internal_unstable` expects a list of feature names - --> $DIR/internal-unstable.rs:59:9 + --> $DIR/internal-unstable.rs:61:9 | LL | #[allow_internal_unstable] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0658]: use of unstable library feature `function` - --> $DIR/internal-unstable.rs:48:25 + --> $DIR/internal-unstable.rs:50:25 | LL | pass_through_allow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -20,7 +20,7 @@ LL | pass_through_allow!(internal_unstable::unstable()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `function` - --> $DIR/internal-unstable.rs:50:27 + --> $DIR/internal-unstable.rs:52:27 | LL | pass_through_noallow!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | pass_through_noallow!(internal_unstable::unstable()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `function` - --> $DIR/internal-unstable.rs:54:22 + --> $DIR/internal-unstable.rs:56:22 | LL | println!("{:?}", internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | println!("{:?}", internal_unstable::unstable()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `function` - --> $DIR/internal-unstable.rs:56:10 + --> $DIR/internal-unstable.rs:58:10 | LL | bar!(internal_unstable::unstable()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | bar!(internal_unstable::unstable()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: use of unstable library feature `function` - --> $DIR/internal-unstable.rs:18:9 + --> $DIR/internal-unstable.rs:20:9 | LL | internal_unstable::unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,6 +59,25 @@ LL | bar!(internal_unstable::unstable()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this error originates in the macro `foo` which comes from the expansion of the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 7 previous errors +warning: `#[allow_internal_unstable]` attribute cannot be used on struct fields + --> $DIR/internal-unstable.rs:10:5 + | +LL | #[allow_internal_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[allow_internal_unstable]` can be applied to functions and macro defs + = note: requested on the command line with `-W unused-attributes` + +warning: `#[allow_internal_unstable]` attribute cannot be used on match arms + --> $DIR/internal-unstable.rs:61:9 + | +LL | #[allow_internal_unstable] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[allow_internal_unstable]` can be applied to functions and macro defs + +error: aborting due to 7 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/intrinsics/intrinsic-fmuladd.rs b/tests/ui/intrinsics/intrinsic-fmuladd.rs index d03297884f791..ab4285590cb95 100644 --- a/tests/ui/intrinsics/intrinsic-fmuladd.rs +++ b/tests/ui/intrinsics/intrinsic-fmuladd.rs @@ -11,7 +11,7 @@ macro_rules! assert_approx_eq { } fn main() { - unsafe { + { let nan: f32 = f32::NAN; let inf: f32 = f32::INFINITY; let neg_inf: f32 = f32::NEG_INFINITY; @@ -25,7 +25,7 @@ fn main() { assert_eq!(fmuladdf32(8.9, inf, 3.2), inf); assert_eq!(fmuladdf32(-3.2, 2.4, neg_inf), neg_inf); } - unsafe { + { let nan: f64 = f64::NAN; let inf: f64 = f64::INFINITY; let neg_inf: f64 = f64::NEG_INFINITY; diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs index db2b4a6ad20a7..00fb2b029f9aa 100644 --- a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -7,7 +7,7 @@ //@ ignore-backends: gcc //@ edition:2024 -#![allow(deprecated, invalid_value)] +#![allow(deprecated, invalid_value, unreachable_code)] #![feature(never_type, rustc_private)] use std::{ diff --git a/tests/ui/intrinsics/reify-intrinsic.stderr b/tests/ui/intrinsics/reify-intrinsic.stderr index aea6f838e0d44..1307a85c8b6ca 100644 --- a/tests/ui/intrinsics/reify-intrinsic.stderr +++ b/tests/ui/intrinsics/reify-intrinsic.stderr @@ -22,7 +22,7 @@ LL | std::intrinsics::floorf32, | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers | = note: expected fn pointer `unsafe fn(_) -> _` - found fn item `unsafe fn(_) -> _ {floorf32}` + found fn item `fn(_) -> _ {floorf32}` error: aborting due to 3 previous errors diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr index dae08119dbc68..277111a41f29c 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGS.stderr @@ -1,2 +1,2 @@ -error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected +error: incorrect value `leaf` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected diff --git a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr index 13f79e94674b2..e1ade01d2fe76 100644 --- a/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr +++ b/tests/ui/invalid-compile-flags/branch-protection-missing-pac-ret.BADFLAGSPC.stderr @@ -1,2 +1,2 @@ -error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `pac-ret`, followed by a combination of `pc`, `b-key`, or `leaf` was expected +error: incorrect value `pc` for unstable option `branch-protection` - a `,` separated combination of `bti`, `gcs`, `pac-ret`, (optionally with `pc`, `b-key`, `leaf` if `pac-ret` is set) was expected diff --git a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs b/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs index c7973c686da00..e46530a12c382 100644 --- a/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs +++ b/tests/ui/invalid-compile-flags/function-return/requires-x86-or-x86_64.rs @@ -13,6 +13,7 @@ //@[aarch64] check-fail //@[aarch64] needs-llvm-components: aarch64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs index bc81c993d26ef..f0409a6f07796 100644 --- a/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs +++ b/tests/ui/invalid-compile-flags/indirect-branch-cs-prefix/requires-x86-or-x86_64.rs @@ -13,6 +13,7 @@ //@[aarch64] check-fail //@[aarch64] needs-llvm-components: aarch64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs b/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs index 832821c9c883f..2ed0014f8b0ef 100644 --- a/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs +++ b/tests/ui/invalid-compile-flags/invalid-llvm-passes.rs @@ -1,5 +1,6 @@ //@ build-fail //@ compile-flags: -Cpasses=unknown-pass +//@ ignore-backends: gcc fn main() {} diff --git a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs b/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs index 436442ee72993..321cf56cd2a0f 100644 --- a/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs +++ b/tests/ui/invalid-compile-flags/reg-struct-return/requires-x86.rs @@ -13,6 +13,7 @@ //@[aarch64] check-fail //@[aarch64] needs-llvm-components: aarch64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs index a66dfe8597718..6999eaac962aa 100644 --- a/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs +++ b/tests/ui/invalid-compile-flags/regparm/regparm-valid-values.rs @@ -17,6 +17,7 @@ //@[regparm4] check-fail //@[regparm4] compile-flags: -Zregparm=4 +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs index 32c4b5af35772..983e412376dc0 100644 --- a/tests/ui/invalid-compile-flags/regparm/requires-x86.rs +++ b/tests/ui/invalid-compile-flags/regparm/requires-x86.rs @@ -13,6 +13,7 @@ //@[aarch64] check-fail //@[aarch64] needs-llvm-components: aarch64 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.rs b/tests/ui/invalid/invalid-debugger-visualizer-option.rs index 0f1cf15a6879a..166962866dce4 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.rs @@ -1,6 +1,6 @@ //@ normalize-stderr: "foo.random:.*\(" -> "foo.random: $$FILE_NOT_FOUND_MSG (" //@ normalize-stderr: "os error \d+" -> "os error $$FILE_NOT_FOUND_CODE" -#![debugger_visualizer(random_file = "../foo.random")] //~ ERROR invalid argument +#![debugger_visualizer(random_file = "../foo.random")] //~ ERROR malformed `debugger_visualizer` attribute input #![debugger_visualizer(natvis_file = "../foo.random")] //~ ERROR fn main() {} diff --git a/tests/ui/invalid/invalid-debugger-visualizer-option.stderr b/tests/ui/invalid/invalid-debugger-visualizer-option.stderr index 6fbb4d641e6f6..e877e39d8f119 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-option.stderr +++ b/tests/ui/invalid/invalid-debugger-visualizer-option.stderr @@ -1,18 +1,20 @@ -error: invalid argument - --> $DIR/invalid-debugger-visualizer-option.rs:4:24 - | -LL | #![debugger_visualizer(random_file = "../foo.random")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: expected: `natvis_file = "..."` - = note: OR - = note: expected: `gdb_script_file = "..."` - error: couldn't read $DIR/../foo.random: $FILE_NOT_FOUND_MSG (os error $FILE_NOT_FOUND_CODE) --> $DIR/invalid-debugger-visualizer-option.rs:5:24 | LL | #![debugger_visualizer(natvis_file = "../foo.random")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0539]: malformed `debugger_visualizer` attribute input + --> $DIR/invalid-debugger-visualizer-option.rs:4:1 + | +LL | #![debugger_visualizer(random_file = "../foo.random")] + | ^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^^^^ + | | | + | | valid arguments are `natvis_file` or `gdb_script_file` + | help: must be of the form: `#![debugger_visualizer(natvis_file = "...", gdb_script_file = "...")]` + | + = note: for more information, visit + error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/invalid/invalid-debugger-visualizer-target.rs b/tests/ui/invalid/invalid-debugger-visualizer-target.rs index 1efb9555c242a..48b041532140a 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-target.rs +++ b/tests/ui/invalid/invalid-debugger-visualizer-target.rs @@ -1,2 +1,3 @@ -#[debugger_visualizer(natvis_file = "./foo.natvis.xml")] //~ ERROR attribute should be applied to a module +#[debugger_visualizer(natvis_file = "./foo.natvis.xml")] +//~^ ERROR `#[debugger_visualizer]` attribute cannot be used on functions fn main() {} diff --git a/tests/ui/invalid/invalid-debugger-visualizer-target.stderr b/tests/ui/invalid/invalid-debugger-visualizer-target.stderr index 1df3453253372..c721e3dc10f59 100644 --- a/tests/ui/invalid/invalid-debugger-visualizer-target.stderr +++ b/tests/ui/invalid/invalid-debugger-visualizer-target.stderr @@ -1,8 +1,10 @@ -error: attribute should be applied to a module +error: `#[debugger_visualizer]` attribute cannot be used on functions --> $DIR/invalid-debugger-visualizer-target.rs:1:1 | LL | #[debugger_visualizer(natvis_file = "./foo.natvis.xml")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `#[debugger_visualizer]` can be applied to crates and modules error: aborting due to 1 previous error diff --git a/tests/ui/invalid/issue-114435-layout-type-err.rs b/tests/ui/invalid/issue-114435-layout-type-err.rs index 07f310478d3c9..ae04759af5df2 100644 --- a/tests/ui/invalid/issue-114435-layout-type-err.rs +++ b/tests/ui/invalid/issue-114435-layout-type-err.rs @@ -1,3 +1,4 @@ +//~ ERROR reached the recursion limit finding the struct tail for `Bottom` //@ check-fail //@ compile-flags: --crate-type lib -Cdebuginfo=2 @@ -40,5 +41,3 @@ link!(J, K); link!(K, Bottom); fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `Bottom` diff --git a/tests/ui/issues/issue-18088.rs b/tests/ui/issues/issue-18088.rs deleted file mode 100644 index ba198884c639f..0000000000000 --- a/tests/ui/issues/issue-18088.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ check-pass - -pub trait Indexable: std::ops::Index { - fn index2(&self, i: usize) -> &T { - &self[i] - } -} -fn main() {} diff --git a/tests/ui/issues/issue-19367.rs b/tests/ui/issues/issue-19367.rs index ce8451dd2de13..1cd6c483375ab 100644 --- a/tests/ui/issues/issue-19367.rs +++ b/tests/ui/issues/issue-19367.rs @@ -1,4 +1,7 @@ //@ run-pass + +#![allow(unused_assignments)] + struct S { o: Option } diff --git a/tests/ui/issues/issue-19479.rs b/tests/ui/issues/issue-19479.rs deleted file mode 100644 index ed586b7655028..0000000000000 --- a/tests/ui/issues/issue-19479.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ check-pass - -trait Base { - fn dummy(&self) { } -} -trait AssocA { - type X: Base; - fn dummy(&self) { } -} -trait AssocB { - type Y: Base; - fn dummy(&self) { } -} -impl AssocB for T { - type Y = ::X; -} - -fn main() {} diff --git a/tests/ui/issues/issue-20261.stderr b/tests/ui/issues/issue-20261.stderr index 6738708ca225d..c5348abb3c501 100644 --- a/tests/ui/issues/issue-20261.stderr +++ b/tests/ui/issues/issue-20261.stderr @@ -1,8 +1,8 @@ error[E0282]: type annotations needed - --> $DIR/issue-20261.rs:4:11 + --> $DIR/issue-20261.rs:4:9 | LL | i.clone(); - | ^^^^^ cannot infer type + | ^ cannot infer type error: aborting due to 1 previous error diff --git a/tests/ui/issues/issue-21950.rs b/tests/ui/issues/issue-21950.rs deleted file mode 100644 index 7a85ac91bca0f..0000000000000 --- a/tests/ui/issues/issue-21950.rs +++ /dev/null @@ -1,12 +0,0 @@ -trait Add { - type Output; -} - -impl Add for i32 { - type Output = i32; -} - -fn main() { - let x = &10 as &dyn Add; - //~^ ERROR E0191 -} diff --git a/tests/ui/issues/issue-21950.stderr b/tests/ui/issues/issue-21950.stderr deleted file mode 100644 index 24230cfe17f3d..0000000000000 --- a/tests/ui/issues/issue-21950.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0191]: the value of the associated type `Output` in `Add` must be specified - --> $DIR/issue-21950.rs:10:25 - | -LL | type Output; - | ----------- `Output` defined here -... -LL | let x = &10 as &dyn Add; - | ^^^ help: specify the associated type: `Add` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/issues/issue-2284.rs b/tests/ui/issues/issue-2284.rs deleted file mode 100644 index 358331ecd9a4c..0000000000000 --- a/tests/ui/issues/issue-2284.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -trait Send { - fn f(&self); -} - -fn f(t: T) { - t.f(); -} - -pub fn main() { -} diff --git a/tests/ui/issues/issue-25089.rs b/tests/ui/issues/issue-25089.rs index 929738c3e794d..63fdf64cea946 100644 --- a/tests/ui/issues/issue-25089.rs +++ b/tests/ui/issues/issue-25089.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc use std::thread; diff --git a/tests/ui/issues/issue-26655.rs b/tests/ui/issues/issue-26655.rs index 416472b0b269e..32c4b33a8c967 100644 --- a/tests/ui/issues/issue-26655.rs +++ b/tests/ui/issues/issue-26655.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc // Check that the destructors of simple enums are run on unwinding diff --git a/tests/ui/issues/issue-27592.stderr b/tests/ui/issues/issue-27592.stderr index c8649d82d7451..f1de7b9e569da 100644 --- a/tests/ui/issues/issue-27592.stderr +++ b/tests/ui/issues/issue-27592.stderr @@ -1,3 +1,9 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/issue-27592.rs:16:14 + | +LL | write(|| format_args!("{}", String::from("Hello world"))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function + error[E0515]: cannot return value referencing temporary value --> $DIR/issue-27592.rs:16:14 | @@ -7,12 +13,6 @@ LL | write(|| format_args!("{}", String::from("Hello world"))); | | temporary value created here | returns a value referencing data owned by the current function -error[E0515]: cannot return reference to temporary value - --> $DIR/issue-27592.rs:16:14 - | -LL | write(|| format_args!("{}", String::from("Hello world"))); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function - error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/issues/issue-27842.stderr b/tests/ui/issues/issue-27842.stderr index b18fe1512b50b..f388fdf85cde5 100644 --- a/tests/ui/issues/issue-27842.stderr +++ b/tests/ui/issues/issue-27842.stderr @@ -2,17 +2,17 @@ error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer --> $DIR/issue-27842.rs:4:16 | LL | let _ = tup[0]; - | ^^^ help: to access tuple elements, use: `.0` + | ^^^ help: to access tuple element `0`, use: `.0` + | + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error[E0608]: cannot index into a value of type `({integer}, {integer}, {integer})` --> $DIR/issue-27842.rs:9:16 | LL | let _ = tup[i]; - | ^-^ - | | - | cannot access tuple elements at a variable index + | ^^^ | - = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error[E0608]: cannot index into a value of type `({integer},)` --> $DIR/issue-27842.rs:14:16 @@ -20,7 +20,7 @@ error[E0608]: cannot index into a value of type `({integer},)` LL | let _ = tup[3]; | ^^^ | - = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-29485.rs b/tests/ui/issues/issue-29485.rs index a44bcd49c6a9c..8e6436cb11e34 100644 --- a/tests/ui/issues/issue-29485.rs +++ b/tests/ui/issues/issue-29485.rs @@ -3,6 +3,7 @@ //@ aux-build:issue-29485.rs //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc #[feature(recover)] diff --git a/tests/ui/issues/issue-30018-panic.rs b/tests/ui/issues/issue-30018-panic.rs index 591848b6f7b4e..09b832bb59d02 100644 --- a/tests/ui/issues/issue-30018-panic.rs +++ b/tests/ui/issues/issue-30018-panic.rs @@ -6,6 +6,7 @@ //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc struct Foo; diff --git a/tests/ui/issues/issue-32782.stderr b/tests/ui/issues/issue-32782.stderr index 96cd0489b2a71..2a1183ab978d0 100644 --- a/tests/ui/issues/issue-32782.stderr +++ b/tests/ui/issues/issue-32782.stderr @@ -20,7 +20,7 @@ LL | #[allow_internal_unstable()] LL | foo!(); | ------ in this macro invocation | - = help: `#[allow_internal_unstable]` can be applied to macro defs and functions + = help: `#[allow_internal_unstable]` can be applied to functions and macro defs = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/issues/issue-44056.rs b/tests/ui/issues/issue-44056.rs index 12e4f018466f0..37d7b00cf7f0e 100644 --- a/tests/ui/issues/issue-44056.rs +++ b/tests/ui/issues/issue-44056.rs @@ -2,5 +2,6 @@ //@ only-x86_64 //@ no-prefer-dynamic //@ compile-flags: -Ctarget-feature=+avx -Clto +//@ ignore-backends: gcc fn main() {} diff --git a/tests/ui/issues/issue-45562.fixed b/tests/ui/issues/issue-45562.fixed index 8dcdd3a541ce4..529b5bd744e03 100644 --- a/tests/ui/issues/issue-45562.fixed +++ b/tests/ui/issues/issue-45562.fixed @@ -1,5 +1,7 @@ //@ run-rustfix +#![deny(unused_attributes)] + #[no_mangle] pub static RAH: usize = 5; //~^ ERROR const items should never be `#[no_mangle]` diff --git a/tests/ui/issues/issue-45562.rs b/tests/ui/issues/issue-45562.rs index 08f6c8046dce4..7c30a967c7848 100644 --- a/tests/ui/issues/issue-45562.rs +++ b/tests/ui/issues/issue-45562.rs @@ -1,5 +1,7 @@ //@ run-rustfix +#![deny(unused_attributes)] + #[no_mangle] pub const RAH: usize = 5; //~^ ERROR const items should never be `#[no_mangle]` diff --git a/tests/ui/issues/issue-45562.stderr b/tests/ui/issues/issue-45562.stderr index 6fae86f9f31ca..55d35f76a0198 100644 --- a/tests/ui/issues/issue-45562.stderr +++ b/tests/ui/issues/issue-45562.stderr @@ -1,5 +1,5 @@ error: const items should never be `#[no_mangle]` - --> $DIR/issue-45562.rs:3:14 + --> $DIR/issue-45562.rs:5:14 | LL | #[no_mangle] pub const RAH: usize = 5; | ---------^^^^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-45731.rs b/tests/ui/issues/issue-45731.rs index 49335362dd0f7..db11d1dbef1c7 100644 --- a/tests/ui/issues/issue-45731.rs +++ b/tests/ui/issues/issue-45731.rs @@ -1,6 +1,10 @@ //@ run-pass #![allow(unused_variables)] //@ compile-flags:--test -g +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device #[cfg(target_vendor = "apple")] #[test] diff --git a/tests/ui/issues/issue-49851/compiler-builtins-error.rs b/tests/ui/issues/issue-49851/compiler-builtins-error.rs index db45d040f7914..aa08b1ee47707 100644 --- a/tests/ui/issues/issue-49851/compiler-builtins-error.rs +++ b/tests/ui/issues/issue-49851/compiler-builtins-error.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv7em-none-eabihf //@ needs-llvm-components: arm +//@ ignore-backends: gcc #![deny(unsafe_code)] #![deny(warnings)] #![no_std] diff --git a/tests/ui/issues/issue-60622.rs b/tests/ui/issues/issue-60622.rs deleted file mode 100644 index 7b9443eee5013..0000000000000 --- a/tests/ui/issues/issue-60622.rs +++ /dev/null @@ -1,16 +0,0 @@ -#![deny(warnings)] - -struct Borked {} - -impl Borked { - fn a(&self) {} -} - -fn run_wild(b: &Borked) { - b.a::<'_, T>(); - //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - //~| ERROR method takes 0 generic arguments but 1 generic argument - //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -} - -fn main() {} diff --git a/tests/ui/issues/issue-60622.stderr b/tests/ui/issues/issue-60622.stderr deleted file mode 100644 index 298ef3799f242..0000000000000 --- a/tests/ui/issues/issue-60622.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/issue-60622.rs:10:11 - | -LL | fn a(&self) {} - | - the late bound lifetime parameter is introduced here -... -LL | b.a::<'_, T>(); - | ^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 -note: the lint level is defined here - --> $DIR/issue-60622.rs:1:9 - | -LL | #![deny(warnings)] - | ^^^^^^^^ - = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]` - -error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied - --> $DIR/issue-60622.rs:10:7 - | -LL | b.a::<'_, T>(); - | ^ - help: remove the unnecessary generic argument - | | - | expected 0 generic arguments - | -note: method defined here, with 0 generic parameters - --> $DIR/issue-60622.rs:6:8 - | -LL | fn a(&self) {} - | ^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/issues/issue-60989.rs b/tests/ui/issues/issue-60989.rs deleted file mode 100644 index 29db3fdb47104..0000000000000 --- a/tests/ui/issues/issue-60989.rs +++ /dev/null @@ -1,18 +0,0 @@ -struct A {} -struct B {} - -impl From for B { - fn from(a: A) -> B { - B{} - } -} - -fn main() { - let c1 = (); - c1::<()>; - //~^ ERROR type arguments are not allowed on local variable - - let c1 = A {}; - c1::>; - //~^ ERROR type arguments are not allowed on local variable -} diff --git a/tests/ui/issues/issue-60989.stderr b/tests/ui/issues/issue-60989.stderr deleted file mode 100644 index e0236567b2fa6..0000000000000 --- a/tests/ui/issues/issue-60989.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0109]: type arguments are not allowed on local variable - --> $DIR/issue-60989.rs:12:10 - | -LL | c1::<()>; - | -- ^^ type argument not allowed - | | - | not allowed on local variable - -error[E0109]: type arguments are not allowed on local variable - --> $DIR/issue-60989.rs:16:10 - | -LL | c1::>; - | -- ^^^^^^^^^^^ type argument not allowed - | | - | not allowed on local variable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/issues/issue-61106.rs b/tests/ui/issues/issue-61106.rs deleted file mode 100644 index 308ef1de3ccc3..0000000000000 --- a/tests/ui/issues/issue-61106.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let x = String::new(); - foo(x.clone()); //~ ERROR mismatched types -} - -fn foo(_: &str) {} diff --git a/tests/ui/issues/issue-61106.stderr b/tests/ui/issues/issue-61106.stderr deleted file mode 100644 index f825141fa062a..0000000000000 --- a/tests/ui/issues/issue-61106.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-61106.rs:3:9 - | -LL | foo(x.clone()); - | --- ^^^^^^^^^ expected `&str`, found `String` - | | - | arguments to this function are incorrect - | -note: function defined here - --> $DIR/issue-61106.rs:6:4 - | -LL | fn foo(_: &str) {} - | ^^^ ------- -help: consider borrowing here - | -LL | foo(&x.clone()); - | + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-61108.rs b/tests/ui/issues/issue-61108.rs deleted file mode 100644 index 0a883b9581835..0000000000000 --- a/tests/ui/issues/issue-61108.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let mut bad_letters = vec!['e', 't', 'o', 'i']; - for l in bad_letters { - // something here - } - bad_letters.push('s'); //~ ERROR borrow of moved value: `bad_letters` -} diff --git a/tests/ui/issues/issue-61108.stderr b/tests/ui/issues/issue-61108.stderr deleted file mode 100644 index d018986efecec..0000000000000 --- a/tests/ui/issues/issue-61108.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0382]: borrow of moved value: `bad_letters` - --> $DIR/issue-61108.rs:6:5 - | -LL | let mut bad_letters = vec!['e', 't', 'o', 'i']; - | --------------- move occurs because `bad_letters` has type `Vec`, which does not implement the `Copy` trait -LL | for l in bad_letters { - | ----------- `bad_letters` moved due to this implicit call to `.into_iter()` -... -LL | bad_letters.push('s'); - | ^^^^^^^^^^^ value borrowed here after move - | -note: `into_iter` takes ownership of the receiver `self`, which moves `bad_letters` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL -help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop - | -LL | for l in &bad_letters { - | + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/issues/issue-61475.rs b/tests/ui/issues/issue-61475.rs deleted file mode 100644 index ff5e109ea7c8c..0000000000000 --- a/tests/ui/issues/issue-61475.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -enum E { - A, B -} - -fn main() { - match &&E::A { - &&E::A => { - } - &&E::B => { - } - }; -} diff --git a/tests/ui/issues/issue-61623.rs b/tests/ui/issues/issue-61623.rs deleted file mode 100644 index 82df50d9dc34f..0000000000000 --- a/tests/ui/issues/issue-61623.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn f1<'a>(_: &'a mut ()) {} - -fn f2

(_: P, _: ()) {} - -fn f3<'a>(x: &'a ((), &'a mut ())) { - f2(|| x.0, f1(x.1)) -//~^ ERROR cannot borrow `*x.1` as mutable, as it is behind a `&` reference -} - -fn main() {} diff --git a/tests/ui/issues/issue-61623.stderr b/tests/ui/issues/issue-61623.stderr deleted file mode 100644 index be6e28edfc24f..0000000000000 --- a/tests/ui/issues/issue-61623.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0596]: cannot borrow `*x.1` as mutable, as it is behind a `&` reference - --> $DIR/issue-61623.rs:6:19 - | -LL | f2(|| x.0, f1(x.1)) - | ^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable - | -help: consider changing this to be a mutable reference - | -LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) { - | +++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/issues/issue-61894.rs b/tests/ui/issues/issue-61894.rs deleted file mode 100644 index 40ad6a8d76a01..0000000000000 --- a/tests/ui/issues/issue-61894.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ run-pass - -#![feature(core_intrinsics)] - -use std::any::type_name; - -struct Bar(#[allow(dead_code)] M); - -impl Bar { - fn foo(&self) -> &'static str { - fn f() {} - fn type_name_of(_: T) -> &'static str { - type_name::() - } - type_name_of(f) - } -} - -fn main() { - assert_eq!(Bar(()).foo(), "issue_61894::Bar<_>::foo::f"); -} diff --git a/tests/ui/issues/issue-62480.rs b/tests/ui/issues/issue-62480.rs deleted file mode 100644 index 94a9c2ab8be8e..0000000000000 --- a/tests/ui/issues/issue-62480.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - // This used to ICE during liveness check because `target_id` passed to - // `propagate_through_expr` would be the closure and not the `loop`, which wouldn't be found in - // `self.break_ln`. (#62480) - 'a: { - || break 'a - //~^ ERROR use of unreachable label `'a` - //~| ERROR `break` inside of a closure - } -} diff --git a/tests/ui/issues/issue-62480.stderr b/tests/ui/issues/issue-62480.stderr deleted file mode 100644 index db230537037a4..0000000000000 --- a/tests/ui/issues/issue-62480.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0767]: use of unreachable label `'a` - --> $DIR/issue-62480.rs:6:18 - | -LL | 'a: { - | -- unreachable label defined here -LL | || break 'a - | ^^ unreachable label `'a` - | - = note: labels are unreachable through functions, closures, async blocks and modules - -error[E0267]: `break` inside of a closure - --> $DIR/issue-62480.rs:6:12 - | -LL | || break 'a - | -- ^^^^^^^^ cannot `break` inside of a closure - | | - | enclosing closure - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0267, E0767. -For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/issues/issue-63983.rs b/tests/ui/issues/issue-63983.rs deleted file mode 100644 index ab952666fd1da..0000000000000 --- a/tests/ui/issues/issue-63983.rs +++ /dev/null @@ -1,15 +0,0 @@ -enum MyEnum { - Tuple(i32), - Struct{ s: i32 }, -} - -fn foo(en: MyEnum) { - match en { - MyEnum::Tuple => "", -//~^ ERROR expected unit struct, unit variant or constant, found tuple variant `MyEnum::Tuple` - MyEnum::Struct => "", -//~^ ERROR expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct` - }; -} - -fn main() {} diff --git a/tests/ui/issues/issue-63983.stderr b/tests/ui/issues/issue-63983.stderr deleted file mode 100644 index 3539732451ce2..0000000000000 --- a/tests/ui/issues/issue-63983.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0532]: expected unit struct, unit variant or constant, found tuple variant `MyEnum::Tuple` - --> $DIR/issue-63983.rs:8:9 - | -LL | Tuple(i32), - | ---------- `MyEnum::Tuple` defined here -... -LL | MyEnum::Tuple => "", - | ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)` - -error[E0533]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct` - --> $DIR/issue-63983.rs:10:9 - | -LL | MyEnum::Struct => "", - | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant - | -help: the struct variant's field is being ignored - | -LL | MyEnum::Struct { s: _ } => "", - | ++++++++ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0532, E0533. -For more information about an error, try `rustc --explain E0532`. diff --git a/tests/ui/issues/issue-64430.rs b/tests/ui/issues/issue-64430.rs deleted file mode 100644 index bc98dbf8520f0..0000000000000 --- a/tests/ui/issues/issue-64430.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ compile-flags:-C panic=abort - -#![no_std] -pub struct Foo; - -fn main() { - Foo.bar() - //~^ ERROR E0599 -} - -#[panic_handler] -fn panic(_info: &core::panic::PanicInfo) -> ! { - loop{} -} diff --git a/tests/ui/issues/issue-64430.stderr b/tests/ui/issues/issue-64430.stderr deleted file mode 100644 index 1c8e020e9cbb4..0000000000000 --- a/tests/ui/issues/issue-64430.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `bar` found for struct `Foo` in the current scope - --> $DIR/issue-64430.rs:7:9 - | -LL | pub struct Foo; - | -------------- method `bar` not found for this struct -... -LL | Foo.bar() - | ^^^ method not found in `Foo` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/issues/issue-64559.rs b/tests/ui/issues/issue-64559.rs deleted file mode 100644 index 71e054b5d9876..0000000000000 --- a/tests/ui/issues/issue-64559.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let orig = vec![true]; - for _val in orig {} - let _closure = || orig; - //~^ ERROR use of moved value: `orig` -} diff --git a/tests/ui/issues/issue-64559.stderr b/tests/ui/issues/issue-64559.stderr deleted file mode 100644 index 0cab37553406c..0000000000000 --- a/tests/ui/issues/issue-64559.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0382]: use of moved value: `orig` - --> $DIR/issue-64559.rs:4:20 - | -LL | let orig = vec![true]; - | ---- move occurs because `orig` has type `Vec`, which does not implement the `Copy` trait -LL | for _val in orig {} - | ---- `orig` moved due to this implicit call to `.into_iter()` -LL | let _closure = || orig; - | ^^ ---- use occurs due to use in closure - | | - | value used here after move - | -note: `into_iter` takes ownership of the receiver `self`, which moves `orig` - --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL -help: consider iterating over a slice of the `Vec`'s content to avoid moving into the `for` loop - | -LL | for _val in &orig {} - | + - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/issues/issue-64593.rs b/tests/ui/issues/issue-64593.rs deleted file mode 100644 index e28b9577347be..0000000000000 --- a/tests/ui/issues/issue-64593.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ check-pass -#![deny(improper_ctypes)] - -pub struct Error(std::num::NonZero); - -extern "Rust" { - fn foo(dest: &mut [u8]) -> Result<(), Error>; -} - -fn main() { - let _ = unsafe { foo(&mut []) }; -} diff --git a/tests/ui/issues/issue-64792-bad-unicode-ctor.rs b/tests/ui/issues/issue-64792-bad-unicode-ctor.rs deleted file mode 100644 index f1427ef46e928..0000000000000 --- a/tests/ui/issues/issue-64792-bad-unicode-ctor.rs +++ /dev/null @@ -1,5 +0,0 @@ -struct X {} - -const Y: X = X("ö"); //~ ERROR expected function, tuple struct or tuple variant, found struct `X` - -fn main() {} diff --git a/tests/ui/issues/issue-64792-bad-unicode-ctor.stderr b/tests/ui/issues/issue-64792-bad-unicode-ctor.stderr deleted file mode 100644 index 7fc414602d281..0000000000000 --- a/tests/ui/issues/issue-64792-bad-unicode-ctor.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0423]: expected function, tuple struct or tuple variant, found struct `X` - --> $DIR/issue-64792-bad-unicode-ctor.rs:3:14 - | -LL | struct X {} - | ----------- `X` defined here -LL | -LL | const Y: X = X("ö"); - | ^^^^^^ help: use struct literal syntax instead: `X {}` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/issues/issue-65131.rs b/tests/ui/issues/issue-65131.rs deleted file mode 100644 index 8b5345da900aa..0000000000000 --- a/tests/ui/issues/issue-65131.rs +++ /dev/null @@ -1,18 +0,0 @@ -fn get_pair(_a: &mut u32, _b: &mut u32) {} - -macro_rules! x10 { - ($($t:tt)*) => { - $($t)* $($t)* $($t)* $($t)* $($t)* - $($t)* $($t)* $($t)* $($t)* $($t)* - } -} - -#[allow(unused_assignments)] -fn main() { - let mut x = 1; - - get_pair(&mut x, &mut x); - //~^ ERROR: cannot borrow `x` as mutable more than once at a time - - x10! { x10!{ x10!{ if x > 0 { x += 2 } else { x += 1 } } } } -} diff --git a/tests/ui/issues/issue-65131.stderr b/tests/ui/issues/issue-65131.stderr deleted file mode 100644 index 70e85b584bd22..0000000000000 --- a/tests/ui/issues/issue-65131.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/issue-65131.rs:14:22 - | -LL | get_pair(&mut x, &mut x); - | -------- ------ ^^^^^^ second mutable borrow occurs here - | | | - | | first mutable borrow occurs here - | first borrow later used by call - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0499`. diff --git a/tests/ui/issues/issue-65230.rs b/tests/ui/issues/issue-65230.rs deleted file mode 100644 index 54141d2214cd9..0000000000000 --- a/tests/ui/issues/issue-65230.rs +++ /dev/null @@ -1,11 +0,0 @@ -trait T0 {} -trait T1: T0 {} - -trait T2 {} - -impl<'a> T0 for &'a (dyn T2 + 'static) {} - -impl T1 for &dyn T2 {} -//~^ ERROR mismatched types - -fn main() {} diff --git a/tests/ui/issues/issue-65230.stderr b/tests/ui/issues/issue-65230.stderr deleted file mode 100644 index c959658c0ce27..0000000000000 --- a/tests/ui/issues/issue-65230.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-65230.rs:8:13 - | -LL | impl T1 for &dyn T2 {} - | ^^^^^^^ lifetime mismatch - | - = note: expected trait `<&dyn T2 as T0>` - found trait `<&(dyn T2 + 'static) as T0>` -note: the anonymous lifetime as defined here... - --> $DIR/issue-65230.rs:8:13 - | -LL | impl T1 for &dyn T2 {} - | ^ - = note: ...does not necessarily outlive the static lifetime - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-65462.rs b/tests/ui/issues/issue-65462.rs deleted file mode 100644 index e148c8aeeb2b5..0000000000000 --- a/tests/ui/issues/issue-65462.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ build-pass - -enum Empty {} -enum Enum { - Empty( Empty ) -} - -fn foobar() -> Option< Enum > { - let value: Option< Empty > = None; - Some( Enum::Empty( value? ) ) -} - -fn main() { - foobar(); -} diff --git a/tests/ui/issues/issue-66308.rs b/tests/ui/issues/issue-66308.rs deleted file mode 100644 index 41f81323e6fbf..0000000000000 --- a/tests/ui/issues/issue-66308.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ build-pass -//@ compile-flags: --crate-type lib -C opt-level=0 - -// Regression test for LLVM crash affecting Emscripten targets - -pub fn foo() { - (0..0).rev().next(); -} diff --git a/tests/ui/issues/issue-66353.rs b/tests/ui/issues/issue-66353.rs deleted file mode 100644 index d8abdd5206ef4..0000000000000 --- a/tests/ui/issues/issue-66353.rs +++ /dev/null @@ -1,15 +0,0 @@ -// #66353: ICE when trying to recover from incorrect associated type - -trait _Func { - fn func(_: Self); -} - -trait _A { - type AssocT; -} - -fn main() { - _Func::< <() as _A>::AssocT >::func(()); - //~^ ERROR the trait bound `(): _A` is not satisfied - //~| ERROR the trait bound `(): _Func<_>` is not satisfied -} diff --git a/tests/ui/issues/issue-66353.stderr b/tests/ui/issues/issue-66353.stderr deleted file mode 100644 index 7ab7547b42dc6..0000000000000 --- a/tests/ui/issues/issue-66353.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: the trait bound `(): _A` is not satisfied - --> $DIR/issue-66353.rs:12:15 - | -LL | _Func::< <() as _A>::AssocT >::func(()); - | ^^ the trait `_A` is not implemented for `()` - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-66353.rs:7:1 - | -LL | trait _A { - | ^^^^^^^^ - -error[E0277]: the trait bound `(): _Func<_>` is not satisfied - --> $DIR/issue-66353.rs:12:41 - | -LL | _Func::< <() as _A>::AssocT >::func(()); - | ----------------------------------- ^^ the trait `_Func<_>` is not implemented for `()` - | | - | required by a bound introduced by this call - | -help: this trait has no implementations, consider adding one - --> $DIR/issue-66353.rs:3:1 - | -LL | trait _Func { - | ^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-66667-function-cmp-cycle.rs b/tests/ui/issues/issue-66667-function-cmp-cycle.rs deleted file mode 100644 index b4f09fbbb04d0..0000000000000 --- a/tests/ui/issues/issue-66667-function-cmp-cycle.rs +++ /dev/null @@ -1,19 +0,0 @@ -fn first() { - second == 1 //~ ERROR binary operation - //~^ ERROR mismatched types - //~| ERROR mismatched types -} - -fn second() { - first == 1 //~ ERROR binary operation - //~^ ERROR mismatched types - //~| ERROR mismatched types -} - -fn bar() { - bar == 1 //~ ERROR binary operation - //~^ ERROR mismatched types - //~| ERROR mismatched types -} - -fn main() {} diff --git a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr b/tests/ui/issues/issue-66667-function-cmp-cycle.stderr deleted file mode 100644 index cec8117702a9b..0000000000000 --- a/tests/ui/issues/issue-66667-function-cmp-cycle.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0369]: binary operation `==` cannot be applied to type `fn() {second}` - --> $DIR/issue-66667-function-cmp-cycle.rs:2:12 - | -LL | second == 1 - | ------ ^^ - {integer} - | | - | fn() {second} - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:2:15 - | -LL | second == 1 - | ^ expected fn item, found integer - | - = note: expected fn item `fn() {second}` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:2:5 - | -LL | fn first() { - | - help: try adding a return type: `-> bool` -LL | second == 1 - | ^^^^^^^^^^^ expected `()`, found `bool` - -error[E0369]: binary operation `==` cannot be applied to type `fn() {first}` - --> $DIR/issue-66667-function-cmp-cycle.rs:8:11 - | -LL | first == 1 - | ----- ^^ - {integer} - | | - | fn() {first} - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:8:14 - | -LL | first == 1 - | ^ expected fn item, found integer - | - = note: expected fn item `fn() {first}` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:8:5 - | -LL | fn second() { - | - help: try adding a return type: `-> bool` -LL | first == 1 - | ^^^^^^^^^^ expected `()`, found `bool` - -error[E0369]: binary operation `==` cannot be applied to type `fn() {bar}` - --> $DIR/issue-66667-function-cmp-cycle.rs:14:9 - | -LL | bar == 1 - | --- ^^ - {integer} - | | - | fn() {bar} - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:14:12 - | -LL | bar == 1 - | ^ expected fn item, found integer - | - = note: expected fn item `fn() {bar}` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/issue-66667-function-cmp-cycle.rs:14:5 - | -LL | fn bar() { - | - help: try adding a return type: `-> bool` -LL | bar == 1 - | ^^^^^^^^ expected `()`, found `bool` - -error: aborting due to 9 previous errors - -Some errors have detailed explanations: E0308, E0369. -For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-66702-break-outside-loop-val.rs b/tests/ui/issues/issue-66702-break-outside-loop-val.rs deleted file mode 100644 index 05b86cbbf8f05..0000000000000 --- a/tests/ui/issues/issue-66702-break-outside-loop-val.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Breaks with values inside closures used to ICE (#66863) - -fn main() { - 'some_label: loop { - || break 'some_label (); - //~^ ERROR: use of unreachable label `'some_label` - //~| ERROR: `break` inside of a closure - } -} diff --git a/tests/ui/issues/issue-66702-break-outside-loop-val.stderr b/tests/ui/issues/issue-66702-break-outside-loop-val.stderr deleted file mode 100644 index f92ede311afb4..0000000000000 --- a/tests/ui/issues/issue-66702-break-outside-loop-val.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0767]: use of unreachable label `'some_label` - --> $DIR/issue-66702-break-outside-loop-val.rs:5:18 - | -LL | 'some_label: loop { - | ----------- unreachable label defined here -LL | || break 'some_label (); - | ^^^^^^^^^^^ unreachable label `'some_label` - | - = note: labels are unreachable through functions, closures, async blocks and modules - -error[E0267]: `break` inside of a closure - --> $DIR/issue-66702-break-outside-loop-val.rs:5:12 - | -LL | || break 'some_label (); - | -- ^^^^^^^^^^^^^^^^^^^^ cannot `break` inside of a closure - | | - | enclosing closure - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0267, E0767. -For more information about an error, try `rustc --explain E0267`. diff --git a/tests/ui/issues/issue-66706.rs b/tests/ui/issues/issue-66706.rs deleted file mode 100644 index 87dc3437a57bd..0000000000000 --- a/tests/ui/issues/issue-66706.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn a() { - [0; [|_: _ &_| ()].len()] - //~^ ERROR expected one of `,` or `|`, found `&` - //~| ERROR type annotations needed -} - -fn b() { - [0; [|f @ &ref _| {} ; 0 ].len() ]; - //~^ ERROR expected identifier, found reserved identifier `_` -} - -fn c() { - [0; [|&_: _ &_| {}; 0 ].len()] - //~^ ERROR expected one of `,` or `|`, found `&` - //~| ERROR type annotations needed -} - -fn d() { - [0; match [|f @ &ref _| () ] {} ] - //~^ ERROR expected identifier, found reserved identifier `_` -} - -fn main() {} diff --git a/tests/ui/issues/issue-66706.stderr b/tests/ui/issues/issue-66706.stderr deleted file mode 100644 index cfe8576400025..0000000000000 --- a/tests/ui/issues/issue-66706.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error: expected one of `,` or `|`, found `&` - --> $DIR/issue-66706.rs:2:16 - | -LL | [0; [|_: _ &_| ()].len()] - | -^ expected one of `,` or `|` - | | - | help: missing `,` - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:8:20 - | -LL | [0; [|f @ &ref _| {} ; 0 ].len() ]; - | ^ expected identifier, found reserved identifier - -error: expected one of `,` or `|`, found `&` - --> $DIR/issue-66706.rs:13:17 - | -LL | [0; [|&_: _ &_| {}; 0 ].len()] - | -^ expected one of `,` or `|` - | | - | help: missing `,` - -error: expected identifier, found reserved identifier `_` - --> $DIR/issue-66706.rs:19:26 - | -LL | [0; match [|f @ &ref _| () ] {} ] - | ----- ^ expected identifier, found reserved identifier - | | - | while parsing this `match` expression - -error[E0282]: type annotations needed - --> $DIR/issue-66706.rs:2:14 - | -LL | [0; [|_: _ &_| ()].len()] - | ^ cannot infer type - -error[E0282]: type annotations needed - --> $DIR/issue-66706.rs:13:11 - | -LL | [0; [|&_: _ &_| {}; 0 ].len()] - | ^^^^^ cannot infer type - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.rs b/tests/ui/issues/issue-66923-show-error-for-correct-call.rs deleted file mode 100644 index 8332807397247..0000000000000 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.rs +++ /dev/null @@ -1,15 +0,0 @@ -// This test checks that errors are showed for lines with `collect` rather than `push` method. - -fn main() { - let v = vec![1_f64, 2.2_f64]; - let mut fft: Vec> = vec![]; - - let x1: &[f64] = &v; - let x2: Vec = x1.into_iter().collect(); - //~^ ERROR a value of type - fft.push(x2); - - let x3 = x1.into_iter().collect::>(); - //~^ ERROR a value of type - fft.push(x3); -} diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr deleted file mode 100644 index d2852093725ce..0000000000000 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39 - | -LL | let x2: Vec = x1.into_iter().collect(); - | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` - | - = help: the trait `FromIterator<&_>` is not implemented for `Vec` - but trait `FromIterator<_>` is implemented for it - = help: for that trait implementation, expected `f64`, found `&f64` -note: the method call chain might not have had the expected associated types - --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27 - | -LL | let x1: &[f64] = &v; - | -- this expression has type `&Vec` -LL | let x2: Vec = x1.into_iter().collect(); - | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here -note: required by a bound in `collect` - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - -error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` - --> $DIR/issue-66923-show-error-for-correct-call.rs:12:39 - | -LL | let x3 = x1.into_iter().collect::>(); - | ------- ^^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` - | | - | required by a bound introduced by this call - | - = help: the trait `FromIterator<&_>` is not implemented for `Vec` - but trait `FromIterator<_>` is implemented for it - = help: for that trait implementation, expected `f64`, found `&f64` -note: the method call chain might not have had the expected associated types - --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17 - | -LL | let x1: &[f64] = &v; - | -- this expression has type `&Vec` -... -LL | let x3 = x1.into_iter().collect::>(); - | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here -note: required by a bound in `collect` - --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-67535.rs b/tests/ui/issues/issue-67535.rs deleted file mode 100644 index 24f50621310f1..0000000000000 --- a/tests/ui/issues/issue-67535.rs +++ /dev/null @@ -1,22 +0,0 @@ -fn main() {} - -impl std::ops::AddAssign for () { - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: ()) -> () { - () - } -} - -impl std::ops::AddAssign for [(); 1] { - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: [(); 1]) -> [(); 1] { - [()] - } -} - -impl std::ops::AddAssign for &[u8] { - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types - fn add_assign(&self, other: &[u8]) -> &[u8] { - self - } -} diff --git a/tests/ui/issues/issue-67535.stderr b/tests/ui/issues/issue-67535.stderr deleted file mode 100644 index 2afa2199a6afe..0000000000000 --- a/tests/ui/issues/issue-67535.stderr +++ /dev/null @@ -1,42 +0,0 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/issue-67535.rs:3:1 - | -LL | impl std::ops::AddAssign for () { - | ^^^^^-------------------^^^^^-- - | | | - | | this is not defined in the current crate because tuples are always foreign - | this is not defined in the current crate because this is a foreign trait - | - = note: impl doesn't have any local type before any uncovered type parameters - = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules - = note: define and implement a trait or new type instead - -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/issue-67535.rs:10:1 - | -LL | impl std::ops::AddAssign for [(); 1] { - | ^^^^^-------------------^^^^^------- - | | | - | | this is not defined in the current crate because arrays are always foreign - | this is not defined in the current crate because this is a foreign trait - | - = note: impl doesn't have any local type before any uncovered type parameters - = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules - = note: define and implement a trait or new type instead - -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/issue-67535.rs:17:1 - | -LL | impl std::ops::AddAssign for &[u8] { - | ^^^^^-------------------^^^^^----- - | | | - | | this is not defined in the current crate because slices are always foreign - | this is not defined in the current crate because this is a foreign trait - | - = note: impl doesn't have any local type before any uncovered type parameters - = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules - = note: define and implement a trait or new type instead - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/issues/issue-68010-large-zst-consts.rs b/tests/ui/issues/issue-68010-large-zst-consts.rs deleted file mode 100644 index 167c92f004e1d..0000000000000 --- a/tests/ui/issues/issue-68010-large-zst-consts.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ build-pass - -fn main() { - println!("{}", [(); usize::MAX].len()); -} diff --git a/tests/ui/issues/issue-68696-catch-during-unwind.rs b/tests/ui/issues/issue-68696-catch-during-unwind.rs deleted file mode 100644 index 80d63b0cde705..0000000000000 --- a/tests/ui/issues/issue-68696-catch-during-unwind.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Checks that catch_unwind can be used if unwinding is already in progress. -// Used to fail when standard library had been compiled with debug assertions, -// due to incorrect assumption that a current thread is not panicking when -// entering the catch_unwind. -// -//@ run-pass - -use std::panic::catch_unwind; - -#[allow(dead_code)] -#[derive(Default)] -struct Guard; - -impl Drop for Guard { - fn drop(&mut self) { - let _ = catch_unwind(|| {}); - } -} - -fn main() { - #[cfg(panic = "unwind")] - let _ = catch_unwind(|| { - let _guard = Guard::default(); - panic!(); - }); -} diff --git a/tests/ui/issues/issue-68951.rs b/tests/ui/issues/issue-68951.rs deleted file mode 100644 index 2d639a62d45ac..0000000000000 --- a/tests/ui/issues/issue-68951.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass - -fn main() { - let array = [0x42u8; 10]; - for b in &array { - let lo = b & 0xf; - let hi = (b >> 4) & 0xf; - } -} diff --git a/tests/ui/issues/issue-69130.stderr b/tests/ui/issues/issue-69130.stderr deleted file mode 100644 index e67cc295d43e1..0000000000000 --- a/tests/ui/issues/issue-69130.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: unknown start of token: \u{a7} - --> $DIR/issue-69130.rs:4:4 - | -LL | M (§& u8)} - | ^ - -error[E0106]: missing lifetime specifier - --> $DIR/issue-69130.rs:4:5 - | -LL | M (§& u8)} - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -LL ~ enum F<'a> { -LL ~ M (§&'a u8)} - | - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/issues/issue-69306.rs b/tests/ui/issues/issue-69306.rs deleted file mode 100644 index 85d60952ac823..0000000000000 --- a/tests/ui/issues/issue-69306.rs +++ /dev/null @@ -1,45 +0,0 @@ -fn main() {} - -struct S0(T); -impl S0 { - const C: S0 = Self(0); - //~^ ERROR mismatched types - //~| ERROR mismatched types - - fn foo() { - Self(0); - //~^ ERROR mismatched types - } -} - -// Testing normalization. -trait Fun { - type Out; -} -impl Fun for S0 { - type Out = Self; -} -trait Foo { - fn foo(); -} -impl Foo for as Fun>::Out { - fn foo() { - Self(0); //~ ERROR mismatched types - } -} - -struct S1(T, U); -impl S1 { - const C: S1 = Self(0, 1); - //~^ ERROR mismatched types - //~| ERROR mismatched types -} - -struct S2(T); -impl S2 { - fn map(x: U) -> S2 { - Self(x) - //~^ ERROR mismatched types - //~| ERROR mismatched types - } -} diff --git a/tests/ui/issues/issue-69306.stderr b/tests/ui/issues/issue-69306.stderr deleted file mode 100644 index 6fc5c33af6acd..0000000000000 --- a/tests/ui/issues/issue-69306.stderr +++ /dev/null @@ -1,138 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:5:28 - | -LL | impl S0 { - | - expected this type parameter -LL | const C: S0 = Self(0); - | ---- ^ expected type parameter `T`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type parameter `T` - found type `{integer}` -note: tuple struct defined here - --> $DIR/issue-69306.rs:3:8 - | -LL | struct S0(T); - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:5:23 - | -LL | impl S0 { - | - found this type parameter -LL | const C: S0 = Self(0); - | ^^^^^^^ expected `S0`, found `S0` - | - = note: expected struct `S0` - found struct `S0` - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:10:14 - | -LL | impl S0 { - | - expected this type parameter -... -LL | Self(0); - | ---- ^ expected type parameter `T`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type parameter `T` - found type `{integer}` -note: tuple struct defined here - --> $DIR/issue-69306.rs:3:8 - | -LL | struct S0(T); - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:27:14 - | -LL | impl Foo for as Fun>::Out { - | - expected this type parameter -LL | fn foo() { -LL | Self(0); - | ---- ^ expected type parameter `T`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type parameter `T` - found type `{integer}` -note: tuple struct defined here - --> $DIR/issue-69306.rs:3:8 - | -LL | struct S0(T); - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:33:32 - | -LL | impl S1 { - | - expected this type parameter -LL | const C: S1 = Self(0, 1); - | ---- ^ expected type parameter `T`, found integer - | | - | arguments to this function are incorrect - | - = note: expected type parameter `T` - found type `{integer}` -note: tuple struct defined here - --> $DIR/issue-69306.rs:31:8 - | -LL | struct S1(T, U); - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:33:27 - | -LL | impl S1 { - | - found this type parameter -LL | const C: S1 = Self(0, 1); - | ^^^^^^^^^^ expected `S1`, found `S1` - | - = note: expected struct `S1` - found struct `S1` - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:41:14 - | -LL | impl S2 { - | - expected type parameter -LL | fn map(x: U) -> S2 { - | - found type parameter -LL | Self(x) - | ---- ^ expected type parameter `T`, found type parameter `U` - | | - | arguments to this function are incorrect - | - = note: expected type parameter `T` - found type parameter `U` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -note: tuple struct defined here - --> $DIR/issue-69306.rs:38:8 - | -LL | struct S2(T); - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-69306.rs:41:9 - | -LL | impl S2 { - | - found type parameter -LL | fn map(x: U) -> S2 { - | - ----- expected `S2` because of return type - | | - | expected type parameter -LL | Self(x) - | ^^^^^^^ expected `S2`, found `S2` - | - = note: expected struct `S2` - found struct `S2` - = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound - = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-69455.stderr b/tests/ui/issues/issue-69455.stderr deleted file mode 100644 index d3e307fba2ce9..0000000000000 --- a/tests/ui/issues/issue-69455.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0284]: type annotations needed - --> $DIR/issue-69455.rs:29:41 - | -LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | | - | type must be known at this point - | - = note: cannot satisfy `>::Output == _` -help: consider specifying the generic argument - | -LL | println!("{}", 23u64.test(xs.iter().sum::())); - | +++++ - -error[E0283]: type annotations needed - --> $DIR/issue-69455.rs:29:41 - | -LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` - | | - | required by a bound introduced by this call - | -note: multiple `impl`s satisfying `u64: Test<_>` found - --> $DIR/issue-69455.rs:11:1 - | -LL | impl Test for u64 { - | ^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Test for u64 { - | ^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying the generic argument - | -LL | println!("{}", 23u64.test(xs.iter().sum::())); - | +++++ - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0283, E0284. -For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/tests/ui/issues/issue-69602-type-err-during-codegen-ice.rs deleted file mode 100644 index 2c5257ce063cb..0000000000000 --- a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.rs +++ /dev/null @@ -1,22 +0,0 @@ -trait TraitA { - const VALUE: usize; -} - -struct A; -impl TraitA for A { - const VALUE: usize = 0; -} - -trait TraitB { - type MyA: TraitA; - const VALUE: usize = Self::MyA::VALUE; -} - -struct B; -impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` - type M = A; //~ ERROR type `M` is not a member of trait `TraitB` -} - -fn main() { - let _ = [0; B::VALUE]; -} diff --git a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr deleted file mode 100644 index fa1d7dffbd49a..0000000000000 --- a/tests/ui/issues/issue-69602-type-err-during-codegen-ice.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0437]: type `M` is not a member of trait `TraitB` - --> $DIR/issue-69602-type-err-during-codegen-ice.rs:17:5 - | -LL | type M = A; - | ^^^^^^^^^^^^^ not a member of trait `TraitB` - -error[E0046]: not all trait items implemented, missing: `MyA` - --> $DIR/issue-69602-type-err-during-codegen-ice.rs:16:1 - | -LL | type MyA: TraitA; - | ---------------- `MyA` from trait -... -LL | impl TraitB for B { - | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0046, E0437. -For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/issues/issue-69683.rs b/tests/ui/issues/issue-69683.rs deleted file mode 100644 index 7a76e9ef205ff..0000000000000 --- a/tests/ui/issues/issue-69683.rs +++ /dev/null @@ -1,33 +0,0 @@ -pub trait Element { - type Array; -} - -impl Element<()> for T { - type Array = T; -} - -impl, S> Element<[S; 3]> for T { - type Array = [T::Array; 3]; -} - -trait Foo -where - u8: Element, -{ - fn foo(self, x: >::Array); -} - -impl Foo for u16 -where - u8: Element, -{ - fn foo(self, _: >::Array) {} -} - -fn main() { - let b: [u8; 3] = [0u8; 3]; - - 0u16.foo(b); //~ ERROR type annotations needed - //~^ ERROR type annotations needed - //>::foo(0u16, b); -} diff --git a/tests/ui/issues/issue-69683.stderr b/tests/ui/issues/issue-69683.stderr deleted file mode 100644 index b8e9e89e56eb9..0000000000000 --- a/tests/ui/issues/issue-69683.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error[E0284]: type annotations needed - --> $DIR/issue-69683.rs:30:10 - | -LL | 0u16.foo(b); - | ^^^ - | - = note: cannot satisfy `>::Array == [u8; 3]` -help: try using a fully qualified path to specify the expected types - | -LL - 0u16.foo(b); -LL + >::foo(0u16, b); - | - -error[E0283]: type annotations needed - --> $DIR/issue-69683.rs:30:10 - | -LL | 0u16.foo(b); - | ^^^ - | -note: multiple `impl`s satisfying `u8: Element<_>` found - --> $DIR/issue-69683.rs:5:1 - | -LL | impl Element<()> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl, S> Element<[S; 3]> for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `Foo::foo` - --> $DIR/issue-69683.rs:15:9 - | -LL | u8: Element, - | ^^^^^^^^^^ required by this bound in `Foo::foo` -LL | { -LL | fn foo(self, x: >::Array); - | --- required by a bound in this associated function -help: try using a fully qualified path to specify the expected types - | -LL - 0u16.foo(b); -LL + >::foo(0u16, b); - | - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0283, E0284. -For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/issues/issue-70381.rs b/tests/ui/issues/issue-70381.rs deleted file mode 100644 index 3df8277b87372..0000000000000 --- a/tests/ui/issues/issue-70381.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Test that multi-byte unicode characters with missing parameters do not ICE. - -fn main() { - println!("\r¡{}") - //~^ ERROR 1 positional argument in format string -} diff --git a/tests/ui/issues/issue-70381.stderr b/tests/ui/issues/issue-70381.stderr deleted file mode 100644 index 298a1cf9e0d5f..0000000000000 --- a/tests/ui/issues/issue-70381.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: 1 positional argument in format string, but no arguments were given - --> $DIR/issue-70381.rs:4:16 - | -LL | println!("\r¡{}") - | ^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs b/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs deleted file mode 100644 index c2683157f797f..0000000000000 --- a/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn a() -> i32 { - 3 -} - -pub fn main() { - assert_eq!(a, 0); - //~^ ERROR binary operation `==` cannot - //~| ERROR mismatched types - //~| ERROR doesn't implement -} diff --git a/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr b/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr deleted file mode 100644 index 736002c9335a3..0000000000000 --- a/tests/ui/issues/issue-70724-add_type_neq_err_label-unwrap.stderr +++ /dev/null @@ -1,37 +0,0 @@ -error[E0369]: binary operation `==` cannot be applied to type `fn() -> i32 {a}` - --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5 - | -LL | assert_eq!(a, 0); - | ^^^^^^^^^^^^^^^^ - | | - | fn() -> i32 {a} - | {integer} - | - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5 - | -LL | assert_eq!(a, 0); - | ^^^^^^^^^^^^^^^^ expected fn item, found integer - | - = note: expected fn item `fn() -> i32 {a}` - found type `{integer}` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0277]: `fn() -> i32 {a}` doesn't implement `Debug` - --> $DIR/issue-70724-add_type_neq_err_label-unwrap.rs:6:5 - | -LL | fn a() -> i32 { - | - consider calling this function -... -LL | assert_eq!(a, 0); - | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn() -> i32 {a}` - | - = help: use parentheses to call this function: `a()` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0277, E0308, E0369. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/issues/issue-70746.rs b/tests/ui/issues/issue-70746.rs deleted file mode 100644 index e7b4855039796..0000000000000 --- a/tests/ui/issues/issue-70746.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ check-pass - -pub trait Trait1 { - type C; -} - -struct T1; -impl Trait1 for T1 { - type C = usize; -} -pub trait Callback: FnMut(::C) {} -impl::C)> Callback for F {} - -pub struct State { - callback: Option>>, -} -impl State { - fn new() -> Self { - Self { callback: None } - } - fn test_cb(&mut self, d: ::C) { - (self.callback.as_mut().unwrap())(d) - } -} - -fn main() { - let mut s = State::::new(); - s.test_cb(1); -} diff --git a/tests/ui/issues/issue-71406.rs b/tests/ui/issues/issue-71406.rs deleted file mode 100644 index 6266112c3a86c..0000000000000 --- a/tests/ui/issues/issue-71406.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::sync::mpsc; - -fn main() { - let (tx, rx) = mpsc::channel::new(1); - //~^ ERROR expected type, found function `channel` in `mpsc` -} diff --git a/tests/ui/issues/issue-71406.stderr b/tests/ui/issues/issue-71406.stderr deleted file mode 100644 index cd7921f550e5d..0000000000000 --- a/tests/ui/issues/issue-71406.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc` - --> $DIR/issue-71406.rs:4:26 - | -LL | let (tx, rx) = mpsc::channel::new(1); - | ^^^^^^^ expected type, found function `channel` in `mpsc` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/issues/issue-72002.rs b/tests/ui/issues/issue-72002.rs deleted file mode 100644 index ce3463069b881..0000000000000 --- a/tests/ui/issues/issue-72002.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ check-pass -struct Indexable; - -impl Indexable { - fn boo(&mut self) {} -} - -impl std::ops::Index<&str> for Indexable { - type Output = Indexable; - - fn index(&self, field: &str) -> &Indexable { - self - } -} - -impl std::ops::IndexMut<&str> for Indexable { - fn index_mut(&mut self, field: &str) -> &mut Indexable { - self - } -} - -fn main() { - let mut v = Indexable; - let field = "hello".to_string(); - - v[field.as_str()].boo(); - - v[&field].boo(); // < This should work -} diff --git a/tests/ui/issues/issue-72076.rs b/tests/ui/issues/issue-72076.rs deleted file mode 100644 index 1659044a64fe1..0000000000000 --- a/tests/ui/issues/issue-72076.rs +++ /dev/null @@ -1,6 +0,0 @@ -trait X { - type S; - fn f() -> Self::S {} //~ ERROR mismatched types -} - -fn main() {} diff --git a/tests/ui/issues/issue-72076.stderr b/tests/ui/issues/issue-72076.stderr deleted file mode 100644 index a08704c907327..0000000000000 --- a/tests/ui/issues/issue-72076.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-72076.rs:3:23 - | -LL | fn f() -> Self::S {} - | ^^ expected associated type, found `()` - | - = note: expected associated type `::S` - found unit type `()` - = help: consider constraining the associated type `::S` to `()` or calling a method that returns `::S` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-72278.rs b/tests/ui/issues/issue-72278.rs deleted file mode 100644 index 2a9cd9423915f..0000000000000 --- a/tests/ui/issues/issue-72278.rs +++ /dev/null @@ -1,19 +0,0 @@ -//@ run-pass - -#![allow(unused)] - -struct S; - -impl S { - fn func<'a, U>(&'a self) -> U { - todo!() - } -} - -fn dont_crash<'a, U>() -> U { - S.func::<'a, U>() - //~^ WARN cannot specify lifetime arguments explicitly - //~| WARN this was previously accepted -} - -fn main() {} diff --git a/tests/ui/issues/issue-72278.stderr b/tests/ui/issues/issue-72278.stderr deleted file mode 100644 index 91efada3d8d12..0000000000000 --- a/tests/ui/issues/issue-72278.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - --> $DIR/issue-72278.rs:14:14 - | -LL | fn func<'a, U>(&'a self) -> U { - | -- the late bound lifetime parameter is introduced here -... -LL | S.func::<'a, U>() - | ^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 - = note: `#[warn(late_bound_lifetime_arguments)]` (part of `#[warn(future_incompatible)]`) on by default - -warning: 1 warning emitted - diff --git a/tests/ui/issues/issue-73112.rs b/tests/ui/issues/issue-73112.rs deleted file mode 100644 index 89075b756249d..0000000000000 --- a/tests/ui/issues/issue-73112.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ aux-build:issue-73112.rs - -extern crate issue_73112; - -fn main() { - use issue_73112::PageTable; - - #[repr(C, packed)] - struct SomeStruct { - //~^ ERROR packed type cannot transitively contain a `#[repr(align)]` type [E0588] - page_table: PageTable, - } -} diff --git a/tests/ui/issues/issue-73112.stderr b/tests/ui/issues/issue-73112.stderr deleted file mode 100644 index c2c15ca10ce2e..0000000000000 --- a/tests/ui/issues/issue-73112.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type - --> $DIR/issue-73112.rs:9:5 - | -LL | struct SomeStruct { - | ^^^^^^^^^^^^^^^^^ - | -note: `PageTable` has a `#[repr(align)]` attribute - --> $DIR/auxiliary/issue-73112.rs:8:1 - | -LL | pub struct PageTable { - | ^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0588`. diff --git a/tests/ui/issues/issue-73229.rs b/tests/ui/issues/issue-73229.rs deleted file mode 100644 index 6d5eec2365e5e..0000000000000 --- a/tests/ui/issues/issue-73229.rs +++ /dev/null @@ -1,33 +0,0 @@ -//@ check-pass - -fn any() -> T { - loop {} -} - -trait Foo { - type V; -} - -trait Callback: Fn(&T, &T::V) {} -impl Callback for F {} - -struct Bar { - callback: Box>, -} - -impl Bar { - fn event(&self) { - (self.callback)(any(), any()); - } -} - -struct A; -struct B; -impl Foo for A { - type V = B; -} - -fn main() { - let foo = Bar:: { callback: Box::new(|_: &A, _: &B| ()) }; - foo.event(); -} diff --git a/tests/ui/issues/issue-74082.rs b/tests/ui/issues/issue-74082.rs deleted file mode 100644 index e3e400c79d658..0000000000000 --- a/tests/ui/issues/issue-74082.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![allow(dead_code)] - -#[repr(i128)] //~ ERROR: attribute should be applied to an enum -struct Foo; - -#[repr(u128)] //~ ERROR: attribute should be applied to an enum -struct Bar; - -fn main() {} diff --git a/tests/ui/issues/issue-74082.stderr b/tests/ui/issues/issue-74082.stderr deleted file mode 100644 index 12f5a3b27bb30..0000000000000 --- a/tests/ui/issues/issue-74082.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0517]: attribute should be applied to an enum - --> $DIR/issue-74082.rs:3:8 - | -LL | #[repr(i128)] - | ^^^^ -LL | struct Foo; - | ----------- not an enum - -error[E0517]: attribute should be applied to an enum - --> $DIR/issue-74082.rs:6:8 - | -LL | #[repr(u128)] - | ^^^^ -LL | struct Bar; - | ----------- not an enum - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/iterators/issue-58952-filter-type-length.rs b/tests/ui/iterators/issue-58952-filter-type-length.rs index 6730865b6c7f7..525a2e39a913c 100644 --- a/tests/ui/iterators/issue-58952-filter-type-length.rs +++ b/tests/ui/iterators/issue-58952-filter-type-length.rs @@ -2,7 +2,7 @@ //! This snippet causes the type length to blowup exponentially, //! so check that we don't accidentally exceed the type length limit. -// FIXME: Once the size of iterator adaptors is further reduced, +// FIXME: Once the size of iterator adapters is further reduced, // increase the complexity of this test. use std::collections::VecDeque; diff --git a/tests/ui/keyword/soup.rs b/tests/ui/keyword/soup.rs new file mode 100644 index 0000000000000..c4dbe3fb48341 --- /dev/null +++ b/tests/ui/keyword/soup.rs @@ -0,0 +1,30 @@ +//@ edition:2024 +//@ check-pass + +#![allow(unused_imports)] +#![allow(missing_abi)] +#![allow(unused_macros)] +#![allow(non_camel_case_types)] +#![allow(unreachable_code)] +#![allow(unused_variables)] +#![allow(dead_code)] +#![allow(unused_must_use)] + +// all 48 keywords in 300 characters +mod x { + pub(super) struct X; + use Ok; + impl X { + pub(in crate) async fn x(self: Self, x: &'static &'_ dyn for<> Fn()) where { + unsafe extern { safe fn x(); } + macro_rules! x { () => {}; } + if 'x: loop { + return match while let true = break 'x false { continue } { + ref x => { &raw mut x; async { const { enum A {} } }.await as () }, + }; + } { type x = X; } else { move || { trait x { } union B { x: () } }; } + } + } +} + +fn main() {} diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs deleted file mode 100644 index 35d5d079c6894..0000000000000 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.rs +++ /dev/null @@ -1,19 +0,0 @@ -#![feature(lang_items, no_core)] -#![no_core] -#![no_main] - -#[lang = "pointee_sized"] -pub trait PointeeSized {} - -#[lang = "meta_sized"] -pub trait MetaSized: PointeeSized {} - -#[lang = "sized"] -trait Sized: MetaSized { } - -struct S; - -#[no_mangle] -extern "C" fn main(argc: i32, _argv: *const *const u8) -> i32 { - argc //~ ERROR requires `copy` lang_item -} diff --git a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr b/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr deleted file mode 100644 index 7b9541f734fa8..0000000000000 --- a/tests/ui/lang-items/missing-copy-lang-item-issue-19660.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: requires `copy` lang_item - --> $DIR/missing-copy-lang-item-issue-19660.rs:18:5 - | -LL | argc - | ^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/layout/hexagon-enum.rs b/tests/ui/layout/hexagon-enum.rs index 02833eb41fad7..22a1d5d10f307 100644 --- a/tests/ui/layout/hexagon-enum.rs +++ b/tests/ui/layout/hexagon-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target hexagon-unknown-linux-musl //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: hexagon +//@ ignore-backends: gcc // // Verify that the hexagon targets implement the repr(C) for enums correctly. // diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index d910456c0e6d1..659013c8a6f1a 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -69,7 +69,7 @@ error: layout_of(A) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:18:1 + --> $DIR/hexagon-enum.rs:19:1 | LL | enum A { Apple } | ^^^^^^ @@ -145,7 +145,7 @@ error: layout_of(B) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:22:1 + --> $DIR/hexagon-enum.rs:23:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -221,7 +221,7 @@ error: layout_of(C) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:26:1 + --> $DIR/hexagon-enum.rs:27:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -297,7 +297,7 @@ error: layout_of(P) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:30:1 + --> $DIR/hexagon-enum.rs:31:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -373,7 +373,7 @@ error: layout_of(T) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/hexagon-enum.rs:36:1 + --> $DIR/hexagon-enum.rs:37:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/reprc-power-alignment.rs b/tests/ui/layout/reprc-power-alignment.rs index f144094d43fbc..c8a6aa86a5081 100644 --- a/tests/ui/layout/reprc-power-alignment.rs +++ b/tests/ui/layout/reprc-power-alignment.rs @@ -2,15 +2,16 @@ //@ compile-flags: --target powerpc64-ibm-aix //@ needs-llvm-components: powerpc //@ add-core-stubs +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] #![no_std] +#![crate_type = "lib"] extern crate minicore; use minicore::*; #[warn(uses_power_alignment)] - #[repr(C)] pub struct Floats { a: f64, @@ -96,32 +97,32 @@ pub struct FloatAgg7 { #[repr(C)] pub struct A { - d: f64, + d: f64, } #[repr(C)] pub struct B { - a: A, - f: f32, - d: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type + a: A, + f: f32, + d: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type } #[repr(C)] pub struct C { - c: u8, - b: B, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type + c: u8, + b: B, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type } #[repr(C)] pub struct D { - x: f64, + x: f64, } #[repr(C)] pub struct E { - x: i32, - d: D, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type + x: i32, + d: D, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type } #[repr(C)] pub struct F { - a: u8, - b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type + a: u8, + b: f64, //~ WARNING repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type } #[repr(C)] pub struct G { @@ -173,4 +174,19 @@ pub struct M { b: K, c: L, } -fn main() { } + +// The lint ignores unions +#[repr(C)] +pub union Union { + a: f64, + b: u8, + c: f64, + d: f32, +} + +// The lint ignores enums +#[repr(C)] +pub enum Enum { + A { a: f64, b: u8, c: f64, d: f32 }, + B, +} diff --git a/tests/ui/layout/reprc-power-alignment.stderr b/tests/ui/layout/reprc-power-alignment.stderr index 18664e4d655d3..5398c7d4871f5 100644 --- a/tests/ui/layout/reprc-power-alignment.stderr +++ b/tests/ui/layout/reprc-power-alignment.stderr @@ -1,17 +1,17 @@ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:18:5 + --> $DIR/reprc-power-alignment.rs:19:5 | LL | c: f64, | ^^^^^^ | note: the lint level is defined here - --> $DIR/reprc-power-alignment.rs:12:8 + --> $DIR/reprc-power-alignment.rs:14:8 | LL | #[warn(uses_power_alignment)] | ^^^^^^^^^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:45:5 + --> $DIR/reprc-power-alignment.rs:46:5 | LL | b: f64, | ^^^^^^ @@ -19,91 +19,91 @@ LL | b: f64, = note: `#[warn(uses_power_alignment)]` on by default warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:52:5 + --> $DIR/reprc-power-alignment.rs:53:5 | LL | y: f64, | ^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:58:5 + --> $DIR/reprc-power-alignment.rs:59:5 | LL | y: Floats, | ^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:65:5 + --> $DIR/reprc-power-alignment.rs:66:5 | LL | y: FloatAgg2, | ^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:66:5 + --> $DIR/reprc-power-alignment.rs:67:5 | LL | z: FloatAgg2, | ^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:72:5 + --> $DIR/reprc-power-alignment.rs:73:5 | LL | y: FloatAgg2, | ^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:78:5 + --> $DIR/reprc-power-alignment.rs:79:5 | LL | y: FloatAgg2, | ^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:79:5 + --> $DIR/reprc-power-alignment.rs:80:5 | LL | z: FloatAgg3, | ^^^^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:85:5 + --> $DIR/reprc-power-alignment.rs:86:5 | LL | y: Floats, | ^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:92:5 + --> $DIR/reprc-power-alignment.rs:93:5 | LL | y: Floats, | ^^^^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:105:3 + --> $DIR/reprc-power-alignment.rs:106:5 | -LL | d: f64, - | ^^^^^^ +LL | d: f64, + | ^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:110:3 + --> $DIR/reprc-power-alignment.rs:111:5 | -LL | b: B, - | ^^^^ +LL | b: B, + | ^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:119:3 + --> $DIR/reprc-power-alignment.rs:120:5 | -LL | d: D, - | ^^^^ +LL | d: D, + | ^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:124:3 + --> $DIR/reprc-power-alignment.rs:125:5 | -LL | b: f64, - | ^^^^^^ +LL | b: f64, + | ^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:130:5 + --> $DIR/reprc-power-alignment.rs:131:5 | LL | c: f64, | ^^^^^^ warning: repr(C) does not follow the power alignment rule. This may affect platform C ABI compatibility for this type - --> $DIR/reprc-power-alignment.rs:132:5 + --> $DIR/reprc-power-alignment.rs:133:5 | LL | e: f64, | ^^^^^^ diff --git a/tests/ui/layout/thaw-transmute-invalid-enum.rs b/tests/ui/layout/thaw-transmute-invalid-enum.rs index a7c2e1a86de7b..20fc8d463594b 100644 --- a/tests/ui/layout/thaw-transmute-invalid-enum.rs +++ b/tests/ui/layout/thaw-transmute-invalid-enum.rs @@ -9,6 +9,7 @@ mod assert { where Dst: TransmuteFrom, //~^ ERROR: use of unstable library feature `transmutability` + //~^^ ERROR: use of unstable library feature `transmutability` { } } diff --git a/tests/ui/layout/thaw-transmute-invalid-enum.stderr b/tests/ui/layout/thaw-transmute-invalid-enum.stderr index d12fc4694e0ab..2b89159c26336 100644 --- a/tests/ui/layout/thaw-transmute-invalid-enum.stderr +++ b/tests/ui/layout/thaw-transmute-invalid-enum.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Subset` in this scope - --> $DIR/thaw-transmute-invalid-enum.rs:34:41 + --> $DIR/thaw-transmute-invalid-enum.rs:35:41 | LL | assert::is_transmutable::(); | ^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | fn test() { | ++++++++ error[E0517]: attribute should be applied to a struct or union - --> $DIR/thaw-transmute-invalid-enum.rs:21:11 + --> $DIR/thaw-transmute-invalid-enum.rs:22:11 | LL | #[repr(C, packed(2))] | ^^^^^^^^^ @@ -50,8 +50,19 @@ LL | Dst: TransmuteFrom, = help: add `#![feature(transmutability)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +error[E0658]: use of unstable library feature `transmutability` + --> $DIR/thaw-transmute-invalid-enum.rs:10:14 + | +LL | Dst: TransmuteFrom, + | ^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(transmutability)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date +note: required by a bound in `TransmuteFrom` + --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL + error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union - --> $DIR/thaw-transmute-invalid-enum.rs:29:9 + --> $DIR/thaw-transmute-invalid-enum.rs:30:9 | LL | a: Ox00, | ^^^^^^^ @@ -62,7 +73,7 @@ help: wrap the field type in `ManuallyDrop<...>` LL | a: std::mem::ManuallyDrop, | +++++++++++++++++++++++ + -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0412, E0517, E0658, E0740. For more information about an error, try `rustc --explain E0412`. diff --git a/tests/ui/layout/thumb-enum.rs b/tests/ui/layout/thumb-enum.rs index 1c4fab812f966..1b516f05ec6f3 100644 --- a/tests/ui/layout/thumb-enum.rs +++ b/tests/ui/layout/thumb-enum.rs @@ -2,6 +2,7 @@ //@ compile-flags: --target thumbv8m.main-none-eabihf //@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" //@ needs-llvm-components: arm +//@ ignore-backends: gcc // // Verify that thumb targets implement the repr(C) for enums correctly. // diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 9bd8ced0c02d6..1ef22daf2a9d6 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -69,7 +69,7 @@ error: layout_of(A) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:18:1 + --> $DIR/thumb-enum.rs:19:1 | LL | enum A { Apple } | ^^^^^^ @@ -145,7 +145,7 @@ error: layout_of(B) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:22:1 + --> $DIR/thumb-enum.rs:23:1 | LL | enum B { Banana = 255, } | ^^^^^^ @@ -221,7 +221,7 @@ error: layout_of(C) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:26:1 + --> $DIR/thumb-enum.rs:27:1 | LL | enum C { Chaenomeles = 256, } | ^^^^^^ @@ -297,7 +297,7 @@ error: layout_of(P) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:30:1 + --> $DIR/thumb-enum.rs:31:1 | LL | enum P { Peach = 0x1000_0000isize, } | ^^^^^^ @@ -373,7 +373,7 @@ error: layout_of(T) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/thumb-enum.rs:36:1 + --> $DIR/thumb-enum.rs:37:1 | LL | enum T { Tangerine = TANGERINE as isize } | ^^^^^^ diff --git a/tests/ui/layout/too-big-with-padding.rs b/tests/ui/layout/too-big-with-padding.rs index 0f03bd10fb63d..b8c75d24f492e 100644 --- a/tests/ui/layout/too-big-with-padding.rs +++ b/tests/ui/layout/too-big-with-padding.rs @@ -2,6 +2,7 @@ //@ build-fail //@ compile-flags: --target i686-unknown-linux-gnu --crate-type lib //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, lang_items)] #![allow(internal_features)] #![no_std] diff --git a/tests/ui/layout/too-big-with-padding.stderr b/tests/ui/layout/too-big-with-padding.stderr index 761ac7514ee37..b57c8a8a48704 100644 --- a/tests/ui/layout/too-big-with-padding.stderr +++ b/tests/ui/layout/too-big-with-padding.stderr @@ -1,5 +1,5 @@ error: values of the type `Example` are too big for the target architecture - --> $DIR/too-big-with-padding.rs:17:1 + --> $DIR/too-big-with-padding.rs:18:1 | LL | pub fn lib(_x: Example) {} | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/layout/unconstrained-param-ice-137308.rs b/tests/ui/layout/unconstrained-param-ice-137308.rs index d05e6e1fd3f33..03b7e7599601a 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.rs +++ b/tests/ui/layout/unconstrained-param-ice-137308.rs @@ -17,3 +17,4 @@ impl A for u8 { //~ ERROR: the type parameter `C` is not constrained #[rustc_layout(debug)] struct S([u8; ::B]); //~^ ERROR: the type has an unknown layout +//~| ERROR: type annotations needed diff --git a/tests/ui/layout/unconstrained-param-ice-137308.stderr b/tests/ui/layout/unconstrained-param-ice-137308.stderr index 615c131eb9045..82cd1217c4903 100644 --- a/tests/ui/layout/unconstrained-param-ice-137308.stderr +++ b/tests/ui/layout/unconstrained-param-ice-137308.stderr @@ -4,12 +4,19 @@ error[E0207]: the type parameter `C` is not constrained by the impl trait, self LL | impl A for u8 { | ^ unconstrained type parameter +error[E0282]: type annotations needed + --> $DIR/unconstrained-param-ice-137308.rs:18:16 + | +LL | struct S([u8; ::B]); + | ^^ cannot infer type for type parameter `C` + error: the type has an unknown layout --> $DIR/unconstrained-param-ice-137308.rs:18:1 | LL | struct S([u8; ::B]); | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/lifetimes/issue-105507.fixed b/tests/ui/lifetimes/issue-105507.fixed index 46d4f14a2457e..a3c4e5784b872 100644 --- a/tests/ui/lifetimes/issue-105507.fixed +++ b/tests/ui/lifetimes/issue-105507.fixed @@ -31,7 +31,7 @@ impl ProjectedMyTrait for T fn require_trait(_: T) {} -fn foo(wrap: Wrapper<'_, Option>, wrap1: Wrapper<'_, Option>) { +fn foo(wrap: Wrapper<'_, Option>, wrap1: Wrapper<'_, Option>) { //~^ HELP consider restricting the type parameter to the `'static` lifetime //~| HELP consider restricting the type parameter to the `'static` lifetime require_trait(wrap); diff --git a/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.rs b/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.rs new file mode 100644 index 0000000000000..81e4d3e7043bd --- /dev/null +++ b/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.rs @@ -0,0 +1,21 @@ +// https://github.com/rust-lang/rust/issues/72278 +// and https://github.com/rust-lang/rust/issues/42868 +//@ run-pass + +#![allow(unused)] + +struct S; + +impl S { + fn func<'a, U>(&'a self) -> U { + todo!() + } +} + +fn dont_crash<'a, U>() -> U { + S.func::<'a, U>() + //~^ WARN cannot specify lifetime arguments explicitly + //~| WARN this was previously accepted +} + +fn main() {} diff --git a/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.stderr b/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.stderr new file mode 100644 index 0000000000000..cffdf0df83cc6 --- /dev/null +++ b/tests/ui/lifetimes/late-bound-lifetime-arguments-warning-72278.stderr @@ -0,0 +1,15 @@ +warning: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/late-bound-lifetime-arguments-warning-72278.rs:16:14 + | +LL | fn func<'a, U>(&'a self) -> U { + | -- the late bound lifetime parameter is introduced here +... +LL | S.func::<'a, U>() + | ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 + = note: `#[warn(late_bound_lifetime_arguments)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.rs b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.rs new file mode 100644 index 0000000000000..d56bc18f669ed --- /dev/null +++ b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.rs @@ -0,0 +1,17 @@ +// https://github.com/rust-lang/rust/issues/60622 +#![deny(warnings)] + +struct Borked {} + +impl Borked { + fn a(&self) {} +} + +fn run_wild(b: &Borked) { + b.a::<'_, T>(); + //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + //~| ERROR method takes 0 generic arguments but 1 generic argument + //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} + +fn main() {} diff --git a/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr new file mode 100644 index 0000000000000..880513e02823b --- /dev/null +++ b/tests/ui/lifetimes/late-bound-lifetime-parameters-60622.stderr @@ -0,0 +1,35 @@ +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/late-bound-lifetime-parameters-60622.rs:11:11 + | +LL | fn a(&self) {} + | - the late bound lifetime parameter is introduced here +... +LL | b.a::<'_, T>(); + | ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 +note: the lint level is defined here + --> $DIR/late-bound-lifetime-parameters-60622.rs:2:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]` + +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/late-bound-lifetime-parameters-60622.rs:11:7 + | +LL | b.a::<'_, T>(); + | ^ - help: remove the unnecessary generic argument + | | + | expected 0 generic arguments + | +note: method defined here, with 0 generic parameters + --> $DIR/late-bound-lifetime-parameters-60622.rs:7:8 + | +LL | fn a(&self) {} + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs new file mode 100644 index 0000000000000..16039f177b4de --- /dev/null +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.rs @@ -0,0 +1,13 @@ +// Regression test for #91831 + +struct Foo<'a>(&'a i32); + +impl<'a> Foo<'a> { + fn modify(&'a mut self) {} +} + +fn bar(foo: &mut Foo) { + foo.modify(); //~ ERROR lifetime may not live long enough +} + +fn main() {} diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr new file mode 100644 index 0000000000000..f02b65230b6eb --- /dev/null +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-5.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/ex3-both-anon-regions-one-is-struct-5.rs:10:5 + | +LL | fn bar(foo: &mut Foo) { + | --- - let's call the lifetime of this reference `'1` + | | + | has type `&mut Foo<'2>` +LL | foo.modify(); + | ^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | + = note: requirement occurs because of a mutable reference to `Foo<'_>` + = note: mutable references are invariant over their type parameter + = help: see for more information about variance +help: consider introducing a named lifetime parameter + | +LL | fn bar<'a>(foo: &'a mut Foo<'a>) { + | ++++ ++ ++++ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lifetimes/re-empty-in-error.stderr b/tests/ui/lifetimes/re-empty-in-error.stderr index 554bcb5451fc0..b3b6d3d269c9b 100644 --- a/tests/ui/lifetimes/re-empty-in-error.stderr +++ b/tests/ui/lifetimes/re-empty-in-error.stderr @@ -4,7 +4,7 @@ error: higher-ranked lifetime error LL | foo(&10); | ^^^^^^^^ | - = note: could not prove `for<'b> &'b (): 'a` + = note: could not prove `for<'b> &'b (): '_` error: aborting due to 1 previous error diff --git a/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs b/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs index bb537f855a4ab..7de786dff3b77 100644 --- a/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs +++ b/tests/ui/lifetimes/temporary-lifetime-extension-tuple-ctor.rs @@ -1,4 +1,4 @@ -//@ edition:2024 +//@ reference: destructors.scope.lifetime-extension.exprs fn temp() -> String { String::from("Hello") @@ -22,7 +22,7 @@ fn main() { let a = &temp(); let b = Some(&temp()); let c = Option::Some::<&String>(&temp()); - use Option::Some as S; + use std::option::Option::Some as S; let d = S(&temp()); let e = X(&temp()); let f = Some(Ok::<_, ()>(std::borrow::Cow::Borrowed(if true { @@ -31,6 +31,6 @@ fn main() { panic!() }))); let some = Some; // Turn the ctor into a regular function. - let g = some(&temp()); //~ERROR temporary value dropped while borrowe + let g = some(&temp()); //~ERROR temporary value dropped while borrowed println!("{a:?} {b:?} {c:?} {d:?} {e:?} {f:?} {g:?}"); } diff --git a/tests/ui/link-native-libs/issue-43925.rs b/tests/ui/link-native-libs/issue-43925.rs index e3ce71352c06b..09248db5a6212 100644 --- a/tests/ui/link-native-libs/issue-43925.rs +++ b/tests/ui/link-native-libs/issue-43925.rs @@ -1,6 +1,6 @@ #[link(name = "foo", cfg("rlib"))] //~^ ERROR link cfg is unstable -//~| ERROR `cfg` predicate key must be an identifier +//~| ERROR malformed `link` attribute input extern "C" {} fn main() {} diff --git a/tests/ui/link-native-libs/issue-43925.stderr b/tests/ui/link-native-libs/issue-43925.stderr index 82d204222dfd0..68a020546c14e 100644 --- a/tests/ui/link-native-libs/issue-43925.stderr +++ b/tests/ui/link-native-libs/issue-43925.stderr @@ -7,12 +7,32 @@ LL | #[link(name = "foo", cfg("rlib"))] = help: add `#![feature(link_cfg)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: `cfg` predicate key must be an identifier - --> $DIR/issue-43925.rs:1:26 +error[E0539]: malformed `link` attribute input + --> $DIR/issue-43925.rs:1:1 | LL | #[link(name = "foo", cfg("rlib"))] - | ^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^------^^^ + | | + | expected a valid identifier here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[link(name = "foo", cfg("rlib"))] +LL + #[link(name = "...")] + | +LL - #[link(name = "foo", cfg("rlib"))] +LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] + | +LL - #[link(name = "foo", cfg("rlib"))] +LL + #[link(name = "...", kind = "dylib|static|...")] + | +LL - #[link(name = "foo", cfg("rlib"))] +LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] + | + = and 1 other candidate error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0539, E0658. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/link-native-libs/link-attr-validation-late.rs b/tests/ui/link-native-libs/link-attr-validation-late.rs index d2947b5f61aff..c24acca0d8408 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.rs +++ b/tests/ui/link-native-libs/link-attr-validation-late.rs @@ -22,7 +22,7 @@ extern "C" {} #[link(name = "...", modifiers())] //~ ERROR malformed `link` attribute input #[link(name = "...", cfg)] //~ ERROR malformed `link` attribute input #[link(name = "...", cfg = "literal")] //~ ERROR malformed `link` attribute input -#[link(name = "...", cfg("literal"))] //~ ERROR `cfg` predicate key must be an identifier +#[link(name = "...", cfg("literal"))] //~ ERROR malformed `link` attribute input #[link(name = "...", wasm_import_module)] //~ ERROR malformed `link` attribute input #[link(name = "...", wasm_import_module())] //~ ERROR malformed `link` attribute input extern "C" {} diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index 834dca0bc0bbe..106b7cebc99f7 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -367,11 +367,30 @@ LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", | = and 1 other candidate -error: `cfg` predicate key must be an identifier - --> $DIR/link-attr-validation-late.rs:25:26 +error[E0539]: malformed `link` attribute input + --> $DIR/link-attr-validation-late.rs:25:1 | LL | #[link(name = "...", cfg("literal"))] - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^---------^^^ + | | + | expected a valid identifier here + | + = note: for more information, visit +help: try changing it to one of the following valid forms of the attribute + | +LL - #[link(name = "...", cfg("literal"))] +LL + #[link(name = "...")] + | +LL - #[link(name = "...", cfg("literal"))] +LL + #[link(name = "...", import_name_type = "decorated|noprefix|undecorated")] + | +LL - #[link(name = "...", cfg("literal"))] +LL + #[link(name = "...", kind = "dylib|static|...")] + | +LL - #[link(name = "...", cfg("literal"))] +LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", import_name_type = "decorated|noprefix|undecorated")] + | + = and 1 other candidate error[E0539]: malformed `link` attribute input --> $DIR/link-attr-validation-late.rs:26:1 diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs b/tests/ui/linkage-attr/common-linkage-non-zero-init.rs index e5de08a7a28bb..512616251c2f7 100644 --- a/tests/ui/linkage-attr/common-linkage-non-zero-init.rs +++ b/tests/ui/linkage-attr/common-linkage-non-zero-init.rs @@ -3,6 +3,7 @@ //@ known-bug: #109681 //@ ignore-wasm32 this appears to SIGABRT on wasm, not fail cleanly //@ compile-flags: -Z verify-llvm-ir +//@ ignore-backends: gcc // This test verifies that we continue to hit the LLVM error for common linkage with non-zero // initializers, since it generates invalid LLVM IR. diff --git a/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs b/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs new file mode 100644 index 0000000000000..48ca39300f41c --- /dev/null +++ b/tests/ui/linkage-attr/raw-dylib/elf/as_needed.rs @@ -0,0 +1,43 @@ +//@ only-elf +//@ needs-dynamic-linking + +//@ only-gnu +//@ only-x86_64 +//@ revisions: as_needed no_as_needed no_modifier merge_1 merge_2 merge_3 merge_4 + +//@ [as_needed] run-pass +//@ [no_as_needed] run-fail +//@ [no_modifier] run-pass +//@ [merge_1] run-fail +//@ [merge_2] run-fail +//@ [merge_3] run-fail +//@ [merge_4] run-pass + +#![allow(incomplete_features)] +#![feature(raw_dylib_elf)] +#![feature(native_link_modifiers_as_needed)] + +#[cfg_attr( + as_needed, + link(name = "taiqannf1y28z2rw", kind = "raw-dylib", modifiers = "+as-needed") +)] +#[cfg_attr( + no_as_needed, + link(name = "taiqannf1y28z2rw", kind = "raw-dylib", modifiers = "-as-needed") +)] +#[cfg_attr(no_modifier, link(name = "taiqannf1y28z2rw", kind = "raw-dylib"))] +unsafe extern "C" {} + +#[cfg_attr(merge_1, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "+as-needed"))] +#[cfg_attr(merge_2, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "-as-needed"))] +#[cfg_attr(merge_3, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "-as-needed"))] +#[cfg_attr(merge_4, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "+as-needed"))] +unsafe extern "C" {} + +#[cfg_attr(merge_1, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "-as-needed"))] +#[cfg_attr(merge_2, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "+as-needed"))] +#[cfg_attr(merge_3, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "-as-needed"))] +#[cfg_attr(merge_4, link(name = "k9nm7qxoa79bg7e6", kind = "raw-dylib", modifiers = "+as-needed"))] +unsafe extern "C" {} + +fn main() {} diff --git a/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs index 57492ed2d0e1f..62d352facd178 100644 --- a/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs +++ b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs @@ -3,6 +3,7 @@ //@ run-pass //@ compile-flags: -Cpanic=abort //@ edition: 2024 +//@ ignore-backends: gcc #![allow(incomplete_features)] #![feature(raw_dylib_elf)] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs index 542f34b3eb1e4..4340703e106da 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr index 6121762fb03af..6b54f3b247d1c 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `link` attribute input - --> $DIR/import-name-type-invalid-format.rs:8:1 + --> $DIR/import-name-type-invalid-format.rs:9:1 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = 6)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------^^ diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs index e2418642aea0c..a03fb53c687b7 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs @@ -2,6 +2,7 @@ //@ add-core-stubs //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr index adfe915b464ec..35ddb2a7e3d36 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr @@ -1,5 +1,5 @@ error[E0538]: malformed `link` attribute input - --> $DIR/import-name-type-multiple.rs:9:1 + --> $DIR/import-name-type-multiple.rs:10:1 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------^^ diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs index 174e8682f29ae..adcacc89e7488 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr index fc24a6bed1798..b0099675dd23d 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr @@ -1,5 +1,5 @@ error[E0539]: malformed `link` attribute input - --> $DIR/import-name-type-unknown-value.rs:8:1 + --> $DIR/import-name-type-unknown-value.rs:9:1 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------^^ diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs index ca6aef79c9553..79aa16b985639 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target i686-pc-windows-msvc //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr index 075e4ffffb895..e66247a41e784 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr @@ -1,11 +1,11 @@ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:8:22 + --> $DIR/import-name-type-unsupported-link-kind.rs:9:22 | LL | #[link(name = "foo", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: import name type can only be used with link kind `raw-dylib` - --> $DIR/import-name-type-unsupported-link-kind.rs:12:39 + --> $DIR/import-name-type-unsupported-link-kind.rs:13:39 | LL | #[link(name = "bar", kind = "static", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs index 5f1410f7d2a51..0b82165f57529 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs @@ -1,6 +1,7 @@ //@ add-core-stubs //@ compile-flags: --target aarch64-pc-windows-msvc //@ needs-llvm-components: aarch64 +//@ ignore-backends: gcc #![feature(no_core, rustc_attrs, lang_items)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr index ad3b9f79c8435..912d1c1f6b915 100644 --- a/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr +++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr @@ -1,5 +1,5 @@ error: import name type is only supported on x86 - --> $DIR/import-name-type-x86-only.rs:8:42 + --> $DIR/import-name-type-x86-only.rs:9:42 | LL | #[link(name = "foo", kind = "raw-dylib", import_name_type = "decorated")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/linking/no-gc-encapsulation-symbols.rs b/tests/ui/linking/no-gc-encapsulation-symbols.rs index 36d69969199ce..c60f35b55eb2f 100644 --- a/tests/ui/linking/no-gc-encapsulation-symbols.rs +++ b/tests/ui/linking/no-gc-encapsulation-symbols.rs @@ -5,6 +5,7 @@ // //@ build-pass //@ only-x86_64-unknown-linux-gnu +//@ ignore-backends: gcc unsafe extern "Rust" { // The __start_ section name is magical for the linker, diff --git a/tests/ui/lint/dead-code/issue-85071-2.rs b/tests/ui/lint/dead-code/issue-85071-2.rs index 5db8735899410..06bbcac737397 100644 --- a/tests/ui/lint/dead-code/issue-85071-2.rs +++ b/tests/ui/lint/dead-code/issue-85071-2.rs @@ -17,6 +17,6 @@ fn main() { let s = S; let x = s.f(); //~^ WARNING: unused variable: `x` + //~| WARNING: unreachable definition let _y = x; - //~^ WARNING: unreachable definition } diff --git a/tests/ui/lint/dead-code/issue-85071-2.stderr b/tests/ui/lint/dead-code/issue-85071-2.stderr index 5e963183d094b..5cc94e25e3a69 100644 --- a/tests/ui/lint/dead-code/issue-85071-2.stderr +++ b/tests/ui/lint/dead-code/issue-85071-2.stderr @@ -1,11 +1,10 @@ warning: unreachable definition - --> $DIR/issue-85071-2.rs:20:9 + --> $DIR/issue-85071-2.rs:18:9 | LL | let x = s.f(); - | ----- any code following this expression is unreachable -LL | -LL | let _y = x; - | ^^ unreachable definition + | ^ ----- any code following this expression is unreachable + | | + | unreachable definition | note: this expression has type `Foo`, which is uninhabited --> $DIR/issue-85071-2.rs:18:13 diff --git a/tests/ui/lint/dead-code/issue-85071.rs b/tests/ui/lint/dead-code/issue-85071.rs index 84f2c9fc74eeb..6f177905b5968 100644 --- a/tests/ui/lint/dead-code/issue-85071.rs +++ b/tests/ui/lint/dead-code/issue-85071.rs @@ -14,6 +14,6 @@ fn f() -> Foo {todo!()} fn main() { let x = f(); //~^ WARNING: unused variable: `x` + //~| WARNING: unreachable definition let _ = x; - //~^ WARNING: unreachable expression } diff --git a/tests/ui/lint/dead-code/issue-85071.stderr b/tests/ui/lint/dead-code/issue-85071.stderr index 721fb8148d96b..b95ae09385dec 100644 --- a/tests/ui/lint/dead-code/issue-85071.stderr +++ b/tests/ui/lint/dead-code/issue-85071.stderr @@ -1,11 +1,10 @@ -warning: unreachable expression - --> $DIR/issue-85071.rs:17:13 +warning: unreachable definition + --> $DIR/issue-85071.rs:15:9 | LL | let x = f(); - | --- any code following this expression is unreachable -LL | -LL | let _ = x; - | ^ unreachable expression + | ^ --- any code following this expression is unreachable + | | + | unreachable definition | note: this expression has type `Foo`, which is uninhabited --> $DIR/issue-85071.rs:15:13 diff --git a/tests/ui/lint/empty-lint-attributes.rs b/tests/ui/lint/empty-lint-attributes.rs index 0193345e5c8c5..4f550eae06363 100644 --- a/tests/ui/lint/empty-lint-attributes.rs +++ b/tests/ui/lint/empty-lint-attributes.rs @@ -3,13 +3,13 @@ // Empty (and reason-only) lint attributes are legal—although we may want to // lint them in the future (Issue #55112). -#![allow()] -#![warn(reason = "observationalism")] +#![allow()] //~ WARN unused attribute +#![warn(reason = "observationalism")] //~ WARN unused attribute -#[forbid()] +#[forbid()] //~ WARN unused attribute fn devoir() {} -#[deny(reason = "ultion")] +#[deny(reason = "ultion")] //~ WARN unused attribute fn waldgrave() {} fn main() {} diff --git a/tests/ui/lint/empty-lint-attributes.stderr b/tests/ui/lint/empty-lint-attributes.stderr new file mode 100644 index 0000000000000..5bf8ae1e9ee7f --- /dev/null +++ b/tests/ui/lint/empty-lint-attributes.stderr @@ -0,0 +1,35 @@ +warning: unused attribute + --> $DIR/empty-lint-attributes.rs:9:1 + | +LL | #[forbid()] + | ^^^^^^^^^^^ help: remove this attribute + | + = note: attribute `forbid` with an empty list has no effect + = note: requested on the command line with `-W unused-attributes` + +warning: unused attribute + --> $DIR/empty-lint-attributes.rs:12:1 + | +LL | #[deny(reason = "ultion")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: attribute `deny` without any lints has no effect + +warning: unused attribute + --> $DIR/empty-lint-attributes.rs:6:1 + | +LL | #![allow()] + | ^^^^^^^^^^^ help: remove this attribute + | + = note: attribute `allow` with an empty list has no effect + +warning: unused attribute + --> $DIR/empty-lint-attributes.rs:7:1 + | +LL | #![warn(reason = "observationalism")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: attribute `warn` without any lints has no effect + +warning: 4 warnings emitted + diff --git a/tests/ui/lint/fn_must_use.rs b/tests/ui/lint/fn_must_use.rs index be18ffedabb19..b0f7a12cec708 100644 --- a/tests/ui/lint/fn_must_use.rs +++ b/tests/ui/lint/fn_must_use.rs @@ -39,6 +39,8 @@ impl Replaceable for MyStruct { // method won't work; the attribute should be on the method signature in // the trait's definition. #[must_use] + //~^ WARN attribute cannot be used on trait methods in impl blocks + //~| WARN previously accepted fn replace(&mut self, substitute: usize) -> usize { let previously = self.n; self.n = substitute; diff --git a/tests/ui/lint/fn_must_use.stderr b/tests/ui/lint/fn_must_use.stderr index e88c1a9b8a9b9..0e8da873e7c3b 100644 --- a/tests/ui/lint/fn_must_use.stderr +++ b/tests/ui/lint/fn_must_use.stderr @@ -1,5 +1,15 @@ +warning: `#[must_use]` attribute cannot be used on trait methods in impl blocks + --> $DIR/fn_must_use.rs:41:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions + = note: requested on the command line with `-W unused-attributes` + warning: unused return value of `need_to_use_this_value` that must be used - --> $DIR/fn_must_use.rs:55:5 + --> $DIR/fn_must_use.rs:57:5 | LL | need_to_use_this_value(); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +26,7 @@ LL | let _ = need_to_use_this_value(); | +++++++ warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used - --> $DIR/fn_must_use.rs:60:5 + --> $DIR/fn_must_use.rs:62:5 | LL | m.need_to_use_this_method_value(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,7 +37,7 @@ LL | let _ = m.need_to_use_this_method_value(); | +++++++ warning: unused return value of `EvenNature::is_even` that must be used - --> $DIR/fn_must_use.rs:61:5 + --> $DIR/fn_must_use.rs:63:5 | LL | m.is_even(); // trait method! | ^^^^^^^^^^^ @@ -39,7 +49,7 @@ LL | let _ = m.is_even(); // trait method! | +++++++ warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` that must be used - --> $DIR/fn_must_use.rs:64:5 + --> $DIR/fn_must_use.rs:66:5 | LL | MyStruct::need_to_use_this_associated_function_value(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -50,7 +60,7 @@ LL | let _ = MyStruct::need_to_use_this_associated_function_value(); | +++++++ warning: unused return value of `std::cmp::PartialEq::eq` that must be used - --> $DIR/fn_must_use.rs:70:5 + --> $DIR/fn_must_use.rs:72:5 | LL | 2.eq(&3); | ^^^^^^^^ @@ -61,7 +71,7 @@ LL | let _ = 2.eq(&3); | +++++++ warning: unused return value of `std::cmp::PartialEq::eq` that must be used - --> $DIR/fn_must_use.rs:71:5 + --> $DIR/fn_must_use.rs:73:5 | LL | m.eq(&n); | ^^^^^^^^ @@ -72,7 +82,7 @@ LL | let _ = m.eq(&n); | +++++++ warning: unused comparison that must be used - --> $DIR/fn_must_use.rs:74:5 + --> $DIR/fn_must_use.rs:76:5 | LL | 2 == 3; | ^^^^^^ the comparison produces a value @@ -83,7 +93,7 @@ LL | let _ = 2 == 3; | +++++++ warning: unused comparison that must be used - --> $DIR/fn_must_use.rs:75:5 + --> $DIR/fn_must_use.rs:77:5 | LL | m == n; | ^^^^^^ the comparison produces a value @@ -93,5 +103,5 @@ help: use `let _ = ...` to ignore the resulting value LL | let _ = m == n; | +++++++ -warning: 8 warnings emitted +warning: 9 warnings emitted diff --git a/tests/ui/lint/forbid-error-capped.rs b/tests/ui/lint/forbid-error-capped.rs index f5059793eddf7..e458ddf90746e 100644 --- a/tests/ui/lint/forbid-error-capped.rs +++ b/tests/ui/lint/forbid-error-capped.rs @@ -6,6 +6,8 @@ #![forbid(warnings)] #![allow(unused)] +//~^ WARN allow(unused) incompatible with previous forbid +//~| WARN previously accepted #[allow(unused)] mod bar { diff --git a/tests/ui/lint/forbid-error-capped.stderr b/tests/ui/lint/forbid-error-capped.stderr new file mode 100644 index 0000000000000..479e7b9412d57 --- /dev/null +++ b/tests/ui/lint/forbid-error-capped.stderr @@ -0,0 +1,27 @@ +warning: allow(unused) incompatible with previous forbid + --> $DIR/forbid-error-capped.rs:8:10 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | #![allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `#[warn(forbidden_lint_groups)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + +Future incompatibility report: Future breakage diagnostic: +warning: allow(unused) incompatible with previous forbid + --> $DIR/forbid-error-capped.rs:8:10 + | +LL | #![forbid(warnings)] + | -------- `forbid` level set here +LL | #![allow(unused)] + | ^^^^^^ overruled by previous forbid + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 + = note: `#[warn(forbidden_lint_groups)]` (part of `#[warn(future_incompatible)]`) on by default + diff --git a/tests/ui/lint/future-incompat-json-test.stderr b/tests/ui/lint/future-incompat-json-test.stderr index bf29b9577db5e..2e7d0cf626f1d 100644 --- a/tests/ui/lint/future-incompat-json-test.stderr +++ b/tests/ui/lint/future-incompat-json-test.stderr @@ -1,4 +1,4 @@ -{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":340,"byte_end":341,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":340,"byte_end":341,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x` +{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":340,"byte_end":341,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":340,"byte_end":341,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x` --> $DIR/future-incompat-json-test.rs:9:9 | LL | let x = 1; diff --git a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs index 8e74531e7762a..5b5843a8ddbb6 100644 --- a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs @@ -13,4 +13,5 @@ macro_rules! pat { fn main() { let pat!(value) = Value { value: () }; + //~^ WARN value assigned to `value` is never read } diff --git a/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr new file mode 100644 index 0000000000000..ba7d3515b0d8d --- /dev/null +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.stderr @@ -0,0 +1,11 @@ +warning: value assigned to `value` is never read + --> $DIR/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs:15:14 + | +LL | let pat!(value) = Value { value: () }; + | ^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr index 0399fab746ec4..bda4ee82d1fc6 100644 --- a/tests/ui/lint/lint-stability-deprecated.stderr +++ b/tests/ui/lint/lint-stability-deprecated.stderr @@ -43,8 +43,8 @@ LL | Trait::trait_deprecated_text(&foo); warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:40:25 | -LL | ::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:42:9 @@ -115,8 +115,8 @@ LL | let _ = Enum::DeprecatedVariant; warning: use of deprecated unit variant `lint_stability::Enum::DeprecatedUnstableVariant`: text --> $DIR/lint-stability-deprecated.rs:121:23 | -LL | let _ = Enum::DeprecatedUnstableVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = Enum::DeprecatedUnstableVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated tuple struct `lint_stability::DeprecatedTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:125:17 @@ -127,8 +127,8 @@ LL | let _ = DeprecatedTupleStruct (1); warning: use of deprecated tuple struct `lint_stability::DeprecatedUnstableTupleStruct`: text --> $DIR/lint-stability-deprecated.rs:126:17 | -LL | let _ = DeprecatedUnstableTupleStruct (1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... let _ = DeprecatedUnstableTupleStruct (1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:135:25 @@ -139,14 +139,14 @@ LL | macro_test_arg!(deprecated_text()); warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:136:25 | -LL | macro_test_arg!(deprecated_unstable_text()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... macro_test_arg!(deprecated_unstable_text()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:137:41 | -LL | macro_test_arg!(macro_test_arg!(deprecated_text())); - | ^^^^^^^^^^^^^^^ +LL | ... macro_test_arg!(macro_test_arg!(deprecated_text())); + | ^^^^^^^^^^^^^^^ warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:142:16 @@ -169,8 +169,8 @@ LL | Trait::trait_deprecated_text(&foo); warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:148:25 | -LL | ::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:150:16 @@ -211,8 +211,8 @@ LL | trait LocalTrait2 : DeprecatedTrait { } warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text --> $DIR/lint-stability-deprecated.rs:205:23 | -LL | unstable_mod::deprecated(); - | ^^^^^^^^^^ +LL | ... unstable_mod::deprecated(); + | ^^^^^^^^^^ warning: use of deprecated function `this_crate::deprecated`: text --> $DIR/lint-stability-deprecated.rs:327:9 @@ -367,14 +367,14 @@ LL | foo.method_deprecated_text(); warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:35:14 | -LL | Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:36:16 | -LL | ::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | ... ::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:37:13 @@ -397,8 +397,8 @@ LL | foo.method_deprecated_unstable(); warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:44:14 | -LL | Foo::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... Foo::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:45:16 diff --git a/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr b/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr index e5f2e65fd91d3..09f76f86a4b14 100644 --- a/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr +++ b/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr @@ -24,14 +24,14 @@ note: the lint level is defined here LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` -help: if this is intentional, prefix it with an underscore - | -LL | _Foo => {} - | + help: you might have meant to pattern match on the similarly named variant `Foo` | LL | foo::Foo::Foo => {} | ++++++++++ +help: if this is intentional, prefix it with an underscore + | +LL | _Foo => {} + | + warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:28:9 @@ -39,14 +39,14 @@ warning: unused variable: `Foo` LL | let Foo = foo::Foo::Foo; | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | let _Foo = foo::Foo::Foo; - | + help: you might have meant to pattern match on the similarly named variant `Foo` | LL | let foo::Foo::Foo = foo::Foo::Foo; | ++++++++++ +help: if this is intentional, prefix it with an underscore + | +LL | let _Foo = foo::Foo::Foo; + | + error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` --> $DIR/lint-uppercase-variables.rs:33:17 @@ -58,16 +58,7 @@ warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:33:17 | LL | fn in_param(Foo: foo::Foo) {} - | ^^^ - | -help: if this is intentional, prefix it with an underscore - | -LL | fn in_param(_Foo: foo::Foo) {} - | + -help: you might have meant to pattern match on the similarly named variant `Foo` - | -LL | fn in_param(foo::Foo::Foo: foo::Foo) {} - | ++++++++++ + | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo` error: structure field `X` should have a snake case name --> $DIR/lint-uppercase-variables.rs:10:5 diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs index 549f031cbf6a3..c93c94ae84a9a 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.rs @@ -23,7 +23,7 @@ pub fn check_expect_on_item() { pub fn check_expect_on_macro() { // This should be fulfilled by the macro - #[expect(unused_variables)] + #[expect(unused_variables)] //~ WARN unused attribute trigger_unused_variables_macro!(); // FIXME: Lint attributes currently don't work directly on macros, and diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr index 49dba1c7ffe8c..f0ee27a99151f 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_lint_from_macro.stderr @@ -1,12 +1,33 @@ +warning: unused attribute `expect` + --> $DIR/expect_lint_from_macro.rs:26:5 + | +LL | #[expect(unused_variables)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the built-in attribute `expect` will be ignored, since it's applied to the macro invocation `trigger_unused_variables_macro` + --> $DIR/expect_lint_from_macro.rs:27:5 + | +LL | trigger_unused_variables_macro!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: requested on the command line with `-W unused-attributes` + warning: unused variable: `x` --> $DIR/expect_lint_from_macro.rs:7:13 | LL | let x = 0; - | ^ help: if this is intentional, prefix it with an underscore: `_x` + | ^ ... LL | trigger_unused_variables_macro!(); | --------------------------------- in this macro invocation | +help: `x` is captured in macro and introduced a unused variable + --> $DIR/expect_lint_from_macro.rs:7:13 + | +LL | let x = 0; + | ^ +... +LL | trigger_unused_variables_macro!(); + | --------------------------------- in this macro invocation note: the lint level is defined here --> $DIR/expect_lint_from_macro.rs:3:9 | @@ -18,12 +39,20 @@ warning: unused variable: `x` --> $DIR/expect_lint_from_macro.rs:7:13 | LL | let x = 0; - | ^ help: if this is intentional, prefix it with an underscore: `_x` + | ^ ... LL | trigger_unused_variables_macro!(); | --------------------------------- in this macro invocation | +help: `x` is captured in macro and introduced a unused variable + --> $DIR/expect_lint_from_macro.rs:7:13 + | +LL | let x = 0; + | ^ +... +LL | trigger_unused_variables_macro!(); + | --------------------------------- in this macro invocation = note: this warning originates in the macro `trigger_unused_variables_macro` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 2 warnings emitted +warning: 3 warnings emitted diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr index eaf9edd8e8fee..dbfdfc7d4fa7a 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr @@ -14,12 +14,6 @@ LL | let x = 2; | = note: requested on the command line with `--force-warn unused-variables` -warning: unused variable: `fox_name` - --> $DIR/force_warn_expected_lints_fulfilled.rs:26:9 - | -LL | let fox_name = "Sir Nibbles"; - | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_fox_name` - warning: variable does not need to be mutable --> $DIR/force_warn_expected_lints_fulfilled.rs:30:9 | @@ -30,6 +24,12 @@ LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*"; | = note: requested on the command line with `--force-warn unused-mut` +warning: unused variable: `fox_name` + --> $DIR/force_warn_expected_lints_fulfilled.rs:26:9 + | +LL | let fox_name = "Sir Nibbles"; + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_fox_name` + warning: unused variable: `this_should_fulfill_the_expectation` --> $DIR/force_warn_expected_lints_fulfilled.rs:41:9 | diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs index 33efdb3f08d3a..28c2a2c33abeb 100644 --- a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs +++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.rs @@ -48,4 +48,5 @@ fn main() { // This `#[allow]` does not work, since the attribute gets dropped // when we expand the macro let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work); + //~^ WARN unused attribute } diff --git a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr index ea72ef84b9dae..0f3a5d7ba547f 100644 --- a/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr +++ b/tests/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr @@ -31,6 +31,19 @@ LL | let _ = foo!(warn_in_expr); = note: for more information, see issue #79813 = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) +warning: unused attribute `allow` + --> $DIR/semicolon-in-expressions-from-macros.rs:50:13 + | +LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `foo` + --> $DIR/semicolon-in-expressions-from-macros.rs:50:60 + | +LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_not_work); + | ^^^ + = note: requested on the command line with `-W unused-attributes` + warning: trailing semicolon in macro used in expression position --> $DIR/semicolon-in-expressions-from-macros.rs:9:13 | @@ -44,7 +57,7 @@ LL | let _ = #[allow(semicolon_in_expressions_from_macros)] foo!(allow_does_ = note: for more information, see issue #79813 = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 3 warnings emitted +warning: 4 warnings emitted Future incompatibility report: Future breakage diagnostic: warning: trailing semicolon in macro used in expression position diff --git a/tests/ui/lint/unused-qualification-in-derive-expansion.rs b/tests/ui/lint/unused-qualification-in-derive-expansion.rs index b2067e22c4443..bf095c6449d8f 100644 --- a/tests/ui/lint/unused-qualification-in-derive-expansion.rs +++ b/tests/ui/lint/unused-qualification-in-derive-expansion.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: add-impl.rs +//@ ignore-backends: gcc #![forbid(unused_qualifications)] diff --git a/tests/ui/lint/unused/auxiliary/must_use_result_unit_uninhabited_extern_crate.rs b/tests/ui/lint/unused/auxiliary/must_use_result_unit_uninhabited_extern_crate.rs new file mode 100644 index 0000000000000..a193dfa8c47bc --- /dev/null +++ b/tests/ui/lint/unused/auxiliary/must_use_result_unit_uninhabited_extern_crate.rs @@ -0,0 +1,4 @@ +pub enum MyUninhabited {} + +#[non_exhaustive] +pub enum MyUninhabitedNonexhaustive {} diff --git a/tests/ui/lint/unused/break-label-with-parens-147542.rs b/tests/ui/lint/unused/break-label-with-parens-147542.rs new file mode 100644 index 0000000000000..227a00ad40882 --- /dev/null +++ b/tests/ui/lint/unused/break-label-with-parens-147542.rs @@ -0,0 +1,22 @@ +//@ check-pass + +// Regression test for #147542 +// Ensures that we don't suggest removing parens in a break with label and loop +// when the parens are necessary for correct parsing. + +#![warn(unused_parens)] +#![warn(break_with_label_and_loop)] + +fn xyz() -> usize { + 'foo: { + // parens bellow are necessary break of break with label and loop + break 'foo ({ + println!("Hello!"); + 123 + }); + } +} + +fn main() { + xyz(); +} diff --git a/tests/ui/lint/unused/issue-117284-arg-in-macro.rs b/tests/ui/lint/unused/issue-117284-arg-in-macro.rs index eea0f4c594dc8..3d622b6991300 100644 --- a/tests/ui/lint/unused/issue-117284-arg-in-macro.rs +++ b/tests/ui/lint/unused/issue-117284-arg-in-macro.rs @@ -1,7 +1,7 @@ #![deny(unused_variables)] macro_rules! make_var { ($struct:ident, $var:ident) => { - let $var = $struct.$var; + let $var = $struct.$var; //~ ERROR unused variable: `var` }; } @@ -12,6 +12,6 @@ struct MyStruct { fn main() { let s = MyStruct { var: 42 }; - make_var!(s, var); //~ ERROR unused variable: `var` + make_var!(s, var); let a = 1; //~ ERROR unused variable: `a` } diff --git a/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr b/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr index 84efaa4f3687b..b4a6871713c06 100644 --- a/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr +++ b/tests/ui/lint/unused/issue-117284-arg-in-macro.stderr @@ -1,8 +1,11 @@ error: unused variable: `var` - --> $DIR/issue-117284-arg-in-macro.rs:15:18 + --> $DIR/issue-117284-arg-in-macro.rs:4:13 | +LL | let $var = $struct.$var; + | ^^^^ +... LL | make_var!(s, var); - | ^^^ + | ----------------- in this macro invocation | help: `var` is captured in macro and introduced a unused variable --> $DIR/issue-117284-arg-in-macro.rs:4:13 diff --git a/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr index fe2e3afc82ec8..c378b307b8b54 100644 --- a/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/tests/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr @@ -1,27 +1,45 @@ -warning: unused variable: `i_think_continually` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 +warning: variable does not need to be mutable + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 | -LL | let i_think_continually = 2; - | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_i_think_continually` +LL | let mut mut_unused_var = 1; + | ----^^^^^^^^^^^^^^ + | | + | help: remove this `mut` | note: the lint level is defined here --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:5:9 | LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) | ^^^^^^ + = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` + +warning: variable does not need to be mutable + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 + | +LL | let (mut var, unused_var) = (1, 2); + | ----^^^ + | | + | help: remove this `mut` + +warning: unused variable: `i_think_continually` + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:26:9 + | +LL | let i_think_continually = 2; + | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_i_think_continually` + | = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `mut_unused_var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 | LL | let mut mut_unused_var = 1; - | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` + | ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` warning: unused variable: `var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 | LL | let (mut var, unused_var) = (1, 2); - | ^^^ help: if this is intentional, prefix it with an underscore: `_var` + | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_var` warning: unused variable: `unused_var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19 @@ -36,22 +54,13 @@ LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:26 | LL | mut hours_are_suns, - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = note: consider using `_hours_are_suns` instead -warning: value assigned to `hours_are_suns` is never read - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9 - | -LL | hours_are_suns = false; - | ^^^^^^^^^^^^^^ - | - = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - warning: unused variable: `fire` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32 | @@ -94,23 +103,14 @@ warning: unused variable: `case` LL | Tuple(Large::Suit { case }, ()) => {} | ^^^^ help: try ignoring the field: `case: _` -warning: variable does not need to be mutable - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 - | -LL | let mut mut_unused_var = 1; - | ----^^^^^^^^^^^^^^ - | | - | help: remove this `mut` +warning: value assigned to `hours_are_suns` is never read + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:48:9 | - = note: `#[warn(unused_mut)]` implied by `#[warn(unused)]` - -warning: variable does not need to be mutable - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 +LL | hours_are_suns = false; + | ^^^^^^^^^^^^^^^^^^^^^^ | -LL | let (mut var, unused_var) = (1, 2); - | ----^^^ - | | - | help: remove this `mut` + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` warning: 16 warnings emitted diff --git a/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr b/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr index f2e6168998c44..c501aa25f1352 100644 --- a/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr +++ b/tests/ui/lint/unused/issue-54180-unused-ref-field.stderr @@ -11,6 +11,12 @@ LL | #![deny(unused)] | ^^^^^^ = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` +error: unused variable: `x` + --> $DIR/issue-54180-unused-ref-field.rs:29:45 + | +LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum(); + | ^ help: try ignoring the field: `x: _` + error: unused variable: `f1` --> $DIR/issue-54180-unused-ref-field.rs:26:13 | @@ -23,11 +29,5 @@ error: unused variable: `x` LL | Point { y, ref mut x } => y, | ^^^^^^^^^ help: try ignoring the field: `x: _` -error: unused variable: `x` - --> $DIR/issue-54180-unused-ref-field.rs:29:45 - | -LL | let _: i32 = points.iter().map(|Point { x, y }| y).sum(); - | ^ help: try ignoring the field: `x: _` - error: aborting due to 4 previous errors diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index 6106d4cd1bfc9..beb1c0d736b35 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -10,24 +10,18 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ -error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:21:9 +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:13:5 | -LL | a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` error: unused variable: `a` - --> $DIR/lint-unused-variables.rs:67:9 + --> $DIR/lint-unused-variables.rs:21:9 | LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` -error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:13:5 - | -LL | b: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_b` - error: unused variable: `b` --> $DIR/lint-unused-variables.rs:28:9 | @@ -70,5 +64,11 @@ error: unused variable: `b` LL | b: i32, | ^ help: if this is intentional, prefix it with an underscore: `_b` +error: unused variable: `a` + --> $DIR/lint-unused-variables.rs:67:9 + | +LL | a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: aborting due to 11 previous errors diff --git a/tests/ui/lint/unused/must_use-result-unit-uninhabited.rs b/tests/ui/lint/unused/must_use-result-unit-uninhabited.rs new file mode 100644 index 0000000000000..8f63e4a7f8323 --- /dev/null +++ b/tests/ui/lint/unused/must_use-result-unit-uninhabited.rs @@ -0,0 +1,101 @@ +//@ edition: 2024 +//@ aux-crate:dep=must_use_result_unit_uninhabited_extern_crate.rs + +#![deny(unused_must_use)] +#![feature(never_type)] + +use core::ops::{ControlFlow, ControlFlow::Continue}; +use dep::{MyUninhabited, MyUninhabitedNonexhaustive}; + +fn result_unit_unit() -> Result<(), ()> { + Ok(()) +} + +fn result_unit_infallible() -> Result<(), core::convert::Infallible> { + Ok(()) +} + +fn result_unit_never() -> Result<(), !> { + Ok(()) +} + +fn result_unit_myuninhabited() -> Result<(), MyUninhabited> { + Ok(()) +} + +fn result_unit_myuninhabited_nonexhaustive() -> Result<(), MyUninhabitedNonexhaustive> { + Ok(()) +} + +trait AssocType { + type Error; +} + +struct S1; +impl AssocType for S1 { + type Error = !; +} + +struct S2; +impl AssocType for S2 { + type Error = (); +} + +fn result_unit_assoctype(_: AT) -> Result<(), AT::Error> { + Ok(()) +} + +trait UsesAssocType { + type Error; + fn method_use_assoc_type(&self) -> Result<(), Self::Error>; +} + +impl UsesAssocType for S1 { + type Error = !; + fn method_use_assoc_type(&self) -> Result<(), Self::Error> { + Ok(()) + } +} + +impl UsesAssocType for S2 { + type Error = (); + fn method_use_assoc_type(&self) -> Result<(), Self::Error> { + Err(()) + } +} + +fn controlflow_unit() -> ControlFlow<()> { + Continue(()) +} + +fn controlflow_infallible_unit() -> ControlFlow { + Continue(()) +} + +fn controlflow_never() -> ControlFlow { + Continue(()) +} + +fn main() { + result_unit_unit(); //~ ERROR: unused `Result` that must be used + result_unit_infallible(); + result_unit_never(); + result_unit_myuninhabited(); + result_unit_myuninhabited_nonexhaustive(); //~ ERROR: unused `Result` that must be used + result_unit_assoctype(S1); + result_unit_assoctype(S2); //~ ERROR: unused `Result` that must be used + S1.method_use_assoc_type(); + S2.method_use_assoc_type(); //~ ERROR: unused `Result` that must be used + + controlflow_unit(); //~ ERROR: unused `ControlFlow` that must be used + controlflow_infallible_unit(); + controlflow_never(); +} + +trait AssocTypeBeforeMonomorphisation { + type Error; + fn generate(&self) -> Result<(), Self::Error>; + fn process(&self) { + self.generate(); //~ ERROR: unused `Result` that must be used + } +} diff --git a/tests/ui/lint/unused/must_use-result-unit-uninhabited.stderr b/tests/ui/lint/unused/must_use-result-unit-uninhabited.stderr new file mode 100644 index 0000000000000..31d6f6bcf2bc7 --- /dev/null +++ b/tests/ui/lint/unused/must_use-result-unit-uninhabited.stderr @@ -0,0 +1,78 @@ +error: unused `Result` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:80:5 + | +LL | result_unit_unit(); + | ^^^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +note: the lint level is defined here + --> $DIR/must_use-result-unit-uninhabited.rs:4:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = result_unit_unit(); + | +++++++ + +error: unused `Result` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:84:5 + | +LL | result_unit_myuninhabited_nonexhaustive(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = result_unit_myuninhabited_nonexhaustive(); + | +++++++ + +error: unused `Result` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:86:5 + | +LL | result_unit_assoctype(S2); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = result_unit_assoctype(S2); + | +++++++ + +error: unused `Result` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:88:5 + | +LL | S2.method_use_assoc_type(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = S2.method_use_assoc_type(); + | +++++++ + +error: unused `ControlFlow` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:90:5 + | +LL | controlflow_unit(); + | ^^^^^^^^^^^^^^^^^^ + | +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = controlflow_unit(); + | +++++++ + +error: unused `Result` that must be used + --> $DIR/must_use-result-unit-uninhabited.rs:99:9 + | +LL | self.generate(); + | ^^^^^^^^^^^^^^^ + | + = note: this `Result` may be an `Err` variant, which should be handled +help: use `let _ = ...` to ignore the resulting value + | +LL | let _ = self.generate(); + | +++++++ + +error: aborting due to 6 previous errors + diff --git a/tests/ui/lint/unused/unused-assign-148960.rs b/tests/ui/lint/unused/unused-assign-148960.rs new file mode 100644 index 0000000000000..2e51c01398a37 --- /dev/null +++ b/tests/ui/lint/unused/unused-assign-148960.rs @@ -0,0 +1,42 @@ +//@ check-fail +#![deny(unused)] +#![allow(dead_code)] + +fn test_one_extra_assign() { + let mut value = b"0".to_vec(); //~ ERROR value assigned to `value` is never read + value = b"1".to_vec(); + println!("{:?}", value); +} + +fn test_two_extra_assign() { + let mut x = 1; //~ ERROR value assigned to `x` is never read + x = 2; //~ ERROR value assigned to `x` is never read + x = 3; + println!("{}", x); +} + +struct Point { + x: i32, + y: i32, +} + +fn test_indirect_assign() { + let mut p = Point { x: 1, y: 1 }; //~ ERROR value assigned to `p` is never read + p = Point { x: 2, y: 2 }; + p.x = 3; + println!("{}", p.y); +} + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +// testcase for issue #148418 +fn test_unused_variable() { + let mut foo = Foo; //~ ERROR variable `foo` is assigned to, but never used + foo = Foo; //~ ERROR value assigned to `foo` is never read +} + +fn main() {} diff --git a/tests/ui/lint/unused/unused-assign-148960.stderr b/tests/ui/lint/unused/unused-assign-148960.stderr new file mode 100644 index 0000000000000..0e23fabd5f561 --- /dev/null +++ b/tests/ui/lint/unused/unused-assign-148960.stderr @@ -0,0 +1,62 @@ +error: value assigned to `value` is never read + --> $DIR/unused-assign-148960.rs:6:21 + | +LL | let mut value = b"0".to_vec(); + | ^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? +note: the lint level is defined here + --> $DIR/unused-assign-148960.rs:2:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_assignments)]` implied by `#[deny(unused)]` + +error: value assigned to `x` is never read + --> $DIR/unused-assign-148960.rs:12:17 + | +LL | let mut x = 1; + | ^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `x` is never read + --> $DIR/unused-assign-148960.rs:13:5 + | +LL | x = 2; + | ^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `p` is never read + --> $DIR/unused-assign-148960.rs:24:17 + | +LL | let mut p = Point { x: 1, y: 1 }; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: variable `foo` is assigned to, but never used + --> $DIR/unused-assign-148960.rs:38:9 + | +LL | let mut foo = Foo; + | ^^^^^^^ + | + = note: consider using `_foo` instead + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` +help: you might have meant to pattern match on the similarly named struct `Foo` + | +LL - let mut foo = Foo; +LL + let Foo = Foo; + | + +error: value assigned to `foo` is never read + --> $DIR/unused-assign-148960.rs:39:5 + | +LL | foo = Foo; + | ^^^ + | + = help: maybe it is overwritten before being read? + +error: aborting due to 6 previous errors + diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 3a3b450f3c55f..fa2c9e59a4184 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -53,18 +53,6 @@ note: attribute also specified here LL | #![no_builtins] | ^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:44:5 - | -LL | #[macro_export] - | ^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:43:5 - | -LL | #[macro_export] - | ^^^^^^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:41:1 | @@ -77,6 +65,18 @@ note: attribute also specified here LL | #[macro_use] | ^^^^^^^^^^^^ +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:44:5 + | +LL | #[macro_export] + | ^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:43:5 + | +LL | #[macro_export] + | ^^^^^^^^^^^^^^^ + error: unused attribute --> $DIR/unused-attr-duplicate.rs:51:1 | diff --git a/tests/ui/lint/unused/unused-attr-macro-rules.stderr b/tests/ui/lint/unused/unused-attr-macro-rules.stderr index 0c6825026ed3b..e251ec65622ee 100644 --- a/tests/ui/lint/unused/unused-attr-macro-rules.stderr +++ b/tests/ui/lint/unused/unused-attr-macro-rules.stderr @@ -5,7 +5,7 @@ LL | #[macro_use] | ^^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[macro_use]` can be applied to modules, extern crates, and crates + = help: `#[macro_use]` can be applied to crates, extern crates, and modules note: the lint level is defined here --> $DIR/unused-attr-macro-rules.rs:1:9 | diff --git a/tests/ui/lint/unused/unused-var-in-unreachable-code.rs b/tests/ui/lint/unused/unused-var-in-unreachable-code.rs new file mode 100644 index 0000000000000..39c5e0315d9ce --- /dev/null +++ b/tests/ui/lint/unused/unused-var-in-unreachable-code.rs @@ -0,0 +1,46 @@ +//@ check-pass + +#![allow(unreachable_code)] +#![allow(dead_code)] +#![warn(unused_variables)] + +fn after_todo() { + todo!("not implemented"); + + // This should not warn - the code is unreachable + let a = 1; + if a < 2 { + eprintln!("a: {}", a); + } +} + +fn after_panic() { + panic!("oops"); + + // This should not warn - the code is unreachable + let b = 2; + println!("{}", b); +} + +fn after_unimplemented() { + unimplemented!(); + + // This should not warn - the code is unreachable + let c = 3; + println!("{}", c); +} + +fn after_unreachable() { + unsafe { std::hint::unreachable_unchecked() } + + // This should not warn - the code is unreachable + let d = 4; + println!("{}", d); +} + +fn reachable_unused() { + // This SHOULD warn - the code is reachable + let e = 5; //~ WARN unused variable: `e` +} + +fn main() {} diff --git a/tests/ui/lint/unused/unused-var-in-unreachable-code.stderr b/tests/ui/lint/unused/unused-var-in-unreachable-code.stderr new file mode 100644 index 0000000000000..dfc2f9c8fc56a --- /dev/null +++ b/tests/ui/lint/unused/unused-var-in-unreachable-code.stderr @@ -0,0 +1,14 @@ +warning: unused variable: `e` + --> $DIR/unused-var-in-unreachable-code.rs:43:9 + | +LL | let e = 5; + | ^ help: if this is intentional, prefix it with an underscore: `_e` + | +note: the lint level is defined here + --> $DIR/unused-var-in-unreachable-code.rs:5:9 + | +LL | #![warn(unused_variables)] + | ^^^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 001ec52ddd9e7..9b9a6a9c9f3d1 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -5,7 +5,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions note: the lint level is defined here --> $DIR/unused_attributes-must_use.rs:4:9 | @@ -19,7 +19,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on modules --> $DIR/unused_attributes-must_use.rs:11:1 @@ -28,7 +28,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on use statements --> $DIR/unused_attributes-must_use.rs:15:1 @@ -37,7 +37,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on constants --> $DIR/unused_attributes-must_use.rs:19:1 @@ -46,7 +46,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on statics --> $DIR/unused_attributes-must_use.rs:22:1 @@ -55,7 +55,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on inherent impl blocks --> $DIR/unused_attributes-must_use.rs:40:1 @@ -64,7 +64,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on foreign modules --> $DIR/unused_attributes-must_use.rs:55:1 @@ -73,7 +73,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on foreign statics --> $DIR/unused_attributes-must_use.rs:59:5 @@ -82,7 +82,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on type aliases --> $DIR/unused_attributes-must_use.rs:73:1 @@ -91,7 +91,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on function params --> $DIR/unused_attributes-must_use.rs:77:8 @@ -100,7 +100,7 @@ LL | fn qux<#[must_use] T>(_: T) {} | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on associated consts --> $DIR/unused_attributes-must_use.rs:82:5 @@ -109,7 +109,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on associated types --> $DIR/unused_attributes-must_use.rs:85:5 @@ -118,7 +118,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on trait impl blocks --> $DIR/unused_attributes-must_use.rs:95:1 @@ -127,7 +127,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on trait methods in impl blocks --> $DIR/unused_attributes-must_use.rs:100:5 @@ -136,7 +136,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to data types, functions, unions, required trait methods, provided trait methods, inherent methods, foreign functions, and traits + = help: `#[must_use]` can be applied to data types, foreign functions, functions, inherent methods, provided trait methods, required trait methods, traits, and unions error: `#[must_use]` attribute cannot be used on trait aliases --> $DIR/unused_attributes-must_use.rs:107:1 @@ -145,7 +145,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on macro defs --> $DIR/unused_attributes-must_use.rs:111:1 @@ -154,7 +154,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on statements --> $DIR/unused_attributes-must_use.rs:120:5 @@ -163,7 +163,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on closures --> $DIR/unused_attributes-must_use.rs:125:13 @@ -172,7 +172,7 @@ LL | let x = #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to methods, data types, functions, unions, foreign functions, and traits + = help: `#[must_use]` can be applied to data types, foreign functions, functions, methods, traits, and unions error: `#[must_use]` attribute cannot be used on match arms --> $DIR/unused_attributes-must_use.rs:148:9 @@ -181,7 +181,7 @@ LL | #[must_use] | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on struct fields --> $DIR/unused_attributes-must_use.rs:157:28 @@ -190,7 +190,7 @@ LL | let s = PatternField { #[must_use] foo: 123 }; | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: `#[must_use]` attribute cannot be used on pattern fields --> $DIR/unused_attributes-must_use.rs:159:24 @@ -199,7 +199,7 @@ LL | let PatternField { #[must_use] foo } = s; | ^^^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[must_use]` can be applied to functions, data types, unions, and traits + = help: `#[must_use]` can be applied to data types, functions, traits, and unions error: unused `X` that must be used --> $DIR/unused_attributes-must_use.rs:130:5 diff --git a/tests/ui/lint/unused_parens_follow_ident.fixed b/tests/ui/lint/unused_parens_follow_ident.fixed new file mode 100644 index 0000000000000..e61b287e5a648 --- /dev/null +++ b/tests/ui/lint/unused_parens_follow_ident.fixed @@ -0,0 +1,17 @@ +//@ run-rustfix + +#![deny(unused_parens)] + +macro_rules! wrap { + ($name:ident $arg:expr) => { + $name($arg); + }; +} + +fn main() { + wrap!(unary routine()); //~ ERROR unnecessary parentheses around function argument + wrap!(unary routine()); //~ ERROR unnecessary parentheses around function argument +} + +fn unary(_: ()) {} +fn routine() {} diff --git a/tests/ui/lint/unused_parens_follow_ident.rs b/tests/ui/lint/unused_parens_follow_ident.rs new file mode 100644 index 0000000000000..32a163345b2cc --- /dev/null +++ b/tests/ui/lint/unused_parens_follow_ident.rs @@ -0,0 +1,17 @@ +//@ run-rustfix + +#![deny(unused_parens)] + +macro_rules! wrap { + ($name:ident $arg:expr) => { + $name($arg); + }; +} + +fn main() { + wrap!(unary(routine())); //~ ERROR unnecessary parentheses around function argument + wrap!(unary (routine())); //~ ERROR unnecessary parentheses around function argument +} + +fn unary(_: ()) {} +fn routine() {} diff --git a/tests/ui/lint/unused_parens_follow_ident.stderr b/tests/ui/lint/unused_parens_follow_ident.stderr new file mode 100644 index 0000000000000..ce7bb26778c0d --- /dev/null +++ b/tests/ui/lint/unused_parens_follow_ident.stderr @@ -0,0 +1,31 @@ +error: unnecessary parentheses around function argument + --> $DIR/unused_parens_follow_ident.rs:12:16 + | +LL | wrap!(unary(routine())); + | ^ ^ + | +note: the lint level is defined here + --> $DIR/unused_parens_follow_ident.rs:3:9 + | +LL | #![deny(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - wrap!(unary(routine())); +LL + wrap!(unary routine()); + | + +error: unnecessary parentheses around function argument + --> $DIR/unused_parens_follow_ident.rs:13:17 + | +LL | wrap!(unary (routine())); + | ^ ^ + | +help: remove these parentheses + | +LL - wrap!(unary (routine())); +LL + wrap!(unary routine()); + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index 558c2260fcede..4dc414b7a65db 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -403,23 +403,23 @@ mod foo { "rendered": null } ], - "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror[E0412]\u001b[0m\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m$DIR/use_suggestion_json.rs:12:12\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m let x: Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9m^^^^\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;9mnot found in this scope\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: consider importing one of these structs\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::binary_heap::Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::btree_map::Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::btree_set::Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m\u001b[1m\u001b[38;5;12mLL\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ use std::collections::hash_map::Iter;\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m -\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m= \u001b[0m\u001b[0mand 9 other candidates\u001b[0m + "rendered": "\u001b[1m\u001b[91merror[E0412]\u001b[0m\u001b[1m: cannot find type `Iter` in this scope\u001b[0m + \u001b[1m\u001b[94m--> \u001b[0m$DIR/use_suggestion_json.rs:12:12 + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[94mLL\u001b[0m \u001b[1m\u001b[94m|\u001b[0m let x: Iter; + \u001b[1m\u001b[94m|\u001b[0m \u001b[1m\u001b[91m^^^^\u001b[0m \u001b[1m\u001b[91mnot found in this scope\u001b[0m + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[96mhelp\u001b[0m: consider importing one of these structs + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[94mLL\u001b[0m \u001b[92m+ use std::collections::binary_heap::Iter;\u001b[0m + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[94mLL\u001b[0m \u001b[92m+ use std::collections::btree_map::Iter;\u001b[0m + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[94mLL\u001b[0m \u001b[92m+ use std::collections::btree_set::Iter;\u001b[0m + \u001b[1m\u001b[94m|\u001b[0m +\u001b[1m\u001b[94mLL\u001b[0m \u001b[92m+ use std::collections::hash_map::Iter;\u001b[0m + \u001b[1m\u001b[94m|\u001b[0m + \u001b[1m\u001b[94m= \u001b[0mand 9 other candidates " } @@ -430,7 +430,7 @@ mod foo { "level": "error", "spans": [], "children": [], - "rendered": "\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: aborting due to 1 previous error\u001b[0m + "rendered": "\u001b[1m\u001b[91merror\u001b[0m\u001b[1m: aborting due to 1 previous error\u001b[0m " } @@ -441,6 +441,6 @@ mod foo { "level": "failure-note", "spans": [], "children": [], - "rendered": "\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m + "rendered": "\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m " } diff --git a/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr index fcce1db7a9ac0..bdeaabbc253f4 100644 --- a/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr +++ b/tests/ui/lint/warn-unused-inline-on-fn-prototypes.stderr @@ -5,7 +5,7 @@ LL | #[inline] | ^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[inline]` can be applied to functions, inherent methods, provided trait methods, trait methods in impl blocks, and closures + = help: `#[inline]` can be applied to closures, functions, inherent methods, provided trait methods, and trait methods in impl blocks note: the lint level is defined here --> $DIR/warn-unused-inline-on-fn-prototypes.rs:1:9 | @@ -19,7 +19,7 @@ LL | #[inline] | ^^^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = help: `#[inline]` can be applied to methods, functions, and closures + = help: `#[inline]` can be applied to closures, functions, and methods error: aborting due to 2 previous errors diff --git a/tests/ui/liveness/liveness-asm.stderr b/tests/ui/liveness/liveness-asm.stderr index 57d89e44dcb86..ca1c07046d0ef 100644 --- a/tests/ui/liveness/liveness-asm.stderr +++ b/tests/ui/liveness/liveness-asm.stderr @@ -1,8 +1,8 @@ warning: value assigned to `src` is never read - --> $DIR/liveness-asm.rs:14:32 + --> $DIR/liveness-asm.rs:14:5 | LL | asm!("/*{0}*/", inout(reg) src); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? note: the lint level is defined here @@ -12,10 +12,10 @@ LL | #![warn(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ warning: value assigned to `src` is never read - --> $DIR/liveness-asm.rs:24:39 + --> $DIR/liveness-asm.rs:24:5 | LL | asm!("/*{0}*/", inout(reg) src => src); - | ^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? diff --git a/tests/ui/liveness/liveness-consts.rs b/tests/ui/liveness/liveness-consts.rs index 40d30fb9113a9..7e56bf8c2cda4 100644 --- a/tests/ui/liveness/liveness-consts.rs +++ b/tests/ui/liveness/liveness-consts.rs @@ -4,16 +4,18 @@ pub static A: i32 = { let mut i = 0; - let mut a = 0; //~ WARN variable `a` is assigned to, but never used + let mut a = 0; + //~^ WARN variable `a` is assigned to, but never used while i < 10 { i += 1; a += 1; + //~^ WARN value assigned to `a` is never read } i }; pub const B: u32 = { - let mut b = 1; + let mut b = 1; //~ WARN value assigned to `b` is never read b += 1; //~ WARN value assigned to `b` is never read b = 42; b diff --git a/tests/ui/liveness/liveness-consts.stderr b/tests/ui/liveness/liveness-consts.stderr index 34ce39473379e..2d2750fbaddff 100644 --- a/tests/ui/liveness/liveness-consts.stderr +++ b/tests/ui/liveness/liveness-consts.stderr @@ -1,5 +1,5 @@ warning: unused variable: `e` - --> $DIR/liveness-consts.rs:24:13 + --> $DIR/liveness-consts.rs:26:13 | LL | let e = 1; | ^ help: if this is intentional, prefix it with an underscore: `_e` @@ -12,53 +12,69 @@ LL | #![warn(unused)] = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `s` - --> $DIR/liveness-consts.rs:33:24 + --> $DIR/liveness-consts.rs:35:24 | LL | pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { | ^ help: if this is intentional, prefix it with an underscore: `_s` warning: unused variable: `z` - --> $DIR/liveness-consts.rs:33:55 + --> $DIR/liveness-consts.rs:35:55 | LL | pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { | ^ help: if this is intentional, prefix it with an underscore: `_z` warning: variable `a` is assigned to, but never used - --> $DIR/liveness-consts.rs:7:13 + --> $DIR/liveness-consts.rs:7:9 | LL | let mut a = 0; - | ^ + | ^^^^^ | = note: consider using `_a` instead +warning: value assigned to `a` is never read + --> $DIR/liveness-consts.rs:11:9 + | +LL | a += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` + warning: value assigned to `b` is never read - --> $DIR/liveness-consts.rs:17:5 + --> $DIR/liveness-consts.rs:18:17 + | +LL | let mut b = 1; + | ^ + | + = help: maybe it is overwritten before being read? + +warning: value assigned to `b` is never read + --> $DIR/liveness-consts.rs:19:5 | LL | b += 1; - | ^ + | ^^^^^^ | = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` warning: unused variable: `z` - --> $DIR/liveness-consts.rs:60:13 + --> $DIR/liveness-consts.rs:62:13 | LL | let z = 42; | ^ help: if this is intentional, prefix it with an underscore: `_z` warning: value assigned to `t` is never read - --> $DIR/liveness-consts.rs:42:9 + --> $DIR/liveness-consts.rs:44:9 | LL | t = t + t; - | ^ + | ^^^^^^^^^ | = help: maybe it is overwritten before being read? warning: unused variable: `w` - --> $DIR/liveness-consts.rs:49:13 + --> $DIR/liveness-consts.rs:51:13 | LL | let w = 10; | ^ help: if this is intentional, prefix it with an underscore: `_w` -warning: 8 warnings emitted +warning: 10 warnings emitted diff --git a/tests/ui/liveness/liveness-dead.stderr b/tests/ui/liveness/liveness-dead.stderr index de6d5bd993d62..4f7dda49cd03e 100644 --- a/tests/ui/liveness/liveness-dead.stderr +++ b/tests/ui/liveness/liveness-dead.stderr @@ -1,8 +1,8 @@ error: value assigned to `x` is never read - --> $DIR/liveness-dead.rs:9:13 + --> $DIR/liveness-dead.rs:9:24 | LL | let mut x: isize = 3; - | ^ + | ^ | = help: maybe it is overwritten before being read? note: the lint level is defined here @@ -15,15 +15,15 @@ error: value assigned to `x` is never read --> $DIR/liveness-dead.rs:17:5 | LL | x = 4; - | ^ + | ^^^^^ | = help: maybe it is overwritten before being read? error: value passed to `x` is never read - --> $DIR/liveness-dead.rs:20:11 + --> $DIR/liveness-dead.rs:20:7 | LL | fn f4(mut x: i32) { - | ^ + | ^^^^^ | = help: maybe it is overwritten before being read? @@ -31,7 +31,7 @@ error: value assigned to `x` is never read --> $DIR/liveness-dead.rs:27:5 | LL | x = 4; - | ^ + | ^^^^^ | = help: maybe it is overwritten before being read? diff --git a/tests/ui/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs index 49e7044aeda1f..a291d2489695f 100644 --- a/tests/ui/liveness/liveness-unused.rs +++ b/tests/ui/liveness/liveness-unused.rs @@ -39,6 +39,7 @@ fn f3b() { //~^ ERROR variable `z` is assigned to, but never used loop { z += 4; + //~^ ERROR value assigned to `z` is never read } } @@ -46,6 +47,7 @@ fn f3b() { fn f3c() { let mut z = 3; loop { z += 4; } + //~^ ERROR value assigned to `z` is never read } #[allow(unused_variables)] @@ -55,6 +57,16 @@ fn f3d() { x += 4; } +fn f3e() { + let a = 13; + let mut z = 3; + //~^ ERROR variable `z` is assigned to, but never used + loop { + z += a; + //~^ ERROR value assigned to `z` is never read + } +} + fn f4() { match Some(3) { Some(i) => { @@ -68,7 +80,15 @@ enum tri { a(isize), b(isize), c(isize) } -fn f4b() -> isize { +fn f4b() { + match tri::a(3) { + tri::a(i) | tri::b(i) | tri::c(i) => { + //~^ ERROR unused variable: `i` + } + } +} + +fn f4c() -> isize { match tri::a(3) { tri::a(i) | tri::b(i) | tri::c(i) => { i @@ -76,6 +96,13 @@ fn f4b() -> isize { } } +fn f4d() { + match tri::a(3) { + tri::a(i) | tri::b(i) | tri::c(i) if i == 0 => {} + _ => {} + } +} + fn f5a() { for x in 1..10 { } //~^ ERROR unused variable: `x` @@ -138,10 +165,92 @@ fn f7() { drop(a); } +fn f8(a: u32) { + let _ = a; +} + +fn f9() { + let mut a = 10; + //~^ ERROR variable `a` is assigned to, but never used + let b = 13; + let c = 13; + let d = 13; + let e = 13; + let f = 13; + let g = 13; + let h = 13; + + a += b; + //~^ ERROR value assigned to `a` is never read + a -= c; + //~^ ERROR value assigned to `a` is never read + a *= d; + //~^ ERROR value assigned to `a` is never read + a /= e; + //~^ ERROR value assigned to `a` is never read + a |= f; + //~^ ERROR value assigned to `a` is never read + a &= g; + //~^ ERROR value assigned to `a` is never read + a %= h; + //~^ ERROR value assigned to `a` is never read +} + +fn f9b() { + let mut a = 10; + let b = 13; + let c = 13; + let d = 13; + let e = 13; + let f = 13; + let g = 13; + let h = 13; + + a += b; + a -= c; + a *= d; + a /= e; + a |= f; + a &= g; + a %= h; + + let _ = a; +} + +fn f9c() { + let mut a = 10.; + //~^ ERROR variable `a` is assigned to, but never used + let b = 13.; + let c = 13.; + let d = 13.; + let e = 13.; + let f = 13.; + + a += b; + //~^ ERROR value assigned to `a` is never read + a -= c; + //~^ ERROR value assigned to `a` is never read + a *= d; + //~^ ERROR value assigned to `a` is never read + a /= e; + //~^ ERROR value assigned to `a` is never read + a %= f; + //~^ ERROR value assigned to `a` is never read +} + +fn f10(mut a: T, b: T) { + //~^ ERROR variable `a` is assigned to, but never used + a = b; + //~^ ERROR value assigned to `a` is never read +} + +fn f10b(mut a: Box, b: Box) { //~ ERROR variable `a` is assigned to, but never used + a = b; //~ ERROR value assigned to `a` is never read +} + // unused params warnings are not needed for intrinsic functions without bodies #[rustc_intrinsic] unsafe fn simd_shuffle(a: T, b: T, i: I) -> U; - fn main() { } diff --git a/tests/ui/liveness/liveness-unused.stderr b/tests/ui/liveness/liveness-unused.stderr index a69fc10dff271..f56ca7823e165 100644 --- a/tests/ui/liveness/liveness-unused.stderr +++ b/tests/ui/liveness/liveness-unused.stderr @@ -1,5 +1,5 @@ warning: unreachable statement - --> $DIR/liveness-unused.rs:93:9 + --> $DIR/liveness-unused.rs:120:9 | LL | continue; | -------- any code following this expression is unreachable @@ -44,10 +44,10 @@ LL | let x = 3; | ^ help: if this is intentional, prefix it with an underscore: `_x` error: variable `x` is assigned to, but never used - --> $DIR/liveness-unused.rs:31:13 + --> $DIR/liveness-unused.rs:31:9 | LL | let mut x = 3; - | ^ + | ^^^^^ | = note: consider using `_x` instead @@ -55,7 +55,7 @@ error: value assigned to `x` is never read --> $DIR/liveness-unused.rs:33:5 | LL | x += 4; - | ^ + | ^^^^^^ | = help: maybe it is overwritten before being read? note: the lint level is defined here @@ -65,39 +65,82 @@ LL | #![deny(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ error: variable `z` is assigned to, but never used - --> $DIR/liveness-unused.rs:38:13 + --> $DIR/liveness-unused.rs:38:9 | LL | let mut z = 3; - | ^ + | ^^^^^ | = note: consider using `_z` instead +error: value assigned to `z` is never read + --> $DIR/liveness-unused.rs:41:9 + | +LL | z += 4; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `z` is never read + --> $DIR/liveness-unused.rs:49:12 + | +LL | loop { z += 4; } + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: variable `z` is assigned to, but never used + --> $DIR/liveness-unused.rs:62:9 + | +LL | let mut z = 3; + | ^^^^^ + | + = note: consider using `_z` instead + +error: value assigned to `z` is never read + --> $DIR/liveness-unused.rs:65:9 + | +LL | z += a; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + error: unused variable: `i` - --> $DIR/liveness-unused.rs:60:12 + --> $DIR/liveness-unused.rs:72:12 | LL | Some(i) => { | ^ help: if this is intentional, prefix it with an underscore: `_i` +error: unused variable: `i` + --> $DIR/liveness-unused.rs:85:14 + | +LL | tri::a(i) | tri::b(i) | tri::c(i) => { + | ^ ^ ^ + | +help: if this is intentional, prefix it with an underscore + | +LL | tri::a(_i) | tri::b(_i) | tri::c(_i) => { + | + + + + error: unused variable: `x` - --> $DIR/liveness-unused.rs:80:9 + --> $DIR/liveness-unused.rs:107:9 | LL | for x in 1..10 { } | ^ help: if this is intentional, prefix it with an underscore: `_x` error: unused variable: `x` - --> $DIR/liveness-unused.rs:85:10 + --> $DIR/liveness-unused.rs:112:10 | LL | for (x, _) in [1, 2, 3].iter().enumerate() { } | ^ help: if this is intentional, prefix it with an underscore: `_x` error: unused variable: `x` - --> $DIR/liveness-unused.rs:90:13 + --> $DIR/liveness-unused.rs:117:13 | LL | for (_, x) in [1, 2, 3].iter().enumerate() { | ^ help: if this is intentional, prefix it with an underscore: `_x` error: variable `x` is assigned to, but never used - --> $DIR/liveness-unused.rs:113:9 + --> $DIR/liveness-unused.rs:140:9 | LL | let x; | ^ @@ -105,12 +148,156 @@ LL | let x; = note: consider using `_x` instead error: value assigned to `x` is never read - --> $DIR/liveness-unused.rs:117:9 + --> $DIR/liveness-unused.rs:144:9 | LL | x = 0; - | ^ + | ^^^^^ + | + = help: maybe it is overwritten before being read? + +error: variable `a` is assigned to, but never used + --> $DIR/liveness-unused.rs:173:9 + | +LL | let mut a = 10; + | ^^^^^ + | + = note: consider using `_a` instead + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:183:5 + | +LL | a += b; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:185:5 + | +LL | a -= c; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:187:5 + | +LL | a *= d; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:189:5 + | +LL | a /= e; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:191:5 + | +LL | a |= f; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:193:5 + | +LL | a &= g; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:195:5 + | +LL | a %= h; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: variable `a` is assigned to, but never used + --> $DIR/liveness-unused.rs:221:9 + | +LL | let mut a = 10.; + | ^^^^^ + | + = note: consider using `_a` instead + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:229:5 + | +LL | a += b; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:231:5 + | +LL | a -= c; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:233:5 + | +LL | a *= d; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:235:5 + | +LL | a /= e; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:237:5 + | +LL | a %= f; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +error: variable `a` is assigned to, but never used + --> $DIR/liveness-unused.rs:241:11 + | +LL | fn f10(mut a: T, b: T) { + | ^^^^^ + | + = note: consider using `_a` instead + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:243:5 + | +LL | a = b; + | ^ + | + = help: maybe it is overwritten before being read? + +error: variable `a` is assigned to, but never used + --> $DIR/liveness-unused.rs:247:12 + | +LL | fn f10b(mut a: Box, b: Box) { + | ^^^^^ + | + = note: consider using `_a` instead + +error: value assigned to `a` is never read + --> $DIR/liveness-unused.rs:248:5 + | +LL | a = b; + | ^ | = help: maybe it is overwritten before being read? -error: aborting due to 13 previous errors; 1 warning emitted +error: aborting due to 36 previous errors; 1 warning emitted diff --git a/tests/ui/liveness/liveness-upvars.rs b/tests/ui/liveness/liveness-upvars.rs index f76efba3e6b3a..be58b48a40576 100644 --- a/tests/ui/liveness/liveness-upvars.rs +++ b/tests/ui/liveness/liveness-upvars.rs @@ -7,8 +7,8 @@ pub fn unintentional_copy_one() { let mut last = None; let mut f = move |s| { - last = Some(s); //~ WARN value assigned to `last` is never read - //~| WARN unused variable: `last` + last = Some(s); //~ WARN value captured by `last` is never read + //~| WARN value assigned to `last` is never read }; f("a"); f("b"); @@ -19,7 +19,9 @@ pub fn unintentional_copy_one() { pub fn unintentional_copy_two() { let mut sum = 0; (1..10).for_each(move |x| { - sum += x; //~ WARN unused variable: `sum` + sum += x; + //~^ WARN value captured by `sum` is never read + //~| WARN value assigned to `sum` is never read }); dbg!(sum); } @@ -39,11 +41,14 @@ pub fn f() { // Read and written to, but never actually used. let _ = move || { - c += 1; //~ WARN unused variable: `c` + c += 1; + //~^ WARN value captured by `c` is never read + //~| WARN value assigned to `c` is never read }; let _ = async move { - c += 1; //~ WARN value assigned to `c` is never read - //~| WARN unused variable: `c` + c += 1; + //~^ WARN value captured by `c` is never read + //~| WARN value assigned to `c` is never read }; let _ = move || { @@ -74,8 +79,8 @@ pub fn nested() { d = Some("d2"); }; let _ = move || { - e = Some("e1"); //~ WARN value assigned to `e` is never read - //~| WARN unused variable: `e` + e = Some("e1"); //~ WARN value captured by `e` is never read + //~| WARN value assigned to `e` is never read e = Some("e2"); //~ WARN value assigned to `e` is never read }; }; @@ -84,7 +89,8 @@ pub fn nested() { pub fn g(mut v: T) { let _ = |r| { if r { - v = T::default(); //~ WARN value assigned to `v` is never read + v = T::default(); + //~^ WARN value assigned to `v` is never read } else { drop(v); } @@ -96,8 +102,8 @@ pub fn h() { let _ = move |b| { loop { if b { - z = T::default(); //~ WARN value assigned to `z` is never read - //~| WARN unused variable: `z` + z = T::default(); //~ WARN value captured by `z` is never read + //~| WARN value assigned to `z` is never read } else { return; } @@ -123,7 +129,7 @@ pub fn async_coroutine() { let _ = async move { state = 4; //~ WARN value assigned to `state` is never read - //~| WARN unused variable: `state` + //~| WARN value captured by `state` is never read yield_now().await; state = 5; //~ WARN value assigned to `state` is never read }; @@ -141,4 +147,21 @@ pub fn coroutine() { }; } +pub fn panics() { + use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind}; + + let mut panic = true; + + // `a` can be called again, even if it has panicked at an earlier run. + let mut a = || { + if panic { + panic = false; + resume_unwind(Box::new(())) + } + }; + + catch_unwind(AssertUnwindSafe(|| a())).ok(); + a(); +} + fn main() {} diff --git a/tests/ui/liveness/liveness-upvars.stderr b/tests/ui/liveness/liveness-upvars.stderr index 82f62371ec59d..cfed2830164ad 100644 --- a/tests/ui/liveness/liveness-upvars.stderr +++ b/tests/ui/liveness/liveness-upvars.stderr @@ -1,10 +1,10 @@ -warning: value assigned to `last` is never read +warning: value captured by `last` is never read --> $DIR/liveness-upvars.rs:10:9 | LL | last = Some(s); | ^^^^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? note: the lint level is defined here --> $DIR/liveness-upvars.rs:4:9 | @@ -12,16 +12,15 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` -warning: unused variable: `last` +warning: value assigned to `last` is never read --> $DIR/liveness-upvars.rs:10:9 | LL | last = Some(s); - | ^^^^ + | ^^^^^^^^^^^^^^ | - = help: did you mean to capture by reference instead? - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` + = help: maybe it is overwritten before being read? -warning: unused variable: `sum` +warning: value captured by `sum` is never read --> $DIR/liveness-upvars.rs:22:9 | LL | sum += x; @@ -29,24 +28,32 @@ LL | sum += x; | = help: did you mean to capture by reference instead? -warning: value captured by `c` is never read - --> $DIR/liveness-upvars.rs:32:9 +warning: value assigned to `sum` is never read + --> $DIR/liveness-upvars.rs:22:9 | -LL | c = 1; - | ^ +LL | sum += x; + | ^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? -warning: value captured by `c` is never read - --> $DIR/liveness-upvars.rs:36:9 +warning: value assigned to `c` is never read + --> $DIR/liveness-upvars.rs:69:9 | -LL | c = 1; - | ^ +LL | c += 1; + | ^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? -warning: unused variable: `c` - --> $DIR/liveness-upvars.rs:42:9 +warning: value assigned to `c` is never read + --> $DIR/liveness-upvars.rs:63:9 + | +LL | c += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `c` is never read + --> $DIR/liveness-upvars.rs:49:9 | LL | c += 1; | ^ @@ -54,15 +61,15 @@ LL | c += 1; = help: did you mean to capture by reference instead? warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:45:9 + --> $DIR/liveness-upvars.rs:49:9 | LL | c += 1; - | ^ + | ^^^^^^ | = help: maybe it is overwritten before being read? -warning: unused variable: `c` - --> $DIR/liveness-upvars.rs:45:9 +warning: value captured by `c` is never read + --> $DIR/liveness-upvars.rs:44:9 | LL | c += 1; | ^ @@ -70,116 +77,124 @@ LL | c += 1; = help: did you mean to capture by reference instead? warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:58:9 + --> $DIR/liveness-upvars.rs:44:9 | LL | c += 1; - | ^ + | ^^^^^^ | = help: maybe it is overwritten before being read? -warning: value assigned to `c` is never read - --> $DIR/liveness-upvars.rs:64:9 +warning: value captured by `c` is never read + --> $DIR/liveness-upvars.rs:38:9 | -LL | c += 1; +LL | c = 1; | ^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? -warning: value assigned to `d` is never read - --> $DIR/liveness-upvars.rs:73:13 +warning: value captured by `c` is never read + --> $DIR/liveness-upvars.rs:34:9 | -LL | d = Some("d1"); +LL | c = 1; + | ^ + | + = help: did you mean to capture by reference instead? + +warning: value captured by `e` is never read + --> $DIR/liveness-upvars.rs:82:13 + | +LL | e = Some("e1"); | ^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? warning: value assigned to `e` is never read - --> $DIR/liveness-upvars.rs:77:13 + --> $DIR/liveness-upvars.rs:82:13 | LL | e = Some("e1"); - | ^ + | ^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? warning: value assigned to `e` is never read - --> $DIR/liveness-upvars.rs:79:13 + --> $DIR/liveness-upvars.rs:84:13 | LL | e = Some("e2"); - | ^ + | ^^^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? -warning: unused variable: `e` - --> $DIR/liveness-upvars.rs:77:13 +warning: value assigned to `d` is never read + --> $DIR/liveness-upvars.rs:78:13 | -LL | e = Some("e1"); - | ^ +LL | d = Some("d1"); + | ^^^^^^^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? warning: value assigned to `v` is never read - --> $DIR/liveness-upvars.rs:87:13 + --> $DIR/liveness-upvars.rs:92:13 | LL | v = T::default(); | ^ | = help: maybe it is overwritten before being read? -warning: value assigned to `z` is never read - --> $DIR/liveness-upvars.rs:99:17 +warning: value captured by `z` is never read + --> $DIR/liveness-upvars.rs:105:17 | LL | z = T::default(); | ^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? -warning: unused variable: `z` - --> $DIR/liveness-upvars.rs:99:17 +warning: value assigned to `z` is never read + --> $DIR/liveness-upvars.rs:105:17 | LL | z = T::default(); - | ^ + | ^^^^^^^^^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? -warning: value assigned to `state` is never read - --> $DIR/liveness-upvars.rs:125:9 +warning: value captured by `state` is never read + --> $DIR/liveness-upvars.rs:131:9 | LL | state = 4; | ^^^^^ | - = help: maybe it is overwritten before being read? + = help: did you mean to capture by reference instead? warning: value assigned to `state` is never read - --> $DIR/liveness-upvars.rs:128:9 + --> $DIR/liveness-upvars.rs:131:9 | -LL | state = 5; - | ^^^^^ +LL | state = 4; + | ^^^^^^^^^ | = help: maybe it is overwritten before being read? -warning: unused variable: `state` - --> $DIR/liveness-upvars.rs:125:9 +warning: value assigned to `state` is never read + --> $DIR/liveness-upvars.rs:134:9 | -LL | state = 4; - | ^^^^^ +LL | state = 5; + | ^^^^^^^^^ | - = help: did you mean to capture by reference instead? + = help: maybe it is overwritten before being read? warning: value assigned to `s` is never read - --> $DIR/liveness-upvars.rs:137:9 + --> $DIR/liveness-upvars.rs:143:9 | LL | s = 1; - | ^ + | ^^^^^ | = help: maybe it is overwritten before being read? warning: value assigned to `s` is never read - --> $DIR/liveness-upvars.rs:139:9 + --> $DIR/liveness-upvars.rs:145:9 | LL | s = yield (); - | ^ + | ^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? -warning: 22 warnings emitted +warning: 24 warnings emitted diff --git a/tests/ui/lto/debuginfo-lto-alloc.rs b/tests/ui/lto/debuginfo-lto-alloc.rs index d6855f8760d52..7c82d978a0753 100644 --- a/tests/ui/lto/debuginfo-lto-alloc.rs +++ b/tests/ui/lto/debuginfo-lto-alloc.rs @@ -12,6 +12,7 @@ //@ compile-flags: --test -C debuginfo=2 -C lto=fat //@ no-prefer-dynamic //@ incremental +//@ ignore-backends: gcc extern crate alloc; diff --git a/tests/ui/lto/debuginfo-lto.rs b/tests/ui/lto/debuginfo-lto.rs index f189a1df05673..6d8b836235cc5 100644 --- a/tests/ui/lto/debuginfo-lto.rs +++ b/tests/ui/lto/debuginfo-lto.rs @@ -7,6 +7,7 @@ //@ aux-build:debuginfo-lto-aux.rs //@ compile-flags: -C lto -g //@ no-prefer-dynamic +//@ ignore-backends: gcc extern crate debuginfo_lto_aux; diff --git a/tests/ui/lto/dwarf-mixed-versions-lto.rs b/tests/ui/lto/dwarf-mixed-versions-lto.rs index 900274eb22f44..8ed3afa5e33ae 100644 --- a/tests/ui/lto/dwarf-mixed-versions-lto.rs +++ b/tests/ui/lto/dwarf-mixed-versions-lto.rs @@ -7,6 +7,7 @@ //@ compile-flags: -C lto -g -Cdwarf-version=5 //@ no-prefer-dynamic //@ build-pass +//@ ignore-backends: gcc extern crate dwarf_mixed_versions_lto_aux; diff --git a/tests/ui/lto/fat-lto.rs b/tests/ui/lto/fat-lto.rs index 73d6801a25acb..fe00d7feb3773 100644 --- a/tests/ui/lto/fat-lto.rs +++ b/tests/ui/lto/fat-lto.rs @@ -1,6 +1,7 @@ //@ run-pass //@ compile-flags: -Clto=fat //@ no-prefer-dynamic +//@ ignore-backends: gcc fn main() { println!("hello!"); diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs index 9468e20894ace..e07d44e3be880 100644 --- a/tests/ui/lto/issue-100772.rs +++ b/tests/ui/lto/issue-100772.rs @@ -3,6 +3,7 @@ //@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer //@ no-prefer-dynamic //@ only-x86_64-unknown-linux-gnu +//@ ignore-backends: gcc #![feature(allocator_api)] diff --git a/tests/ui/lto/lto-duplicate-symbols.rs b/tests/ui/lto/lto-duplicate-symbols.rs index a62ab2e22172b..08465eb0fb27a 100644 --- a/tests/ui/lto/lto-duplicate-symbols.rs +++ b/tests/ui/lto/lto-duplicate-symbols.rs @@ -4,6 +4,7 @@ //@ compile-flags: -C lto //@ no-prefer-dynamic //@ normalize-stderr: "lto-duplicate-symbols2\.lto_duplicate_symbols2\.[0-9a-zA-Z]+-cgu" -> "lto-duplicate-symbols2.lto_duplicate_symbols2.HASH-cgu" +//@ ignore-backends: gcc extern crate lto_duplicate_symbols1; extern crate lto_duplicate_symbols2; diff --git a/tests/ui/lto/lto-many-codegen-units.rs b/tests/ui/lto/lto-many-codegen-units.rs index fb6636fb81514..6761510e4274d 100644 --- a/tests/ui/lto/lto-many-codegen-units.rs +++ b/tests/ui/lto/lto-many-codegen-units.rs @@ -1,6 +1,7 @@ //@ run-pass //@ compile-flags: -C lto -C codegen-units=8 //@ no-prefer-dynamic +//@ ignore-backends: gcc fn main() { } diff --git a/tests/ui/lto/lto-rustc-loads-linker-plugin.rs b/tests/ui/lto/lto-rustc-loads-linker-plugin.rs index 18e937cb29a62..2be320f0bffca 100644 --- a/tests/ui/lto/lto-rustc-loads-linker-plugin.rs +++ b/tests/ui/lto/lto-rustc-loads-linker-plugin.rs @@ -2,6 +2,7 @@ //@ aux-build:lto-rustc-loads-linker-plugin.rs //@ run-pass //@ no-prefer-dynamic +//@ ignore-backends: gcc // This test ensures that if a dependency was compiled with // `-Clinker-plugin-lto` then we can compile with `-Clto` and still link against diff --git a/tests/ui/lto/lto-still-runs-thread-dtors.rs b/tests/ui/lto/lto-still-runs-thread-dtors.rs index 900368496ebde..9a97677773cca 100644 --- a/tests/ui/lto/lto-still-runs-thread-dtors.rs +++ b/tests/ui/lto/lto-still-runs-thread-dtors.rs @@ -2,6 +2,7 @@ //@ compile-flags: -C lto //@ no-prefer-dynamic //@ needs-threads +//@ ignore-backends: gcc // FIXME(static_mut_refs): this could use an atomic #![allow(static_mut_refs)] diff --git a/tests/ui/macros/issue-61053-duplicate-binder.stderr b/tests/ui/macros/issue-61053-duplicate-binder.stderr index 7c7cb26b4071e..1ecbc3f86d0de 100644 --- a/tests/ui/macros/issue-61053-duplicate-binder.stderr +++ b/tests/ui/macros/issue-61053-duplicate-binder.stderr @@ -2,9 +2,9 @@ error: duplicate matcher binding --> $DIR/issue-61053-duplicate-binder.rs:7:20 | LL | ($x:tt $x:tt) => { $x }; - | -- ^^ + | -- ^^ duplicate binding | | - | previous declaration + | previous binding | note: the lint level is defined here --> $DIR/issue-61053-duplicate-binder.rs:1:9 diff --git a/tests/ui/macros/issue-68060.stderr b/tests/ui/macros/issue-68060.stderr index 4699594a2b002..54a6baaa39369 100644 --- a/tests/ui/macros/issue-68060.stderr +++ b/tests/ui/macros/issue-68060.stderr @@ -4,7 +4,7 @@ error: `#[target_feature]` attribute cannot be used on closures LL | #[target_feature(enable = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: `#[target_feature]` can be applied to methods and functions + = help: `#[target_feature]` can be applied to functions and methods error[E0658]: `#[track_caller]` on closures is currently unstable --> $DIR/issue-68060.rs:6:13 diff --git a/tests/ui/macros/macro-local-data-key-priv.stderr b/tests/ui/macros/macro-local-data-key-priv.stderr index e93bd11046d09..8df1aec140d0e 100644 --- a/tests/ui/macros/macro-local-data-key-priv.stderr +++ b/tests/ui/macros/macro-local-data-key-priv.stderr @@ -9,7 +9,7 @@ note: the constant `baz` is defined here | LL | thread_local!(static baz: f64 = 0.0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::thread::local_impl::thread_local_process_attrs` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 1 previous error diff --git a/tests/ui/macros/macro-rules-attr-error.rs b/tests/ui/macros/macro-rules-attr-error.rs index 81eadb6692f22..60290b883cb86 100644 --- a/tests/ui/macros/macro-rules-attr-error.rs +++ b/tests/ui/macros/macro-rules-attr-error.rs @@ -50,3 +50,22 @@ macro_rules! forward_referenced_attr { macro_rules! cyclic_attr { attr() {} => {} } + +macro_rules! attr_with_safety { + unsafe attr() { struct RequiresUnsafe; } => {}; + attr() { struct SafeInvocation; } => {}; +} + +#[attr_with_safety] +struct SafeInvocation; + +//~v ERROR: unnecessary `unsafe` on safe attribute invocation +#[unsafe(attr_with_safety)] +struct SafeInvocation; + +//~v ERROR: unsafe attribute invocation requires `unsafe` +#[attr_with_safety] +struct RequiresUnsafe; + +#[unsafe(attr_with_safety)] +struct RequiresUnsafe; diff --git a/tests/ui/macros/macro-rules-attr-error.stderr b/tests/ui/macros/macro-rules-attr-error.stderr index 674d35091b68d..27527a2da7ef2 100644 --- a/tests/ui/macros/macro-rules-attr-error.stderr +++ b/tests/ui/macros/macro-rules-attr-error.stderr @@ -9,6 +9,18 @@ LL | #[local_attr] | = note: this error originates in the attribute macro `local_attr` (in Nightly builds, run with -Z macro-backtrace for more info) +error: unnecessary `unsafe` on safe attribute invocation + --> $DIR/macro-rules-attr-error.rs:63:3 + | +LL | #[unsafe(attr_with_safety)] + | ^^^^^^ + +error: unsafe attribute invocation requires `unsafe` + --> $DIR/macro-rules-attr-error.rs:67:1 + | +LL | #[attr_with_safety] + | ^^^^^^^^^^^^^^^^^^^ + error: cannot find macro `local_attr` in this scope --> $DIR/macro-rules-attr-error.rs:27:5 | @@ -59,5 +71,5 @@ note: a macro with the same name exists, but it appears later LL | macro_rules! cyclic_attr { | ^^^^^^^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors diff --git a/tests/ui/macros/macro-use-all-and-none.stderr b/tests/ui/macros/macro-use-all-and-none.stderr index a5efb065a21b1..b4c05adcb33d0 100644 --- a/tests/ui/macros/macro-use-all-and-none.stderr +++ b/tests/ui/macros/macro-use-all-and-none.stderr @@ -2,8 +2,9 @@ warning: unused attribute --> $DIR/macro-use-all-and-none.rs:7:12 | LL | #[macro_use()] - | ^^ help: remove this attribute + | ^^ help: remove these parentheses | + = note: using `macro_use` with an empty list is equivalent to not using a list at all note: the lint level is defined here --> $DIR/macro-use-all-and-none.rs:4:9 | diff --git a/tests/ui/macros/same-sequence-span.rs b/tests/ui/macros/same-sequence-span.rs index dfaf669a769a6..9fae847a4e2fa 100644 --- a/tests/ui/macros/same-sequence-span.rs +++ b/tests/ui/macros/same-sequence-span.rs @@ -1,4 +1,5 @@ //@ proc-macro: proc_macro_sequence.rs +//@ ignore-backends: gcc // Regression test for issue #62831: Check that multiple sequences with the same span in the // left-hand side of a macro definition behave as if they had unique spans, and in particular that diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 34df201f5a5c7..1ca89b6b595c8 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -1,5 +1,5 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments - --> $DIR/same-sequence-span.rs:14:18 + --> $DIR/same-sequence-span.rs:15:18 | LL | (1 $x:expr $($y:tt,)* | ^^^^^ not allowed after `expr` fragments @@ -7,7 +7,7 @@ LL | (1 $x:expr $($y:tt,)* = note: allowed there are: `=>`, `,` or `;` error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments - --> $DIR/same-sequence-span.rs:15:18 + --> $DIR/same-sequence-span.rs:16:18 | LL | $(= $z:tt)* | ^ not allowed after `expr` fragments @@ -15,10 +15,10 @@ LL | $(= $z:tt)* = note: allowed there are: `=>`, `,` or `;` error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments - --> $DIR/same-sequence-span.rs:19:1 + --> $DIR/same-sequence-span.rs:20:1 | -LL | | macro_rules! manual_foo { - | |__________________________^not allowed after `expr` fragments +LL | | // `proc_macro_sequence.rs`. + | |_____________________________^not allowed after `expr` fragments ... LL | proc_macro_sequence::make_foo!(); | ^------------------------------- @@ -30,7 +30,7 @@ LL | proc_macro_sequence::make_foo!(); = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments - --> $DIR/same-sequence-span.rs:19:1 + --> $DIR/same-sequence-span.rs:20:1 | LL | proc_macro_sequence::make_foo!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments diff --git a/tests/ui/malformed/malformed-regressions.rs b/tests/ui/malformed/malformed-regressions.rs index 407920c4e4ece..c0f8c0d15bb8f 100644 --- a/tests/ui/malformed/malformed-regressions.rs +++ b/tests/ui/malformed/malformed-regressions.rs @@ -5,6 +5,8 @@ #[inline = ""] //~ ERROR valid forms for the attribute are //~^ WARN this was previously accepted #[link] //~ ERROR malformed +//~^ WARN attribute should be applied to an `extern` block with non-Rust ABI +//~| WARN previously accepted #[link = ""] //~ ERROR malformed fn main() {} diff --git a/tests/ui/malformed/malformed-regressions.stderr b/tests/ui/malformed/malformed-regressions.stderr index 850bcb6cbc2de..1812079848774 100644 --- a/tests/ui/malformed/malformed-regressions.stderr +++ b/tests/ui/malformed/malformed-regressions.stderr @@ -29,7 +29,7 @@ LL | #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", = and 1 other candidate error[E0539]: malformed `link` attribute input - --> $DIR/malformed-regressions.rs:8:1 + --> $DIR/malformed-regressions.rs:10:1 | LL | #[link = ""] | ^^^^^^^^^^^^ expected this to be a list @@ -51,6 +51,18 @@ LL + #[link(name = "...", kind = "dylib|static|...", wasm_import_module = "...", | = and 1 other candidate +warning: attribute should be applied to an `extern` block with non-Rust ABI + --> $DIR/malformed-regressions.rs:7:1 + | +LL | #[link] + | ^^^^^^^ +... +LL | fn main() {} + | ------------ not an `extern` block + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: requested on the command line with `-W unused-attributes` + error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` --> $DIR/malformed-regressions.rs:3:1 | @@ -69,7 +81,7 @@ LL | #[inline = ""] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 -error: aborting due to 5 previous errors +error: aborting due to 5 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0539`. Future incompatibility report: Future breakage diagnostic: diff --git a/tests/ui/malformed/malformed-special-attrs.stderr b/tests/ui/malformed/malformed-special-attrs.stderr index b6a1a6b50e468..91e5939eb1f9f 100644 --- a/tests/ui/malformed/malformed-special-attrs.stderr +++ b/tests/ui/malformed/malformed-special-attrs.stderr @@ -1,27 +1,24 @@ -error: malformed `cfg_attr` attribute input +error[E0539]: malformed `cfg_attr` attribute input --> $DIR/malformed-special-attrs.rs:1:1 | LL | #[cfg_attr] | ^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit -help: missing condition and attribute - | -LL | #[cfg_attr(condition, attribute, other_attribute, ...)] - | ++++++++++++++++++++++++++++++++++++++++++++ -error: malformed `cfg_attr` attribute input +error[E0539]: malformed `cfg_attr` attribute input --> $DIR/malformed-special-attrs.rs:4:1 | LL | #[cfg_attr = ""] | ^^^^^^^^^^^^^^^^ + | | + | expected this to be a list + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | = note: for more information, visit -help: missing condition and attribute - | -LL - #[cfg_attr = ""] -LL + #[cfg_attr(condition, attribute, other_attribute, ...)] - | error: malformed `derive` attribute input --> $DIR/malformed-special-attrs.rs:7:1 @@ -37,3 +34,4 @@ LL | #[derive = ""] error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0539`. diff --git a/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.rs b/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.rs new file mode 100644 index 0000000000000..e53d14f256e79 --- /dev/null +++ b/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/63983 +enum MyEnum { + Tuple(i32), + Struct{ s: i32 }, +} + +fn foo(en: MyEnum) { + match en { + MyEnum::Tuple => "", +//~^ ERROR expected unit struct, unit variant or constant, found tuple variant `MyEnum::Tuple` + MyEnum::Struct => "", +//~^ ERROR expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct` + }; +} + +fn main() {} diff --git a/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.stderr b/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.stderr new file mode 100644 index 0000000000000..5c937a9ddab0b --- /dev/null +++ b/tests/ui/match/unit-pattern-error-on-tuple-and-struct-variants-63983.stderr @@ -0,0 +1,24 @@ +error[E0532]: expected unit struct, unit variant or constant, found tuple variant `MyEnum::Tuple` + --> $DIR/unit-pattern-error-on-tuple-and-struct-variants-63983.rs:9:9 + | +LL | Tuple(i32), + | ---------- `MyEnum::Tuple` defined here +... +LL | MyEnum::Tuple => "", + | ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)` + +error[E0533]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct` + --> $DIR/unit-pattern-error-on-tuple-and-struct-variants-63983.rs:11:9 + | +LL | MyEnum::Struct => "", + | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant + | +help: the struct variant's field is being ignored + | +LL | MyEnum::Struct { s: _ } => "", + | ++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0532, E0533. +For more information about an error, try `rustc --explain E0532`. diff --git a/tests/ui/methods/call_method_unknown_pointee.stderr b/tests/ui/methods/call_method_unknown_pointee.stderr index 9d0f38cf6b5c1..e20c6f8e8a17c 100644 --- a/tests/ui/methods/call_method_unknown_pointee.stderr +++ b/tests/ui/methods/call_method_unknown_pointee.stderr @@ -1,11 +1,10 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:10:41 + --> $DIR/call_method_unknown_pointee.rs:10:23 | LL | let _a: i32 = (ptr as *const _).read(); - | ^^^^ - | | - | cannot infer type - | cannot call a method on a raw pointer with an unknown pointee type + | ^^^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type + | | + | cannot infer type error[E0282]: type annotations needed for `*const _` --> $DIR/call_method_unknown_pointee.rs:12:13 @@ -22,13 +21,12 @@ LL | let b: *const _ = ptr as *const _; | ++++++++++ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_pointee.rs:21:39 + --> $DIR/call_method_unknown_pointee.rs:21:23 | LL | let _a: i32 = (ptr as *mut _).read(); - | ^^^^ - | | - | cannot infer type - | cannot call a method on a raw pointer with an unknown pointee type + | ^^^^^^^^^^^^^^^ ---- cannot call a method on a raw pointer with an unknown pointee type + | | + | cannot infer type error[E0282]: type annotations needed for `*mut _` --> $DIR/call_method_unknown_pointee.rs:23:13 diff --git a/tests/ui/methods/call_method_unknown_referent.stderr b/tests/ui/methods/call_method_unknown_referent.stderr index 5d6974a00c695..35c7d9caf3efa 100644 --- a/tests/ui/methods/call_method_unknown_referent.stderr +++ b/tests/ui/methods/call_method_unknown_referent.stderr @@ -1,14 +1,14 @@ error[E0282]: type annotations needed - --> $DIR/call_method_unknown_referent.rs:20:31 + --> $DIR/call_method_unknown_referent.rs:20:19 | LL | let _a: i32 = (ptr as &_).read(); - | ^^^^ cannot infer type + | ^^^^^^^^^^^ cannot infer type error[E0282]: type annotations needed - --> $DIR/call_method_unknown_referent.rs:26:37 + --> $DIR/call_method_unknown_referent.rs:26:14 | LL | let _b = (rc as std::rc::Rc<_>).read(); - | ^^^^ cannot infer type + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type error[E0599]: no method named `read` found for struct `SmartPtr` in the current scope --> $DIR/call_method_unknown_referent.rs:46:35 diff --git a/tests/ui/methods/overflow-if-subtyping.rs b/tests/ui/methods/overflow-if-subtyping.rs new file mode 100644 index 0000000000000..a97f29f1f6dfc --- /dev/null +++ b/tests/ui/methods/overflow-if-subtyping.rs @@ -0,0 +1,30 @@ +//@ check-pass + +// Regression test for #128887. +#![allow(unconditional_recursion)] +trait Mappable { + type Output; +} + +trait Bound {} +// Deleting this impl made it compile on beta +impl Bound for T {} + +trait Generic {} + +// Deleting the `: Mappable` already made it error on stable. +struct IndexWithIter, T>(I, M, T); + +impl IndexWithIter +where + >::Output: Bound, + // Flipping these where bounds causes this to succeed, even when removing + // the where-clause on the struct definition. + M: Mappable, + I: Generic, +{ + fn new(x: I) { + IndexWithIter::<_, _, _>::new(x); + } +} +fn main() {} diff --git a/tests/ui/mir/gvn-loop-miscompile.rs b/tests/ui/mir/gvn-loop-miscompile.rs new file mode 100644 index 0000000000000..8e987c5c94662 --- /dev/null +++ b/tests/ui/mir/gvn-loop-miscompile.rs @@ -0,0 +1,34 @@ +//@ compile-flags: -O +//@ run-pass + +pub enum Value { + V0(i32), + V1, +} + +fn set_discriminant(val: &mut Value) -> Value { + let val_alias: &Value = get(val); + let mut stop = false; + let Value::V0(v) = *val_alias else { + unreachable!(); + }; + loop { + let v = Value::V0(v); + if stop { + return v; + } + stop = true; + *val = Value::V1; + } +} + +fn main() { + let mut v = Value::V0(1); + let v = set_discriminant(&mut v); + assert!(matches!(v, Value::V0(1))); +} + +#[inline(never)] +fn get(v: &T) -> &T { + v +} diff --git a/tests/ui/mir/lint/assignment-overlap.rs b/tests/ui/mir/lint/assignment-overlap.rs index bbc140904671e..5d1213a77585f 100644 --- a/tests/ui/mir/lint/assignment-overlap.rs +++ b/tests/ui/mir/lint/assignment-overlap.rs @@ -13,7 +13,7 @@ pub fn main() { let a: [u8; 1024]; { a = a; //~ ERROR broken MIR - //~^ ERROR encountered `Assign` statement with overlapping memory + //~^ ERROR encountered `_1 = copy _1` statement with overlapping memory Return() } } diff --git a/tests/ui/mir/mir-cfg-unpretty-check-81918.rs b/tests/ui/mir/mir-cfg-unpretty-no-panic-81918.rs similarity index 100% rename from tests/ui/mir/mir-cfg-unpretty-check-81918.rs rename to tests/ui/mir/mir-cfg-unpretty-no-panic-81918.rs diff --git a/tests/ui/mismatched_types/collect-method-type-mismatch-66923.rs b/tests/ui/mismatched_types/collect-method-type-mismatch-66923.rs new file mode 100644 index 0000000000000..d20228891c027 --- /dev/null +++ b/tests/ui/mismatched_types/collect-method-type-mismatch-66923.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/66923 +// This test checks that errors are showed for lines with `collect` rather than `push` method. + +fn main() { + let v = vec![1_f64, 2.2_f64]; + let mut fft: Vec> = vec![]; + + let x1: &[f64] = &v; + let x2: Vec = x1.into_iter().collect(); + //~^ ERROR a value of type + fft.push(x2); + + let x3 = x1.into_iter().collect::>(); + //~^ ERROR a value of type + fft.push(x3); +} diff --git a/tests/ui/mismatched_types/collect-method-type-mismatch-66923.stderr b/tests/ui/mismatched_types/collect-method-type-mismatch-66923.stderr new file mode 100644 index 0000000000000..89c755cdf47a7 --- /dev/null +++ b/tests/ui/mismatched_types/collect-method-type-mismatch-66923.stderr @@ -0,0 +1,44 @@ +error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` + --> $DIR/collect-method-type-mismatch-66923.rs:9:39 + | +LL | let x2: Vec = x1.into_iter().collect(); + | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | + = help: the trait `FromIterator<&_>` is not implemented for `Vec` + but trait `FromIterator<_>` is implemented for it + = help: for that trait implementation, expected `f64`, found `&f64` +note: the method call chain might not have had the expected associated types + --> $DIR/collect-method-type-mismatch-66923.rs:9:27 + | +LL | let x1: &[f64] = &v; + | -- this expression has type `&Vec` +LL | let x2: Vec = x1.into_iter().collect(); + | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error[E0277]: a value of type `Vec` cannot be built from an iterator over elements of type `&f64` + --> $DIR/collect-method-type-mismatch-66923.rs:13:39 + | +LL | let x3 = x1.into_iter().collect::>(); + | ------- ^^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` + | | + | required by a bound introduced by this call + | + = help: the trait `FromIterator<&_>` is not implemented for `Vec` + but trait `FromIterator<_>` is implemented for it + = help: for that trait implementation, expected `f64`, found `&f64` +note: the method call chain might not have had the expected associated types + --> $DIR/collect-method-type-mismatch-66923.rs:13:17 + | +LL | let x1: &[f64] = &v; + | -- this expression has type `&Vec` +... +LL | let x3 = x1.into_iter().collect::>(); + | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr b/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr deleted file mode 100644 index bbd73347d0272..0000000000000 --- a/tests/ui/mismatched_types/mismatched-types-in-trait-implementation-87490.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/mismatched-types-in-trait-implementation-87490.rs:10:5 - | -LL | fn follow(_: &str) -> <&str as StreamOnce>::Position { - | ------------------------------ expected `usize` because of return type -LL | String::new - | ^^^^^^^^^^^ expected `usize`, found fn item - | - = note: expected type `usize` - found fn item `fn() -> String {String::new}` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/mismatched_types/string-clone-mismatch-61106.rs b/tests/ui/mismatched_types/string-clone-mismatch-61106.rs new file mode 100644 index 0000000000000..1582ed3ec978d --- /dev/null +++ b/tests/ui/mismatched_types/string-clone-mismatch-61106.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/61106 +fn main() { + let x = String::new(); + foo(x.clone()); //~ ERROR mismatched types +} + +fn foo(_: &str) {} diff --git a/tests/ui/mismatched_types/string-clone-mismatch-61106.stderr b/tests/ui/mismatched_types/string-clone-mismatch-61106.stderr new file mode 100644 index 0000000000000..8e41f42a6d8f8 --- /dev/null +++ b/tests/ui/mismatched_types/string-clone-mismatch-61106.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/string-clone-mismatch-61106.rs:4:9 + | +LL | foo(x.clone()); + | --- ^^^^^^^^^ expected `&str`, found `String` + | | + | arguments to this function are incorrect + | +note: function defined here + --> $DIR/string-clone-mismatch-61106.rs:7:4 + | +LL | fn foo(_: &str) {} + | ^^^ ------- +help: consider borrowing here + | +LL | foo(&x.clone()); + | + + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/never_type/defaulted-never-note.fallback.stderr b/tests/ui/never_type/defaulted-never-note.fallback.stderr index 7526a399bf177..299f4630d0a5f 100644 --- a/tests/ui/never_type/defaulted-never-note.fallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.fallback.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied - --> $DIR/defaulted-never-note.rs:32:9 + --> $DIR/defaulted-never-note.rs:31:9 | LL | foo(_x); | --- ^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!` @@ -10,7 +10,7 @@ LL | foo(_x); = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: you might have intended to use the type `()` here instead note: required by a bound in `foo` - --> $DIR/defaulted-never-note.rs:25:11 + --> $DIR/defaulted-never-note.rs:26:11 | LL | fn foo(_t: T) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index b82bea0bc48f0..05e5f6d35580e 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -1,41 +1,16 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/defaulted-never-note.rs:28:1 - | -LL | fn smeg() { - | ^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail - --> $DIR/defaulted-never-note.rs:32:9 - | -LL | foo(_x); - | ^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: use `()` annotations to avoid fallback changes - | -LL | let _x: () = return; - | ++++ - -warning: 1 warning emitted - Future incompatibility report: Future breakage diagnostic: warning: this function depends on never type fallback being `()` - --> $DIR/defaulted-never-note.rs:28:1 + --> $DIR/defaulted-never-note.rs:29:1 | LL | fn smeg() { | ^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail - --> $DIR/defaulted-never-note.rs:32:9 + --> $DIR/defaulted-never-note.rs:31:9 | LL | foo(_x); | ^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let _x: () = return; diff --git a/tests/ui/never_type/defaulted-never-note.rs b/tests/ui/never_type/defaulted-never-note.rs index 71f0d9fa5bb5f..8164d00ded22c 100644 --- a/tests/ui/never_type/defaulted-never-note.rs +++ b/tests/ui/never_type/defaulted-never-note.rs @@ -7,6 +7,7 @@ #![cfg_attr(fallback, feature(never_type, never_type_fallback))] #![allow(unused)] +#![expect(dependency_on_unit_never_type_fallback)] trait Deserialize: Sized { fn deserialize() -> Result; @@ -23,19 +24,17 @@ trait ImplementedForUnitButNotNever {} impl ImplementedForUnitButNotNever for () {} fn foo(_t: T) {} -//[fallback]~^ NOTE required by this bound in `foo` -//[fallback]~| NOTE required by a bound in `foo` +//[fallback]~^ note: required by this bound in `foo` +//[fallback]~| note: required by a bound in `foo` fn smeg() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! let _x = return; foo(_x); - //[fallback]~^ ERROR the trait bound - //[fallback]~| NOTE the trait `ImplementedForUnitButNotNever` is not implemented - //[fallback]~| HELP trait `ImplementedForUnitButNotNever` is implemented for `()` - //[fallback]~| NOTE this error might have been caused - //[fallback]~| NOTE required by a bound introduced by this call - //[fallback]~| HELP you might have intended to use the type `()` + //[fallback]~^ error: the trait bound + //[fallback]~| note: the trait `ImplementedForUnitButNotNever` is not implemented + //[fallback]~| help: trait `ImplementedForUnitButNotNever` is implemented for `()` + //[fallback]~| note: this error might have been caused + //[fallback]~| note: required by a bound introduced by this call + //[fallback]~| help: you might have intended to use the type `()` } fn main() { diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.rs b/tests/ui/never_type/dependency-on-fallback-to-unit.rs index fad4c7c7df7b8..9cbce58ba4ad7 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.rs +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.rs @@ -1,12 +1,10 @@ -//@ check-pass - fn main() { def(); _ = question_mark(); } fn def() { - //~^ warn: this function depends on never type fallback being `()` + //~^ error: this function depends on never type fallback being `()` //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! match true { false => <_>::default(), @@ -17,7 +15,7 @@ fn def() { // // fn question_mark() -> Result<(), ()> { - //~^ warn: this function depends on never type fallback being `()` + //~^ error: this function depends on never type fallback being `()` //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! deserialize()?; Ok(()) diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index 6394bab895222..0b8d9657c7b0a 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -1,5 +1,5 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/dependency-on-fallback-to-unit.rs:8:1 +error: this function depends on never type fallback being `()` + --> $DIR/dependency-on-fallback-to-unit.rs:6:1 | LL | fn def() { | ^^^^^^^^ @@ -8,19 +8,19 @@ LL | fn def() { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dependency-on-fallback-to-unit.rs:12:19 + --> $DIR/dependency-on-fallback-to-unit.rs:10:19 | LL | false => <_>::default(), | ^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL - false => <_>::default(), LL + false => <()>::default(), | -warning: this function depends on never type fallback being `()` - --> $DIR/dependency-on-fallback-to-unit.rs:19:1 +error: this function depends on never type fallback being `()` + --> $DIR/dependency-on-fallback-to-unit.rs:17:1 | LL | fn question_mark() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | fn question_mark() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dependency-on-fallback-to-unit.rs:22:5 + --> $DIR/dependency-on-fallback-to-unit.rs:20:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ @@ -38,11 +38,11 @@ help: use `()` annotations to avoid fallback changes LL | deserialize::<()>()?; | ++++++ -warning: 2 warnings emitted +error: aborting due to 2 previous errors Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/dependency-on-fallback-to-unit.rs:8:1 +error: this function depends on never type fallback being `()` + --> $DIR/dependency-on-fallback-to-unit.rs:6:1 | LL | fn def() { | ^^^^^^^^ @@ -51,11 +51,11 @@ LL | fn def() { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dependency-on-fallback-to-unit.rs:12:19 + --> $DIR/dependency-on-fallback-to-unit.rs:10:19 | LL | false => <_>::default(), | ^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL - false => <_>::default(), @@ -63,8 +63,8 @@ LL + false => <()>::default(), | Future breakage diagnostic: -warning: this function depends on never type fallback being `()` - --> $DIR/dependency-on-fallback-to-unit.rs:19:1 +error: this function depends on never type fallback being `()` + --> $DIR/dependency-on-fallback-to-unit.rs:17:1 | LL | fn question_mark() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,11 +73,11 @@ LL | fn question_mark() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dependency-on-fallback-to-unit.rs:22:5 + --> $DIR/dependency-on-fallback-to-unit.rs:20:5 | LL | deserialize()?; | ^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | deserialize::<()>()?; diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index 7f857c83655a5..49930e0d3449a 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -1,60 +1,16 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-control-flow.rs:30:1 - | -LL | fn assignment() { - | ^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: UnitDefault` will fail - --> $DIR/diverging-fallback-control-flow.rs:36:13 - | -LL | x = UnitDefault::default(); - | ^^^^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: use `()` annotations to avoid fallback changes - | -LL | let x: (); - | ++++ - -warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-control-flow.rs:42:1 - | -LL | fn assignment_rev() { - | ^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: UnitDefault` will fail - --> $DIR/diverging-fallback-control-flow.rs:50:13 - | -LL | x = UnitDefault::default(); - | ^^^^^^^^^^^^^^^^^^^^^^ -help: use `()` annotations to avoid fallback changes - | -LL | let x: (); - | ++++ - -warning: 2 warnings emitted - Future incompatibility report: Future breakage diagnostic: warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-control-flow.rs:30:1 + --> $DIR/diverging-fallback-control-flow.rs:32:1 | LL | fn assignment() { | ^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: UnitDefault` will fail --> $DIR/diverging-fallback-control-flow.rs:36:13 | LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let x: (); @@ -67,15 +23,12 @@ warning: this function depends on never type fallback being `()` LL | fn assignment_rev() { | ^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: UnitDefault` will fail - --> $DIR/diverging-fallback-control-flow.rs:50:13 + --> $DIR/diverging-fallback-control-flow.rs:48:13 | LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let x: (); diff --git a/tests/ui/never_type/diverging-fallback-control-flow.rs b/tests/ui/never_type/diverging-fallback-control-flow.rs index 647667126d493..c00c97ecb143a 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.rs +++ b/tests/ui/never_type/diverging-fallback-control-flow.rs @@ -1,10 +1,12 @@ //@ revisions: nofallback fallback -//@ run-pass +//@ check-pass #![allow(dead_code)] #![allow(unused_assignments)] #![allow(unused_variables)] #![allow(unreachable_code)] +#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))] + // Test various cases where we permit an unconstrained variable // to fallback based on control-flow. In all of these cases, // the type variable winds up being the target of both a `!` coercion @@ -28,8 +30,6 @@ impl UnitDefault for () { } fn assignment() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! let x; if true { @@ -40,8 +40,6 @@ fn assignment() { } fn assignment_rev() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! let x; if true { diff --git a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr index 610c687194b76..56bff12055059 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.fallback.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `!: Test` is not satisfied - --> $DIR/diverging-fallback-no-leak.rs:20:23 + --> $DIR/diverging-fallback-no-leak.rs:18:23 | LL | unconstrained_arg(return); | ----------------- ^^^^^^ the trait `Test` is not implemented for `!` @@ -12,7 +12,7 @@ LL | unconstrained_arg(return); = note: this error might have been caused by changes to Rust's type-inference algorithm (see issue #48950 for more information) = help: you might have intended to use the type `()` here instead note: required by a bound in `unconstrained_arg` - --> $DIR/diverging-fallback-no-leak.rs:12:25 + --> $DIR/diverging-fallback-no-leak.rs:13:25 | LL | fn unconstrained_arg(_: T) {} | ^^^^ required by this bound in `unconstrained_arg` diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr index d4bb5f9442ec0..8423261ed610c 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr @@ -1,41 +1,16 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-no-leak.rs:14:1 - | -LL | fn main() { - | ^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: Test` will fail - --> $DIR/diverging-fallback-no-leak.rs:20:23 - | -LL | unconstrained_arg(return); - | ^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: use `()` annotations to avoid fallback changes - | -LL | unconstrained_arg::<()>(return); - | ++++++ - -warning: 1 warning emitted - Future incompatibility report: Future breakage diagnostic: warning: this function depends on never type fallback being `()` - --> $DIR/diverging-fallback-no-leak.rs:14:1 + --> $DIR/diverging-fallback-no-leak.rs:15:1 | LL | fn main() { | ^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Test` will fail - --> $DIR/diverging-fallback-no-leak.rs:20:23 + --> $DIR/diverging-fallback-no-leak.rs:18:23 | LL | unconstrained_arg(return); | ^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | unconstrained_arg::<()>(return); diff --git a/tests/ui/never_type/diverging-fallback-no-leak.rs b/tests/ui/never_type/diverging-fallback-no-leak.rs index 75ca491bf46a5..b00802d172496 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.rs +++ b/tests/ui/never_type/diverging-fallback-no-leak.rs @@ -2,6 +2,7 @@ //@[nofallback] check-pass #![cfg_attr(fallback, feature(never_type, never_type_fallback))] +#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))] fn make_unit() {} @@ -12,11 +13,8 @@ impl Test for () {} fn unconstrained_arg(_: T) {} fn main() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - // Here the type variable falls back to `!`, // and hence we get a type error. unconstrained_arg(return); - //[fallback]~^ ERROR trait bound `!: Test` is not satisfied + //[fallback]~^ error: trait bound `!: Test` is not satisfied } diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index a706ad8b09b94..1a6ea52246201 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -1,4 +1,4 @@ -warning: this function depends on never type fallback being `()` +error: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-unconstrained-return.rs:28:1 | LL | fn main() { @@ -12,16 +12,16 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail | LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let _: () = if true { unconstrained_return() } else { panic!() }; | ++++ -warning: 1 warning emitted +error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: -warning: this function depends on never type fallback being `()` +error: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-unconstrained-return.rs:28:1 | LL | fn main() { @@ -35,7 +35,7 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail | LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let _: () = if true { unconstrained_return() } else { panic!() }; diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs index fdea3a94d28f6..62042912f03ae 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.rs +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.rs @@ -4,7 +4,7 @@ // in the objc crate, where changing the fallback from `!` to `()` // resulted in unsoundness. // -//@ check-pass +//@[fallback] check-pass //@ revisions: nofallback fallback @@ -26,7 +26,7 @@ fn unconstrained_return() -> T { } fn main() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` + //[nofallback]~^ error: this function depends on never type fallback being `()` //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! // In Ye Olde Days, the `T` parameter of `unconstrained_return` diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs index 9a53358464d8c..7bae1ddc027f6 100644 --- a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.rs @@ -1,5 +1,3 @@ -#![deny(dependency_on_unit_never_type_fallback)] - fn create_ok_default() -> Result where C: Default, diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr index d2d108edb4dbd..9795acffe7058 100644 --- a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr +++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr @@ -1,5 +1,5 @@ error: this function depends on never type fallback being `()` - --> $DIR/dont-suggest-turbofish-from-expansion.rs:10:1 + --> $DIR/dont-suggest-turbofish-from-expansion.rs:8:1 | LL | fn main() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,15 +8,11 @@ LL | fn main() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23 + --> $DIR/dont-suggest-turbofish-from-expansion.rs:12:23 | LL | let created = create_ok_default()?; | ^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/dont-suggest-turbofish-from-expansion.rs:1:9 - | -LL | #![deny(dependency_on_unit_never_type_fallback)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let created: () = create_ok_default()?; @@ -26,7 +22,7 @@ error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/dont-suggest-turbofish-from-expansion.rs:10:1 + --> $DIR/dont-suggest-turbofish-from-expansion.rs:8:1 | LL | fn main() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,15 +31,11 @@ LL | fn main() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23 + --> $DIR/dont-suggest-turbofish-from-expansion.rs:12:23 | LL | let created = create_ok_default()?; | ^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/dont-suggest-turbofish-from-expansion.rs:1:9 - | -LL | #![deny(dependency_on_unit_never_type_fallback)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let created: () = create_ok_default()?; diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr index 39b40cdd76d8e..3c5c24853d687 100644 --- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr +++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr @@ -1,41 +1,16 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/fallback-closure-ret.rs:21:1 - | -LL | fn main() { - | ^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: Bar` will fail - --> $DIR/fallback-closure-ret.rs:24:5 - | -LL | foo(|| panic!()); - | ^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default -help: use `()` annotations to avoid fallback changes - | -LL | foo::<()>(|| panic!()); - | ++++++ - -warning: 1 warning emitted - Future incompatibility report: Future breakage diagnostic: warning: this function depends on never type fallback being `()` - --> $DIR/fallback-closure-ret.rs:21:1 + --> $DIR/fallback-closure-ret.rs:22:1 | LL | fn main() { | ^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Bar` will fail - --> $DIR/fallback-closure-ret.rs:24:5 + --> $DIR/fallback-closure-ret.rs:23:5 | LL | foo(|| panic!()); | ^^^^^^^^^^^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | foo::<()>(|| panic!()); diff --git a/tests/ui/never_type/fallback-closure-ret.rs b/tests/ui/never_type/fallback-closure-ret.rs index f1423354f1325..0d92b39d42d7b 100644 --- a/tests/ui/never_type/fallback-closure-ret.rs +++ b/tests/ui/never_type/fallback-closure-ret.rs @@ -11,6 +11,7 @@ //@ check-pass #![cfg_attr(fallback, feature(never_type_fallback))] +#![cfg_attr(nofallback, expect(dependency_on_unit_never_type_fallback))] trait Bar {} impl Bar for () {} @@ -19,7 +20,5 @@ impl Bar for u32 {} fn foo(_: impl Fn() -> R) {} fn main() { - //[nofallback]~^ warn: this function depends on never type fallback being `()` - //[nofallback]~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! foo(|| panic!()); } diff --git a/tests/ui/never_type/impl_trait_fallback.rs b/tests/ui/never_type/impl_trait_fallback.rs index bd4caeb2b726d..dafbd5af9a1ef 100644 --- a/tests/ui/never_type/impl_trait_fallback.rs +++ b/tests/ui/never_type/impl_trait_fallback.rs @@ -1,4 +1,5 @@ //@ check-pass +#![expect(dependency_on_unit_never_type_fallback)] fn main() {} @@ -6,7 +7,5 @@ trait T {} impl T for () {} fn should_ret_unit() -> impl T { - //~^ warn: this function depends on never type fallback being `()` - //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! panic!() } diff --git a/tests/ui/never_type/impl_trait_fallback.stderr b/tests/ui/never_type/impl_trait_fallback.stderr index 7d8624b1fe58f..bdf6df9878323 100644 --- a/tests/ui/never_type/impl_trait_fallback.stderr +++ b/tests/ui/never_type/impl_trait_fallback.stderr @@ -1,35 +1,14 @@ -warning: this function depends on never type fallback being `()` - --> $DIR/impl_trait_fallback.rs:8:1 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see - = help: specify the types explicitly -note: in edition 2024, the requirement `!: T` will fail - --> $DIR/impl_trait_fallback.rs:8:25 - | -LL | fn should_ret_unit() -> impl T { - | ^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default - -warning: 1 warning emitted - Future incompatibility report: Future breakage diagnostic: warning: this function depends on never type fallback being `()` - --> $DIR/impl_trait_fallback.rs:8:1 + --> $DIR/impl_trait_fallback.rs:9:1 | LL | fn should_ret_unit() -> impl T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions! - = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: T` will fail - --> $DIR/impl_trait_fallback.rs:8:25 + --> $DIR/impl_trait_fallback.rs:9:25 | LL | fn should_ret_unit() -> impl T { | ^^^^^^ - = note: `#[warn(dependency_on_unit_never_type_fallback)]` (part of `#[warn(rust_2024_compatibility)]`) on by default diff --git a/tests/ui/never_type/lint-breaking-2024-assign-underscore.fixed b/tests/ui/never_type/lint-breaking-2024-assign-underscore.fixed index f9f2b59a8c285..b235c6e4eb464 100644 --- a/tests/ui/never_type/lint-breaking-2024-assign-underscore.fixed +++ b/tests/ui/never_type/lint-breaking-2024-assign-underscore.fixed @@ -1,7 +1,5 @@ //@ run-rustfix - #![allow(unused)] -#![deny(dependency_on_unit_never_type_fallback)] fn foo() -> Result { Err(()) diff --git a/tests/ui/never_type/lint-breaking-2024-assign-underscore.rs b/tests/ui/never_type/lint-breaking-2024-assign-underscore.rs index 8a2f3d311ab90..14d88503e85f0 100644 --- a/tests/ui/never_type/lint-breaking-2024-assign-underscore.rs +++ b/tests/ui/never_type/lint-breaking-2024-assign-underscore.rs @@ -1,7 +1,5 @@ //@ run-rustfix - #![allow(unused)] -#![deny(dependency_on_unit_never_type_fallback)] fn foo() -> Result { Err(()) diff --git a/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr b/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr index 6a85b9923d3e9..96749de1195eb 100644 --- a/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr +++ b/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr @@ -1,5 +1,5 @@ error: this function depends on never type fallback being `()` - --> $DIR/lint-breaking-2024-assign-underscore.rs:10:1 + --> $DIR/lint-breaking-2024-assign-underscore.rs:8:1 | LL | fn test() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,15 +8,11 @@ LL | fn test() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/lint-breaking-2024-assign-underscore.rs:13:9 + --> $DIR/lint-breaking-2024-assign-underscore.rs:11:9 | LL | _ = foo()?; | ^^^^^ -note: the lint level is defined here - --> $DIR/lint-breaking-2024-assign-underscore.rs:4:9 - | -LL | #![deny(dependency_on_unit_never_type_fallback)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | _ = foo::<()>()?; @@ -26,7 +22,7 @@ error: aborting due to 1 previous error Future incompatibility report: Future breakage diagnostic: error: this function depends on never type fallback being `()` - --> $DIR/lint-breaking-2024-assign-underscore.rs:10:1 + --> $DIR/lint-breaking-2024-assign-underscore.rs:8:1 | LL | fn test() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,15 +31,11 @@ LL | fn test() -> Result<(), ()> { = note: for more information, see = help: specify the types explicitly note: in edition 2024, the requirement `!: Default` will fail - --> $DIR/lint-breaking-2024-assign-underscore.rs:13:9 + --> $DIR/lint-breaking-2024-assign-underscore.rs:11:9 | LL | _ = foo()?; | ^^^^^ -note: the lint level is defined here - --> $DIR/lint-breaking-2024-assign-underscore.rs:4:9 - | -LL | #![deny(dependency_on_unit_never_type_fallback)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(dependency_on_unit_never_type_fallback)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | _ = foo::<()>()?; diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index f9d0a89eabc41..84e143b024acc 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -1,5 +1,5 @@ -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:10:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -7,14 +7,14 @@ LL | unsafe { mem::zeroed() } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | unsafe { mem::zeroed::<()>() } | ++++++ -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:27:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -27,8 +27,8 @@ help: use `()` annotations to avoid fallback changes LL | core::mem::transmute::<_, ()>(Zst) | +++++++++ -warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 +error: never type fallback affects this union access + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:44:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -37,8 +37,8 @@ LL | unsafe { Union { a: () }.b } = note: for more information, see = help: specify the type explicitly -warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 +error: never type fallback affects this raw pointer dereference + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:55:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -51,8 +51,8 @@ help: use `()` annotations to avoid fallback changes LL | unsafe { *ptr::from_ref(&()).cast::<()>() } | ++++++ -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:76:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -65,8 +65,8 @@ help: use `()` annotations to avoid fallback changes LL | unsafe { internally_create::<()>(x) } | ++++++ -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:94:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -79,8 +79,8 @@ help: use `()` annotations to avoid fallback changes LL | let zeroed = mem::zeroed::<()>; | ++++++ -warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:89:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -93,8 +93,8 @@ help: use `()` annotations to avoid fallback changes LL | let zeroed = mem::zeroed::<()>; | ++++++ -warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:112:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -107,8 +107,8 @@ help: use `()` annotations to avoid fallback changes LL | let f = internally_create::<()>; | ++++++ -warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 +error: never type fallback affects this call to an `unsafe` method + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:137:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,8 +117,8 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = note: for more information, see = help: specify the type explicitly -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:155:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -129,13 +129,13 @@ LL | msg_send!(); = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 10 warnings emitted +error: aborting due to 10 previous errors Future incompatibility report: Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:10:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -143,15 +143,15 @@ LL | unsafe { mem::zeroed() } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | unsafe { mem::zeroed::<()>() } | ++++++ Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:27:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -159,15 +159,15 @@ LL | core::mem::transmute(Zst) = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | core::mem::transmute::<_, ()>(Zst) | +++++++++ Future breakage diagnostic: -warning: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 +error: never type fallback affects this union access + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:44:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -175,11 +175,11 @@ LL | unsafe { Union { a: () }.b } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default Future breakage diagnostic: -warning: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 +error: never type fallback affects this raw pointer dereference + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:55:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -187,15 +187,15 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | unsafe { *ptr::from_ref(&()).cast::<()>() } | ++++++ Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:76:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -203,15 +203,15 @@ LL | unsafe { internally_create(x) } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | unsafe { internally_create::<()>(x) } | ++++++ Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:94:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -219,15 +219,15 @@ LL | unsafe { zeroed() } = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let zeroed = mem::zeroed::<()>; | ++++++ Future breakage diagnostic: -warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:89:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -235,15 +235,15 @@ LL | let zeroed = mem::zeroed; = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let zeroed = mem::zeroed::<()>; | ++++++ Future breakage diagnostic: -warning: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 +error: never type fallback affects this `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:112:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -251,15 +251,15 @@ LL | let f = internally_create; = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: use `()` annotations to avoid fallback changes | LL | let f = internally_create::<()>; | ++++++ Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 +error: never type fallback affects this call to an `unsafe` method + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:137:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -267,11 +267,11 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default Future breakage diagnostic: -warning: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 +error: never type fallback affects this call to an `unsafe` function + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:155:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -282,6 +282,6 @@ LL | msg_send!(); = warning: this changes meaning in Rust 2024 and in a future release in all editions! = note: for more information, see = help: specify the type explicitly - = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` (part of `#[warn(rust_2024_compatibility)]`) on by default - = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` (part of `#[deny(rust_2024_compatibility)]`) on by default + = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 7205c13cc2a1b..09e4d02384e92 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -1,5 +1,5 @@ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:10:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | unsafe { mem::zeroed::<()>() } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:27:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,7 +28,7 @@ LL | core::mem::transmute::<_, ()>(Zst) | +++++++++ error: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:44:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -38,7 +38,7 @@ LL | unsafe { Union { a: () }.b } = help: specify the type explicitly error: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:55:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ LL | unsafe { *ptr::from_ref(&()).cast::<()>() } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:76:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -66,7 +66,7 @@ LL | unsafe { internally_create::<()>(x) } | ++++++ error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:94:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -80,7 +80,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:89:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -94,7 +94,7 @@ LL | let zeroed = mem::zeroed::<()>; | ++++++ error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:112:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -108,7 +108,7 @@ LL | let f = internally_create::<()>; | ++++++ error: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:137:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -118,7 +118,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() = help: specify the type explicitly error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:155:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -132,7 +132,7 @@ LL | msg_send!(); = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) warning: the type `!` does not permit zero-initialization - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:10:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ this code causes undefined behavior when executed @@ -144,7 +144,7 @@ error: aborting due to 10 previous errors; 1 warning emitted Future incompatibility report: Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:12:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:10:18 | LL | unsafe { mem::zeroed() } | ^^^^^^^^^^^^^ @@ -160,7 +160,7 @@ LL | unsafe { mem::zeroed::<()>() } Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:29:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:27:13 | LL | core::mem::transmute(Zst) | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -176,7 +176,7 @@ LL | core::mem::transmute::<_, ()>(Zst) Future breakage diagnostic: error: never type fallback affects this union access - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:46:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:44:18 | LL | unsafe { Union { a: () }.b } | ^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ LL | unsafe { Union { a: () }.b } Future breakage diagnostic: error: never type fallback affects this raw pointer dereference - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:57:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:55:18 | LL | unsafe { *ptr::from_ref(&()).cast() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL | unsafe { *ptr::from_ref(&()).cast::<()>() } Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:78:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:76:18 | LL | unsafe { internally_create(x) } | ^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ LL | unsafe { internally_create::<()>(x) } Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:96:18 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:94:18 | LL | unsafe { zeroed() } | ^^^^^^^^ @@ -236,7 +236,7 @@ LL | let zeroed = mem::zeroed::<()>; Future breakage diagnostic: error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:91:22 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:89:22 | LL | let zeroed = mem::zeroed; | ^^^^^^^^^^^ @@ -252,7 +252,7 @@ LL | let zeroed = mem::zeroed::<()>; Future breakage diagnostic: error: never type fallback affects this `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:114:17 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:112:17 | LL | let f = internally_create; | ^^^^^^^^^^^^^^^^^ @@ -268,7 +268,7 @@ LL | let f = internally_create::<()>; Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` method - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:139:13 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:137:13 | LL | S(marker::PhantomData).create_out_of_thin_air() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ LL | S(marker::PhantomData).create_out_of_thin_air() Future breakage diagnostic: error: never type fallback affects this call to an `unsafe` function - --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:157:19 + --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:155:19 | LL | match send_message::<_ /* ?0 */>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs index 97e7a2f56bdaa..744fff4194cbb 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.rs @@ -1,6 +1,4 @@ //@ revisions: e2015 e2024 -//@[e2015] check-pass -//@[e2024] check-fail //@[e2024] edition:2024 use std::{marker, mem, ptr}; @@ -10,10 +8,10 @@ fn main() {} fn _zero() { if false { unsafe { mem::zeroed() } - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ error: never type fallback affects this call to an `unsafe` function //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! - //[e2024]~| warning: the type `!` does not permit zero-initialization + //[e2024]~| warn: the type `!` does not permit zero-initialization } else { return; }; @@ -27,7 +25,7 @@ fn _trans() { unsafe { struct Zst; core::mem::transmute(Zst) - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ error: never type fallback affects this call to an `unsafe` function //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! } @@ -44,7 +42,7 @@ fn _union() { } unsafe { Union { a: () }.b } - //[e2015]~^ warn: never type fallback affects this union access + //[e2015]~^ error: never type fallback affects this union access //[e2024]~^^ error: never type fallback affects this union access //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! } else { @@ -55,7 +53,7 @@ fn _union() { fn _deref() { if false { unsafe { *ptr::from_ref(&()).cast() } - //[e2015]~^ warn: never type fallback affects this raw pointer dereference + //[e2015]~^ error: never type fallback affects this raw pointer dereference //[e2024]~^^ error: never type fallback affects this raw pointer dereference //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! } else { @@ -76,7 +74,7 @@ fn _only_generics() { let x = None; unsafe { internally_create(x) } - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ error: never type fallback affects this call to an `unsafe` function //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! @@ -89,12 +87,12 @@ fn _only_generics() { fn _stored_function() { if false { let zeroed = mem::zeroed; - //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ error: never type fallback affects this `unsafe` function //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! unsafe { zeroed() } - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ error: never type fallback affects this call to an `unsafe` function //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! } else { @@ -112,7 +110,7 @@ fn _only_generics_stored_function() { let x = None; let f = internally_create; - //[e2015]~^ warn: never type fallback affects this `unsafe` function + //[e2015]~^ error: never type fallback affects this `unsafe` function //[e2024]~^^ error: never type fallback affects this `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! @@ -137,7 +135,7 @@ fn _method() { if false { unsafe { S(marker::PhantomData).create_out_of_thin_air() - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` method + //[e2015]~^ error: never type fallback affects this call to an `unsafe` method //[e2024]~^^ error: never type fallback affects this call to an `unsafe` method //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! } @@ -155,7 +153,7 @@ fn _objc() { macro_rules! msg_send { () => { match send_message::<_ /* ?0 */>() { - //[e2015]~^ warn: never type fallback affects this call to an `unsafe` function + //[e2015]~^ error: never type fallback affects this call to an `unsafe` function //[e2024]~^^ error: never type fallback affects this call to an `unsafe` function //~| warn: this changes meaning in Rust 2024 and in a future release in all editions! Ok(x) => x, diff --git a/tests/ui/never_type/never-pattern-as-closure-param-141592.rs b/tests/ui/never_type/never-pattern-as-closure-param-141592.rs new file mode 100644 index 0000000000000..78939199d09cc --- /dev/null +++ b/tests/ui/never_type/never-pattern-as-closure-param-141592.rs @@ -0,0 +1,24 @@ +#![feature(never_patterns)] +#![allow(incomplete_features)] + +enum Never {} + +fn example(x: Never) -> [i32; 1] { + let ! = x; + [1] +} + +fn function_param_never(!: Never) -> [i32; 1] { + [1] +} + +fn generic_never(!: T) -> [i32; 1] //~ ERROR mismatched types +where + T: Copy, +{ + [1] +} + +fn main() { + let _ = "12".lines().map(|!| [1]); //~ ERROR mismatched types +} diff --git a/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr b/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr new file mode 100644 index 0000000000000..ce5d3a57862bf --- /dev/null +++ b/tests/ui/never_type/never-pattern-as-closure-param-141592.stderr @@ -0,0 +1,18 @@ +error: mismatched types + --> $DIR/never-pattern-as-closure-param-141592.rs:15:21 + | +LL | fn generic_never(!: T) -> [i32; 1] + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `T` + +error: mismatched types + --> $DIR/never-pattern-as-closure-param-141592.rs:23:31 + | +LL | let _ = "12".lines().map(|!| [1]); + | ^ a never pattern must be used on an uninhabited type + | + = note: the matched value is of type `str` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index e13653f342342..af07745a00af4 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -69,6 +69,12 @@ LL | cell_x.set(cell_a.get()); // forces 'a: 'x, implies 'a = 'static -> LL | }) LL | } | - `a` dropped here while still borrowed + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:13:8 + | +LL | F: for<'x> FnOnce(Cell<&'a u32>, Cell<&'x u32>), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr index 15f48d88c379b..4136ac418deb4 100644 --- a/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr +++ b/tests/ui/nll/closure-requirements/propagate-multiple-requirements.stderr @@ -13,6 +13,12 @@ LL | z = &local_arr; ... LL | } | - `local_arr` dropped here while still borrowed + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/propagate-multiple-requirements.rs:4:21 + | +LL | fn once U>(f: F, s: S, t: T) -> U { + | ^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/nll/ice-106874.stderr b/tests/ui/nll/ice-106874.stderr index 0edbd7b44ef1c..629570b602ed6 100644 --- a/tests/ui/nll/ice-106874.stderr +++ b/tests/ui/nll/ice-106874.stderr @@ -17,6 +17,20 @@ LL | A(B(C::new(D::new(move |st| f(st))))) = note: ...but it actually implements `FnOnce<(&'1 mut V,)>`, for some specific lifetime `'1` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error: higher-ranked subtype error + --> $DIR/ice-106874.rs:8:5 + | +LL | A(B(C::new(D::new(move |st| f(st))))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: higher-ranked subtype error + --> $DIR/ice-106874.rs:8:5 + | +LL | A(B(C::new(D::new(move |st| f(st))))) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: implementation of `FnOnce` is not general enough --> $DIR/ice-106874.rs:8:7 | @@ -75,17 +89,5 @@ LL | A(B(C::new(D::new(move |st| f(st))))) = note: ...but it actually implements `Fn<(&'2 mut V,)>`, for some specific lifetime `'2` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: higher-ranked subtype error - --> $DIR/ice-106874.rs:8:7 - | -LL | A(B(C::new(D::new(move |st| f(st))))) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: higher-ranked subtype error - --> $DIR/ice-106874.rs:8:41 - | -LL | A(B(C::new(D::new(move |st| f(st))))) - | ^ - error: aborting due to 10 previous errors diff --git a/tests/ui/nll/local-outlives-static-via-hrtb.stderr b/tests/ui/nll/local-outlives-static-via-hrtb.stderr index a98f11ce51363..263d271b6b3d0 100644 --- a/tests/ui/nll/local-outlives-static-via-hrtb.stderr +++ b/tests/ui/nll/local-outlives-static-via-hrtb.stderr @@ -17,6 +17,11 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} | ^^^^^^^^^^^^^^^^^^^^^^^ +note: requirement that the value outlives `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:15:53 + | +LL | fn assert_static_via_hrtb(_: G) where for<'a> G: Outlives<'a> {} + | ^^^^^^^^^^^^ error[E0597]: `local` does not live long enough --> $DIR/local-outlives-static-via-hrtb.rs:25:45 @@ -37,6 +42,11 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | for<'a> &'a T: Reference, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: requirement that the value outlives `'static` introduced here + --> $DIR/local-outlives-static-via-hrtb.rs:19:30 + | +LL | for<'a> &'a T: Reference, + | ^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr b/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr index bf8546b63bf30..fa201b89048af 100644 --- a/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr +++ b/tests/ui/nll/polonius/lending-iterator-sanity-checks.polonius.stderr @@ -1,13 +1,15 @@ error[E0499]: cannot borrow `*t` as mutable more than once at a time --> $DIR/lending-iterator-sanity-checks.rs:19:19 | +LL | fn use_live(t: &mut T) -> Option<(T::Item<'_>, T::Item<'_>)> { + | - let's call the lifetime of this reference `'1` LL | let Some(i) = t.next() else { return None }; | - first mutable borrow occurs here LL | let Some(j) = t.next() else { return None }; | ^ second mutable borrow occurs here ... -LL | } - | - first borrow might be used here, when `i` is dropped and runs the destructor for type `::Item<'_>` +LL | Some((i, j)) + | ------------ returning this value requires that `*t` is borrowed for `'1` error[E0499]: cannot borrow `*t` as mutable more than once at a time --> $DIR/lending-iterator-sanity-checks.rs:31:13 diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr index 6e47b8e59f5c6..804b3f00a2642 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.nll.stderr @@ -18,6 +18,11 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ +note: requirement that the value outlives `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ error: implementation of `Fn` is not general enough --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5 diff --git a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr index 6e47b8e59f5c6..804b3f00a2642 100644 --- a/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr +++ b/tests/ui/nll/polonius/location-insensitive-scopes-issue-117146.polonius.stderr @@ -18,6 +18,11 @@ note: due to a current limitation of the type system, this implies a `'static` l | LL | fn bad &()>(_: F) {} | ^^^^^^^^^^^^^^ +note: requirement that the value outlives `'static` introduced here + --> $DIR/location-insensitive-scopes-issue-117146.rs:20:22 + | +LL | fn bad &()>(_: F) {} + | ^^^ error: implementation of `Fn` is not general enough --> $DIR/location-insensitive-scopes-issue-117146.rs:13:5 diff --git a/tests/ui/nll/user-annotations/dump-fn-method.rs b/tests/ui/nll/user-annotations/dump-fn-method.rs index 26714b6ffe3a6..ec349e36839ad 100644 --- a/tests/ui/nll/user-annotations/dump-fn-method.rs +++ b/tests/ui/nll/user-annotations/dump-fn-method.rs @@ -31,7 +31,7 @@ fn main() { // Here: we only want the `T` to be given, the rest should be variables. // // (`T` refers to the declaration of `Bazoom`) - let x = <_ as Bazoom>::method::<_>; //~ ERROR [^0, u32, ^1] + let x = <_ as Bazoom>::method::<_>; //~ ERROR [^c_0, u32, ^c_1] x(&22, 44, 66); // Here: all are given and definitely contain no lifetimes, so we @@ -48,7 +48,7 @@ fn main() { // // (`U` refers to the declaration of `Bazoom`) let y = 22_u32; - y.method::(44, 66); //~ ERROR [^0, ^1, u32] + y.method::(44, 66); //~ ERROR [^c_0, ^c_1, u32] // Here: nothing is given, so we don't have any annotation. let y = 22_u32; diff --git a/tests/ui/nll/user-annotations/dump-fn-method.stderr b/tests/ui/nll/user-annotations/dump-fn-method.stderr index 8e847b464e181..f00fb0013dfd8 100644 --- a/tests/ui/nll/user-annotations/dump-fn-method.stderr +++ b/tests/ui/nll/user-annotations/dump-fn-method.stderr @@ -4,7 +4,7 @@ error: user args: UserArgs { args: [&'static u32], user_self_ty: None } LL | let x = foo::<&'static u32>; | ^^^^^^^^^^^^^^^^^^^ -error: user args: UserArgs { args: [^0, u32, ^1], user_self_ty: None } +error: user args: UserArgs { args: [^c_0, u32, ^c_1], user_self_ty: None } --> $DIR/dump-fn-method.rs:34:13 | LL | let x = <_ as Bazoom>::method::<_>; @@ -16,7 +16,7 @@ error: user args: UserArgs { args: [u8, &'static u16, u32], user_self_ty: None } LL | let x = >::method::; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: user args: UserArgs { args: [^0, ^1, u32], user_self_ty: None } +error: user args: UserArgs { args: [^c_0, ^c_1, u32], user_self_ty: None } --> $DIR/dump-fn-method.rs:51:5 | LL | y.method::(44, 66); diff --git a/tests/ui/no_std/no-std-panic-abort-error-64430.rs b/tests/ui/no_std/no-std-panic-abort-error-64430.rs new file mode 100644 index 0000000000000..bd25597d6d754 --- /dev/null +++ b/tests/ui/no_std/no-std-panic-abort-error-64430.rs @@ -0,0 +1,15 @@ +// https://github.com/rust-lang/rust/issues/64430 +//@ compile-flags:-C panic=abort + +#![no_std] +pub struct Foo; + +fn main() { + Foo.bar() + //~^ ERROR E0599 +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop{} +} diff --git a/tests/ui/no_std/no-std-panic-abort-error-64430.stderr b/tests/ui/no_std/no-std-panic-abort-error-64430.stderr new file mode 100644 index 0000000000000..452721cd4fdd7 --- /dev/null +++ b/tests/ui/no_std/no-std-panic-abort-error-64430.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `bar` found for struct `Foo` in the current scope + --> $DIR/no-std-panic-abort-error-64430.rs:8:9 + | +LL | pub struct Foo; + | -------------- method `bar` not found for this struct +... +LL | Foo.bar() + | ^^^ method not found in `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/not-panic/not-panic-safe-2.stderr b/tests/ui/not-panic/not-panic-safe-2.stderr index 0c399f15a25bb..86b829f726295 100644 --- a/tests/ui/not-panic/not-panic-safe-2.stderr +++ b/tests/ui/not-panic/not-panic-safe-2.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `RefCell` @@ -14,11 +14,11 @@ note: required by a bound in `assert` LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-2.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `Cell` diff --git a/tests/ui/not-panic/not-panic-safe-3.stderr b/tests/ui/not-panic/not-panic-safe-3.stderr index 53028d6a3371a..34ad92361a4f9 100644 --- a/tests/ui/not-panic/not-panic-safe-3.stderr +++ b/tests/ui/not-panic/not-panic-safe-3.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `RefCell` @@ -14,11 +14,11 @@ note: required by a bound in `assert` LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-3.rs:10:14 | LL | assert::>>(); - | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `Cell` diff --git a/tests/ui/not-panic/not-panic-safe-4.stderr b/tests/ui/not-panic/not-panic-safe-4.stderr index b1361cfd87ef2..8597bc3c0dd0d 100644 --- a/tests/ui/not-panic/not-panic-safe-4.stderr +++ b/tests/ui/not-panic/not-panic-safe-4.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `RefCell` @@ -19,11 +19,11 @@ LL - assert::<&RefCell>(); LL + assert::>(); | -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-4.rs:9:14 | LL | assert::<&RefCell>(); - | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `Cell` diff --git a/tests/ui/not-panic/not-panic-safe-5.stderr b/tests/ui/not-panic/not-panic-safe-5.stderr index fbbd81d6d4c53..c987b746988e7 100644 --- a/tests/ui/not-panic/not-panic-safe-5.stderr +++ b/tests/ui/not-panic/not-panic-safe-5.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-5.rs:9:14 | LL | assert::<*const UnsafeCell>(); - | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell` = note: required for `*const UnsafeCell` to implement `UnwindSafe` diff --git a/tests/ui/not-panic/not-panic-safe-6.stderr b/tests/ui/not-panic/not-panic-safe-6.stderr index 47f28257409eb..720f114f6d936 100644 --- a/tests/ui/not-panic/not-panic-safe-6.stderr +++ b/tests/ui/not-panic/not-panic-safe-6.stderr @@ -1,8 +1,8 @@ -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `RefCell` @@ -14,11 +14,11 @@ note: required by a bound in `assert` LL | fn assert() {} | ^^^^^^^^^^ required by this bound in `assert` -error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary +error[E0277]: the type `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary --> $DIR/not-panic-safe-6.rs:9:14 | LL | assert::<*mut RefCell>(); - | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | ^^^^^^^^^^^^^^^^^ `UnsafeCell` may contain interior mutability and a reference may not be safely transferable across a catch_unwind boundary | = help: within `RefCell`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell` note: required because it appears within the type `Cell` diff --git a/tests/ui/numbers-arithmetic/int-abs-overflow.rs b/tests/ui/numbers-arithmetic/int-abs-overflow.rs index 6397f62d06551..fd4a5a6052b83 100644 --- a/tests/ui/numbers-arithmetic/int-abs-overflow.rs +++ b/tests/ui/numbers-arithmetic/int-abs-overflow.rs @@ -2,6 +2,7 @@ //@ compile-flags: -C overflow-checks=on //@ needs-threads //@ needs-unwind +//@ ignore-backends: gcc use std::thread; diff --git a/tests/ui/numbers-arithmetic/issue-8460.rs b/tests/ui/numbers-arithmetic/issue-8460.rs index 87867fdc93e41..52df432669f12 100644 --- a/tests/ui/numbers-arithmetic/issue-8460.rs +++ b/tests/ui/numbers-arithmetic/issue-8460.rs @@ -2,6 +2,7 @@ #![allow(unused_must_use)] //@ needs-threads //@ needs-unwind +//@ ignore-backends: gcc #![feature(rustc_attrs)] use std::thread; diff --git a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs index 23e5852335611..ab3887f2e4108 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-default-to-static.rs @@ -3,7 +3,7 @@ // fields and fn arguments. -#![allow(dead_code)] +#![allow(dead_code, unused)] trait Test { fn foo(&self) { } diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs index 040ac1f891326..e74e67f5b6891 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-ref-struct.rs @@ -3,7 +3,7 @@ // lifetime bound. -#![allow(dead_code)] +#![allow(dead_code, unused)] use std::fmt::Display; diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs index c3f3101155cf1..2402bb24d787f 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-box.rs @@ -3,7 +3,7 @@ // through the `Box` struct. -#![allow(dead_code)] +#![allow(dead_code, unused)] trait Test { fn foo(&self) { } diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs index db4f9a40235d4..03a4cb9ec709e 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-mut.rs @@ -3,7 +3,7 @@ // lifetime bound. -#![allow(dead_code)] +#![allow(dead_code, unused)] trait Test { fn foo(&self) { } diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs index 5163ff1c2455a..988cef49fe03e 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr-struct.rs @@ -3,7 +3,7 @@ // through the `MyBox` struct. -#![allow(dead_code)] +#![allow(dead_code, unused)] trait Test { fn foo(&self) { } diff --git a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs index 556bde784152d..d4fc295f4fc62 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-from-rptr.rs @@ -3,7 +3,7 @@ // lifetime bound. -#![allow(dead_code)] +#![allow(dead_code, unused)] use std::fmt::Display; diff --git a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs index 1ab821764de08..d3162231faf77 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-inferred.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-inferred.rs @@ -3,7 +3,7 @@ // valid. -#![allow(dead_code)] +#![allow(dead_code, unused)] trait Test { fn foo(&self) { } diff --git a/tests/ui/or-patterns/binding-typo-2.rs b/tests/ui/or-patterns/binding-typo-2.rs index 275b68a22e22f..59df4459b88ef 100644 --- a/tests/ui/or-patterns/binding-typo-2.rs +++ b/tests/ui/or-patterns/binding-typo-2.rs @@ -16,8 +16,8 @@ fn foo(x: (Lol, Lol)) { //~| HELP: you might have meant to use the similarly named previously used binding `Bar` //~| NOTE: pattern doesn't bind `Ban` //~| NOTE: variable not in all patterns - //~| ERROR: variable `Ban` is assigned to, but never used - //~| NOTE: consider using `_Ban` instead + //~| ERROR: unused variable: `Ban` + //~| HELP: if this is intentional, prefix it with an underscore //~| HELP: you might have meant to pattern match on the similarly named _ => {} } @@ -27,8 +27,8 @@ fn foo(x: (Lol, Lol)) { //~| HELP: you might have meant to use the similarly named unit variant `Bar` //~| NOTE: pattern doesn't bind `Ban` //~| NOTE: variable not in all patterns - //~| ERROR: variable `Ban` is assigned to, but never used - //~| NOTE: consider using `_Ban` instead + //~| ERROR: unused variable: `Ban` + //~| HELP: if this is intentional, prefix it with an underscore //~| HELP: you might have meant to pattern match on the similarly named _ => {} } @@ -73,8 +73,8 @@ fn bar(x: (Lol, Lol)) { //~| HELP: you might have meant to use the similarly named constant `Bat` //~| NOTE: pattern doesn't bind `Ban` //~| NOTE: variable not in all patterns - //~| ERROR: variable `Ban` is assigned to, but never used - //~| NOTE: consider using `_Ban` instead + //~| ERROR: unused variable: `Ban` + //~| HELP: if this is intentional, prefix it with an underscore //~| HELP: you might have meant to pattern match on the similarly named _ => {} } @@ -89,8 +89,8 @@ fn baz(x: (Lol, Lol)) { //~| HELP: you might have meant to use the similarly named constant `Bat` //~| NOTE: pattern doesn't bind `Ban` //~| NOTE: variable not in all patterns - //~| ERROR: variable `Ban` is assigned to, but never used - //~| NOTE: consider using `_Ban` instead + //~| ERROR: unused variable: `Ban` + //~| HELP: if this is intentional, prefix it with an underscore //~| HELP: you might have meant to pattern match on the similarly named _ => {} } diff --git a/tests/ui/or-patterns/binding-typo-2.stderr b/tests/ui/or-patterns/binding-typo-2.stderr index 81ea6e6b1bc08..23b570b3c23cf 100644 --- a/tests/ui/or-patterns/binding-typo-2.stderr +++ b/tests/ui/or-patterns/binding-typo-2.stderr @@ -97,13 +97,12 @@ LL - (Foo, _) | (Ban, Foo) => {} LL + (Foo, _) | (Bat, Foo) => {} | -error: variable `Ban` is assigned to, but never used +error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:14:23 | LL | (Foo, Bar) | (Ban, Foo) => {} | ^^^ | - = note: consider using `_Ban` instead note: the lint level is defined here --> $DIR/binding-typo-2.rs:2:9 | @@ -114,19 +113,26 @@ help: you might have meant to pattern match on the similarly named variant `Bar` LL - (Foo, Bar) | (Ban, Foo) => {} LL + (Foo, Bar) | (Lol::Bar, Foo) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | (Foo, Bar) | (_Ban, Foo) => {} + | + -error: variable `Ban` is assigned to, but never used +error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:25:21 | LL | (Foo, _) | (Ban, Foo) => {} | ^^^ | - = note: consider using `_Ban` instead help: you might have meant to pattern match on the similarly named variant `Bar` | LL - (Foo, _) | (Ban, Foo) => {} LL + (Foo, _) | (Lol::Bar, Foo) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | (Foo, _) | (_Ban, Foo) => {} + | + error: unused variable: `Non` --> $DIR/binding-typo-2.rs:37:9 @@ -134,15 +140,15 @@ error: unused variable: `Non` LL | Non => {} | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | _Non => {} - | + help: you might have meant to pattern match on the similarly named variant `None` | LL - Non => {} LL + std::prelude::v1::None => {} | +help: if this is intentional, prefix it with an underscore + | +LL | _Non => {} + | + error: unused variable: `Non` --> $DIR/binding-typo-2.rs:44:9 @@ -150,15 +156,15 @@ error: unused variable: `Non` LL | Non | None => {} | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | _Non | None => {} - | + help: you might have meant to pattern match on the similarly named variant `None` | LL - Non | None => {} LL + std::prelude::v1::None | None => {} | +help: if this is intentional, prefix it with an underscore + | +LL | _Non | None => {} + | + error: unused variable: `Non` --> $DIR/binding-typo-2.rs:54:9 @@ -166,41 +172,47 @@ error: unused variable: `Non` LL | Non | Some(_) => {} | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | _Non | Some(_) => {} - | + help: you might have meant to pattern match on the similarly named variant `None` | LL - Non | Some(_) => {} LL + std::prelude::v1::None | Some(_) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | _Non | Some(_) => {} + | + -error: variable `Ban` is assigned to, but never used +error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:69:21 | LL | (Foo, _) | (Ban, Foo) => {} | ^^^ | - = note: consider using `_Ban` instead help: you might have meant to pattern match on the similarly named variant `Bar` | LL - (Foo, _) | (Ban, Foo) => {} LL + (Foo, _) | (Lol::Bar, Foo) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | (Foo, _) | (_Ban, Foo) => {} + | + -error: variable `Ban` is assigned to, but never used +error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:86:21 | LL | (Foo, _) | (Ban, Foo) => {} | ^^^ | - = note: consider using `_Ban` instead help: you might have meant to pattern match on the similarly named variant `Bar` | LL - (Foo, _) | (Ban, Foo) => {} LL + (Foo, _) | (Lol::Bar, Foo) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | (Foo, _) | (_Ban, Foo) => {} + | + error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:98:10 @@ -208,15 +220,15 @@ error: unused variable: `Ban` LL | (Ban, _) => {} | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | (_Ban, _) => {} - | + help: you might have meant to pattern match on the similarly named variant `Bar` | LL - (Ban, _) => {} LL + (Lol::Bar, _) => {} | +help: if this is intentional, prefix it with an underscore + | +LL | (_Ban, _) => {} + | + error: unused variable: `Ban` --> $DIR/binding-typo-2.rs:104:9 @@ -224,15 +236,15 @@ error: unused variable: `Ban` LL | Ban => {} | ^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | _Ban => {} - | + help: you might have meant to pattern match on the similarly named struct `Bay` | LL - Ban => {} LL + Bay => {} | +help: if this is intentional, prefix it with an underscore + | +LL | _Ban => {} + | + error: unused variable: `Batery` --> $DIR/binding-typo-2.rs:110:9 @@ -240,14 +252,14 @@ error: unused variable: `Batery` LL | Batery => {} | ^^^^^^ | -help: if this is intentional, prefix it with an underscore - | -LL | _Batery => {} - | + help: you might have meant to pattern match on the similarly named constant `Battery` | LL | Battery => {} | + +help: if this is intentional, prefix it with an underscore + | +LL | _Batery => {} + | + error: aborting due to 16 previous errors diff --git a/tests/ui/packed/packed-struct-drop-aligned.rs b/tests/ui/packed/packed-struct-drop-aligned.rs index ba3dcb10c61e5..e8125115d45e6 100644 --- a/tests/ui/packed/packed-struct-drop-aligned.rs +++ b/tests/ui/packed/packed-struct-drop-aligned.rs @@ -1,6 +1,8 @@ //@ run-pass #![feature(coroutines, stmt_expr_attributes)] #![feature(coroutine_trait)] +#![allow(unused_assignments, unused_variables)] + use std::cell::Cell; use std::mem; use std::ops::Coroutine; diff --git a/tests/ui/panic-handler/catch-unwind-during-unwind-68696.rs b/tests/ui/panic-handler/catch-unwind-during-unwind-68696.rs new file mode 100644 index 0000000000000..b4645a39691c2 --- /dev/null +++ b/tests/ui/panic-handler/catch-unwind-during-unwind-68696.rs @@ -0,0 +1,28 @@ +// https://github.com/rust-lang/rust/issues/68696 +// Checks that catch_unwind can be used if unwinding is already in progress. +// Used to fail when standard library had been compiled with debug assertions, +// due to incorrect assumption that a current thread is not panicking when +// entering the catch_unwind. +// +//@ run-pass +//@ ignore-backends: gcc + +use std::panic::catch_unwind; + +#[allow(dead_code)] +#[derive(Default)] +struct Guard; + +impl Drop for Guard { + fn drop(&mut self) { + let _ = catch_unwind(|| {}); + } +} + +fn main() { + #[cfg(panic = "unwind")] + let _ = catch_unwind(|| { + let _guard = Guard::default(); + panic!(); + }); +} diff --git a/tests/ui/panic-runtime/auxiliary/needs-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-abort.rs index 21f862e4b431c..cba4907dbb633 100644 --- a/tests/ui/panic-runtime/auxiliary/needs-abort.rs +++ b/tests/ui/panic-runtime/auxiliary/needs-abort.rs @@ -1,5 +1,7 @@ //@ compile-flags:-C panic=abort //@ no-prefer-dynamic +#![feature(no_core)] #![crate_type = "rlib"] #![no_std] +#![no_core] diff --git a/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs new file mode 100644 index 0000000000000..4a41d16faa080 --- /dev/null +++ b/tests/ui/panic-runtime/auxiliary/needs-immediate-abort.rs @@ -0,0 +1,7 @@ +//@ compile-flags:-C panic=immediate-abort -Zunstable-options +//@ no-prefer-dynamic + +#![feature(no_core)] +#![crate_type = "rlib"] +#![no_std] +#![no_core] diff --git a/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs new file mode 100644 index 0000000000000..295876fec5279 --- /dev/null +++ b/tests/ui/panic-runtime/auxiliary/needs-unwind-immediate-abort.rs @@ -0,0 +1,18 @@ +//@ compile-flags:-C panic=unwind +//@ no-prefer-dynamic +//@ add-core-stubs + +#![crate_type = "rlib"] +#![feature(no_core)] +#![no_std] +#![no_core] + +extern crate minicore; + +extern "C-unwind" fn foo() {} + +#[inline] +fn bar() { + let ptr: extern "C-unwind" fn() = foo; + ptr(); +} diff --git a/tests/ui/panic-runtime/bad-panic-flag1.rs b/tests/ui/panic-runtime/bad-panic-flag1.rs index 117935847cbd7..575e30f785cf5 100644 --- a/tests/ui/panic-runtime/bad-panic-flag1.rs +++ b/tests/ui/panic-runtime/bad-panic-flag1.rs @@ -2,4 +2,4 @@ fn main() {} -//~? ERROR incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected +//~? ERROR incorrect value `foo` for codegen option `panic` - either `unwind`, `abort`, or `immediate-abort` was expected diff --git a/tests/ui/panic-runtime/bad-panic-flag1.stderr b/tests/ui/panic-runtime/bad-panic-flag1.stderr index 013373c6f9313..c30598bba538e 100644 --- a/tests/ui/panic-runtime/bad-panic-flag1.stderr +++ b/tests/ui/panic-runtime/bad-panic-flag1.stderr @@ -1,2 +1,2 @@ -error: incorrect value `foo` for codegen option `panic` - either `unwind` or `abort` was expected +error: incorrect value `foo` for codegen option `panic` - either `unwind`, `abort`, or `immediate-abort` was expected diff --git a/tests/ui/panic-runtime/bad-panic-flag2.rs b/tests/ui/panic-runtime/bad-panic-flag2.rs index b5d0442a03326..4e34da217d7d2 100644 --- a/tests/ui/panic-runtime/bad-panic-flag2.rs +++ b/tests/ui/panic-runtime/bad-panic-flag2.rs @@ -2,4 +2,4 @@ fn main() {} -//~? ERROR codegen option `panic` requires either `unwind` or `abort` +//~? ERROR codegen option `panic` requires either `unwind`, `abort`, or `immediate-abort` diff --git a/tests/ui/panic-runtime/bad-panic-flag2.stderr b/tests/ui/panic-runtime/bad-panic-flag2.stderr index 6ab94ea704d30..c8d12749c5d96 100644 --- a/tests/ui/panic-runtime/bad-panic-flag2.stderr +++ b/tests/ui/panic-runtime/bad-panic-flag2.stderr @@ -1,2 +1,2 @@ -error: codegen option `panic` requires either `unwind` or `abort` (C panic=) +error: codegen option `panic` requires either `unwind`, `abort`, or `immediate-abort` (C panic=) diff --git a/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs b/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs new file mode 100644 index 0000000000000..94dc7c5671ead --- /dev/null +++ b/tests/ui/panic-runtime/immediate-abort-default-sysroot.rs @@ -0,0 +1,15 @@ +//@ build-fail +//@ aux-build:needs-unwind.rs +//@ compile-flags:-C panic=immediate-abort -Zunstable-options +//@ no-prefer-dynamic + +extern crate needs_unwind; + +// immediate-abort does not require any panic runtime, so trying to build a binary crate with +// panic=immediate-abort and the precompiled sysroot will fail to link, because no panic runtime +// provides the panic entrypoints used by sysroot crates. +// This test ensures that we get a clean compile error instead of a linker error. + +fn main() {} + +//~? ERROR the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort` diff --git a/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr b/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr new file mode 100644 index 0000000000000..bd6bdd8b6673a --- /dev/null +++ b/tests/ui/panic-runtime/immediate-abort-default-sysroot.stderr @@ -0,0 +1,4 @@ +error: the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort` + +error: aborting due to 1 previous error + diff --git a/tests/ui/panic-runtime/lto-unwind.rs b/tests/ui/panic-runtime/lto-unwind.rs index 93275052f8527..bafc6d5aaa5c5 100644 --- a/tests/ui/panic-runtime/lto-unwind.rs +++ b/tests/ui/panic-runtime/lto-unwind.rs @@ -3,6 +3,7 @@ //@ needs-unwind //@ no-prefer-dynamic //@ needs-subprocess +//@ ignore-backends: gcc use std::process::Command; use std::env; diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs new file mode 100644 index 0000000000000..78977c60be985 --- /dev/null +++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.rs @@ -0,0 +1,21 @@ +//@ build-fail +//@ aux-build:needs-abort.rs +//@ compile-flags:-Cpanic=immediate-abort -Zunstable-options +//@ no-prefer-dynamic +//@ add-core-stubs +//@ core-stubs-compile-flags: -Cpanic=immediate-abort -Zunstable-options + +#![feature(no_core)] +#![no_std] +#![no_main] +#![no_core] + +extern crate minicore; +extern crate needs_abort; + +#[no_mangle] +extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { + 0 +} + +//~? ERROR the crate `needs_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` diff --git a/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr b/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr new file mode 100644 index 0000000000000..65a26b676b92e --- /dev/null +++ b/tests/ui/panic-runtime/need-abort-got-immediate-abort.stderr @@ -0,0 +1,4 @@ +error: the crate `needs_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` + +error: aborting due to 1 previous error + diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs new file mode 100644 index 0000000000000..1c5f597a3f992 --- /dev/null +++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.rs @@ -0,0 +1,20 @@ +//@ build-fail +//@ aux-build:needs-immediate-abort.rs +//@ compile-flags:-C panic=abort +//@ no-prefer-dynamic +//@ add-core-stubs +//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort + +#![feature(no_core)] +#![no_std] +#![no_main] +#![no_core] + +extern crate minicore; +extern crate needs_immediate_abort; + +extern "C" fn main(argc: i32, argv: *const *const u8) -> i32 { + 0 +} + +//~? ERROR the crate `need_immediate_abort_got_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr b/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr new file mode 100644 index 0000000000000..8dcf120cb9f46 --- /dev/null +++ b/tests/ui/panic-runtime/need-immediate-abort-got-abort.stderr @@ -0,0 +1,4 @@ +error: the crate `need_immediate_abort_got_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` + +error: aborting due to 1 previous error + diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs new file mode 100644 index 0000000000000..24d521230d49a --- /dev/null +++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.rs @@ -0,0 +1,20 @@ +//@ build-fail +//@ needs-unwind +//@ aux-build:needs-immediate-abort.rs +//@ no-prefer-dynamic +//@ add-core-stubs +//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort + +#![feature(no_core)] +#![no_std] +#![no_main] +#![no_core] + +extern crate minicore; +extern crate needs_immediate_abort; + +extern "C" fn main(argc: i32, argv: *const *const u8) -> i32 { + 0 +} + +//~? ERROR the crate `need_immediate_abort_got_unwind` was compiled with a panic strategy which is incompatible with `immediate-abort` diff --git a/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr new file mode 100644 index 0000000000000..740fc80a77df8 --- /dev/null +++ b/tests/ui/panic-runtime/need-immediate-abort-got-unwind.stderr @@ -0,0 +1,4 @@ +error: the crate `need_immediate_abort_got_unwind` was compiled with a panic strategy which is incompatible with `immediate-abort` + +error: aborting due to 1 previous error + diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs new file mode 100644 index 0000000000000..5aec028a46cf7 --- /dev/null +++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.rs @@ -0,0 +1,21 @@ +//@ build-fail +//@ aux-build:needs-unwind-immediate-abort.rs +//@ compile-flags:-C panic=immediate-abort -Zunstable-options +//@ no-prefer-dynamic +//@ add-core-stubs +//@ core-stubs-compile-flags: -Zunstable-options -Cpanic=immediate-abort + +#![feature(no_core)] +#![no_std] +#![no_main] +#![no_core] + +extern crate minicore; +extern crate needs_unwind_immediate_abort; + +#[no_mangle] +extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 { + 0 +} + +//~? ERROR the crate `needs_unwind_immediate_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` diff --git a/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr new file mode 100644 index 0000000000000..8b3747d644f13 --- /dev/null +++ b/tests/ui/panic-runtime/need-unwind-got-immediate-abort.stderr @@ -0,0 +1,4 @@ +error: the crate `needs_unwind_immediate_abort` was compiled with a panic strategy which is incompatible with `immediate-abort` + +error: aborting due to 1 previous error + diff --git a/tests/ui/panics/oom-panic-unwind.rs b/tests/ui/panics/oom-panic-unwind.rs index 5974ad91406f3..4f7939ce60b20 100644 --- a/tests/ui/panics/oom-panic-unwind.rs +++ b/tests/ui/panics/oom-panic-unwind.rs @@ -5,6 +5,7 @@ //@ no-prefer-dynamic //@ needs-unwind //@ only-linux +//@ ignore-backends: gcc use std::hint::black_box; use std::mem::forget; diff --git a/tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs b/tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs new file mode 100644 index 0000000000000..00c90b30af968 --- /dev/null +++ b/tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs @@ -0,0 +1,58 @@ +//! Test that with `-C panic=abort` the backtrace is not cut off by default +//! (i.e. without using `-C force-unwind-tables=yes`) by ensuring that our own +//! functions are in the backtrace. If we just check one function it might be +//! the last function, so make sure the backtrace can continue by checking for +//! two functions. Regression test for +//! . + +//@ run-pass +//@ needs-subprocess +// We want to test if unwind tables are emitted by default. We must make sure +// to disable debuginfo to test that, because enabling debuginfo also means that +// unwind tables are emitted, which prevents us from testing what we want. +// We also need to set opt-level=0 to avoid optimizing away our functions. +//@ compile-flags: -C panic=abort -C opt-level=0 -C debuginfo=0 +//@ no-prefer-dynamic +//@ ignore-apple +//@ ignore-arm-unknown-linux-gnueabihf FIXME(#146996) Try removing this once #146996 has been fixed. +//@ ignore-msvc Backtraces on Windows requires debuginfo which we can't use here +//@ ignore-backends: gcc + +static FN_1: &str = "this_function_must_be_in_the_backtrace"; +fn this_function_must_be_in_the_backtrace() { + and_this_function_too(); +} + +static FN_2: &str = "and_this_function_too"; +fn and_this_function_too() { + panic!("generate panic backtrace"); +} + +fn run_test() { + let output = std::process::Command::new(std::env::current_exe().unwrap()) + .arg("whatever") + .env("RUST_BACKTRACE", "full") + .output() + .unwrap(); + let backtrace = std::str::from_utf8(&output.stderr).unwrap(); + + fn assert(function_name: &str, backtrace: &str) { + assert!( + backtrace.contains(function_name), + "ERROR: no `{}` in stderr! actual stderr: {}", + function_name, + backtrace + ); + } + assert(FN_1, backtrace); + assert(FN_2, backtrace); +} + +fn main() { + let args: Vec = std::env::args().collect(); + if args.len() == 1 { + run_test(); + } else { + this_function_must_be_in_the_backtrace(); + } +} diff --git a/tests/ui/panics/panic-handler-chain-update-hook.rs b/tests/ui/panics/panic-handler-chain-update-hook.rs index 662ea9e978f70..2ae79ad236ef2 100644 --- a/tests/ui/panics/panic-handler-chain-update-hook.rs +++ b/tests/ui/panics/panic-handler-chain-update-hook.rs @@ -3,6 +3,7 @@ #![allow(stable_features)] //@ needs-threads +//@ ignore-backends: gcc #![feature(std_panic)] #![feature(panic_update_hook)] diff --git a/tests/ui/panics/panic-handler-chain.rs b/tests/ui/panics/panic-handler-chain.rs index fea71ad9ec4e3..cc591c1d9992d 100644 --- a/tests/ui/panics/panic-handler-chain.rs +++ b/tests/ui/panics/panic-handler-chain.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc #![allow(stable_features)] #![feature(std_panic)] diff --git a/tests/ui/panics/panic-handler-flail-wildly.rs b/tests/ui/panics/panic-handler-flail-wildly.rs index d42dfd68d9cf8..d5f5195d38121 100644 --- a/tests/ui/panics/panic-handler-flail-wildly.rs +++ b/tests/ui/panics/panic-handler-flail-wildly.rs @@ -5,6 +5,7 @@ #![allow(unused_must_use)] //@ needs-threads +//@ ignore-backends: gcc #![feature(std_panic)] diff --git a/tests/ui/panics/panic-handler-set-twice.rs b/tests/ui/panics/panic-handler-set-twice.rs index 5f670d5f49298..ca4ed65f5683d 100644 --- a/tests/ui/panics/panic-handler-set-twice.rs +++ b/tests/ui/panics/panic-handler-set-twice.rs @@ -6,6 +6,7 @@ #![feature(std_panic)] //@ needs-threads +//@ ignore-backends: gcc use std::sync::atomic::{AtomicUsize, Ordering}; use std::panic; diff --git a/tests/ui/panics/panic-in-dtor-drops-fields.rs b/tests/ui/panics/panic-in-dtor-drops-fields.rs index 38eb6d0acfb81..db07923433752 100644 --- a/tests/ui/panics/panic-in-dtor-drops-fields.rs +++ b/tests/ui/panics/panic-in-dtor-drops-fields.rs @@ -4,6 +4,7 @@ #![allow(non_upper_case_globals)] //@ needs-threads +//@ ignore-backends: gcc use std::thread; diff --git a/tests/ui/panics/panic-recover-propagate.rs b/tests/ui/panics/panic-recover-propagate.rs index ef6ae4fd7887d..36ca279bdbd25 100644 --- a/tests/ui/panics/panic-recover-propagate.rs +++ b/tests/ui/panics/panic-recover-propagate.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc use std::sync::atomic::{AtomicUsize, Ordering}; use std::panic; diff --git a/tests/ui/panics/rvalue-cleanup-during-box-panic.rs b/tests/ui/panics/rvalue-cleanup-during-box-panic.rs index 84c5d85d7e096..03571f111aac0 100644 --- a/tests/ui/panics/rvalue-cleanup-during-box-panic.rs +++ b/tests/ui/panics/rvalue-cleanup-during-box-panic.rs @@ -21,6 +21,7 @@ // scenario worth testing. //@ needs-threads +//@ ignore-backends: gcc use std::thread; diff --git a/tests/ui/panics/unwind-force-no-unwind-tables.rs b/tests/ui/panics/unwind-force-no-unwind-tables.rs index 2226e4dd03ebc..715f288fff10e 100644 --- a/tests/ui/panics/unwind-force-no-unwind-tables.rs +++ b/tests/ui/panics/unwind-force-no-unwind-tables.rs @@ -6,6 +6,7 @@ //@ needs-unwind //@ ignore-windows target requires uwtable //@ compile-flags: -C panic=unwind -C force-unwind-tables=n +//@ ignore-backends: gcc use std::panic::{self, AssertUnwindSafe}; diff --git a/tests/ui/issues/issue-69130.rs b/tests/ui/parser/character-indexing-bug-in-splice-lines-69130.rs similarity index 100% rename from tests/ui/issues/issue-69130.rs rename to tests/ui/parser/character-indexing-bug-in-splice-lines-69130.rs diff --git a/tests/ui/parser/character-indexing-bug-in-splice-lines-69130.stderr b/tests/ui/parser/character-indexing-bug-in-splice-lines-69130.stderr new file mode 100644 index 0000000000000..a06532b67d3a3 --- /dev/null +++ b/tests/ui/parser/character-indexing-bug-in-splice-lines-69130.stderr @@ -0,0 +1,21 @@ +error: unknown start of token: \u{a7} + --> $DIR/character-indexing-bug-in-splice-lines-69130.rs:4:4 + | +LL | M (§& u8)} + | ^ + +error[E0106]: missing lifetime specifier + --> $DIR/character-indexing-bug-in-splice-lines-69130.rs:4:5 + | +LL | M (§& u8)} + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ enum F<'a> { +LL ~ M (§&'a u8)} + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/parser/expr-as-stmt.fixed b/tests/ui/parser/expr-as-stmt.fixed index bfae55047ed1b..b3a491200ed10 100644 --- a/tests/ui/parser/expr-as-stmt.fixed +++ b/tests/ui/parser/expr-as-stmt.fixed @@ -66,7 +66,7 @@ fn asteroids() -> impl FnOnce() -> bool { // https://github.com/rust-lang/rust/issues/105179 fn r#match() -> i32 { - ((match () { () => 1 })) + match () { () => 1 } //~ ERROR expected expression, found `+` + (match () { () => 1 }) + match () { () => 1 } //~ ERROR expected expression, found `+` //~^ ERROR mismatched types } @@ -82,7 +82,7 @@ fn matches() -> bool { (match () { _ => true }) && match () { _ => true }; //~ ERROR mismatched types //~^ ERROR expected `;`, found keyword `match` (match () { _ => true }) && true; //~ ERROR mismatched types - ((match () { _ => true })) && true //~ ERROR mismatched types + (match () { _ => true }) && true //~ ERROR mismatched types //~^ ERROR mismatched types } fn main() {} diff --git a/tests/ui/parser/inner-attr.rs b/tests/ui/parser/inner-attr.rs index 1b405e20e0384..e66227c3d2b9f 100644 --- a/tests/ui/parser/inner-attr.rs +++ b/tests/ui/parser/inner-attr.rs @@ -1,4 +1,4 @@ -#[feature(lang_items)] +#[feature(lang_items)] //~ WARN crate-level attribute should be an inner attribute #![recursion_limit="100"] //~ ERROR an inner attribute is not permitted following an outer attribute fn main() {} diff --git a/tests/ui/parser/inner-attr.stderr b/tests/ui/parser/inner-attr.stderr index 18a82ea4c3856..3fb2d60ee5b66 100644 --- a/tests/ui/parser/inner-attr.stderr +++ b/tests/ui/parser/inner-attr.stderr @@ -11,5 +11,17 @@ LL | fn main() {} | = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -error: aborting due to 1 previous error +warning: crate-level attribute should be an inner attribute + --> $DIR/inner-attr.rs:1:1 + | +LL | #[feature(lang_items)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` +help: add a `!` + | +LL | #![feature(lang_items)] + | + + +error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/parser/intersection-patterns-1.fixed b/tests/ui/parser/intersection-patterns-1.fixed index 8ade795f7eef9..3ac9837e1a4da 100644 --- a/tests/ui/parser/intersection-patterns-1.fixed +++ b/tests/ui/parser/intersection-patterns-1.fixed @@ -9,6 +9,7 @@ //@ run-rustfix #![allow(unused_variables)] +#![allow(unused_assignments)] fn main() { let s: Option = None; diff --git a/tests/ui/parser/intersection-patterns-1.rs b/tests/ui/parser/intersection-patterns-1.rs index b5a7892fd1c5a..aab3655540505 100644 --- a/tests/ui/parser/intersection-patterns-1.rs +++ b/tests/ui/parser/intersection-patterns-1.rs @@ -9,6 +9,7 @@ //@ run-rustfix #![allow(unused_variables)] +#![allow(unused_assignments)] fn main() { let s: Option = None; diff --git a/tests/ui/parser/intersection-patterns-1.stderr b/tests/ui/parser/intersection-patterns-1.stderr index c191b46fa45db..8bcb884d8e7cb 100644 --- a/tests/ui/parser/intersection-patterns-1.stderr +++ b/tests/ui/parser/intersection-patterns-1.stderr @@ -1,5 +1,5 @@ error: pattern on wrong side of `@` - --> $DIR/intersection-patterns-1.rs:17:9 + --> $DIR/intersection-patterns-1.rs:18:9 | LL | Some(x) @ y => {} | -------^^^- @@ -14,7 +14,7 @@ LL + y @ Some(x) => {} | error: pattern on wrong side of `@` - --> $DIR/intersection-patterns-1.rs:27:9 + --> $DIR/intersection-patterns-1.rs:28:9 | LL | 1 ..= 5 @ e => {} | -------^^^- diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr index e96c004fb3516..40916ce321e37 100644 --- a/tests/ui/parser/issues/issue-24375.stderr +++ b/tests/ui/parser/issues/issue-24375.stderr @@ -13,7 +13,7 @@ LL + val if val == tmp[0] => {} help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = tmp[0]; -LL ~ match z { +LL | match z { LL ~ VAL => {} | diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs index d081c06044f14..e1ea38f2795df 100644 --- a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs +++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs @@ -37,10 +37,9 @@ fn g1() { //~| HELP: maybe write a path separator here _ => {} } - if let Foo:Bar = f() { //~ WARN: irrefutable `if let` pattern + if let Foo:Bar = f() { //~^ ERROR: expected one of //~| HELP: maybe write a path separator here - //~| HELP: consider replacing the `if let` with a `let` } } diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr index a9bad96f9af76..061586882e0c9 100644 --- a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr +++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr @@ -64,7 +64,7 @@ LL | if let Foo::Bar = f() { | + error: expected one of `@` or `|`, found `:` - --> $DIR/issue-87086-colon-path-sep.rs:49:16 + --> $DIR/issue-87086-colon-path-sep.rs:48:16 | LL | ref qux: Foo::Baz => {} | ^ -------- specifying the type of a pattern isn't supported @@ -77,7 +77,7 @@ LL | ref qux::Foo::Baz => {} | ~~ error: expected one of `@` or `|`, found `:` - --> $DIR/issue-87086-colon-path-sep.rs:58:16 + --> $DIR/issue-87086-colon-path-sep.rs:57:16 | LL | mut qux: Foo::Baz => {} | ^ -------- specifying the type of a pattern isn't supported @@ -90,7 +90,7 @@ LL | mut qux::Foo::Baz => {} | ~~ error: expected one of `@` or `|`, found `:` - --> $DIR/issue-87086-colon-path-sep.rs:69:12 + --> $DIR/issue-87086-colon-path-sep.rs:68:12 | LL | Foo:Bar::Baz => {} | ^-------- specifying the type of a pattern isn't supported @@ -103,7 +103,7 @@ LL | Foo::Bar::Baz => {} | + error: expected one of `@` or `|`, found `:` - --> $DIR/issue-87086-colon-path-sep.rs:75:12 + --> $DIR/issue-87086-colon-path-sep.rs:74:12 | LL | Foo:Bar => {} | ^--- specifying the type of a pattern isn't supported @@ -115,15 +115,5 @@ help: maybe write a path separator here LL | Foo::Bar => {} | + -warning: irrefutable `if let` pattern - --> $DIR/issue-87086-colon-path-sep.rs:40:8 - | -LL | if let Foo:Bar = f() { - | ^^^^^^^^^^^^^^^^^ - | - = note: this pattern will always match, so the `if let` is useless - = help: consider replacing the `if let` with a `let` - = note: `#[warn(irrefutable_let_patterns)]` on by default - -error: aborting due to 9 previous errors; 1 warning emitted +error: aborting due to 9 previous errors diff --git a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs index 461890e63e37b..c82efe79e4d0f 100644 --- a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs +++ b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-89971-outer-attr-following-inner-attr-ice.rs +//@ ignore-backends: gcc #[macro_use] extern crate issue_89971_outer_attr_following_inner_attr_ice; diff --git a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr index 51df17c7cc670..392e7d0321f03 100644 --- a/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr +++ b/tests/ui/parser/issues/issue-89971-outer-attr-following-inner-attr-ice.stderr @@ -1,5 +1,5 @@ error: an inner attribute is not permitted in this context - --> $DIR/issue-89971-outer-attr-following-inner-attr-ice.rs:11:1 + --> $DIR/issue-89971-outer-attr-following-inner-attr-ice.rs:12:1 | LL | #![deny(missing_docs)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/parser/macro/bad-macro-definition.rs b/tests/ui/parser/macro/bad-macro-definition.rs index 3c5c93ea3b3e4..12df6e64bd2ca 100644 --- a/tests/ui/parser/macro/bad-macro-definition.rs +++ b/tests/ui/parser/macro/bad-macro-definition.rs @@ -20,3 +20,6 @@ macro_rules! e { {} } macro_rules! f {} //~^ ERROR: macros must contain at least one rule + +macro_rules! g { unsafe {} => {} } +//~^ ERROR: `unsafe` is only supported on `attr` rules diff --git a/tests/ui/parser/macro/bad-macro-definition.stderr b/tests/ui/parser/macro/bad-macro-definition.stderr index de6d9d6a38b15..d15f33f708ded 100644 --- a/tests/ui/parser/macro/bad-macro-definition.stderr +++ b/tests/ui/parser/macro/bad-macro-definition.stderr @@ -52,5 +52,11 @@ error: macros must contain at least one rule LL | macro_rules! f {} | ^^^^^^^^^^^^^^^^^ -error: aborting due to 9 previous errors +error: `unsafe` is only supported on `attr` rules + --> $DIR/bad-macro-definition.rs:24:18 + | +LL | macro_rules! g { unsafe {} => {} } + | ^^^^^^ + +error: aborting due to 10 previous errors diff --git a/tests/ui/parser/macro/macro-attr-bad.rs b/tests/ui/parser/macro/macro-attr-bad.rs index 9f50b057a7a49..0ac46c8b76812 100644 --- a/tests/ui/parser/macro/macro-attr-bad.rs +++ b/tests/ui/parser/macro/macro-attr-bad.rs @@ -13,6 +13,12 @@ macro_rules! attr_incomplete_3 { attr() {} } macro_rules! attr_incomplete_4 { attr() {} => } //~^ ERROR macro definition ended unexpectedly +macro_rules! attr_incomplete_5 { unsafe } +//~^ ERROR macro definition ended unexpectedly + +macro_rules! attr_incomplete_6 { unsafe attr } +//~^ ERROR macro definition ended unexpectedly + macro_rules! attr_noparens_1 { attr{} {} => {} } //~^ ERROR `attr` rule argument matchers require parentheses diff --git a/tests/ui/parser/macro/macro-attr-bad.stderr b/tests/ui/parser/macro/macro-attr-bad.stderr index bf0ed13cd553f..481ef8118aebb 100644 --- a/tests/ui/parser/macro/macro-attr-bad.stderr +++ b/tests/ui/parser/macro/macro-attr-bad.stderr @@ -22,8 +22,20 @@ error: macro definition ended unexpectedly LL | macro_rules! attr_incomplete_4 { attr() {} => } | ^ expected right-hand side of macro rule +error: macro definition ended unexpectedly + --> $DIR/macro-attr-bad.rs:16:40 + | +LL | macro_rules! attr_incomplete_5 { unsafe } + | ^ expected `attr` + +error: macro definition ended unexpectedly + --> $DIR/macro-attr-bad.rs:19:45 + | +LL | macro_rules! attr_incomplete_6 { unsafe attr } + | ^ expected macro attr args + error: `attr` rule argument matchers require parentheses - --> $DIR/macro-attr-bad.rs:16:36 + --> $DIR/macro-attr-bad.rs:22:36 | LL | macro_rules! attr_noparens_1 { attr{} {} => {} } | ^^ @@ -35,7 +47,7 @@ LL + macro_rules! attr_noparens_1 { attr() {} => {} } | error: `attr` rule argument matchers require parentheses - --> $DIR/macro-attr-bad.rs:19:36 + --> $DIR/macro-attr-bad.rs:25:36 | LL | macro_rules! attr_noparens_2 { attr[] {} => {} } | ^^ @@ -47,13 +59,13 @@ LL + macro_rules! attr_noparens_2 { attr() {} => {} } | error: invalid macro matcher; matchers must be contained in balanced delimiters - --> $DIR/macro-attr-bad.rs:22:37 + --> $DIR/macro-attr-bad.rs:28:37 | LL | macro_rules! attr_noparens_3 { attr _ {} => {} } | ^ error: duplicate matcher binding - --> $DIR/macro-attr-bad.rs:25:52 + --> $DIR/macro-attr-bad.rs:31:52 | LL | macro_rules! attr_dup_matcher_1 { attr() {$x:ident $x:ident} => {} } | -------- ^^^^^^^^ duplicate binding @@ -61,7 +73,7 @@ LL | macro_rules! attr_dup_matcher_1 { attr() {$x:ident $x:ident} => {} } | previous binding error: duplicate matcher binding - --> $DIR/macro-attr-bad.rs:28:49 + --> $DIR/macro-attr-bad.rs:34:49 | LL | macro_rules! attr_dup_matcher_2 { attr($x:ident $x:ident) {} => {} } | -------- ^^^^^^^^ duplicate binding @@ -69,12 +81,12 @@ LL | macro_rules! attr_dup_matcher_2 { attr($x:ident $x:ident) {} => {} } | previous binding error: duplicate matcher binding - --> $DIR/macro-attr-bad.rs:31:51 + --> $DIR/macro-attr-bad.rs:37:51 | LL | macro_rules! attr_dup_matcher_3 { attr($x:ident) {$x:ident} => {} } | -------- ^^^^^^^^ duplicate binding | | | previous binding -error: aborting due to 10 previous errors +error: aborting due to 12 previous errors diff --git a/tests/ui/parser/macro/macro-derive-bad.rs b/tests/ui/parser/macro/macro-derive-bad.rs index 79b9eb8c113ca..74e7d9acdafc3 100644 --- a/tests/ui/parser/macro/macro-derive-bad.rs +++ b/tests/ui/parser/macro/macro-derive-bad.rs @@ -41,3 +41,6 @@ macro_rules! derive_dup_matcher { derive() {$x:ident $x:ident} => {} } //~^ ERROR duplicate matcher binding //~| NOTE duplicate binding //~| NOTE previous binding + +macro_rules! derive_unsafe { unsafe derive() {} => {} } +//~^ ERROR `unsafe` is only supported on `attr` rules diff --git a/tests/ui/parser/macro/macro-derive-bad.stderr b/tests/ui/parser/macro/macro-derive-bad.stderr index ec750c9ac8220..c98535f4031f3 100644 --- a/tests/ui/parser/macro/macro-derive-bad.stderr +++ b/tests/ui/parser/macro/macro-derive-bad.stderr @@ -86,5 +86,11 @@ LL | macro_rules! derive_dup_matcher { derive() {$x:ident $x:ident} => {} } | | | previous binding -error: aborting due to 12 previous errors +error: `unsafe` is only supported on `attr` rules + --> $DIR/macro-derive-bad.rs:45:30 + | +LL | macro_rules! derive_unsafe { unsafe derive() {} => {} } + | ^^^^^^ + +error: aborting due to 13 previous errors diff --git a/tests/ui/parser/macro/unicode-control-codepoints-macros.rs b/tests/ui/parser/macro/unicode-control-codepoints-macros.rs index 775c50779760a..701e7dfa30a39 100644 --- a/tests/ui/parser/macro/unicode-control-codepoints-macros.rs +++ b/tests/ui/parser/macro/unicode-control-codepoints-macros.rs @@ -1,6 +1,7 @@ // Regression test for #140281 //@ edition: 2021 //@ proc-macro: unicode-control.rs +//@ ignore-backends: gcc extern crate unicode_control; use unicode_control::*; diff --git a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr index ca813399eac27..22fb1b945c654 100644 --- a/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr +++ b/tests/ui/parser/macro/unicode-control-codepoints-macros.stderr @@ -1,5 +1,5 @@ error: unicode codepoint changing visible direction of text present in doc comment - --> $DIR/unicode-control-codepoints-macros.rs:20:9 + --> $DIR/unicode-control-codepoints-macros.rs:21:9 | LL | /// �test� RTL in doc in vec | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints @@ -10,7 +10,7 @@ LL | /// �test� RTL in doc in vec = note: `#[deny(text_direction_codepoint_in_literal)]` on by default error: unicode codepoint changing visible direction of text present in doc comment - --> $DIR/unicode-control-codepoints-macros.rs:25:9 + --> $DIR/unicode-control-codepoints-macros.rs:26:9 | LL | / /** LL | | * �test� RTL in doc in macro @@ -22,7 +22,7 @@ LL | | */ = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment - --> $DIR/unicode-control-codepoints-macros.rs:32:9 + --> $DIR/unicode-control-codepoints-macros.rs:33:9 | LL | / /** LL | | * �test� RTL in doc in macro @@ -34,7 +34,7 @@ LL | | */ = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment - --> $DIR/unicode-control-codepoints-macros.rs:40:9 + --> $DIR/unicode-control-codepoints-macros.rs:41:9 | LL | /// �test� RTL in doc in proc macro | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints @@ -44,7 +44,7 @@ LL | /// �test� RTL in doc in proc macro = note: if you want to keep them but make them visible in your source code, you can escape them: '\u{202e}', '\u{2066}' error: unicode codepoint changing visible direction of text present in doc comment - --> $DIR/unicode-control-codepoints-macros.rs:45:9 + --> $DIR/unicode-control-codepoints-macros.rs:46:9 | LL | /// �test� RTL in doc in proc macro | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment contains invisible unicode text flow control codepoints diff --git a/tests/ui/parser/match-arm-without-body.rs b/tests/ui/parser/match-arm-without-body.rs index 4723abff8b6ae..7fe5b6d253980 100644 --- a/tests/ui/parser/match-arm-without-body.rs +++ b/tests/ui/parser/match-arm-without-body.rs @@ -17,13 +17,13 @@ fn main() { Some(_), //~^ ERROR unexpected `,` in pattern //~| HELP try adding parentheses to match on a tuple - //~| HELP or a vertical bar to match on multiple alternatives + //~| HELP or a vertical bar to match on alternative } match Some(false) { Some(_), //~^ ERROR unexpected `,` in pattern //~| HELP try adding parentheses to match on a tuple - //~| HELP or a vertical bar to match on multiple alternatives + //~| HELP or a vertical bar to match on alternative _ => {} } match Some(false) { diff --git a/tests/ui/parser/match-arm-without-body.stderr b/tests/ui/parser/match-arm-without-body.stderr index a65875b787a39..59a323f2cc1cf 100644 --- a/tests/ui/parser/match-arm-without-body.stderr +++ b/tests/ui/parser/match-arm-without-body.stderr @@ -16,7 +16,7 @@ help: try adding parentheses to match on a tuple... | LL | (Some(_),) | + + -help: ...or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on alternatives | LL - Some(_), LL + Some(_) | @@ -36,13 +36,10 @@ LL | LL | LL ~ _) => {} | -help: ...or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on alternatives | -LL ~ Some(_) | -LL + -LL + -LL + -LL ~ _ => {} +LL - Some(_), +LL + Some(_) | | error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_` diff --git a/tests/ui/parser/pattern-matching-with-double-references-61475.rs b/tests/ui/parser/pattern-matching-with-double-references-61475.rs new file mode 100644 index 0000000000000..bf800ec8b2c66 --- /dev/null +++ b/tests/ui/parser/pattern-matching-with-double-references-61475.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/61475 +//@ run-pass +#![allow(dead_code)] + +enum E { + A, B +} + +fn main() { + match &&E::A { + &&E::A => { + } + &&E::B => { + } + }; +} diff --git a/tests/ui/parser/raw/too-many-hash.stderr b/tests/ui/parser/raw/too-many-hash.stderr index 6b3854eb4a237..499b21d3982c8 100644 --- a/tests/ui/parser/raw/too-many-hash.stderr +++ b/tests/ui/parser/raw/too-many-hash.stderr @@ -1,8 +1,8 @@ error: too many `#` symbols: raw strings may be delimited by up to 255 `#` symbols, but found 256 --> $DIR/too-many-hash.rs:4:19 | -LL | ... = r####################################################...#######################################; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... = r###################################################...######################################; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr b/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr index cf50c026665b5..2d8ab7a3e2f76 100644 --- a/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr +++ b/tests/ui/parser/recover/recover-assoc-eq-missing-term.stderr @@ -11,7 +11,7 @@ LL | bar::(); help: remove the `=` if `Item` is a type | LL - bar::(); -LL + bar::(); +LL + bar::(); | error: aborting due to 1 previous error diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr index a99f7e16fca83..60e8386bcba78 100644 --- a/tests/ui/parser/recover/recover-pat-exprs.stderr +++ b/tests/ui/parser/recover/recover-pat-exprs.stderr @@ -13,7 +13,7 @@ LL + val if val == x.y => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.y; -LL ~ match 0 { +LL | match 0 { LL | x => (), LL ~ VAL => (), | @@ -33,7 +33,7 @@ LL + val if val == x.0 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.0; -LL ~ match 0 { +LL | match 0 { LL | x => (), LL | x.y => (), LL ~ VAL => (), @@ -54,7 +54,7 @@ LL + val if val == x._0 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x._0; -LL ~ match 0 { +LL | match 0 { LL | x => (), LL | x.y => (), LL | x.0 => (), @@ -76,7 +76,7 @@ LL + val if val == x.0.1 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.0.1; -LL ~ match 0 { +LL | match 0 { LL | x => (), ... LL | x._0 => (), @@ -98,7 +98,7 @@ LL + val if val == x.4.y.17.__z => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.4.y.17.__z; -LL ~ match 0 { +LL | match 0 { LL | x => (), ... LL | x.0.1 => (), @@ -150,7 +150,7 @@ LL + val if val == x[0] => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x[0]; -LL ~ match 0 { +LL | match 0 { LL ~ VAL => (), | @@ -169,7 +169,7 @@ LL + val if val == x[..] => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x[..]; -LL ~ match 0 { +LL | match 0 { LL | x[0] => (), LL ~ VAL => (), | @@ -216,7 +216,7 @@ LL + val if val == x.f() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.f(); -LL ~ match 0 { +LL | match 0 { LL ~ VAL => (), | @@ -235,7 +235,7 @@ LL + val if val == x._f() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x._f(); -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), LL ~ VAL => (), | @@ -255,7 +255,7 @@ LL + val if val == x? => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x?; -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), LL | x._f() => (), LL ~ VAL => (), @@ -276,7 +276,7 @@ LL + val if val == ().f() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = ().f(); -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), LL | x._f() => (), LL | x? => (), @@ -298,7 +298,7 @@ LL + val if val == (0, x)?.f() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = (0, x)?.f(); -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), ... LL | ().f() => (), @@ -320,7 +320,7 @@ LL + val if val == x.f().g() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.f().g(); -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), ... LL | (0, x)?.f() => (), @@ -342,7 +342,7 @@ LL + val if val == 0.f()?.g()?? => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 0.f()?.g()??; -LL ~ match 0 { +LL | match 0 { LL | x.f() => (), ... LL | x.f().g() => (), @@ -364,7 +364,7 @@ LL + val if val == x as usize => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x as usize; -LL ~ match 0 { +LL | match 0 { LL ~ VAL => (), | @@ -383,7 +383,7 @@ LL + val if val == 0 as usize => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 0 as usize; -LL ~ match 0 { +LL | match 0 { LL | x as usize => (), LL ~ VAL => (), | @@ -403,7 +403,7 @@ LL + val if val == x.f().0.4 as f32 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.f().0.4 as f32; -LL ~ match 0 { +LL | match 0 { LL | x as usize => (), LL | 0 as usize => (), LL ~ VAL => (), @@ -424,7 +424,7 @@ LL + val if val == 1 + 1 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 1; -LL ~ match 0 { +LL | match 0 { LL ~ VAL => (), | @@ -443,7 +443,7 @@ LL + val if val == (1 + 2) * 3 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = (1 + 2) * 3; -LL ~ match 0 { +LL | match 0 { LL | 1 + 1 => (), LL ~ VAL => (), | @@ -463,7 +463,7 @@ LL + val if val == (x.0 > 2) => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.0 > 2; -LL ~ match 0 { +LL | match 0 { LL | 1 + 1 => (), ... LL | @@ -485,7 +485,7 @@ LL + val if val == (x.0 == 2) => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = x.0 == 2; -LL ~ match 0 { +LL | match 0 { LL | 1 + 1 => (), ... LL | x.0 > 2 => (), @@ -507,7 +507,7 @@ LL + (x, val) if x != 0 && val == (y.0 > 2) => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = y.0 > 2; -LL ~ match (0, 0) { +LL | match (0, 0) { LL ~ (x, VAL) if x != 0 => (), | @@ -526,7 +526,7 @@ LL + (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = y.0 > 2; -LL ~ match (0, 0) { +LL | match (0, 0) { LL | (x, y.0 > 2) if x != 0 => (), LL ~ (x, VAL) if x != 0 || x != 1 => (), | @@ -563,7 +563,7 @@ LL + val if val == u8::MAX.abs() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = u8::MAX.abs(); -LL ~ match u8::MAX { +LL | match u8::MAX { LL ~ VAL => (), | @@ -582,7 +582,7 @@ LL + z @ w @ val if val == v.u() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = v.u(); -LL ~ match u8::MAX { +LL | match u8::MAX { LL | u8::MAX.abs() => (), ... LL | @@ -604,7 +604,7 @@ LL + val if val == y.ilog(3) => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = y.ilog(3); -LL ~ match u8::MAX { +LL | match u8::MAX { LL | u8::MAX.abs() => (), ... LL | @@ -626,7 +626,7 @@ LL + val if val == n + 1 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = n + 1; -LL ~ match u8::MAX { +LL | match u8::MAX { LL | u8::MAX.abs() => (), ... LL | @@ -648,7 +648,7 @@ LL + (val) if val == "".f() + 14 * 8 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = "".f() + 14 * 8; -LL ~ match u8::MAX { +LL | match u8::MAX { LL | u8::MAX.abs() => (), ... LL | @@ -670,7 +670,7 @@ LL + val if val == f?() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = f?(); -LL ~ match u8::MAX { +LL | match u8::MAX { LL | u8::MAX.abs() => (), ... LL | 0 | ((1) | 2) | 3 => (), diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr index ec7fcda3497f4..27754289f534f 100644 --- a/tests/ui/parser/recover/recover-pat-issues.stderr +++ b/tests/ui/parser/recover/recover-pat-issues.stderr @@ -13,7 +13,7 @@ LL + Foo(val) if val == "hi".to_owned() => true, help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = "hi".to_owned(); -LL ~ match foo { +LL | match foo { LL ~ Foo(VAL) => true, | @@ -32,7 +32,7 @@ LL + Bar { baz } if baz == "hi".to_owned() => true, help: consider extracting the expression into a `const` | LL + const BAZ: /* Type */ = "hi".to_owned(); -LL ~ match bar { +LL | match bar { LL ~ Bar { baz: BAZ } => true, | @@ -51,7 +51,7 @@ LL + &[val] if val == "foo".to_string() => {} help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = "foo".to_string(); -LL ~ match foo.as_slice() { +LL | match foo.as_slice() { LL ~ &[VAL] => {} | diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr index afa7f25405435..edda9a8e7570a 100644 --- a/tests/ui/parser/recover/recover-pat-ranges.stderr +++ b/tests/ui/parser/recover/recover-pat-ranges.stderr @@ -92,7 +92,7 @@ LL | ..=1 + 2 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 2; -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | @@ -109,7 +109,7 @@ LL | (-4 + 0).. => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = -4 + 0; -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | @@ -126,7 +126,7 @@ LL | (1 + 4)...1 * 2 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 + 4; -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | @@ -143,7 +143,7 @@ LL | (1 + 4)...1 * 2 => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 1 * 2; -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | @@ -160,7 +160,7 @@ LL | 0.x()..="y".z() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 0.x(); -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | @@ -177,7 +177,7 @@ LL | 0.x()..="y".z() => (), help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = "y".z(); -LL ~ match -1 { +LL | match -1 { LL | 0..=1 => (), ... LL | diff --git a/tests/ui/parser/recover/recover-pat-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr index ebc1cbf7d591e..97dc842b85919 100644 --- a/tests/ui/parser/recover/recover-pat-wildcards.stderr +++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr @@ -81,7 +81,7 @@ LL | 4..=(2 + _) => () help: consider extracting the expression into a `const` | LL + const VAL: /* Type */ = 2 + _; -LL ~ match 9 { +LL | match 9 { LL ~ 4..=(VAL) => () | diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr index f498d7d36bba6..c43ca23c4885d 100644 --- a/tests/ui/parser/trait-object-trait-parens.stderr +++ b/tests/ui/parser/trait-object-trait-parens.stderr @@ -3,18 +3,24 @@ error: relaxed bounds are not permitted in trait object types | LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:13:16 | LL | let _: Box Trait<'a>) + (Obj)>; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types --> $DIR/trait-object-trait-parens.rs:18:44 | LL | let _: Box Trait<'a> + (Obj) + (?Sized)>; | ^^^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax warning: trait objects without an explicit `dyn` are deprecated --> $DIR/trait-object-trait-parens.rs:8:16 diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.rs b/tests/ui/parser/tuple-index-suffix-proc-macro.rs index 557c67738d30f..2463897381ec2 100644 --- a/tests/ui/parser/tuple-index-suffix-proc-macro.rs +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.rs @@ -3,6 +3,7 @@ //! Like `tuple-index-suffix.rs`, but exercises the proc-macro interaction. //@ proc-macro: tuple-index-suffix-proc-macro-aux.rs +//@ ignore-backends: gcc extern crate tuple_index_suffix_proc_macro_aux; use tuple_index_suffix_proc_macro_aux as aux; diff --git a/tests/ui/parser/tuple-index-suffix-proc-macro.stderr b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr index 47d179d355513..a242af5a789f7 100644 --- a/tests/ui/parser/tuple-index-suffix-proc-macro.stderr +++ b/tests/ui/parser/tuple-index-suffix-proc-macro.stderr @@ -1,23 +1,23 @@ error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:17:28 + --> $DIR/tuple-index-suffix-proc-macro.rs:18:28 | LL | aux::bad_tup_indexing!(0usize); | ^^^^^^ invalid suffix `usize` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:19:47 + --> $DIR/tuple-index-suffix-proc-macro.rs:20:47 | LL | aux::bad_tup_struct_indexing!(tup_struct, 0isize); | ^^^^^^ invalid suffix `isize` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:24:28 + --> $DIR/tuple-index-suffix-proc-macro.rs:25:28 | LL | aux::bad_tup_indexing!(0u8); | ^^^ invalid suffix `u8` error: suffixes on a tuple index are invalid - --> $DIR/tuple-index-suffix-proc-macro.rs:26:47 + --> $DIR/tuple-index-suffix-proc-macro.rs:27:47 | LL | aux::bad_tup_struct_indexing!(tup_struct, 0u64); | ^^^^ invalid suffix `u64` diff --git a/tests/ui/parser/type-ascription-in-pattern.rs b/tests/ui/parser/type-ascription-in-pattern.rs index 18d7061d69c8d..75059d33db645 100644 --- a/tests/ui/parser/type-ascription-in-pattern.rs +++ b/tests/ui/parser/type-ascription-in-pattern.rs @@ -1,15 +1,16 @@ fn foo(x: bool) -> i32 { - match x { //~ ERROR struct literals are not allowed here - x: i32 => x, //~ ERROR expected - true => 42., //~ ERROR expected identifier - false => 0.333, //~ ERROR expected identifier + match x { + x: i32 => x, //~ ERROR: expected + //~^ ERROR: mismatched types + true => 42., + false => 0.333, } -} //~ ERROR expected one of +} fn main() { match foo(true) { - 42: i32 => (), //~ ERROR expected - _: f64 => (), //~ ERROR expected - x: i32 => (), //~ ERROR expected + 42: i32 => (), //~ ERROR: expected + _: f64 => (), //~ ERROR: expected + x: i32 => (), //~ ERROR: expected } } diff --git a/tests/ui/parser/type-ascription-in-pattern.stderr b/tests/ui/parser/type-ascription-in-pattern.stderr index 135879f208b2b..0919075499368 100644 --- a/tests/ui/parser/type-ascription-in-pattern.stderr +++ b/tests/ui/parser/type-ascription-in-pattern.stderr @@ -1,64 +1,18 @@ -error: expected one of `!`, `,`, `.`, `::`, `?`, `{`, `}`, or an operator, found `=>` - --> $DIR/type-ascription-in-pattern.rs:3:16 - | -LL | match x { - | - while parsing this struct -LL | x: i32 => x, - | -^^ expected one of 8 possible tokens - | | - | help: try adding a comma: `,` - -error: expected identifier, found keyword `true` - --> $DIR/type-ascription-in-pattern.rs:4:9 - | -LL | match x { - | - while parsing this struct -LL | x: i32 => x, -LL | true => 42., - | ^^^^ expected identifier, found keyword - -error: expected identifier, found keyword `false` - --> $DIR/type-ascription-in-pattern.rs:5:9 - | -LL | match x { - | - while parsing this struct -... -LL | false => 0.333, - | ^^^^^ expected identifier, found keyword - -error: struct literals are not allowed here - --> $DIR/type-ascription-in-pattern.rs:2:11 - | -LL | match x { - | ___________^ -LL | | x: i32 => x, -LL | | true => 42., -LL | | false => 0.333, -LL | | } - | |_____^ - | -help: surround the struct literal with parentheses +error: expected one of `@` or `|`, found `:` + --> $DIR/type-ascription-in-pattern.rs:3:10 | -LL ~ match (x { LL | x: i32 => x, -LL | true => 42., -LL | false => 0.333, -LL ~ }) + | ^ --- specifying the type of a pattern isn't supported + | | + | expected one of `@` or `|` | - -error: expected one of `.`, `?`, `{`, or an operator, found `}` - --> $DIR/type-ascription-in-pattern.rs:7:1 +help: maybe write a path separator here | -LL | match x { - | ----- while parsing this `match` expression -... -LL | } - | - expected one of `.`, `?`, `{`, or an operator -LL | } - | ^ unexpected token +LL | x::i32 => x, + | ~~ error: expected one of `...`, `..=`, `..`, or `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:11:11 + --> $DIR/type-ascription-in-pattern.rs:12:11 | LL | 42: i32 => (), | ^ --- specifying the type of a pattern isn't supported @@ -66,7 +20,7 @@ LL | 42: i32 => (), | expected one of `...`, `..=`, `..`, or `|` error: expected `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:12:10 + --> $DIR/type-ascription-in-pattern.rs:13:10 | LL | _: f64 => (), | ^ --- specifying the type of a pattern isn't supported @@ -74,7 +28,7 @@ LL | _: f64 => (), | expected `|` error: expected one of `@` or `|`, found `:` - --> $DIR/type-ascription-in-pattern.rs:13:10 + --> $DIR/type-ascription-in-pattern.rs:14:10 | LL | x: i32 => (), | ^ --- specifying the type of a pattern isn't supported @@ -86,5 +40,15 @@ help: maybe write a path separator here LL | x::i32 => (), | ~~ -error: aborting due to 8 previous errors +error[E0308]: mismatched types + --> $DIR/type-ascription-in-pattern.rs:3:19 + | +LL | fn foo(x: bool) -> i32 { + | --- expected `i32` because of return type +LL | match x { +LL | x: i32 => x, + | ^ expected `i32`, found `bool` + +error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/parser/unicode-string-literal-syntax-error-64792.rs b/tests/ui/parser/unicode-string-literal-syntax-error-64792.rs new file mode 100644 index 0000000000000..6497509a1233c --- /dev/null +++ b/tests/ui/parser/unicode-string-literal-syntax-error-64792.rs @@ -0,0 +1,6 @@ +// https://github.com/rust-lang/rust/issues/64792 +struct X {} + +const Y: X = X("ö"); //~ ERROR expected function, tuple struct or tuple variant, found struct `X` + +fn main() {} diff --git a/tests/ui/parser/unicode-string-literal-syntax-error-64792.stderr b/tests/ui/parser/unicode-string-literal-syntax-error-64792.stderr new file mode 100644 index 0000000000000..7a37b4a5f3a0c --- /dev/null +++ b/tests/ui/parser/unicode-string-literal-syntax-error-64792.stderr @@ -0,0 +1,12 @@ +error[E0423]: expected function, tuple struct or tuple variant, found struct `X` + --> $DIR/unicode-string-literal-syntax-error-64792.rs:4:14 + | +LL | struct X {} + | ----------- `X` defined here +LL | +LL | const Y: X = X("ö"); + | ^^^^^^ help: use struct literal syntax instead: `X {}` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0423`. diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs index 4db056f15a51f..415472176d9c4 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs @@ -53,30 +53,30 @@ struct X; impl X { fn i_f1(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f2(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn i_f3(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function fn i_f4(..., x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR `...` must be the last argument of a C-variadic function const fn i_f5(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions //~| ERROR functions cannot be both `const` and C-variadic //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time } trait T { fn t_f1(x: isize, ...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f2(x: isize, ...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f3(...) {} - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f4(...); - //~^ ERROR associated functions cannot have a C variable argument list + //~^ ERROR `...` is not supported for non-extern functions fn t_f5(..., x: isize) {} //~^ ERROR `...` must be the last argument of a C-variadic function fn t_f6(..., x: isize); diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr index 0cd78318de6a8..da9c9b0f76099 100644 --- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr +++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr @@ -132,17 +132,21 @@ error: `...` must be the last argument of a C-variadic function LL | fn e_f2(..., x: isize); | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:55:23 | LL | fn i_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:57:13 | LL | fn i_f2(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13 @@ -150,11 +154,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f3(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:59:28 | LL | fn i_f3(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13 @@ -162,11 +168,13 @@ error: `...` must be the last argument of a C-variadic function LL | fn i_f4(..., x: isize, ...) {} | ^^^ -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:62:28 | LL | fn i_f4(..., x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: functions cannot be both `const` and C-variadic --> $DIR/variadic-ffi-semantic-restrictions.rs:65:5 @@ -176,35 +184,45 @@ LL | const fn i_f5(x: isize, ...) {} | | | `const` because of this -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:65:29 | LL | const fn i_f5(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:72:23 | LL | fn t_f1(x: isize, ...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23 | LL | fn t_f2(x: isize, ...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:76:13 | LL | fn t_f3(...) {} | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list -error: associated functions cannot have a C variable argument list +error: `...` is not supported for non-extern functions --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13 | LL | fn t_f4(...); | ^^^ + | + = help: only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list error: `...` must be the last argument of a C-variadic function --> $DIR/variadic-ffi-semantic-restrictions.rs:80:13 diff --git a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs index 3d26b5e87d93f..d766411e4f980 100644 --- a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs +++ b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs @@ -1,5 +1,6 @@ //@ run-pass #![allow(unused)] +#![warn(unused_assignments)] // Test copy @@ -34,10 +35,12 @@ pub fn main() { let mut x@B {b, ..} = B {a: 10, b: C {c: 20}}; assert_eq!(x.a, 10); x.b.c = 30; + //~^ WARN value assigned to `x` is never read assert_eq!(b.c, 20); let mut y@D {d, ..} = D {a: 10, d: C {c: 20}}; assert_eq!(y.a, 10); y.d.c = 30; + //~^ WARN value assigned to `y` is never read assert_eq!(d.c, 20); match (E::E { a: 10, e: C { c: 20 } }) { @@ -50,7 +53,9 @@ pub fn main() { } match (E::E { a: 10, e: C { c: 20 } }) { mut x @ E::E{ a, e: C { mut c } } => { + //~^ WARN value assigned to `a` is never read x = E::NotE; + //~^ WARN value assigned to `x` is never read c += 30; assert_eq!(c, 50); } diff --git a/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr b/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr new file mode 100644 index 0000000000000..d775b69ef0a5e --- /dev/null +++ b/tests/ui/pattern/bindings-after-at/bind-by-copy.stderr @@ -0,0 +1,39 @@ +warning: value assigned to `x` is never read + --> $DIR/bind-by-copy.rs:37:5 + | +LL | x.b.c = 30; + | ^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? +note: the lint level is defined here + --> $DIR/bind-by-copy.rs:3:9 + | +LL | #![warn(unused_assignments)] + | ^^^^^^^^^^^^^^^^^^ + +warning: value assigned to `y` is never read + --> $DIR/bind-by-copy.rs:42:5 + | +LL | y.d.c = 30; + | ^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value assigned to `x` is never read + --> $DIR/bind-by-copy.rs:57:13 + | +LL | x = E::NotE; + | ^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value assigned to `a` is never read + --> $DIR/bind-by-copy.rs:55:23 + | +LL | mut x @ E::E{ a, e: C { mut c } } => { + | ^ + | + = help: maybe it is overwritten before being read? + +warning: 4 warnings emitted + diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr index 7e3caaf979748..fc1ca18c12026 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2021.stderr @@ -59,20 +59,20 @@ LL | let [&bind_ref_mut!(x)] = &mut [0]; | | | help: replace this `&` with `&mut`: `&mut` -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/mixed-editions.rs:30:10 | LL | let [bind_ref!(y)] = &[0]; | ^^^^^^^^^^^^ occurs within macro expansion | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/mixed-editions.rs:30:9 | LL | let [bind_ref!(y)] = &[0]; - | ^^^^^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) -help: make the implied reference pattern explicit +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[bind_ref!(y)] = &[0]; | + diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr index 466993a1671f4..9377d535f1874 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.classic2024.stderr @@ -58,14 +58,14 @@ LL | let [&bind_ref_mut!(x)] = &mut [0]; | | | help: replace this `&` with `&mut`: `&mut` -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/mixed-editions.rs:26:21 | LL | let match_ctor!(ref x) = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -help: make the implied reference pattern explicit + = note: for more information, see +help: match on the reference with a reference pattern to avoid implicitly borrowing --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 | LL | &[$p] diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs index 0a22b55ab6374..3580ed3862703 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.rs @@ -24,11 +24,11 @@ fn assert_type_eq>(_: T, _: U) {} /// only when the binding is from edition 2024. fn ref_binding_tests() { let match_ctor!(ref x) = &[0]; - //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2024,structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(classic2021, structural2021))] assert_type_eq(x, &0u32); let [bind_ref!(y)] = &[0]; - //[classic2021,structural2021]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2021,structural2021]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(classic2024, structural2024))] assert_type_eq(y, &0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr index 4075dc9529da1..69ddb0720526e 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2021.stderr @@ -37,20 +37,20 @@ LL | let [&bind_ref_mut!(x)] = &mut [0]; | | | help: replace this `&` with `&mut`: `&mut` -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/mixed-editions.rs:30:10 | LL | let [bind_ref!(y)] = &[0]; | ^^^^^^^^^^^^ occurs within macro expansion | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/mixed-editions.rs:30:9 | LL | let [bind_ref!(y)] = &[0]; - | ^^^^^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` = note: this error originates in the macro `bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) -help: make the implied reference pattern explicit +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[bind_ref!(y)] = &[0]; | + diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr index 819a54299ea1c..bc1fee35a6bb4 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/mixed-editions.structural2024.stderr @@ -36,14 +36,14 @@ LL | let [&bind_ref_mut!(x)] = &mut [0]; | | | help: replace this `&` with `&mut`: `&mut` -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/mixed-editions.rs:26:21 | LL | let match_ctor!(ref x) = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -help: make the implied reference pattern explicit + = note: for more information, see +help: match on the reference with a reference pattern to avoid implicitly borrowing --> $DIR/auxiliary/mixed-editions-macros.rs:11:9 | LL | &[$p] diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr index 04e53e06a22e6..956cd2166433a 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.classic2024.stderr @@ -11,19 +11,19 @@ LL - let [&mut ref x] = &[&mut 0]; LL + let [&ref x] = &[&mut 0]; | -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^ binding modifier not allowed under `ref` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:73:9 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[ref mut x] = &[0]; | + @@ -34,53 +34,53 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 | LL | let [ref x] = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:81:9 | LL | let [ref x] = &[0]; - | ^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[ref x] = &[0]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:85:10 | LL | let [ref x] = &mut [0]; - | ^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:85:9 | LL | let [ref x] = &mut [0]; - | ^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [ref x] = &mut [0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:89:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:89:9 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [ref mut x] = &mut [0]; | ++++ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs index c9e3f75cf178a..628cb60b8495c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.rs @@ -17,22 +17,22 @@ /// The eat-outer variant eats the inherited reference, so binding with `ref` isn't a problem. fn errors_from_eating_the_real_reference() { let [&ref x] = &[&0]; - //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&ref x] = &mut [&0]; - //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&u32 = x; let [&mut ref x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&mut ref mut x] = &mut [&mut 0]; - //[structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; #[cfg(classic2024)] let _: &mut &mut u32 = x; } @@ -43,14 +43,14 @@ fn errors_from_eating_the_real_reference_caught_in_hir_typeck_on_stable() { let [&ref x] = &[&mut 0]; //[stable2021]~^ ERROR: mismatched types //[stable2021]~| NOTE types differ in mutability - //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^^^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; let [&ref x] = &mut [&mut 0]; //[stable2021]~^ ERROR: mismatched types //[stable2021]~| NOTE types differ in mutability - //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^^^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(classic2021, structural2021))] let _: &u32 = x; #[cfg(classic2024)] let _: &&mut u32 = x; } @@ -60,7 +60,7 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { let [&mut ref x] = &[&mut 0]; //[classic2024]~^ ERROR: mismatched types //[classic2024]~| NOTE cannot match inherited `&` with `&mut` pattern - //[structural2024]~^^^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[structural2024]~^^^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; } @@ -72,21 +72,21 @@ fn errors_dependent_on_eating_order_caught_in_hir_typeck_when_eating_outer() { fn borrowck_errors_in_old_editions() { let [ref mut x] = &[0]; //~^ ERROR: cannot borrow data in a `&` reference as mutable - //[classic2024,structural2024]~| ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2024,structural2024]~| ERROR: cannot explicitly borrow within an implicitly-borrowing pattern } /// The remaining tests are purely for testing `ref` bindings in the presence of an inherited /// reference. These should always fail on edition 2024 and succeed on edition 2021. pub fn main() { let [ref x] = &[0]; - //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2024,structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref x] = &mut [0]; - //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2024,structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &u32 = x; let [ref mut x] = &mut [0]; - //[classic2024,structural2024]~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //[classic2024,structural2024]~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern #[cfg(any(stable2021, classic2021, structural2021))] let _: &mut u32 = x; } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr index def6deb325acd..9753e3e5fbfea 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/ref-binding-on-inh-ref-errors.structural2024.stderr @@ -1,135 +1,135 @@ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:19:11 | LL | let [&ref x] = &[&0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:19:9 | LL | let [&ref x] = &[&0]; - | ^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&ref x] = &[&0]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:24:11 | LL | let [&ref x] = &mut [&0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:24:9 | LL | let [&ref x] = &mut [&0]; - | ^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [&ref x] = &mut [&0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:29:15 | LL | let [&mut ref x] = &mut [&mut 0]; - | ^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:29:9 | LL | let [&mut ref x] = &mut [&mut 0]; - | ^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [&mut ref x] = &mut [&mut 0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:34:15 | LL | let [&mut ref mut x] = &mut [&mut 0]; - | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:34:9 | LL | let [&mut ref mut x] = &mut [&mut 0]; - | ^^^^^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [&mut ref mut x] = &mut [&mut 0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:43:11 | LL | let [&ref x] = &[&mut 0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:43:9 | LL | let [&ref x] = &[&mut 0]; - | ^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&ref x] = &[&mut 0]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:50:11 | LL | let [&ref x] = &mut [&mut 0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:50:9 | LL | let [&ref x] = &mut [&mut 0]; - | ^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [&ref x] = &mut [&mut 0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:60:15 | LL | let [&mut ref x] = &[&mut 0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:60:9 | LL | let [&mut ref x] = &[&mut 0]; - | ^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&mut ref x] = &[&mut 0]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:73:10 | LL | let [ref mut x] = &[0]; - | ^^^^^^^ binding modifier not allowed under `ref` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:73:9 | LL | let [ref mut x] = &[0]; - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[ref mut x] = &[0]; | + @@ -140,53 +140,53 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | let [ref mut x] = &[0]; | ^^^^^^^^^ cannot borrow as mutable -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:81:10 | LL | let [ref x] = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:81:9 | LL | let [ref x] = &[0]; - | ^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[ref x] = &[0]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:85:10 | LL | let [ref x] = &mut [0]; - | ^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:85:9 | LL | let [ref x] = &mut [0]; - | ^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [ref x] = &mut [0]; | ++++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/ref-binding-on-inh-ref-errors.rs:89:10 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/ref-binding-on-inh-ref-errors.rs:89:9 | LL | let [ref mut x] = &mut [0]; - | ^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut [ref mut x] = &mut [0]; | ++++ diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed index bb4ecc09063b7..2df39fdd6103d 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.fixed @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let &Foo(mut x) = &Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(mut x) = &mut Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(x) = &Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let &mut Foo(ref x) = &mut Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); @@ -55,22 +55,22 @@ fn main() { assert_type_eq(x, &0u8); let &Foo(&x) = &Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&x) = &mut Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let &mut Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); @@ -79,25 +79,25 @@ fn main() { } if let &&&&&Some(&x) = &&&&&Some(&0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -109,20 +109,20 @@ fn main() { } let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ fn main() { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } @@ -143,26 +143,26 @@ fn main() { } let &mut [&mut &[ref a]] = &mut [&mut &[0]]; - //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); let &[&(_)] = &[&0]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 // NB: Most of the following tests are for possible future improvements to migration suggestions // Test removing multiple binding modifiers. let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(c, &0u32); // Test that we don't change bindings' modes when removing binding modifiers. let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &mut 0u32); @@ -170,7 +170,7 @@ fn main() { // Test removing multiple reference patterns of various mutabilities, plus a binding modifier. let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -178,13 +178,13 @@ fn main() { // Test that we don't change bindings' types when removing reference patterns. let &Foo(&ref a) = &Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); // Test that we don't change bindings' modes when adding reference paterns (caught early). let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); @@ -194,7 +194,7 @@ fn main() { // Test that we don't change bindings' modes when adding reference patterns (caught late). let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -202,7 +202,7 @@ fn main() { // Test featuring both additions and removals. let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0])); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); @@ -210,21 +210,21 @@ fn main() { // Test that bindings' subpatterns' modes are updated properly. let &[mut a @ ref b] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); // Test that bindings' subpatterns' modes are checked properly. let &[ref a @ mut b] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); // Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`. let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -233,7 +233,7 @@ fn main() { // Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`. let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &[0u32]); assert_type_eq(b, &0u32); @@ -242,12 +242,32 @@ fn main() { // Test that we use the correct message and suggestion style when pointing inside expansions. let &[migration_lint_macros::bind_ref!(a)] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern assert_type_eq(a, &0u32); // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); + + // Test the primary diagnostic message for mixes of `mut`/`ref`/`&`. + let &(mut a, ref b) = &(0, 0); + //~^ ERROR: cannot write explicit binding modifiers within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &0u32); + + let &(mut a, &b) = &(0, &0); + //~^ ERROR: cannot mutably bind by value or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, 0u32); + + let &(mut a, ref b, &c) = &(0, 0, &0); + //~^ ERROR: cannot write explicit binding modifiers or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &0u32); + assert_type_eq(c, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs index 2837c8d81dbdd..0d727ad7d7a5c 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.rs @@ -23,22 +23,22 @@ fn main() { assert_type_eq(x, &mut 0u8); let Foo(mut x) = &Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(mut x) = &mut Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(ref x) = &Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); let Foo(ref x) = &mut Foo(0); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &0u8); @@ -55,22 +55,22 @@ fn main() { assert_type_eq(x, &0u8); let Foo(&x) = &Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &Foo(&mut 0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&x) = &mut Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); let Foo(&mut x) = &mut Foo(&mut 0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); @@ -79,25 +79,25 @@ fn main() { } if let Some(&x) = &&&&&Some(&0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut x) = &&&&&Some(&mut 0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&x) = &&&&&mut Some(&0u8) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, 0u8); } if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(x, &mut 0u8); } @@ -109,20 +109,20 @@ fn main() { } let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &&0u32); assert_type_eq(c, &&0u32); if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 &(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) }) { @@ -135,7 +135,7 @@ fn main() { // The two patterns are the same syntactically, but because they're defined in different // editions they don't mean the same thing. (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern assert_type_eq(x, 0u32); assert_type_eq(y, 0u32); } @@ -143,26 +143,26 @@ fn main() { } let [&mut [ref a]] = &mut [&mut &[0]]; - //~^ ERROR: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); let [&(_)] = &[&0]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 // NB: Most of the following tests are for possible future improvements to migration suggestions // Test removing multiple binding modifiers. let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(c, &0u32); // Test that we don't change bindings' modes when removing binding modifiers. let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 }; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &mut 0u32); @@ -170,7 +170,7 @@ fn main() { // Test removing multiple reference patterns of various mutabilities, plus a binding modifier. let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -178,13 +178,13 @@ fn main() { // Test that we don't change bindings' types when removing reference patterns. let Foo(&ref a) = &Foo(&0); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); // Test that we don't change bindings' modes when adding reference paterns (caught early). let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); @@ -194,7 +194,7 @@ fn main() { // Test that we don't change bindings' modes when adding reference patterns (caught late). let (a, [b], [mut c]) = &(0, &mut [0], &[0]); - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -202,7 +202,7 @@ fn main() { // Test featuring both additions and removals. let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0])); - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); @@ -210,21 +210,21 @@ fn main() { // Test that bindings' subpatterns' modes are updated properly. let [mut a @ b] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, 0u32); assert_type_eq(b, &0u32); // Test that bindings' subpatterns' modes are checked properly. let [a @ mut b] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, 0u32); // Test that we respect bindings' subpatterns' types when rewriting `&ref x` to `x`. let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); assert_type_eq(b, &0u32); @@ -233,7 +233,7 @@ fn main() { // Test that we respect bindings' subpatterns' modes when rewriting `&ref x` to `x`. let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &[0u32]); assert_type_eq(b, &0u32); @@ -242,12 +242,32 @@ fn main() { // Test that we use the correct message and suggestion style when pointing inside expansions. let [migration_lint_macros::bind_ref!(a)] = &[0]; - //~^ ERROR: binding modifiers may only be written when the default binding mode is `move` + //~^ ERROR: cannot explicitly borrow within an implicitly-borrowing pattern assert_type_eq(a, &0u32); // Test that we use the correct span when labeling a `&` whose subpattern is from an expansion. let [&migration_lint_macros::bind_ref!(a)] = &[&0]; - //~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024 + //~^ ERROR: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 //~| WARN: this changes meaning in Rust 2024 assert_type_eq(a, &0u32); + + // Test the primary diagnostic message for mixes of `mut`/`ref`/`&`. + let (mut a, ref b) = &(0, 0); + //~^ ERROR: cannot write explicit binding modifiers within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &0u32); + + let (mut a, &b) = &(0, &0); + //~^ ERROR: cannot mutably bind by value or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, 0u32); + + let (mut a, ref b, &c) = &(0, 0, &0); + //~^ ERROR: cannot write explicit binding modifiers or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + //~| WARN: this changes meaning in Rust 2024 + assert_type_eq(a, 0u32); + assert_type_eq(b, &0u32); + assert_type_eq(c, 0u32); } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr index 6efda4f757ff6..01fcfdc8be6ee 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/migration_lint.stderr @@ -1,602 +1,663 @@ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:25:13 | LL | let Foo(mut x) = &Foo(0); - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:25:9 | LL | let Foo(mut x) = &Foo(0); - | ^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` note: the lint level is defined here --> $DIR/migration_lint.rs:7:9 | LL | #![deny(rust_2024_incompatible_pat)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: make the implied reference pattern explicit +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(mut x) = &Foo(0); | + -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:30:13 | LL | let Foo(mut x) = &mut Foo(0); - | ^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:30:9 | LL | let Foo(mut x) = &mut Foo(0); - | ^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(mut x) = &mut Foo(0); | ++++ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:35:13 | LL | let Foo(ref x) = &Foo(0); - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:35:9 | LL | let Foo(ref x) = &Foo(0); - | ^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` help: remove the unnecessary binding modifier | LL - let Foo(ref x) = &Foo(0); LL + let Foo(x) = &Foo(0); | -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:40:13 | LL | let Foo(ref x) = &mut Foo(0); - | ^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:40:9 | LL | let Foo(ref x) = &mut Foo(0); - | ^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(ref x) = &mut Foo(0); | ++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:57:13 | LL | let Foo(&x) = &Foo(&0); - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:57:9 | LL | let Foo(&x) = &Foo(&0); - | ^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&x) = &Foo(&0); | + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:62:13 | LL | let Foo(&mut x) = &Foo(&mut 0); - | ^^^^ reference pattern not allowed under `ref` default binding mode + | ^^^^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:62:9 | LL | let Foo(&mut x) = &Foo(&mut 0); - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&mut x) = &Foo(&mut 0); | + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:67:13 | LL | let Foo(&x) = &mut Foo(&0); - | ^ reference pattern not allowed under `ref mut` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:67:9 | LL | let Foo(&x) = &mut Foo(&0); - | ^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(&x) = &mut Foo(&0); | ++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:72:13 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | ^^^^ reference pattern not allowed under `ref mut` default binding mode + | ^^^^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:72:9 | LL | let Foo(&mut x) = &mut Foo(&mut 0); - | ^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &mut Foo(&mut x) = &mut Foo(&mut 0); | ++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:81:17 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:81:12 | LL | if let Some(&x) = &&&&&Some(&0u8) { - | ^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&Some(&x) = &&&&&Some(&0u8) { | +++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:87:17 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | ^^^^ reference pattern not allowed under `ref` default binding mode + | ^^^^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:87:12 | LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) { - | ^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns explicit + | ^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) { | +++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:93:17 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:93:12 | LL | if let Some(&x) = &&&&&mut Some(&0u8) { - | ^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) { | ++++++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:99:17 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - | ^^^^ reference pattern not allowed under `ref mut` default binding mode + | ^^^^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:99:12 | LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) { - | ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference patterns and variable binding mode explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) { | ++++ ++++ +++++++ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:111:21 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:111:9 | LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern and variable binding modes explicit + | ^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern and borrow explicitly using variable binding modes | LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 }; | + +++ +++ -error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:117:21 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - | ^ ^^^ binding modifier not allowed under `ref` default binding mode + | ^ ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:117:9 | LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern and variable binding mode explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 }; | + +++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:124:24 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - | ^ ^ reference pattern not allowed under `ref` default binding mode + | ^ ^ reference pattern not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:124:12 | LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } = - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns and variable binding mode explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } = | + + + +++ -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot mutably bind by value within an implicitly-borrowing pattern --> $DIR/migration_lint.rs:137:15 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion | | - | binding modifier not allowed under `ref` default binding mode + | `mut` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:137:9 | LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` = note: this error originates in the macro `migration_lint_macros::mixed_edition_pat` (in Nightly builds, run with -Z macro-backtrace for more info) -help: make the implied reference pattern explicit +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | &(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => { | + -error: binding modifiers and reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow or dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:145:10 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | ^^^^ ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^^ ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref mut` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:145:15 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | ^^^^^^^ this matches on type `&_` -note: matching on a reference type with a non-reference pattern changes the default binding mode + | ^^^^^^^ this non-reference pattern matches on a reference type `&_` +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:145:9 | LL | let [&mut [ref a]] = &mut [&mut &[0]]; - | ^^^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference patterns explicit + | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | let &mut [&mut &[ref a]] = &mut [&mut &[0]]; | ++++ + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:150:10 | LL | let [&(_)] = &[&0]; - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:150:9 | LL | let [&(_)] = &[&0]; - | ^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&(_)] = &[&0]; | + -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:157:18 | LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^ ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | | - | binding modifier not allowed under `ref` default binding mode + | explicit `ref` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:157:9 | LL | let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` help: remove the unnecessary binding modifiers | LL - let Struct { ref a, ref b, c } = &Struct { a: 0, b: 0, c: 0 }; LL + let Struct { a, b, c } = &Struct { a: 0, b: 0, c: 0 }; | -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly borrow within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:164:18 | LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 }; - | ^^^ ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^ ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | | - | binding modifier not allowed under `ref mut` default binding mode + | explicit `ref` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:164:9 | LL | let Struct { ref a, ref mut b, c } = &mut Struct { a: 0, b: 0, c: 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&mut _` -help: make the implied reference pattern and variable binding mode explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` +help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &mut Struct { ref a, ref mut b, ref mut c } = &mut Struct { a: 0, b: 0, c: 0 }; | ++++ +++++++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:172:21 | LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; - | ^ ^^^^ reference pattern not allowed under `ref` default binding mode + | ^ ^^^^ reference pattern not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:172:9 | LL | let Struct { a: &[ref a], b: &mut [[b]], c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns and variable binding modes explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &mut &Struct { a: &[ref a], b: &mut [&[ref b]], ref c } = &mut &Struct { a: &[0], b: &mut [&[0]], c: 0 }; | ++++++ + +++ +++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:180:13 | LL | let Foo(&ref a) = &Foo(&0); - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:180:9 | LL | let Foo(&ref a) = &Foo(&0); - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &Foo(&ref a) = &Foo(&0); | + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:186:10 | LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:186:9 | LL | let (&a, b, [c], [(d, [e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); - | ^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns and variable binding modes explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &(&a, ref b, &[ref c], &mut [&mut (ref d, &[ref e])]) = &(&0, 0, &[0], &mut [&mut (0, &[0])]); | + +++ + +++ ++++ ++++ +++ + +++ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:196:19 | LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]); - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:196:9 | LL | let (a, [b], [mut c]) = &(0, &mut [0], &[0]); - | ^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns and variable binding modes explicit + | ^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns and borrow explicitly using variable binding modes | LL | let &(ref a, &mut [ref b], &[mut c]) = &(0, &mut [0], &[0]); | + +++ ++++ +++ + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:204:10 | LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0])); - | ^ ^ reference pattern not allowed under `ref` default binding mode + | ^ ^ reference pattern not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:204:9 | LL | let (&a, (b, &[ref c])) = &(&0, &mut (0, &[0])); - | ^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns and variable binding mode explicit + | ^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns and borrow explicitly using a variable binding mode | LL | let &(&a, &mut (ref b, &[ref c])) = &(&0, &mut (0, &[0])); | + ++++ +++ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:212:10 | LL | let [mut a @ b] = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:212:9 | LL | let [mut a @ b] = &[0]; - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern and variable binding mode explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &[mut a @ ref b] = &[0]; | + +++ -error: binding modifiers may only be written when the default binding mode is `move` in Rust 2024 +error: cannot mutably bind by value within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:219:14 | LL | let [a @ mut b] = &[0]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:219:9 | LL | let [a @ mut b] = &[0]; - | ^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern and variable binding mode explicit + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern and borrow explicitly using a variable binding mode | LL | let &[ref a @ mut b] = &[0]; | + +++ -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:226:14 | LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; - | ^ ^ reference pattern not allowed under `ref` default binding mode + | ^ ^ reference pattern not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:226:31 | LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; - | ^^^^^^^^^^^^^^^ this matches on type `&_` -note: matching on a reference type with a non-reference pattern changes the default binding mode + | ^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:226:10 | LL | let [Foo(&ref a @ ref b), Foo(&ref c @ d)] = [&Foo(&0); 2]; - | ^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns explicit + | ^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | let [&Foo(&ref a @ ref b), &Foo(&ref c @ d)] = [&Foo(&0); 2]; | + + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:235:14 | LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; - | ^ ^ reference pattern not allowed under `ref` default binding mode + | ^ ^ reference pattern not allowed when implicitly borrowing | | - | reference pattern not allowed under `ref` default binding mode + | reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:235:33 | LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; - | ^^^^^^^^^^^^^^^^^ this matches on type `&_` -note: matching on a reference type with a non-reference pattern changes the default binding mode + | ^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:235:10 | LL | let [Foo(&ref a @ [ref b]), Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; - | ^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference patterns explicit + | ^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on these references with reference patterns to avoid implicitly borrowing | LL | let [&Foo(&ref a @ [ref b]), &Foo(&ref c @ [d])] = [&Foo(&[0]); 2]; | + + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/migration_lint.rs:244:10 | LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ occurs within macro expansion | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:244:9 | LL | let [migration_lint_macros::bind_ref!(a)] = &[0]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` = note: this error originates in the macro `migration_lint_macros::bind_ref` (in Nightly builds, run with -Z macro-backtrace for more info) -help: make the implied reference pattern explicit +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[migration_lint_macros::bind_ref!(a)] = &[0]; | + -error: reference patterns may only be written when the default binding mode is `move` in Rust 2024 +error: cannot explicitly dereference within an implicitly-borrowing pattern in Rust 2024 --> $DIR/migration_lint.rs:249:10 | LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | = warning: this changes meaning in Rust 2024 - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/migration_lint.rs:249:9 | LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0]; | + -error: aborting due to 31 previous errors +error: cannot write explicit binding modifiers within an implicitly-borrowing pattern in Rust 2024 + --> $DIR/migration_lint.rs:255:10 + | +LL | let (mut a, ref b) = &(0, 0); + | ^^^ ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing + | | + | `mut` binding modifier not allowed when implicitly borrowing + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents + --> $DIR/migration_lint.rs:255:9 + | +LL | let (mut a, ref b) = &(0, 0); + | ^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing + | +LL | let &(mut a, ref b) = &(0, 0); + | + + +error: cannot mutably bind by value or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + --> $DIR/migration_lint.rs:261:10 + | +LL | let (mut a, &b) = &(0, &0); + | ^^^ ^ reference pattern not allowed when implicitly borrowing + | | + | `mut` binding modifier not allowed when implicitly borrowing + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents + --> $DIR/migration_lint.rs:261:9 + | +LL | let (mut a, &b) = &(0, &0); + | ^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing + | +LL | let &(mut a, &b) = &(0, &0); + | + + +error: cannot write explicit binding modifiers or explicitly dereference within an implicitly-borrowing pattern in Rust 2024 + --> $DIR/migration_lint.rs:267:10 + | +LL | let (mut a, ref b, &c) = &(0, 0, &0); + | ^^^ ^^^ ^ reference pattern not allowed when implicitly borrowing + | | | + | | explicit `ref` binding modifier not allowed when implicitly borrowing + | `mut` binding modifier not allowed when implicitly borrowing + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents + --> $DIR/migration_lint.rs:267:9 + | +LL | let (mut a, ref b, &c) = &(0, 0, &0); + | ^^^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing + | +LL | let &(mut a, ref b, &c) = &(0, 0, &0); + | + + +error: aborting due to 34 previous errors diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs index 4dc04d90aaf5e..d56b835ac5dfc 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.rs @@ -21,17 +21,17 @@ macro_rules! test_pat_on_type { } test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types -test_pat_on_type![(&x,): &(&T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move` +test_pat_on_type![(&x,): &(&T,)]; //~ ERROR cannot explicitly dereference within an implicitly-borrowing pattern test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types -test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR reference patterns may only be written when the default binding mode is `move` +test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR cannot explicitly dereference within an implicitly-borrowing pattern test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types -test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR reference patterns may only be written when the default binding mode is `move` -test_pat_on_type![(mut x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move` -test_pat_on_type![(ref x,): &(T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move` -test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR binding modifiers may only be written when the default binding mode is `move` +test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR cannot explicitly dereference within an implicitly-borrowing pattern +test_pat_on_type![(mut x,): &(T,)]; //~ ERROR cannot mutably bind by value within an implicitly-borrowing pattern +test_pat_on_type![(ref x,): &(T,)]; //~ ERROR cannot explicitly borrow within an implicitly-borrowing pattern +test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR cannot explicitly borrow within an implicitly-borrowing pattern fn get() -> X { unimplemented!() @@ -40,6 +40,6 @@ fn get() -> X { // Make sure this works even when the underlying type is inferred. This test passes on rust stable. fn infer() -> X { match &get() { - (&x,) => x, //~ ERROR reference patterns may only be written when the default binding mode is `move` + (&x,) => x, //~ ERROR cannot explicitly dereference within an implicitly-borrowing pattern } } diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr index 0c6b2ff3a2f09..23f1557e56d39 100644 --- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr +++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/min_match_ergonomics_fail.stderr @@ -99,123 +99,123 @@ LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo]; | -error: reference patterns may only be written when the default binding mode is `move` +error: cannot explicitly dereference within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:24:20 | LL | test_pat_on_type![(&x,): &(&T,)]; - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:24:19 | LL | test_pat_on_type![(&x,): &(&T,)]; - | ^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | test_pat_on_type![&(&x,): &(&T,)]; | + -error: reference patterns may only be written when the default binding mode is `move` +error: cannot explicitly dereference within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:27:20 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | ^^^^ reference pattern not allowed under `ref` default binding mode + | ^^^^ reference pattern not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:27:19 | LL | test_pat_on_type![(&mut x,): &(&mut T,)]; - | ^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | test_pat_on_type![&(&mut x,): &(&mut T,)]; | + -error: reference patterns may only be written when the default binding mode is `move` +error: cannot explicitly dereference within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:31:28 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:31:19 | LL | test_pat_on_type![Foo { f: &(x,) }: &Foo]; - | ^^^^^^^^^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | test_pat_on_type![&Foo { f: &(x,) }: &Foo]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot mutably bind by value within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:32:20 | LL | test_pat_on_type![(mut x,): &(T,)]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ `mut` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:32:19 | LL | test_pat_on_type![(mut x,): &(T,)]; - | ^^^^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | test_pat_on_type![&(mut x,): &(T,)]; | + -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:33:20 | LL | test_pat_on_type![(ref x,): &(T,)]; - | ^^^ binding modifier not allowed under `ref` default binding mode + | ^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:33:19 | LL | test_pat_on_type![(ref x,): &(T,)]; - | ^^^^^^^^ this matches on type `&_` + | ^^^^^^^^ this non-reference pattern matches on a reference type `&_` help: remove the unnecessary binding modifier | LL - test_pat_on_type![(ref x,): &(T,)]; LL + test_pat_on_type![(x,): &(T,)]; | -error: binding modifiers may only be written when the default binding mode is `move` +error: cannot explicitly borrow within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:34:20 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | ^^^^^^^ binding modifier not allowed under `ref mut` default binding mode + | ^^^^^^^ explicit `ref` binding modifier not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:34:19 | LL | test_pat_on_type![(ref mut x,): &mut (T,)]; - | ^^^^^^^^^^^^ this matches on type `&mut _` + | ^^^^^^^^^^^^ this non-reference pattern matches on a reference type `&mut _` help: remove the unnecessary binding modifier | LL - test_pat_on_type![(ref mut x,): &mut (T,)]; LL + test_pat_on_type![(x,): &mut (T,)]; | -error: reference patterns may only be written when the default binding mode is `move` +error: cannot explicitly dereference within an implicitly-borrowing pattern --> $DIR/min_match_ergonomics_fail.rs:43:10 | LL | (&x,) => x, - | ^ reference pattern not allowed under `ref` default binding mode + | ^ reference pattern not allowed when implicitly borrowing | - = note: for more information, see -note: matching on a reference type with a non-reference pattern changes the default binding mode + = note: for more information, see +note: matching on a reference type with a non-reference pattern implicitly borrows the contents --> $DIR/min_match_ergonomics_fail.rs:43:9 | LL | (&x,) => x, - | ^^^^^ this matches on type `&_` -help: make the implied reference pattern explicit + | ^^^^^ this non-reference pattern matches on a reference type `&_` +help: match on the reference with a reference pattern to avoid implicitly borrowing | LL | &(&x,) => x, | + diff --git a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr index f2067f0341fcd..b649aa122b255 100644 --- a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr +++ b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr @@ -346,8 +346,8 @@ LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!() error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered --> $DIR/empty-match.rs:71:24 | -LL | match_guarded_arm!(NonEmptyEnum5::V1); - | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered +LL | ...ded_arm!(NonEmptyEnum5::V1); + | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | note: `NonEmptyEnum5` defined here --> $DIR/empty-match.rs:38:10 diff --git a/tests/ui/pattern/usefulness/empty-match.normal.stderr b/tests/ui/pattern/usefulness/empty-match.normal.stderr index f2067f0341fcd..b649aa122b255 100644 --- a/tests/ui/pattern/usefulness/empty-match.normal.stderr +++ b/tests/ui/pattern/usefulness/empty-match.normal.stderr @@ -346,8 +346,8 @@ LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!() error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered --> $DIR/empty-match.rs:71:24 | -LL | match_guarded_arm!(NonEmptyEnum5::V1); - | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered +LL | ...ded_arm!(NonEmptyEnum5::V1); + | ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered | note: `NonEmptyEnum5` defined here --> $DIR/empty-match.rs:38:10 diff --git a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr index 7caee64a33fbc..099d6e862434c 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr @@ -5,7 +5,7 @@ LL | match 0usize { | ^^^^^^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ 0..=usize::MAX => {}, @@ -19,7 +19,7 @@ LL | match 0isize { | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ isize::MIN..=isize::MAX => {}, @@ -33,7 +33,7 @@ LL | m!(0usize, 0..=usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } @@ -46,7 +46,7 @@ LL | m!(0usize, 0..5 | 5..=usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } @@ -59,7 +59,7 @@ LL | m!(0usize, 0..usize::MAX | usize::MAX); | ^^^^^^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL | match $s { $($t)+ => {}, usize::MAX.. => todo!() } @@ -72,7 +72,7 @@ LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize:: | ^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered | = note: the matched value is of type `(usize, bool)` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL | match $s { $($t)+ => {}, (usize::MAX.., _) => todo!() } @@ -85,7 +85,7 @@ LL | m!(0isize, isize::MIN..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } @@ -98,7 +98,7 @@ LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } @@ -111,7 +111,7 @@ LL | m!(0isize, isize::MIN..=-1 | 0 | 1..=isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } @@ -124,7 +124,7 @@ LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX); | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match $s { $($t)+ => {}, ..isize::MIN | isize::MAX.. => todo!() } @@ -137,7 +137,7 @@ LL | (0isize, true), | ^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered | = note: the matched value is of type `(isize, bool)` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL | match $s { $($t)+ => {}, (..isize::MIN, _) | (isize::MAX.., _) => todo!() } diff --git a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs index d60f479c0d155..6a0106134b50a 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs +++ b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs @@ -4,7 +4,7 @@ fn main() { //~^ ERROR non-exhaustive patterns: `usize::MAX..` not covered //~| NOTE pattern `usize::MAX..` not covered //~| NOTE the matched value is of type `usize` - //~| NOTE `usize` does not have a fixed maximum value + //~| NOTE `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively 0..=usize::MAX => {} } @@ -12,7 +12,7 @@ fn main() { //~^ ERROR non-exhaustive patterns: `..isize::MIN` and `isize::MAX..` not covered //~| NOTE patterns `..isize::MIN` and `isize::MAX..` not covered //~| NOTE the matched value is of type `isize` - //~| NOTE `isize` does not have fixed minimum and maximum values + //~| NOTE `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively isize::MIN..=isize::MAX => {} } } diff --git a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr index 36743aa810296..fefe7f46ead9d 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr @@ -5,7 +5,7 @@ LL | match 0usize { | ^^^^^^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ 0..=usize::MAX => {}, @@ -19,7 +19,7 @@ LL | match 0isize { | ^^^^^^ patterns `..isize::MIN` and `isize::MAX..` not covered | = note: the matched value is of type `isize` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ isize::MIN..=isize::MAX => {}, diff --git a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr index c31411018bc46..9d7b53093df98 100644 --- a/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr +++ b/tests/ui/pattern/usefulness/issue-85222-types-containing-non-exhaustive-types.stderr @@ -5,7 +5,7 @@ LL | match 0 { | ^ pattern `usize::MAX..` not covered | = note: the matched value is of type `usize` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ 1..=usize::MAX => (), @@ -19,7 +19,7 @@ LL | match (0usize, 0usize) { | ^^^^^^^^^^^^^^^^ pattern `(usize::MAX.., _)` not covered | = note: the matched value is of type `(usize, usize)` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ (1..=usize::MAX, 1..=usize::MAX) => (), @@ -33,7 +33,7 @@ LL | match (0isize, 0usize) { | ^^^^^^^^^^^^^^^^ patterns `(..isize::MIN, _)` and `(isize::MAX.., _)` not covered | = note: the matched value is of type `(isize, usize)` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ (isize::MIN..=isize::MAX, 1..=usize::MAX) => (), @@ -70,7 +70,7 @@ note: `Option` defined here | = note: not covered = note: the matched value is of type `Option` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ None => (), @@ -93,7 +93,7 @@ note: `Option>>` defined here | = note: not covered = note: the matched value is of type `Option>>` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ None => (), @@ -112,7 +112,7 @@ note: `A` defined here LL | struct A { | ^ = note: the matched value is of type `A` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ A { a: 1..=usize::MAX } => (), @@ -131,7 +131,7 @@ note: `B` defined here LL | struct B(T, U); | ^ = note: the matched value is of type `B` - = note: `isize` does not have fixed minimum and maximum values, so half-open ranges are necessary to match exhaustively + = note: `isize::MIN` and `isize::MAX` are not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms | LL ~ B(isize::MIN..=isize::MAX, 1..=usize::MAX) => (), @@ -150,7 +150,7 @@ note: `B` defined here LL | struct B(T, U); | ^ = note: the matched value is of type `B` - = note: `usize` does not have a fixed maximum value, so half-open ranges are necessary to match exhaustively + = note: `usize::MAX` is not treated as exhaustive, so half-open ranges are necessary to match exhaustively help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | LL ~ B(_, 1..=usize::MAX) => (), diff --git a/tests/ui/pin/pin-deref-target-partial-eq-67039.rs b/tests/ui/pin/pin-deref-target-partial-eq-67039.rs new file mode 100644 index 0000000000000..541960012bd3a --- /dev/null +++ b/tests/ui/pin/pin-deref-target-partial-eq-67039.rs @@ -0,0 +1,28 @@ +// https://github.com/rust-lang/rust/issues/67039 +// Pin's PartialEq implementation allowed to access the pointer allowing for +// unsoundness by using Rc::get_mut to move value within Rc. +// See https://internals.rust-lang.org/t/unsoundness-in-pin/11311/73 for more details. + +use std::ops::Deref; +use std::pin::Pin; +use std::rc::Rc; + +struct Apple; + +impl Deref for Apple { + type Target = Apple; + fn deref(&self) -> &Apple { + &Apple + } +} + +impl PartialEq> for Apple { + fn eq(&self, _rc: &Rc) -> bool { + unreachable!() + } +} + +fn main() { + let _ = Pin::new(Apple) == Rc::pin(Apple); + //~^ ERROR type mismatch resolving +} diff --git a/tests/ui/pin/pin-deref-target-partial-eq-67039.stderr b/tests/ui/pin/pin-deref-target-partial-eq-67039.stderr new file mode 100644 index 0000000000000..541656dd7437e --- /dev/null +++ b/tests/ui/pin/pin-deref-target-partial-eq-67039.stderr @@ -0,0 +1,13 @@ +error[E0271]: type mismatch resolving ` as Deref>::Target == Rc` + --> $DIR/pin-deref-target-partial-eq-67039.rs:26:29 + | +LL | let _ = Pin::new(Apple) == Rc::pin(Apple); + | ^^ expected `Rc`, found `Apple` + | + = note: expected struct `Rc` + found struct `Apple` + = note: required for `Pin` to implement `PartialEq>>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed new file mode 100644 index 0000000000000..63cc3333b6b77 --- /dev/null +++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.fixed @@ -0,0 +1,20 @@ +#![allow(dead_code, unused_variables)] +//@ run-rustfix +pub use my_mod::Foo; +//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields +//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields + +mod my_mod { + pub struct Foo(u32); + + mod my_sub_mod { + fn my_func() { + let crate::my_mod::Foo(x) = crate::my_mod::Foo(42); + //~^ ERROR cannot initialize a tuple struct which contains private fields + //~| HELP the type can be constructed directly, because its fields are available from the current scope + //~| ERROR cannot match against a tuple struct which contains private fields + //~| HELP the type can be constructed directly, because its fields are available from the current scope + } + } +} +fn main() {} diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs new file mode 100644 index 0000000000000..0b695f9065459 --- /dev/null +++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs @@ -0,0 +1,20 @@ +#![allow(dead_code, unused_variables)] +//@ run-rustfix +pub use my_mod::Foo; +//~^ NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields +//~| NOTE the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields + +mod my_mod { + pub struct Foo(u32); + + mod my_sub_mod { + fn my_func() { + let crate::Foo(x) = crate::Foo(42); + //~^ ERROR cannot initialize a tuple struct which contains private fields + //~| HELP the type can be constructed directly, because its fields are available from the current scope + //~| ERROR cannot match against a tuple struct which contains private fields + //~| HELP the type can be constructed directly, because its fields are available from the current scope + } + } +} +fn main() {} diff --git a/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr new file mode 100644 index 0000000000000..6ab324cb32f39 --- /dev/null +++ b/tests/ui/privacy/ctor-not-accessible-due-to-inaccessible-field-in-reexport.stderr @@ -0,0 +1,36 @@ +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:33 + | +LL | let crate::Foo(x) = crate::Foo(42); + | ^^^^^^^^^^ + | +note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields + --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9 + | +LL | pub use my_mod::Foo; + | ^^^^^^^^^^^ +help: the type can be constructed directly, because its fields are available from the current scope + | +LL | let crate::Foo(x) = crate::my_mod::Foo(42); + | ++++++++ + +error[E0532]: cannot match against a tuple struct which contains private fields + --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:12:17 + | +LL | let crate::Foo(x) = crate::Foo(42); + | ^^^^^^^^^^ + | +note: the type is accessed through this re-export, but the type's constructor is not visible in this import's scope due to private fields + --> $DIR/ctor-not-accessible-due-to-inaccessible-field-in-reexport.rs:3:9 + | +LL | pub use my_mod::Foo; + | ^^^^^^^^^^^ +help: the type can be constructed directly, because its fields are available from the current scope + | +LL | let crate::my_mod::Foo(x) = crate::Foo(42); + | ++++++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0532. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr b/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr deleted file mode 100644 index 070fa1a53a547..0000000000000 --- a/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error: pattern requires `..` due to inaccessible fields - --> $DIR/inaccessible-fields-pattern-matching-76077.rs:14:9 - | -LL | let foo::Foo {} = foo::Foo::default(); - | ^^^^^^^^^^^ - | -help: ignore the inaccessible and unused fields - | -LL | let foo::Foo { .. } = foo::Foo::default(); - | ++ - -error: pattern requires `..` due to inaccessible fields - --> $DIR/inaccessible-fields-pattern-matching-76077.rs:17:9 - | -LL | let foo::Bar { visible } = foo::Bar::default(); - | ^^^^^^^^^^^^^^^^^^^^ - | -help: ignore the inaccessible and unused fields - | -LL | let foo::Bar { visible, .. } = foo::Bar::default(); - | ++++ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.fixed b/tests/ui/privacy/inaccessible-private-fields-76077.fixed similarity index 100% rename from tests/ui/privacy/inaccessible-fields-pattern-matching-76077.fixed rename to tests/ui/privacy/inaccessible-private-fields-76077.fixed diff --git a/tests/ui/privacy/inaccessible-fields-pattern-matching-76077.rs b/tests/ui/privacy/inaccessible-private-fields-76077.rs similarity index 100% rename from tests/ui/privacy/inaccessible-fields-pattern-matching-76077.rs rename to tests/ui/privacy/inaccessible-private-fields-76077.rs diff --git a/tests/ui/privacy/inaccessible-private-fields-76077.stderr b/tests/ui/privacy/inaccessible-private-fields-76077.stderr new file mode 100644 index 0000000000000..7b9f495920768 --- /dev/null +++ b/tests/ui/privacy/inaccessible-private-fields-76077.stderr @@ -0,0 +1,24 @@ +error: pattern requires `..` due to inaccessible fields + --> $DIR/inaccessible-private-fields-76077.rs:14:9 + | +LL | let foo::Foo {} = foo::Foo::default(); + | ^^^^^^^^^^^ + | +help: ignore the inaccessible and unused fields + | +LL | let foo::Foo { .. } = foo::Foo::default(); + | ++ + +error: pattern requires `..` due to inaccessible fields + --> $DIR/inaccessible-private-fields-76077.rs:17:9 + | +LL | let foo::Bar { visible } = foo::Bar::default(); + | ^^^^^^^^^^^^^^^^^^^^ + | +help: ignore the inaccessible and unused fields + | +LL | let foo::Bar { visible, .. } = foo::Bar::default(); + | ++++ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/proc-macro/add-impl.rs b/tests/ui/proc-macro/add-impl.rs index 2299f05c2e7fa..645e9321bba04 100644 --- a/tests/ui/proc-macro/add-impl.rs +++ b/tests/ui/proc-macro/add-impl.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: add-impl.rs +//@ ignore-backends: gcc #[macro_use] extern crate add_impl; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs index 8ee2223822a3c..e580e0784b34e 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.rs @@ -1,5 +1,6 @@ //@ proc-macro: builtin-attrs.rs //@ compile-flags:--test +//@ ignore-backends: gcc #![feature(decl_macro, test)] diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr index 346cebf639d17..e5de873cf31f8 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs-test.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `NonExistent` in this scope - --> $DIR/ambiguous-builtin-attrs-test.rs:19:5 + --> $DIR/ambiguous-builtin-attrs-test.rs:20:5 | LL | NonExistent; | ^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs index edc7748eff3da..63d3c79055ca2 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.rs +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.rs @@ -1,5 +1,6 @@ //@ edition:2018 //@ proc-macro: builtin-attrs.rs +//@ ignore-backends: gcc #![feature(decl_macro)] //~ ERROR `feature` is ambiguous extern crate builtin_attrs; diff --git a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr index 0f4ddc065a742..ff7894a41eab0 100644 --- a/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr +++ b/tests/ui/proc-macro/ambiguous-builtin-attrs.stderr @@ -1,11 +1,11 @@ error[E0425]: cannot find value `NonExistent` in this scope - --> $DIR/ambiguous-builtin-attrs.rs:34:5 + --> $DIR/ambiguous-builtin-attrs.rs:35:5 | LL | NonExistent; | ^^^^^^^^^^^ not found in this scope error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:9:3 + --> $DIR/ambiguous-builtin-attrs.rs:10:3 | LL | #[repr(C)] | ^^^^ ambiguous name @@ -13,14 +13,14 @@ LL | #[repr(C)] = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:6:5 + --> $DIR/ambiguous-builtin-attrs.rs:7:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:11:19 + --> $DIR/ambiguous-builtin-attrs.rs:12:19 | LL | #[cfg_attr(all(), repr(C))] | ^^^^ ambiguous name @@ -28,14 +28,14 @@ LL | #[cfg_attr(all(), repr(C))] = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:6:5 + --> $DIR/ambiguous-builtin-attrs.rs:7:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:20:34 + --> $DIR/ambiguous-builtin-attrs.rs:21:34 | LL | fn non_macro_expanded_location<#[repr(C)] T>() { | ^^^^ ambiguous name @@ -43,14 +43,14 @@ LL | fn non_macro_expanded_location<#[repr(C)] T>() { = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:6:5 + --> $DIR/ambiguous-builtin-attrs.rs:7:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:24:11 + --> $DIR/ambiguous-builtin-attrs.rs:25:11 | LL | #[repr(C)] | ^^^^ ambiguous name @@ -58,14 +58,14 @@ LL | #[repr(C)] = note: ambiguous because of a name conflict with a builtin attribute = note: `repr` could refer to a built-in attribute note: `repr` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:6:5 + --> $DIR/ambiguous-builtin-attrs.rs:7:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::repr` to refer to this attribute macro unambiguously error[E0659]: `allow` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:38:3 + --> $DIR/ambiguous-builtin-attrs.rs:39:3 | LL | #[allow(unused)] | ^^^^^ ambiguous name @@ -73,14 +73,14 @@ LL | #[allow(unused)] = note: ambiguous because of a name conflict with a builtin attribute = note: `allow` could refer to a built-in attribute note: `allow` could also refer to the built-in attribute imported here - --> $DIR/ambiguous-builtin-attrs.rs:37:5 + --> $DIR/ambiguous-builtin-attrs.rs:38:5 | LL | use deny as allow; | ^^^^^^^^^^^^^ = help: use `crate::allow` to refer to this built-in attribute unambiguously error[E0659]: `feature` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:3:4 + --> $DIR/ambiguous-builtin-attrs.rs:4:4 | LL | #![feature(decl_macro)] | ^^^^^^^ ambiguous name @@ -88,20 +88,20 @@ LL | #![feature(decl_macro)] = note: ambiguous because of a name conflict with a builtin attribute = note: `feature` could refer to a built-in attribute note: `feature` could also refer to the attribute macro imported here - --> $DIR/ambiguous-builtin-attrs.rs:6:5 + --> $DIR/ambiguous-builtin-attrs.rs:7:5 | LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ = help: use `crate::feature` to refer to this attribute macro unambiguously error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/ambiguous-builtin-attrs.rs:20:39 + --> $DIR/ambiguous-builtin-attrs.rs:21:39 | LL | fn non_macro_expanded_location<#[repr(C)] T>() { | ^ - not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/ambiguous-builtin-attrs.rs:24:16 + --> $DIR/ambiguous-builtin-attrs.rs:25:16 | LL | #[repr(C)] | ^ diff --git a/tests/ui/proc-macro/append-impl.rs b/tests/ui/proc-macro/append-impl.rs index c0f208460b297..48d21968de0ce 100644 --- a/tests/ui/proc-macro/append-impl.rs +++ b/tests/ui/proc-macro/append-impl.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: append-impl.rs +//@ ignore-backends: gcc #![allow(warnings)] diff --git a/tests/ui/proc-macro/attr-args.rs b/tests/ui/proc-macro/attr-args.rs index 1d3e0f725d250..4109b450a8ab3 100644 --- a/tests/ui/proc-macro/attr-args.rs +++ b/tests/ui/proc-macro/attr-args.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: attr-args.rs +//@ ignore-backends: gcc #![allow(warnings)] diff --git a/tests/ui/proc-macro/attr-invalid-exprs.rs b/tests/ui/proc-macro/attr-invalid-exprs.rs index f476858a32ba1..bdfc0587b3b02 100644 --- a/tests/ui/proc-macro/attr-invalid-exprs.rs +++ b/tests/ui/proc-macro/attr-invalid-exprs.rs @@ -1,6 +1,7 @@ //! Attributes producing expressions in invalid locations //@ proc-macro: attr-stmt-expr.rs +//@ ignore-backends: gcc #![feature(proc_macro_hygiene)] #![feature(stmt_expr_attributes)] diff --git a/tests/ui/proc-macro/attr-invalid-exprs.stderr b/tests/ui/proc-macro/attr-invalid-exprs.stderr index 0d500c871453f..43241e1e6fd5c 100644 --- a/tests/ui/proc-macro/attr-invalid-exprs.stderr +++ b/tests/ui/proc-macro/attr-invalid-exprs.stderr @@ -1,11 +1,11 @@ error: expected expression, found end of macro arguments - --> $DIR/attr-invalid-exprs.rs:12:13 + --> $DIR/attr-invalid-exprs.rs:13:13 | LL | let _ = #[no_output] "Hello, world!"; | ^^^^^^^^^^^^ error: macro expansion ignores `,` and any tokens following - --> $DIR/attr-invalid-exprs.rs:15:13 + --> $DIR/attr-invalid-exprs.rs:16:13 | LL | let _ = #[duplicate] "Hello, world!"; | ^^^^^^^^^^^^ caused by the macro expansion here @@ -17,7 +17,7 @@ LL | let _ = #[duplicate]; "Hello, world!"; | + error: macro expansion ignores `,` and any tokens following - --> $DIR/attr-invalid-exprs.rs:24:9 + --> $DIR/attr-invalid-exprs.rs:25:9 | LL | #[duplicate] | ^^^^^^^^^^^^ caused by the macro expansion here diff --git a/tests/ui/proc-macro/attr-on-trait.rs b/tests/ui/proc-macro/attr-on-trait.rs index e95760a837c05..345653864f841 100644 --- a/tests/ui/proc-macro/attr-on-trait.rs +++ b/tests/ui/proc-macro/attr-on-trait.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: attr-on-trait.rs +//@ ignore-backends: gcc extern crate attr_on_trait; diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.rs b/tests/ui/proc-macro/attributes-on-modules-fail.rs index 80300b47c5fc1..59da87a1dde16 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.rs +++ b/tests/ui/proc-macro/attributes-on-modules-fail.rs @@ -17,11 +17,11 @@ type A = X; //~ ERROR cannot find type `X` in this scope mod n {} #[empty_attr] -mod module; //~ ERROR non-inline modules in proc macro input are unstable +mod module; //~ ERROR file modules in proc macro input are unstable #[empty_attr] mod outer { - mod inner; //~ ERROR non-inline modules in proc macro input are unstable + mod inner; //~ ERROR file modules in proc macro input are unstable mod inner_inline {} // OK } @@ -30,16 +30,16 @@ mod outer { struct S { field: [u8; { #[path = "outer/inner.rs"] - mod inner; //~ ERROR non-inline modules in proc macro input are unstable + mod inner; //~ ERROR file modules in proc macro input are unstable mod inner_inline {} // OK 0 - }] + }], } #[identity_attr] fn f() { #[path = "outer/inner.rs"] - mod inner; //~ ERROR non-inline modules in proc macro input are unstable + mod inner; //~ ERROR file modules in proc macro input are unstable mod inner_inline {} // OK } diff --git a/tests/ui/proc-macro/attributes-on-modules-fail.stderr b/tests/ui/proc-macro/attributes-on-modules-fail.stderr index e69ab78723861..26b20a3ee6cb8 100644 --- a/tests/ui/proc-macro/attributes-on-modules-fail.stderr +++ b/tests/ui/proc-macro/attributes-on-modules-fail.stderr @@ -6,7 +6,7 @@ LL | #[derive(Copy)] LL | mod n {} | -------- not a `struct`, `enum` or `union` -error[E0658]: non-inline modules in proc macro input are unstable +error[E0658]: file modules in proc macro input are unstable --> $DIR/attributes-on-modules-fail.rs:20:1 | LL | mod module; @@ -16,7 +16,7 @@ LL | mod module; = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: non-inline modules in proc macro input are unstable +error[E0658]: file modules in proc macro input are unstable --> $DIR/attributes-on-modules-fail.rs:24:5 | LL | mod inner; @@ -26,7 +26,7 @@ LL | mod inner; = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: non-inline modules in proc macro input are unstable +error[E0658]: file modules in proc macro input are unstable --> $DIR/attributes-on-modules-fail.rs:33:9 | LL | mod inner; @@ -36,7 +36,7 @@ LL | mod inner; = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0658]: non-inline modules in proc macro input are unstable +error[E0658]: file modules in proc macro input are unstable --> $DIR/attributes-on-modules-fail.rs:42:5 | LL | mod inner; diff --git a/tests/ui/proc-macro/bang-macro.rs b/tests/ui/proc-macro/bang-macro.rs index 2287e34c5dda9..75f40de242ec9 100644 --- a/tests/ui/proc-macro/bang-macro.rs +++ b/tests/ui/proc-macro/bang-macro.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: bang-macro.rs +//@ ignore-backends: gcc extern crate bang_macro; use bang_macro::rewrite; diff --git a/tests/ui/proc-macro/call-site.rs b/tests/ui/proc-macro/call-site.rs index 9c285e1ed117a..5de4061b2a948 100644 --- a/tests/ui/proc-macro/call-site.rs +++ b/tests/ui/proc-macro/call-site.rs @@ -1,5 +1,6 @@ //@ check-pass //@ proc-macro: call-site.rs +//@ ignore-backends: gcc extern crate call_site; diff --git a/tests/ui/proc-macro/cfg-eval.rs b/tests/ui/proc-macro/cfg-eval.rs index ddf3708059608..9e9e469125883 100644 --- a/tests/ui/proc-macro/cfg-eval.rs +++ b/tests/ui/proc-macro/cfg-eval.rs @@ -19,7 +19,7 @@ struct S1 { field_false: u8, #[cfg(all(/*true*/))] #[cfg_attr(FALSE, unknown_attr)] - #[cfg_attr(all(/*true*/), allow())] + #[cfg_attr(all(/*true*/), allow())] //~ WARN unused attribute field_true: u8, } diff --git a/tests/ui/proc-macro/cfg-eval.stderr b/tests/ui/proc-macro/cfg-eval.stderr new file mode 100644 index 0000000000000..1429dbde7bfc2 --- /dev/null +++ b/tests/ui/proc-macro/cfg-eval.stderr @@ -0,0 +1,11 @@ +warning: unused attribute + --> $DIR/cfg-eval.rs:22:5 + | +LL | #[cfg_attr(all(/*true*/), allow())] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | + = note: attribute `allow` with an empty list has no effect + = note: requested on the command line with `-W unused-attributes` + +warning: 1 warning emitted + diff --git a/tests/ui/proc-macro/count_compound_ops.rs b/tests/ui/proc-macro/count_compound_ops.rs index 20b0b87817e2f..fe90e7bfbe49a 100644 --- a/tests/ui/proc-macro/count_compound_ops.rs +++ b/tests/ui/proc-macro/count_compound_ops.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: count_compound_ops.rs +//@ ignore-backends: gcc extern crate count_compound_ops; use count_compound_ops::count_compound_ops; diff --git a/tests/ui/proc-macro/derive-bad.rs b/tests/ui/proc-macro/derive-bad.rs index 9b237c731dbe4..9b9a2bc33c946 100644 --- a/tests/ui/proc-macro/derive-bad.rs +++ b/tests/ui/proc-macro/derive-bad.rs @@ -1,4 +1,5 @@ //@ proc-macro: derive-bad.rs +//@ ignore-backends: gcc #[macro_use] extern crate derive_bad; diff --git a/tests/ui/proc-macro/derive-bad.stderr b/tests/ui/proc-macro/derive-bad.stderr index 43e97f40ba884..8a252e826efff 100644 --- a/tests/ui/proc-macro/derive-bad.stderr +++ b/tests/ui/proc-macro/derive-bad.stderr @@ -1,5 +1,5 @@ error: expected `:`, found `}` - --> $DIR/derive-bad.rs:6:10 + --> $DIR/derive-bad.rs:7:10 | LL | #[derive(A)] | ^ @@ -10,13 +10,13 @@ LL | #[derive(A)] = note: this error originates in the derive macro `A` (in Nightly builds, run with -Z macro-backtrace for more info) error: proc-macro derive produced unparsable tokens - --> $DIR/derive-bad.rs:6:10 + --> $DIR/derive-bad.rs:7:10 | LL | #[derive(A)] | ^ error[E0428]: the name `A` is defined multiple times - --> $DIR/derive-bad.rs:9:1 + --> $DIR/derive-bad.rs:10:1 | LL | #[derive(A)] | - previous definition of the type `A` here diff --git a/tests/ui/proc-macro/derive-helper-shadowing.rs b/tests/ui/proc-macro/derive-helper-shadowing.rs index ee883be33526c..5ddd914d1026c 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.rs +++ b/tests/ui/proc-macro/derive-helper-shadowing.rs @@ -1,6 +1,7 @@ //@ edition:2018 //@ proc-macro: test-macros.rs //@ proc-macro: derive-helper-shadowing.rs +//@ ignore-backends: gcc #[macro_use] extern crate test_macros; diff --git a/tests/ui/proc-macro/derive-helper-shadowing.stderr b/tests/ui/proc-macro/derive-helper-shadowing.stderr index 2e4ddd19b7e1f..90b42e8d6e228 100644 --- a/tests/ui/proc-macro/derive-helper-shadowing.stderr +++ b/tests/ui/proc-macro/derive-helper-shadowing.stderr @@ -1,17 +1,17 @@ error: cannot use a derive helper attribute through an import - --> $DIR/derive-helper-shadowing.rs:42:15 + --> $DIR/derive-helper-shadowing.rs:43:15 | LL | #[renamed] | ^^^^^^^ | note: the derive helper attribute imported here - --> $DIR/derive-helper-shadowing.rs:41:17 + --> $DIR/derive-helper-shadowing.rs:42:17 | LL | use empty_helper as renamed; | ^^^^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `empty_helper` in this scope - --> $DIR/derive-helper-shadowing.rs:38:22 + --> $DIR/derive-helper-shadowing.rs:39:22 | LL | #[derive(GenHelperUse)] | ^^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL + use empty_helper; | error: cannot find attribute `empty_helper` in this scope - --> $DIR/derive-helper-shadowing.rs:14:11 + --> $DIR/derive-helper-shadowing.rs:15:11 | LL | #[empty_helper] | ^^^^^^^^^^^^ @@ -40,26 +40,26 @@ LL + use crate::empty_helper; | error[E0659]: `empty_helper` is ambiguous - --> $DIR/derive-helper-shadowing.rs:19:3 + --> $DIR/derive-helper-shadowing.rs:20:3 | LL | #[empty_helper] | ^^^^^^^^^^^^ ambiguous name | = note: ambiguous because of a name conflict with a derive helper attribute note: `empty_helper` could refer to the derive helper attribute defined here - --> $DIR/derive-helper-shadowing.rs:22:10 + --> $DIR/derive-helper-shadowing.rs:23:10 | LL | #[derive(Empty)] | ^^^^^ note: `empty_helper` could also refer to the attribute macro imported here - --> $DIR/derive-helper-shadowing.rs:10:5 + --> $DIR/derive-helper-shadowing.rs:11:5 | LL | use test_macros::empty_attr as empty_helper; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `crate::empty_helper` to refer to this attribute macro unambiguously error: derive helper attribute is used before it is introduced - --> $DIR/derive-helper-shadowing.rs:19:3 + --> $DIR/derive-helper-shadowing.rs:20:3 | LL | #[empty_helper] | ^^^^^^^^^^^^ @@ -76,7 +76,7 @@ error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0659`. Future incompatibility report: Future breakage diagnostic: error: derive helper attribute is used before it is introduced - --> $DIR/derive-helper-shadowing.rs:19:3 + --> $DIR/derive-helper-shadowing.rs:20:3 | LL | #[empty_helper] | ^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/derive-same-struct.rs b/tests/ui/proc-macro/derive-same-struct.rs index f7669ba1480b2..04ab08dc76e5b 100644 --- a/tests/ui/proc-macro/derive-same-struct.rs +++ b/tests/ui/proc-macro/derive-same-struct.rs @@ -3,6 +3,7 @@ #![allow(path_statements)] #![allow(dead_code)] //@ proc-macro: derive-same-struct.rs +//@ ignore-backends: gcc #[macro_use] extern crate derive_same_struct; diff --git a/tests/ui/proc-macro/edition-imports-2018.rs b/tests/ui/proc-macro/edition-imports-2018.rs index a3808d9dce823..af9eed74adb9b 100644 --- a/tests/ui/proc-macro/edition-imports-2018.rs +++ b/tests/ui/proc-macro/edition-imports-2018.rs @@ -1,6 +1,7 @@ //@ check-pass //@ edition:2018 //@ proc-macro: edition-imports-2015.rs +//@ ignore-backends: gcc #[macro_use] extern crate edition_imports_2015; diff --git a/tests/ui/proc-macro/env.rs b/tests/ui/proc-macro/env.rs index 94e3b09e5269b..fc248f8835964 100644 --- a/tests/ui/proc-macro/env.rs +++ b/tests/ui/proc-macro/env.rs @@ -2,6 +2,7 @@ //@ run-pass //@ rustc-env: THE_CONST=1 //@ compile-flags: -Zunstable-options --env-set THE_CONST=12 --env-set ANOTHER=4 +//@ ignore-backends: gcc #![crate_name = "foo"] diff --git a/tests/ui/proc-macro/expand-expr.rs b/tests/ui/proc-macro/expand-expr.rs index 8a4ed9768d53a..c3dddd8e45940 100644 --- a/tests/ui/proc-macro/expand-expr.rs +++ b/tests/ui/proc-macro/expand-expr.rs @@ -1,5 +1,6 @@ //@ proc-macro: expand-expr.rs -// no-remap-src-base: check_expand_expr_file!() fails when enabled. +//@ ignore-backends: gcc +// No `remap-src-base`, since `check_expand_expr_file!()` fails when enabled. #![feature(concat_bytes)] extern crate expand_expr; @@ -10,7 +11,7 @@ use expand_expr::{ // Check builtin macros can be expanded. -expand_expr_is!(13u32, line!()); +expand_expr_is!(14u32, line!()); expand_expr_is!(24u32, column!()); expand_expr_is!("Hello, World!", concat!("Hello, ", "World", "!")); diff --git a/tests/ui/proc-macro/expand-expr.stderr b/tests/ui/proc-macro/expand-expr.stderr index 8b1df177cfa6d..fd5f672adf5c0 100644 --- a/tests/ui/proc-macro/expand-expr.stderr +++ b/tests/ui/proc-macro/expand-expr.stderr @@ -1,29 +1,29 @@ error: expected one of `.`, `?`, or an operator, found `;` - --> $DIR/expand-expr.rs:108:27 + --> $DIR/expand-expr.rs:109:27 | LL | expand_expr_fail!("string"; hello); | ^ expected one of `.`, `?`, or an operator error: expected expression, found `$` - --> $DIR/expand-expr.rs:111:19 + --> $DIR/expand-expr.rs:112:19 | LL | expand_expr_fail!($); | ^ expected expression error: expected expression, found `$` - --> $DIR/expand-expr.rs:112:29 + --> $DIR/expand-expr.rs:113:29 | LL | expand_expr_fail!(echo_tts!($)); | ^ expected expression error: expected expression, found `$` - --> $DIR/expand-expr.rs:113:28 + --> $DIR/expand-expr.rs:114:28 | LL | expand_expr_fail!(echo_pm!($)); | ^ expected expression error: macro expansion ignores `hello` and any tokens following - --> $DIR/expand-expr.rs:117:47 + --> $DIR/expand-expr.rs:118:47 | LL | expand_expr_is!("string", echo_tts!("string"; hello)); | --------------------^^^^^- caused by the macro expansion here @@ -35,7 +35,7 @@ LL | expand_expr_is!("string", echo_tts!("string"; hello);); | + error: macro expansion ignores `;` and any tokens following - --> $DIR/expand-expr.rs:118:44 + --> $DIR/expand-expr.rs:119:44 | LL | expand_expr_is!("string", echo_pm!("string"; hello)); | -----------------^------- caused by the macro expansion here @@ -47,7 +47,7 @@ LL | expand_expr_is!("string", echo_pm!("string"; hello);); | + error: recursion limit reached while expanding `recursive_expand!` - --> $DIR/expand-expr.rs:126:16 + --> $DIR/expand-expr.rs:127:16 | LL | const _: u32 = recursive_expand!(); | ^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/expand-to-unstable.rs b/tests/ui/proc-macro/expand-to-unstable.rs index 8968471ebd872..37bfeab1fe71e 100644 --- a/tests/ui/proc-macro/expand-to-unstable.rs +++ b/tests/ui/proc-macro/expand-to-unstable.rs @@ -1,4 +1,5 @@ //@ proc-macro: derive-unstable.rs +//@ ignore-backends: gcc #![allow(warnings)] diff --git a/tests/ui/proc-macro/expand-to-unstable.stderr b/tests/ui/proc-macro/expand-to-unstable.stderr index 563c7ae8f9561..255f80501ea73 100644 --- a/tests/ui/proc-macro/expand-to-unstable.stderr +++ b/tests/ui/proc-macro/expand-to-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature `core_intrinsics`: intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library - --> $DIR/expand-to-unstable.rs:8:10 + --> $DIR/expand-to-unstable.rs:9:10 | LL | #[derive(Unstable)] | ^^^^^^^^ diff --git a/tests/ui/proc-macro/expand-with-a-macro.rs b/tests/ui/proc-macro/expand-with-a-macro.rs index e5baf3601db0a..aa02cefbec684 100644 --- a/tests/ui/proc-macro/expand-with-a-macro.rs +++ b/tests/ui/proc-macro/expand-with-a-macro.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ proc-macro: expand-with-a-macro.rs +//@ ignore-backends: gcc #![deny(warnings)] diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs index 3deec94fa3411..fb7c830c2edf4 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.rs +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.rs @@ -3,6 +3,7 @@ // `$crate` refers to the crate that defines `macro_rules` and not the outer transparent macro. //@ proc-macro: gen-macro-rules-hygiene.rs +//@ ignore-backends: gcc #[macro_use] extern crate gen_macro_rules_hygiene; diff --git a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr index df7c4f72eb0b6..e904b43aaae06 100644 --- a/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr +++ b/tests/ui/proc-macro/gen-macro-rules-hygiene.stderr @@ -1,5 +1,5 @@ error[E0426]: use of undeclared label `'label_use` - --> $DIR/gen-macro-rules-hygiene.rs:12:1 + --> $DIR/gen-macro-rules-hygiene.rs:13:1 | LL | gen_macro_rules!(); | ^^^^^^^^^^^^^^^^^^ undeclared label `'label_use` @@ -10,7 +10,7 @@ LL | generated!(); = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_use` in this scope - --> $DIR/gen-macro-rules-hygiene.rs:12:1 + --> $DIR/gen-macro-rules-hygiene.rs:13:1 | LL | gen_macro_rules!(); | ^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` @@ -21,7 +21,7 @@ LL | generated!(); = note: this error originates in the macro `generated` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope - --> $DIR/gen-macro-rules-hygiene.rs:21:9 + --> $DIR/gen-macro-rules-hygiene.rs:22:9 | LL | local_def; | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` diff --git a/tests/ui/proc-macro/gen-macro-rules.rs b/tests/ui/proc-macro/gen-macro-rules.rs index 121d029e2e346..8ee38b2cc2795 100644 --- a/tests/ui/proc-macro/gen-macro-rules.rs +++ b/tests/ui/proc-macro/gen-macro-rules.rs @@ -2,6 +2,7 @@ //@ check-pass //@ proc-macro: gen-macro-rules.rs +//@ ignore-backends: gcc extern crate gen_macro_rules as repro; diff --git a/tests/ui/proc-macro/generate-mod.rs b/tests/ui/proc-macro/generate-mod.rs index 729bfc1db6674..0a1629e75ec17 100644 --- a/tests/ui/proc-macro/generate-mod.rs +++ b/tests/ui/proc-macro/generate-mod.rs @@ -1,6 +1,7 @@ // Modules generated by transparent proc macros still acts as barriers for names (issue #50504). //@ proc-macro: generate-mod.rs +//@ ignore-backends: gcc extern crate generate_mod; diff --git a/tests/ui/proc-macro/generate-mod.stderr b/tests/ui/proc-macro/generate-mod.stderr index 142ff1abeed6b..03cf8c35188ac 100644 --- a/tests/ui/proc-macro/generate-mod.stderr +++ b/tests/ui/proc-macro/generate-mod.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:9:1 + --> $DIR/generate-mod.rs:10:1 | LL | generate_mod::check!(); | ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -9,7 +9,7 @@ LL | generate_mod::check!(); = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `Outer` in this scope - --> $DIR/generate-mod.rs:9:1 + --> $DIR/generate-mod.rs:10:1 | LL | generate_mod::check!(); | ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -19,7 +19,7 @@ LL | generate_mod::check!(); = note: this error originates in the macro `generate_mod::check` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:12:1 + --> $DIR/generate-mod.rs:13:1 | LL | #[generate_mod::check_attr] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -29,7 +29,7 @@ LL | #[generate_mod::check_attr] = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `OuterAttr` in this scope - --> $DIR/generate-mod.rs:12:1 + --> $DIR/generate-mod.rs:13:1 | LL | #[generate_mod::check_attr] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -39,7 +39,7 @@ LL | #[generate_mod::check_attr] = note: this error originates in the attribute macro `generate_mod::check_attr` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:16:10 + --> $DIR/generate-mod.rs:17:10 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -50,7 +50,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:16:10 + --> $DIR/generate-mod.rs:17:10 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -60,7 +60,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:23:14 + --> $DIR/generate-mod.rs:24:14 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -70,7 +70,7 @@ LL | #[derive(generate_mod::CheckDerive)] = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:23:14 + --> $DIR/generate-mod.rs:24:14 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -84,7 +84,7 @@ error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0412`. Future incompatibility report: Future breakage diagnostic: error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:16:10 + --> $DIR/generate-mod.rs:17:10 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -96,7 +96,7 @@ LL | #[derive(generate_mod::CheckDerive)] Future breakage diagnostic: error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:16:10 + --> $DIR/generate-mod.rs:17:10 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -108,7 +108,7 @@ LL | #[derive(generate_mod::CheckDerive)] Future breakage diagnostic: error: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:23:14 + --> $DIR/generate-mod.rs:24:14 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -120,7 +120,7 @@ LL | #[derive(generate_mod::CheckDerive)] Future breakage diagnostic: error: cannot find type `OuterDerive` in this scope - --> $DIR/generate-mod.rs:23:14 + --> $DIR/generate-mod.rs:24:14 | LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -132,7 +132,7 @@ LL | #[derive(generate_mod::CheckDerive)] Future breakage diagnostic: warning: cannot find type `FromOutside` in this scope - --> $DIR/generate-mod.rs:30:10 + --> $DIR/generate-mod.rs:31:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import @@ -143,7 +143,7 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed Future breakage diagnostic: warning: cannot find type `OuterDeriveLint` in this scope - --> $DIR/generate-mod.rs:30:10 + --> $DIR/generate-mod.rs:31:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import diff --git a/tests/ui/proc-macro/hygiene_example.rs b/tests/ui/proc-macro/hygiene_example.rs index 84b5e345608aa..f74f22fb3b0e0 100644 --- a/tests/ui/proc-macro/hygiene_example.rs +++ b/tests/ui/proc-macro/hygiene_example.rs @@ -1,5 +1,6 @@ //@ check-pass //@ aux-build:hygiene_example.rs +//@ ignore-backends: gcc extern crate hygiene_example; use hygiene_example::hello; diff --git a/tests/ui/proc-macro/inner-attr-file-mod.rs b/tests/ui/proc-macro/inner-attr-file-mod.rs new file mode 100644 index 0000000000000..e592331c2c6db --- /dev/null +++ b/tests/ui/proc-macro/inner-attr-file-mod.rs @@ -0,0 +1,18 @@ +//@ compile-flags: -Z span-debug +//@ proc-macro: test-macros.rs + +#![no_std] // Don't load unnecessary hygiene information from std +extern crate std; + +#[macro_use] +extern crate test_macros; + +#[deny(unused_attributes)] +mod module_with_attrs; +//~^ ERROR file modules in proc macro input are unstable +//~| ERROR custom inner attributes are unstable + +fn main() {} + +//~? ERROR custom inner attributes are unstable +//~? ERROR inner macro attributes are unstable diff --git a/tests/ui/proc-macro/inner-attr-file-mod.stderr b/tests/ui/proc-macro/inner-attr-file-mod.stderr new file mode 100644 index 0000000000000..92262284a00c4 --- /dev/null +++ b/tests/ui/proc-macro/inner-attr-file-mod.stderr @@ -0,0 +1,43 @@ +error[E0658]: custom inner attributes are unstable + --> $DIR/module_with_attrs.rs:3:4 + | +LL | #![rustfmt::skip] + | ^^^^^^^^^^^^^ + | + = note: see issue #54726 for more information + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: inner macro attributes are unstable + --> $DIR/module_with_attrs.rs:4:4 + | +LL | #![print_attr] + | ^^^^^^^^^^ + | + = note: see issue #54726 for more information + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: file modules in proc macro input are unstable + --> $DIR/inner-attr-file-mod.rs:11:1 + | +LL | mod module_with_attrs; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54727 for more information + = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: custom inner attributes are unstable + --> $DIR/inner-attr-file-mod.rs:11:1 + | +LL | mod module_with_attrs; + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #54726 for more information + = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/proc-macro/inner-attr-file-mod.stdout b/tests/ui/proc-macro/inner-attr-file-mod.stdout new file mode 100644 index 0000000000000..6f893875657b0 --- /dev/null +++ b/tests/ui/proc-macro/inner-attr-file-mod.stdout @@ -0,0 +1,77 @@ +PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #![rustfmt::skip] } +PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #! [rustfmt :: skip] } +PRINT-ATTR INPUT (DEBUG): TokenStream [ + Punct { + ch: '#', + spacing: Alone, + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "deny", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Group { + delimiter: Parenthesis, + stream: TokenStream [ + Ident { + ident: "unused_attributes", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + ], + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + ], + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Ident { + ident: "mod", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Ident { + ident: "module_with_attrs", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Group { + delimiter: Brace, + stream: TokenStream [ + Punct { + ch: '#', + spacing: Joint, + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Punct { + ch: '!', + spacing: Alone, + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Group { + delimiter: Bracket, + stream: TokenStream [ + Ident { + ident: "rustfmt", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Punct { + ch: ':', + spacing: Joint, + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Punct { + ch: ':', + spacing: Alone, + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + Ident { + ident: "skip", + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + ], + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, + ], + span: $DIR/inner-attr-file-mod.rs:11:1: 11:23 (#0), + }, +] diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs b/tests/ui/proc-macro/inner-attr-non-inline-mod.rs deleted file mode 100644 index 2dcdbf3c40226..0000000000000 --- a/tests/ui/proc-macro/inner-attr-non-inline-mod.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ compile-flags: -Z span-debug -//@ proc-macro: test-macros.rs - -#![no_std] // Don't load unnecessary hygiene information from std -extern crate std; - -#[macro_use] -extern crate test_macros; - -#[deny(unused_attributes)] -mod module_with_attrs; -//~^ ERROR non-inline modules in proc macro input are unstable -//~| ERROR custom inner attributes are unstable - -fn main() {} - -//~? ERROR custom inner attributes are unstable -//~? ERROR inner macro attributes are unstable diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr b/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr deleted file mode 100644 index c0a9385f4c688..0000000000000 --- a/tests/ui/proc-macro/inner-attr-non-inline-mod.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0658]: custom inner attributes are unstable - --> $DIR/module_with_attrs.rs:3:4 - | -LL | #![rustfmt::skip] - | ^^^^^^^^^^^^^ - | - = note: see issue #54726 for more information - = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: inner macro attributes are unstable - --> $DIR/module_with_attrs.rs:4:4 - | -LL | #![print_attr] - | ^^^^^^^^^^ - | - = note: see issue #54726 for more information - = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: non-inline modules in proc macro input are unstable - --> $DIR/inner-attr-non-inline-mod.rs:11:1 - | -LL | mod module_with_attrs; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #54727 for more information - = help: add `#![feature(proc_macro_hygiene)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: custom inner attributes are unstable - --> $DIR/inner-attr-non-inline-mod.rs:11:1 - | -LL | mod module_with_attrs; - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #54726 for more information - = help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout b/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout deleted file mode 100644 index 219794a8eb8cd..0000000000000 --- a/tests/ui/proc-macro/inner-attr-non-inline-mod.stdout +++ /dev/null @@ -1,77 +0,0 @@ -PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #![rustfmt::skip] } -PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #! [rustfmt :: skip] } -PRINT-ATTR INPUT (DEBUG): TokenStream [ - Punct { - ch: '#', - spacing: Alone, - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "deny", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Group { - delimiter: Parenthesis, - stream: TokenStream [ - Ident { - ident: "unused_attributes", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - ], - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - ], - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Ident { - ident: "mod", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Ident { - ident: "module_with_attrs", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Group { - delimiter: Brace, - stream: TokenStream [ - Punct { - ch: '#', - spacing: Joint, - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Punct { - ch: '!', - spacing: Alone, - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - ident: "rustfmt", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Punct { - ch: ':', - spacing: Joint, - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Punct { - ch: ':', - spacing: Alone, - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - Ident { - ident: "skip", - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - ], - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, - ], - span: $DIR/inner-attr-non-inline-mod.rs:11:1: 11:23 (#0), - }, -] diff --git a/tests/ui/proc-macro/is-available.rs b/tests/ui/proc-macro/is-available.rs index faee560d7a975..9e9cf5d11b661 100644 --- a/tests/ui/proc-macro/is-available.rs +++ b/tests/ui/proc-macro/is-available.rs @@ -3,6 +3,7 @@ extern crate proc_macro; //@ proc-macro: is-available.rs +//@ ignore-backends: gcc extern crate is_available; fn main() { diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs index abdd6bf136dcf..d420f2641daf5 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-104884.rs +//@ ignore-backends: gcc use std::collections::BinaryHeap; diff --git a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr index f3ed9e5761d67..b7aed4a8485a8 100644 --- a/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr +++ b/tests/ui/proc-macro/issue-104884-trait-impl-sugg-err.stderr @@ -1,11 +1,11 @@ error[E0277]: can't compare `PriorityQueue` with `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^^^^ no implementation for `PriorityQueue == PriorityQueue` | help: the trait `PartialEq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:20:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,13 +13,13 @@ note: required by a bound in `PartialOrd` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: the trait bound `PriorityQueue: Eq` is not satisfied - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ unsatisfied trait bound | help: the trait `Eq` is not implemented for `PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:20:1 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:1 | LL | struct PriorityQueue(BinaryHeap>); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -28,13 +28,13 @@ note: required by a bound in `Ord` = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't compare `T` with `T` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ no implementation for `T < T` and `T > T` | note: required for `PriorityQueue` to implement `PartialOrd` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:10 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:10 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro @@ -42,7 +42,7 @@ note: required by a bound in `Ord` --> $SRC_DIR/core/src/cmp.rs:LL:COL error[E0277]: can't compare `BinaryHeap>` with `_` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:20:25 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:21:25 | LL | #[derive(PartialOrd, AddImpl)] | ---------- in this derive macro expansion @@ -53,7 +53,7 @@ LL | struct PriorityQueue(BinaryHeap>); = help: the trait `PartialOrd<_>` is not implemented for `BinaryHeap>` error[E0599]: no method named `cmp` found for struct `BinaryHeap>` in the current scope - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ `BinaryHeap>` is not an iterator @@ -61,7 +61,7 @@ LL | #[derive(PartialOrd, AddImpl)] = note: this error originates in the derive macro `AddImpl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0609]: no field `height` on type `&PriorityQueue` - --> $DIR/issue-104884-trait-impl-sugg-err.rs:13:22 + --> $DIR/issue-104884-trait-impl-sugg-err.rs:14:22 | LL | #[derive(PartialOrd, AddImpl)] | ^^^^^^^ unknown field diff --git a/tests/ui/proc-macro/issue-107113-wrap.rs b/tests/ui/proc-macro/issue-107113-wrap.rs index 2799e79bb1cb4..a46cf893d90e8 100644 --- a/tests/ui/proc-macro/issue-107113-wrap.rs +++ b/tests/ui/proc-macro/issue-107113-wrap.rs @@ -1,5 +1,6 @@ //@ edition:2021 //@ proc-macro: issue-107113.rs +//@ ignore-backends: gcc #[macro_use] extern crate issue_107113; diff --git a/tests/ui/proc-macro/issue-107113-wrap.stderr b/tests/ui/proc-macro/issue-107113-wrap.stderr index b541051147d53..9b5b0333256e6 100644 --- a/tests/ui/proc-macro/issue-107113-wrap.stderr +++ b/tests/ui/proc-macro/issue-107113-wrap.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-107113-wrap.rs:7:1 + --> $DIR/issue-107113-wrap.rs:8:1 | LL | #[issue_107113::main] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/issue-118809.rs b/tests/ui/proc-macro/issue-118809.rs index a6a3956981a78..3ceede7e885cf 100644 --- a/tests/ui/proc-macro/issue-118809.rs +++ b/tests/ui/proc-macro/issue-118809.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-118809.rs +//@ ignore-backends: gcc #[macro_use] extern crate issue_118809; diff --git a/tests/ui/proc-macro/issue-118809.stderr b/tests/ui/proc-macro/issue-118809.stderr index 30b09fd4006bf..98329fea11940 100644 --- a/tests/ui/proc-macro/issue-118809.stderr +++ b/tests/ui/proc-macro/issue-118809.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-118809.rs:6:10 + --> $DIR/issue-118809.rs:7:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[derive(Deserialize)] | arguments to this enum variant are incorrect | help: the type constructed contains `u32` due to the type of the argument passed - --> $DIR/issue-118809.rs:6:10 + --> $DIR/issue-118809.rs:7:10 | LL | #[derive(Deserialize)] | ^^^^^^^^^^^ this argument influences the type of `Some` diff --git a/tests/ui/proc-macro/issue-38586.rs b/tests/ui/proc-macro/issue-38586.rs index 88dbb8037bebd..c9623fd383b1a 100644 --- a/tests/ui/proc-macro/issue-38586.rs +++ b/tests/ui/proc-macro/issue-38586.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-38586.rs +//@ ignore-backends: gcc #[macro_use] extern crate issue_38586; diff --git a/tests/ui/proc-macro/issue-38586.stderr b/tests/ui/proc-macro/issue-38586.stderr index 0049155645078..e49d4c83e2734 100644 --- a/tests/ui/proc-macro/issue-38586.stderr +++ b/tests/ui/proc-macro/issue-38586.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `foo` in this scope - --> $DIR/issue-38586.rs:6:10 + --> $DIR/issue-38586.rs:7:10 | LL | #[derive(A)] | ^ not found in this scope diff --git a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs index df236cce6d2a8..988641b2b9c48 100644 --- a/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs +++ b/tests/ui/proc-macro/issue-59191-replace-root-with-fn.rs @@ -4,6 +4,7 @@ //@ edition:2018 //@ proc-macro: issue-59191.rs //@ needs-unwind (affects error output) +//@ ignore-backends: gcc #![feature(custom_inner_attributes)] #![issue_59191::no_main] diff --git a/tests/ui/proc-macro/issue-79148.rs b/tests/ui/proc-macro/issue-79148.rs index b2248759b5f8e..7ce6216c842a6 100644 --- a/tests/ui/proc-macro/issue-79148.rs +++ b/tests/ui/proc-macro/issue-79148.rs @@ -1,5 +1,6 @@ //@ proc-macro: re-export.rs //@ edition:2018 +//@ ignore-backends: gcc extern crate re_export; diff --git a/tests/ui/proc-macro/issue-79148.stderr b/tests/ui/proc-macro/issue-79148.stderr index 8adc4c6e0dbe4..80a5b1a0855f7 100644 --- a/tests/ui/proc-macro/issue-79148.stderr +++ b/tests/ui/proc-macro/issue-79148.stderr @@ -1,11 +1,11 @@ error[E0364]: `Variant` is only public within the crate, and cannot be re-exported outside - --> $DIR/issue-79148.rs:8:1 + --> $DIR/issue-79148.rs:9:1 | LL | cause_ice!(); | ^^^^^^^^^^^^ | note: consider marking `Variant` as `pub` in the imported module - --> $DIR/issue-79148.rs:8:1 + --> $DIR/issue-79148.rs:9:1 | LL | cause_ice!(); | ^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/issue-83510.rs b/tests/ui/proc-macro/issue-83510.rs index 67469511fc367..d49e1867f1d67 100644 --- a/tests/ui/proc-macro/issue-83510.rs +++ b/tests/ui/proc-macro/issue-83510.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-83510.rs +//@ ignore-backends: gcc extern crate issue_83510; diff --git a/tests/ui/proc-macro/issue-83510.stderr b/tests/ui/proc-macro/issue-83510.stderr index e59b77af3dc39..a7c3f5a1d5b67 100644 --- a/tests/ui/proc-macro/issue-83510.stderr +++ b/tests/ui/proc-macro/issue-83510.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Foo` in this scope - --> $DIR/issue-83510.rs:5:1 + --> $DIR/issue-83510.rs:6:1 | LL | issue_83510::dance_like_you_want_to_ice!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -7,7 +7,7 @@ LL | issue_83510::dance_like_you_want_to_ice!(); = note: this error originates in the macro `issue_83510::dance_like_you_want_to_ice` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0404]: expected trait, found struct `Box` - --> $DIR/issue-83510.rs:5:1 + --> $DIR/issue-83510.rs:6:1 | LL | issue_83510::dance_like_you_want_to_ice!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a trait @@ -15,7 +15,7 @@ LL | issue_83510::dance_like_you_want_to_ice!(); = note: this error originates in the macro `issue_83510::dance_like_you_want_to_ice` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0405]: cannot find trait `Baz` in this scope - --> $DIR/issue-83510.rs:5:1 + --> $DIR/issue-83510.rs:6:1 | LL | issue_83510::dance_like_you_want_to_ice!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope @@ -23,7 +23,7 @@ LL | issue_83510::dance_like_you_want_to_ice!(); = note: this error originates in the macro `issue_83510::dance_like_you_want_to_ice` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0658]: inherent associated types are unstable - --> $DIR/issue-83510.rs:5:1 + --> $DIR/issue-83510.rs:6:1 | LL | issue_83510::dance_like_you_want_to_ice!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/issue-91800.rs b/tests/ui/proc-macro/issue-91800.rs index 8cecfad32b55b..79cbf8632f009 100644 --- a/tests/ui/proc-macro/issue-91800.rs +++ b/tests/ui/proc-macro/issue-91800.rs @@ -1,4 +1,5 @@ //@ proc-macro: issue-91800-macro.rs +//@ ignore-backends: gcc #[macro_use] extern crate issue_91800_macro; diff --git a/tests/ui/proc-macro/issue-91800.stderr b/tests/ui/proc-macro/issue-91800.stderr index 63ebc0a552e33..be5a8ece38404 100644 --- a/tests/ui/proc-macro/issue-91800.stderr +++ b/tests/ui/proc-macro/issue-91800.stderr @@ -1,5 +1,5 @@ error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-91800.rs:6:10 + --> $DIR/issue-91800.rs:7:10 | LL | #[derive(MyTrait)] | ^^^^^^^ @@ -7,13 +7,13 @@ LL | #[derive(MyTrait)] = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) error: proc-macro derive produced unparsable tokens - --> $DIR/issue-91800.rs:6:10 + --> $DIR/issue-91800.rs:7:10 | LL | #[derive(MyTrait)] | ^^^^^^^ error: - --> $DIR/issue-91800.rs:6:10 + --> $DIR/issue-91800.rs:7:10 | LL | #[derive(MyTrait)] | ^^^^^^^ @@ -21,7 +21,7 @@ LL | #[derive(MyTrait)] = note: this error originates in the derive macro `MyTrait` (in Nightly builds, run with -Z macro-backtrace for more info) error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-91800.rs:10:1 + --> $DIR/issue-91800.rs:11:1 | LL | #[attribute_macro] | ^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | #[attribute_macro] = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: - --> $DIR/issue-91800.rs:10:1 + --> $DIR/issue-91800.rs:11:1 | LL | #[attribute_macro] | ^^^^^^^^^^^^^^^^^^ @@ -37,7 +37,7 @@ LL | #[attribute_macro] = note: this error originates in the attribute macro `attribute_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: macros that expand to items must be delimited with braces or followed by a semicolon - --> $DIR/issue-91800.rs:15:1 + --> $DIR/issue-91800.rs:16:1 | LL | fn_macro! {} | ^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | fn_macro! {} = note: this error originates in the macro `fn_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: - --> $DIR/issue-91800.rs:15:1 + --> $DIR/issue-91800.rs:16:1 | LL | fn_macro! {} | ^^^^^^^^^^^^ diff --git a/tests/ui/proc-macro/lifetimes-rpass.rs b/tests/ui/proc-macro/lifetimes-rpass.rs index c462b27722f7e..9b794e695cd1c 100644 --- a/tests/ui/proc-macro/lifetimes-rpass.rs +++ b/tests/ui/proc-macro/lifetimes-rpass.rs @@ -2,6 +2,7 @@ #![allow(unused_variables)] //@ proc-macro: lifetimes-rpass.rs +//@ ignore-backends: gcc extern crate lifetimes_rpass as lifetimes; use lifetimes::*; diff --git a/tests/ui/proc-macro/lints_in_proc_macros.rs b/tests/ui/proc-macro/lints_in_proc_macros.rs index 6714b8b6e1d5f..2c22c787982eb 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.rs +++ b/tests/ui/proc-macro/lints_in_proc_macros.rs @@ -1,4 +1,5 @@ //@ proc-macro: bang_proc_macro2.rs +//@ ignore-backends: gcc extern crate bang_proc_macro2; diff --git a/tests/ui/proc-macro/lints_in_proc_macros.stderr b/tests/ui/proc-macro/lints_in_proc_macros.stderr index 244d218608be7..016b236bda881 100644 --- a/tests/ui/proc-macro/lints_in_proc_macros.stderr +++ b/tests/ui/proc-macro/lints_in_proc_macros.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `foobar2` in this scope - --> $DIR/lints_in_proc_macros.rs:9:5 + --> $DIR/lints_in_proc_macros.rs:10:5 | LL | bang_proc_macro2!(); | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `foobar` diff --git a/tests/ui/proc-macro/load-two.rs b/tests/ui/proc-macro/load-two.rs index 608379949e665..197e7845db33b 100644 --- a/tests/ui/proc-macro/load-two.rs +++ b/tests/ui/proc-macro/load-two.rs @@ -4,6 +4,7 @@ #![allow(dead_code)] //@ proc-macro: derive-atob.rs //@ proc-macro: derive-ctod.rs +//@ ignore-backends: gcc #[macro_use] extern crate derive_atob; diff --git a/tests/ui/proc-macro/macro-crate-multi-decorator.rs b/tests/ui/proc-macro/macro-crate-multi-decorator.rs index c4f02e7adfcbc..e247c9526a4c9 100644 --- a/tests/ui/proc-macro/macro-crate-multi-decorator.rs +++ b/tests/ui/proc-macro/macro-crate-multi-decorator.rs @@ -2,6 +2,7 @@ //@ check-pass //@ proc-macro: duplicate.rs +//@ ignore-backends: gcc #[macro_use] extern crate duplicate; diff --git a/tests/ui/proc-macro/macro_rules_edition_from_pm.rs b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs index 8fc7d9097493d..fc3ae3ef2c814 100644 --- a/tests/ui/proc-macro/macro_rules_edition_from_pm.rs +++ b/tests/ui/proc-macro/macro_rules_edition_from_pm.rs @@ -7,6 +7,7 @@ //@[edition2021] edition:2021 //@[edition2024] edition:2024 //@ check-pass +//@ ignore-backends: gcc // This checks how the expr fragment specifier works. macro_rules_edition_pm::make_edition_macro!{} diff --git a/tests/ui/proc-macro/match-expander.rs b/tests/ui/proc-macro/match-expander.rs index 23e5746c540f7..b7245c7e682c1 100644 --- a/tests/ui/proc-macro/match-expander.rs +++ b/tests/ui/proc-macro/match-expander.rs @@ -1,4 +1,5 @@ //@ proc-macro: match-expander.rs +//@ ignore-backends: gcc // Ensure that we don't point at macro invocation when providing inference contexts. #[macro_use] diff --git a/tests/ui/proc-macro/match-expander.stderr b/tests/ui/proc-macro/match-expander.stderr index b77468ec60a5e..d2423336b1d22 100644 --- a/tests/ui/proc-macro/match-expander.stderr +++ b/tests/ui/proc-macro/match-expander.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/match-expander.rs:8:5 + --> $DIR/match-expander.rs:9:5 | LL | match_expander::matcher!(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `S`, found `bool` diff --git a/tests/ui/proc-macro/mixed-site-span.rs b/tests/ui/proc-macro/mixed-site-span.rs index 442b440c1211a..98a022632cd59 100644 --- a/tests/ui/proc-macro/mixed-site-span.rs +++ b/tests/ui/proc-macro/mixed-site-span.rs @@ -2,6 +2,7 @@ //@ aux-build: token-site-span.rs //@ proc-macro: mixed-site-span.rs +//@ ignore-backends: gcc extern crate mixed_site_span; extern crate token_site_span; diff --git a/tests/ui/proc-macro/mixed-site-span.stderr b/tests/ui/proc-macro/mixed-site-span.stderr index d62031a853c05..2d2d55fe148d5 100644 --- a/tests/ui/proc-macro/mixed-site-span.stderr +++ b/tests/ui/proc-macro/mixed-site-span.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:47:5 + --> $DIR/mixed-site-span.rs:48:5 | LL | invoke_with_crate!{input proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -7,7 +7,7 @@ LL | invoke_with_crate!{input proc_macro_item} = note: this error originates in the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:48:5 + --> $DIR/mixed-site-span.rs:49:5 | LL | invoke_with_ident!{input proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -15,7 +15,7 @@ LL | invoke_with_ident!{input proc_macro_item} = note: this error originates in the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:49:5 + --> $DIR/mixed-site-span.rs:50:5 | LL | invoke_with_crate!{call proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -23,7 +23,7 @@ LL | invoke_with_crate!{call proc_macro_item} = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:50:5 + --> $DIR/mixed-site-span.rs:51:5 | LL | invoke_with_ident!{call proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -31,7 +31,7 @@ LL | invoke_with_ident!{call proc_macro_item} = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:51:5 + --> $DIR/mixed-site-span.rs:52:5 | LL | invoke_with_ident!{hello call proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -39,7 +39,7 @@ LL | invoke_with_ident!{hello call proc_macro_item} = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate::proc_macro_item` - --> $DIR/mixed-site-span.rs:54:5 + --> $DIR/mixed-site-span.rs:55:5 | LL | invoke_with_ident!{krate input proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -50,7 +50,7 @@ LL | invoke_with_ident!{krate input proc_macro_item} = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `invoke_with_ident` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate::proc_macro_item` - --> $DIR/mixed-site-span.rs:55:5 + --> $DIR/mixed-site-span.rs:56:5 | LL | with_crate!{krate input proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -61,7 +61,7 @@ LL | with_crate!{krate input proc_macro_item} = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:56:5 + --> $DIR/mixed-site-span.rs:57:5 | LL | with_crate!{krate call proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -72,7 +72,7 @@ LL | with_crate!{krate call proc_macro_item} = note: this error originates in the macro `with_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:60:28 + --> $DIR/mixed-site-span.rs:61:28 | LL | invoke_with_ident!{$crate input proc_macro_item} | ^^^^^^ --------------- help: a similar name exists in the module: `proc_macro_rules` @@ -85,7 +85,7 @@ LL | test!(); = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:61:21 + --> $DIR/mixed-site-span.rs:62:21 | LL | with_crate!{$crate input proc_macro_item} | ^^^^^^ --------------- help: a similar name exists in the module: `proc_macro_rules` @@ -98,7 +98,7 @@ LL | test!(); = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:62:9 + --> $DIR/mixed-site-span.rs:63:9 | LL | with_crate!{$crate call proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^---------------^ @@ -112,7 +112,7 @@ LL | test!(); = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:67:5 + --> $DIR/mixed-site-span.rs:68:5 | LL | test!(); | ^^^^^^^ no `proc_macro_item` in the root @@ -120,7 +120,7 @@ LL | test!(); = note: this error originates in the macro `with_crate` which comes from the expansion of the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate::TokenItem` - --> $DIR/mixed-site-span.rs:87:5 + --> $DIR/mixed-site-span.rs:88:5 | LL | invoke_with_ident!{krate input TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -133,7 +133,7 @@ LL | quote!(use $krate::$ident as token_site_span::TokenItem as _;) | +++++++++++++++++++++++++++++ error[E0432]: unresolved import `$crate::TokenItem` - --> $DIR/mixed-site-span.rs:88:5 + --> $DIR/mixed-site-span.rs:89:5 | LL | with_crate!{krate input TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -146,7 +146,7 @@ LL | quote!(use $krate::$ident as token_site_span::TokenItem as _;) | +++++++++++++++++++++++++++++ error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:89:5 + --> $DIR/mixed-site-span.rs:90:5 | LL | with_crate!{krate call TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -159,7 +159,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:92:5 + --> $DIR/mixed-site-span.rs:93:5 | LL | invoke_with_crate!{mixed TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -173,7 +173,7 @@ LL + ($s:ident $i:ident) => { token_site_span::TokenItem as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:93:5 + --> $DIR/mixed-site-span.rs:94:5 | LL | invoke_with_ident!{mixed TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -187,7 +187,7 @@ LL + ($s:ident $i:ident) => { token_site_span::TokenItem as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:94:5 + --> $DIR/mixed-site-span.rs:95:5 | LL | invoke_with_ident!{krate mixed TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -201,7 +201,7 @@ LL + ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:95:5 + --> $DIR/mixed-site-span.rs:96:5 | LL | with_crate!{krate mixed TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -214,7 +214,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:99:28 + --> $DIR/mixed-site-span.rs:100:28 | LL | invoke_with_ident!{$crate input TokenItem} | ^^^^^^ no `TokenItem` in the root @@ -230,7 +230,7 @@ LL + invoke_with_ident!{token_site_span::TokenItem as _ input TokenItem} | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:100:21 + --> $DIR/mixed-site-span.rs:101:21 | LL | with_crate!{$crate input TokenItem} | ^^^^^^ no `TokenItem` in the root @@ -246,7 +246,7 @@ LL + with_crate!{token_site_span::TokenItem as _ input TokenItem} | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:101:9 + --> $DIR/mixed-site-span.rs:102:9 | LL | with_crate!{$crate call TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -262,7 +262,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:108:5 + --> $DIR/mixed-site-span.rs:109:5 | LL | test!(); | ^^^^^^^ no `TokenItem` in the root @@ -276,7 +276,7 @@ LL + ($m:ident $s:ident $i:ident) => { token_site_span::TokenItem as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:105:9 + --> $DIR/mixed-site-span.rs:106:9 | LL | with_crate!{$crate mixed TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -292,7 +292,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:129:5 + --> $DIR/mixed-site-span.rs:130:5 | LL | invoke_with_crate!{input ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -306,7 +306,7 @@ LL + ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:130:5 + --> $DIR/mixed-site-span.rs:131:5 | LL | invoke_with_ident!{input ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -320,7 +320,7 @@ LL + ($s:ident $i:ident) => { with_crate!{ItemUse as _ $s $i} }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:133:5 + --> $DIR/mixed-site-span.rs:134:5 | LL | invoke_with_crate!{mixed ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -334,7 +334,7 @@ LL + ($s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:134:5 + --> $DIR/mixed-site-span.rs:135:5 | LL | invoke_with_ident!{mixed ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -348,7 +348,7 @@ LL + ($s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:135:5 + --> $DIR/mixed-site-span.rs:136:5 | LL | invoke_with_ident!{krate mixed ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -362,7 +362,7 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:136:5 + --> $DIR/mixed-site-span.rs:137:5 | LL | with_crate!{krate mixed ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -375,7 +375,7 @@ LL + ItemUse as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:138:5 + --> $DIR/mixed-site-span.rs:139:5 | LL | invoke_with_crate!{call ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -389,7 +389,7 @@ LL + ($s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:139:5 + --> $DIR/mixed-site-span.rs:140:5 | LL | invoke_with_ident!{call ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -403,7 +403,7 @@ LL + ($s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:140:5 + --> $DIR/mixed-site-span.rs:141:5 | LL | invoke_with_ident!{hello call ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -417,7 +417,7 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:148:5 + --> $DIR/mixed-site-span.rs:149:5 | LL | test!(); | ^^^^^^^ no `ItemUse` in the root @@ -431,7 +431,7 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:144:9 + --> $DIR/mixed-site-span.rs:145:9 | LL | with_crate!{$crate mixed ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -447,7 +447,7 @@ LL + ItemUse as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:148:5 + --> $DIR/mixed-site-span.rs:149:5 | LL | test!(); | ^^^^^^^ no `ItemUse` in the root @@ -461,7 +461,7 @@ LL + ($m:ident $s:ident $i:ident) => { ItemUse as _ }; | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:153:1 + --> $DIR/mixed-site-span.rs:154:1 | LL | use_input_crate!{proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -469,7 +469,7 @@ LL | use_input_crate!{proc_macro_item} = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:154:1 + --> $DIR/mixed-site-span.rs:155:1 | LL | use_input_krate!{proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -477,7 +477,7 @@ LL | use_input_krate!{proc_macro_item} = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:157:1 + --> $DIR/mixed-site-span.rs:158:1 | LL | use_call_crate!{proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -485,7 +485,7 @@ LL | use_call_crate!{proc_macro_item} = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:158:1 + --> $DIR/mixed-site-span.rs:159:1 | LL | use_call_krate!{proc_macro_item} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `proc_macro_item` in the root @@ -493,7 +493,7 @@ LL | use_call_krate!{proc_macro_item} = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:163:1 + --> $DIR/mixed-site-span.rs:164:1 | LL | use_mixed_crate!{TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -507,7 +507,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:164:1 + --> $DIR/mixed-site-span.rs:165:1 | LL | use_mixed_krate!{TokenItem} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `TokenItem` in the root @@ -521,7 +521,7 @@ LL + token_site_span::TokenItem as _ | error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:169:1 + --> $DIR/mixed-site-span.rs:170:1 | LL | use_input_crate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -529,7 +529,7 @@ LL | use_input_crate!{ItemUse} = note: this error originates in the macro `use_input_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:170:1 + --> $DIR/mixed-site-span.rs:171:1 | LL | use_input_krate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -537,7 +537,7 @@ LL | use_input_krate!{ItemUse} = note: this error originates in the macro `use_input_krate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:171:1 + --> $DIR/mixed-site-span.rs:172:1 | LL | use_mixed_crate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -545,7 +545,7 @@ LL | use_mixed_crate!{ItemUse} = note: this error originates in the macro `use_mixed_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:172:1 + --> $DIR/mixed-site-span.rs:173:1 | LL | use_mixed_krate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -553,7 +553,7 @@ LL | use_mixed_krate!{ItemUse} = note: this error originates in the macro `use_mixed_krate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:173:1 + --> $DIR/mixed-site-span.rs:174:1 | LL | use_call_crate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -561,7 +561,7 @@ LL | use_call_crate!{ItemUse} = note: this error originates in the macro `use_call_crate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0432]: unresolved import `$crate` - --> $DIR/mixed-site-span.rs:174:1 + --> $DIR/mixed-site-span.rs:175:1 | LL | use_call_krate!{ItemUse} | ^^^^^^^^^^^^^^^^^^^^^^^^ no `ItemUse` in the root @@ -569,7 +569,7 @@ LL | use_call_krate!{ItemUse} = note: this error originates in the macro `use_call_krate` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0426]: use of undeclared label `'label_use` - --> $DIR/mixed-site-span.rs:21:9 + --> $DIR/mixed-site-span.rs:22:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ undeclared label `'label_use` @@ -577,7 +577,7 @@ LL | proc_macro_rules!(); = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0412]: cannot find type `ItemUse` in crate `$crate` - --> $DIR/mixed-site-span.rs:21:9 + --> $DIR/mixed-site-span.rs:22:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ not found in `$crate` @@ -589,7 +589,7 @@ LL + use ItemUse; | error[E0425]: cannot find value `local_use` in this scope - --> $DIR/mixed-site-span.rs:21:9 + --> $DIR/mixed-site-span.rs:22:9 | LL | proc_macro_rules!(); | ^^^^^^^^^^^^^^^^^^^ help: a local variable with a similar name exists: `local_def` @@ -597,7 +597,7 @@ LL | proc_macro_rules!(); = note: this error originates in the macro `proc_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `local_def` in this scope - --> $DIR/mixed-site-span.rs:26:9 + --> $DIR/mixed-site-span.rs:27:9 | LL | local_def; | ^^^^^^^^^ help: a local variable with a similar name exists: `local_use` diff --git a/tests/ui/proc-macro/modify-ast.rs b/tests/ui/proc-macro/modify-ast.rs index 9e890f3ebaad9..75aea597ed576 100644 --- a/tests/ui/proc-macro/modify-ast.rs +++ b/tests/ui/proc-macro/modify-ast.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: modify-ast.rs +//@ ignore-backends: gcc extern crate modify_ast; diff --git a/tests/ui/proc-macro/panic-abort.rs b/tests/ui/proc-macro/panic-abort.rs index 58e1d00643309..adedba4ebca61 100644 --- a/tests/ui/proc-macro/panic-abort.rs +++ b/tests/ui/proc-macro/panic-abort.rs @@ -2,4 +2,4 @@ //@ force-host //@ check-pass -//~? WARN building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic +//~? WARN building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic diff --git a/tests/ui/proc-macro/panic-abort.stderr b/tests/ui/proc-macro/panic-abort.stderr index a6e18614f8f06..3dd75768bc4ab 100644 --- a/tests/ui/proc-macro/panic-abort.stderr +++ b/tests/ui/proc-macro/panic-abort.stderr @@ -1,4 +1,4 @@ -warning: building proc macro crate with `panic=abort` may crash the compiler should the proc-macro panic +warning: building proc macro crate with `panic=abort` or `panic=immediate-abort` may crash the compiler should the proc-macro panic warning: 1 warning emitted diff --git a/tests/ui/proc-macro/parent-source-spans.rs b/tests/ui/proc-macro/parent-source-spans.rs index cc3ac795f7f17..f675f6fb6f7da 100644 --- a/tests/ui/proc-macro/parent-source-spans.rs +++ b/tests/ui/proc-macro/parent-source-spans.rs @@ -1,4 +1,5 @@ //@ proc-macro: parent-source-spans.rs +//@ ignore-backends: gcc #![feature(decl_macro)] diff --git a/tests/ui/proc-macro/parent-source-spans.stderr b/tests/ui/proc-macro/parent-source-spans.stderr index db1eed5e4588e..28a70eea873d1 100644 --- a/tests/ui/proc-macro/parent-source-spans.stderr +++ b/tests/ui/proc-macro/parent-source-spans.stderr @@ -1,5 +1,5 @@ error: first final: "hello" - --> $DIR/parent-source-spans.rs:16:12 + --> $DIR/parent-source-spans.rs:17:12 | LL | three!($a, $b); | ^^ @@ -10,7 +10,7 @@ LL | one!("hello", "world"); = note: this error originates in the macro `two` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) error: second final: "world" - --> $DIR/parent-source-spans.rs:16:16 + --> $DIR/parent-source-spans.rs:17:16 | LL | three!($a, $b); | ^^ @@ -21,7 +21,7 @@ LL | one!("hello", "world"); = note: this error originates in the macro `two` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) error: first parent: "hello" - --> $DIR/parent-source-spans.rs:10:5 + --> $DIR/parent-source-spans.rs:11:5 | LL | two!($a, $b); | ^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | one!("hello", "world"); = note: this error originates in the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) error: second parent: "world" - --> $DIR/parent-source-spans.rs:10:5 + --> $DIR/parent-source-spans.rs:11:5 | LL | two!($a, $b); | ^^^^^^^^^^^^ @@ -43,31 +43,31 @@ LL | one!("hello", "world"); = note: this error originates in the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) error: first grandparent: "hello" - --> $DIR/parent-source-spans.rs:36:5 + --> $DIR/parent-source-spans.rs:37:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^ error: second grandparent: "world" - --> $DIR/parent-source-spans.rs:36:5 + --> $DIR/parent-source-spans.rs:37:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^ error: first source: "hello" - --> $DIR/parent-source-spans.rs:36:5 + --> $DIR/parent-source-spans.rs:37:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^ error: second source: "world" - --> $DIR/parent-source-spans.rs:36:5 + --> $DIR/parent-source-spans.rs:37:5 | LL | one!("hello", "world"); | ^^^^^^^^^^^^^^^^^^^^^^ error: first final: "yay" - --> $DIR/parent-source-spans.rs:16:12 + --> $DIR/parent-source-spans.rs:17:12 | LL | three!($a, $b); | ^^ @@ -78,7 +78,7 @@ LL | two!("yay", "rust"); = note: this error originates in the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) error: second final: "rust" - --> $DIR/parent-source-spans.rs:16:16 + --> $DIR/parent-source-spans.rs:17:16 | LL | three!($a, $b); | ^^ @@ -89,55 +89,55 @@ LL | two!("yay", "rust"); = note: this error originates in the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) error: first parent: "yay" - --> $DIR/parent-source-spans.rs:42:5 + --> $DIR/parent-source-spans.rs:43:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^ error: second parent: "rust" - --> $DIR/parent-source-spans.rs:42:5 + --> $DIR/parent-source-spans.rs:43:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^ error: first source: "yay" - --> $DIR/parent-source-spans.rs:42:5 + --> $DIR/parent-source-spans.rs:43:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^ error: second source: "rust" - --> $DIR/parent-source-spans.rs:42:5 + --> $DIR/parent-source-spans.rs:43:5 | LL | two!("yay", "rust"); | ^^^^^^^^^^^^^^^^^^^ error: first final: "hip" - --> $DIR/parent-source-spans.rs:48:12 + --> $DIR/parent-source-spans.rs:49:12 | LL | three!("hip", "hop"); | ^^^^^ error: second final: "hop" - --> $DIR/parent-source-spans.rs:48:19 + --> $DIR/parent-source-spans.rs:49:19 | LL | three!("hip", "hop"); | ^^^^^ error: first source: "hip" - --> $DIR/parent-source-spans.rs:48:12 + --> $DIR/parent-source-spans.rs:49:12 | LL | three!("hip", "hop"); | ^^^^^ error: second source: "hop" - --> $DIR/parent-source-spans.rs:48:19 + --> $DIR/parent-source-spans.rs:49:19 | LL | three!("hip", "hop"); | ^^^^^ error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:29:5 + --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` @@ -152,7 +152,7 @@ LL | one!("hello", "world"); = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `one` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:29:5 + --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` @@ -167,7 +167,7 @@ LL | two!("yay", "rust"); = note: this error originates in the macro `parent_source_spans` which comes from the expansion of the macro `two` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `ok` in this scope - --> $DIR/parent-source-spans.rs:29:5 + --> $DIR/parent-source-spans.rs:30:5 | LL | parent_source_spans!($($tokens)*); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: a tuple variant with a similar name exists: `Ok` diff --git a/tests/ui/proc-macro/pretty-print-hack-show.rs b/tests/ui/proc-macro/pretty-print-hack-show.rs index 70f0d5f6ea975..08e26c8114276 100644 --- a/tests/ui/proc-macro/pretty-print-hack-show.rs +++ b/tests/ui/proc-macro/pretty-print-hack-show.rs @@ -1,7 +1,6 @@ //@ proc-macro: test-macros.rs //@ compile-flags: -Z span-debug //@ revisions: local remapped -// [local] no-remap-src-base: The hack should work regardless of remapping. //@ [remapped] remap-src-base #![no_std] // Don't load unnecessary hygiene information from std diff --git a/tests/ui/proc-macro/quote/basic.rs b/tests/ui/proc-macro/quote/basic.rs index 0336dbb785623..4c6fb2408fb49 100644 --- a/tests/ui/proc-macro/quote/basic.rs +++ b/tests/ui/proc-macro/quote/basic.rs @@ -1,5 +1,6 @@ //@ run-pass //@ proc-macro: basic.rs +//@ ignore-backends: gcc extern crate basic; diff --git a/tests/ui/proc-macro/quote/not-quotable.stderr b/tests/ui/proc-macro/quote/not-quotable.stderr index d1c3d06f2b661..62a02638e548b 100644 --- a/tests/ui/proc-macro/quote/not-quotable.stderr +++ b/tests/ui/proc-macro/quote/not-quotable.stderr @@ -15,8 +15,8 @@ LL | let _ = quote! { $ip }; Cow<'_, T> Option Rc - RepInterp - and 25 others + bool + and 24 others error: aborting due to 1 previous error diff --git a/tests/ui/proc-macro/quote/not-repeatable.rs b/tests/ui/proc-macro/quote/not-repeatable.rs index 0291e4ddf88d6..373f0e74dbdac 100644 --- a/tests/ui/proc-macro/quote/not-repeatable.rs +++ b/tests/ui/proc-macro/quote/not-repeatable.rs @@ -8,5 +8,7 @@ struct Ipv4Addr; fn main() { let ip = Ipv4Addr; - let _ = quote! { $($ip)* }; //~ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied + let _ = quote! { $($ip)* }; + //~^ ERROR the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied + //~| ERROR type annotations needed } diff --git a/tests/ui/proc-macro/quote/not-repeatable.stderr b/tests/ui/proc-macro/quote/not-repeatable.stderr index aeda08d7de68b..5943111efd585 100644 --- a/tests/ui/proc-macro/quote/not-repeatable.stderr +++ b/tests/ui/proc-macro/quote/not-repeatable.stderr @@ -20,6 +20,13 @@ note: the traits `Iterator` and `ToTokens` must be implemented --> $SRC_DIR/proc_macro/src/to_tokens.rs:LL:COL --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/not-repeatable.rs:11:25 + | +LL | let _ = quote! { $($ip)* }; + | ^^ cannot infer type + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0599`. +Some errors have detailed explanations: E0282, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/proc-macro/span-api-tests.rs b/tests/ui/proc-macro/span-api-tests.rs index 792859ed05b16..12832ba116397 100644 --- a/tests/ui/proc-macro/span-api-tests.rs +++ b/tests/ui/proc-macro/span-api-tests.rs @@ -2,6 +2,7 @@ //@ proc-macro: span-api-tests.rs //@ aux-build:span-test-macros.rs //@ compile-flags: -Ztranslate-remapped-path-to-local-path=yes +//@ ignore-backends: gcc #[macro_use] extern crate span_test_macros; diff --git a/tests/ui/proc-macro/span-from-proc-macro.rs b/tests/ui/proc-macro/span-from-proc-macro.rs index 4e12a695a5c09..24a28d53476c1 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.rs +++ b/tests/ui/proc-macro/span-from-proc-macro.rs @@ -1,6 +1,7 @@ //@ proc-macro: custom-quote.rs //@ proc-macro: span-from-proc-macro.rs //@ compile-flags: -Z macro-backtrace +//@ ignore-backends: gcc #[macro_use] extern crate span_from_proc_macro; diff --git a/tests/ui/proc-macro/span-from-proc-macro.stderr b/tests/ui/proc-macro/span-from-proc-macro.stderr index c79ab04eadf4e..945a5620fac48 100644 --- a/tests/ui/proc-macro/span-from-proc-macro.stderr +++ b/tests/ui/proc-macro/span-from-proc-macro.stderr @@ -7,7 +7,7 @@ LL | pub fn error_from_attribute(_args: TokenStream, _input: TokenStream) -> Tok LL | field: MissingType | ^^^^^^^^^^^ not found in this scope | - ::: $DIR/span-from-proc-macro.rs:8:1 + ::: $DIR/span-from-proc-macro.rs:9:1 | LL | #[error_from_attribute] | ----------------------- in this attribute macro expansion @@ -21,7 +21,7 @@ LL | pub fn error_from_derive(_input: TokenStream) -> TokenStream { LL | Variant(OtherMissingType) | ^^^^^^^^^^^^^^^^ not found in this scope | - ::: $DIR/span-from-proc-macro.rs:11:10 + ::: $DIR/span-from-proc-macro.rs:12:10 | LL | #[derive(ErrorFromDerive)] | --------------- in this derive macro expansion @@ -35,7 +35,7 @@ LL | custom_quote::custom_quote! { LL | my_ident | ^^^^^^^^ not found in this scope | - ::: $DIR/span-from-proc-macro.rs:16:5 + ::: $DIR/span-from-proc-macro.rs:17:5 | LL | other_error_from_bang!(); | ------------------------ in this macro invocation @@ -51,7 +51,7 @@ LL | let bang_error: bool = 25; LL | pub fn error_from_bang(_input: TokenStream) -> TokenStream { | ---------------------------------------------------------- in this expansion of `error_from_bang!` | - ::: $DIR/span-from-proc-macro.rs:15:5 + ::: $DIR/span-from-proc-macro.rs:16:5 | LL | error_from_bang!(); | ------------------ in this macro invocation diff --git a/tests/ui/proc-macro/weird-hygiene.rs b/tests/ui/proc-macro/weird-hygiene.rs index de55484109ae3..8d8427d0e417e 100644 --- a/tests/ui/proc-macro/weird-hygiene.rs +++ b/tests/ui/proc-macro/weird-hygiene.rs @@ -1,4 +1,5 @@ //@ proc-macro: weird-hygiene.rs +//@ ignore-backends: gcc #![feature(stmt_expr_attributes)] #![feature(proc_macro_hygiene)] diff --git a/tests/ui/proc-macro/weird-hygiene.stderr b/tests/ui/proc-macro/weird-hygiene.stderr index 256e68e8970e6..0cfac3f89a045 100644 --- a/tests/ui/proc-macro/weird-hygiene.stderr +++ b/tests/ui/proc-macro/weird-hygiene.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `hidden_ident` in this scope - --> $DIR/weird-hygiene.rs:23:43 + --> $DIR/weird-hygiene.rs:24:43 | LL | Value = (stringify!($tokens + hidden_ident), 1).1 | ^^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | other!(50); = note: this error originates in the macro `inner` which comes from the expansion of the macro `other` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0425]: cannot find value `hidden_ident` in this scope - --> $DIR/weird-hygiene.rs:34:13 + --> $DIR/weird-hygiene.rs:35:13 | LL | hidden_ident | ^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui/process/core-run-destroy.rs b/tests/ui/process/core-run-destroy.rs index f4be54da8fe67..f381997ef7931 100644 --- a/tests/ui/process/core-run-destroy.rs +++ b/tests/ui/process/core-run-destroy.rs @@ -8,6 +8,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'cat' and 'sleep' //@ ignore-fuchsia no 'cat' +//@ ignore-ios no 'cat' and 'sleep' +//@ ignore-tvos no 'cat' and 'sleep' +//@ ignore-watchos no 'cat' and 'sleep' +//@ ignore-visionos no 'cat' and 'sleep' // N.B., these tests kill child processes. Valgrind sees these children as leaking // memory, which makes for some *confusing* logs. That's why these are here diff --git a/tests/ui/process/env-funky-keys.rs b/tests/ui/process/env-funky-keys.rs index a4a71c94020cd..193659bea293e 100644 --- a/tests/ui/process/env-funky-keys.rs +++ b/tests/ui/process/env-funky-keys.rs @@ -1,8 +1,7 @@ //@ run-pass //@ edition: 2021 -// Ignore this test on Android, because it segfaults there. -//@ ignore-android +//@ ignore-android segfaults //@ ignore-windows //@ ignore-wasm32 no execve //@ ignore-sgx no execve @@ -24,6 +23,9 @@ use std::ptr; fn main() { if env::args_os().count() == 2 { for (key, value) in env::vars_os() { + if key == "DYLD_ROOT_PATH" { + continue; + } panic!("found env value {:?} {:?}", key, value); } return; @@ -35,7 +37,18 @@ fn main() { .as_bytes()).unwrap(); let filename: *const c_char = current_exe.as_ptr(); let argv: &[*const c_char] = &[filename, filename, ptr::null()]; - let envp: &[*const c_char] = &[c"FOOBAR".as_ptr(), ptr::null()]; + + let root; + let envp: &[*const c_char] = if cfg!(all(target_vendor = "apple", target_env = "sim")) { + // Workaround: iOS/tvOS/watchOS/visionOS simulators need the root path + // from the current process. + root = format!("DYLD_ROOT_PATH={}\0", std::env::var("DYLD_ROOT_PATH").unwrap()); + &[c"FOOBAR".as_ptr(), root.as_ptr().cast(), ptr::null()] + } else { + // Try to set an environment variable without a value. + &[c"FOOBAR".as_ptr(), ptr::null()] + }; + unsafe { execve(filename, &argv[0], &envp[0]); } diff --git a/tests/ui/process/fds-are-cloexec.rs b/tests/ui/process/fds-are-cloexec.rs index f6678379dd675..0fae7c2b5024d 100644 --- a/tests/ui/process/fds-are-cloexec.rs +++ b/tests/ui/process/fds-are-cloexec.rs @@ -74,8 +74,15 @@ fn child(args: &[String]) { let fd: libc::c_int = arg.parse().unwrap(); unsafe { assert_eq!(libc::read(fd, b.as_mut_ptr() as *mut _, 2), -1); - assert_eq!(io::Error::last_os_error().raw_os_error(), - Some(libc::EBADF)); + let raw = io::Error::last_os_error().raw_os_error(); + if cfg!(all(target_vendor = "apple", not(target_os = "macos"))) { + // Workaround: iOS/tvOS/watchOS/visionOS seems to treat `tcp6` + // as a directory? + if raw == Some(libc::EISDIR) { + continue; + } + } + assert_eq!(raw, Some(libc::EBADF)); } } } diff --git a/tests/ui/process/multi-panic.rs b/tests/ui/process/multi-panic.rs index 1fddffeb770a3..67bbd16fba75e 100644 --- a/tests/ui/process/multi-panic.rs +++ b/tests/ui/process/multi-panic.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-subprocess //@ needs-unwind +//@ ignore-backends: gcc fn check_for_no_backtrace(test: std::process::Output) { assert!(!test.status.success()); diff --git a/tests/ui/process/println-with-broken-pipe.rs b/tests/ui/process/println-with-broken-pipe.rs index 58b83a2dd9a2f..e87e207737027 100644 --- a/tests/ui/process/println-with-broken-pipe.rs +++ b/tests/ui/process/println-with-broken-pipe.rs @@ -5,6 +5,10 @@ //@ ignore-fuchsia //@ ignore-horizon //@ ignore-android +//@ ignore-ios no 'head' +//@ ignore-tvos no 'head' +//@ ignore-watchos no 'head' +//@ ignore-visionos no 'head' //@ ignore-backends: gcc //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" //@ compile-flags: -Zon-broken-pipe=error diff --git a/tests/ui/process/process-envs.rs b/tests/ui/process/process-envs.rs index 98052f1d3a5d7..cbe16704a8e19 100644 --- a/tests/ui/process/process-envs.rs +++ b/tests/ui/process/process-envs.rs @@ -2,6 +2,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' +//@ ignore-ios no 'env' +//@ ignore-tvos no 'env' +//@ ignore-watchos no 'env' +//@ ignore-visionos no 'env' use std::process::Command; use std::env; diff --git a/tests/ui/process/process-panic-after-fork.rs b/tests/ui/process/process-panic-after-fork.rs index 6e0267e0a54f5..154ff51878d6e 100644 --- a/tests/ui/process/process-panic-after-fork.rs +++ b/tests/ui/process/process-panic-after-fork.rs @@ -3,6 +3,9 @@ //@ only-unix //@ needs-subprocess //@ ignore-fuchsia no fork +//@ ignore-tvos fork is prohibited +//@ ignore-watchos fork is prohibited +//@ ignore-backends: gcc #![feature(rustc_private)] #![feature(never_type)] diff --git a/tests/ui/process/process-remove-from-env.rs b/tests/ui/process/process-remove-from-env.rs index c1a2b2daf5b63..68c3909b15ae0 100644 --- a/tests/ui/process/process-remove-from-env.rs +++ b/tests/ui/process/process-remove-from-env.rs @@ -2,6 +2,10 @@ //@ needs-subprocess //@ ignore-vxworks no 'env' //@ ignore-fuchsia no 'env' +//@ ignore-ios no 'env' +//@ ignore-tvos no 'env' +//@ ignore-watchos no 'env' +//@ ignore-visionos no 'env' use std::process::Command; use std::env; diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 3ecf271599d23..574d79ee1ddaf 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -15,6 +15,10 @@ //@ ignore-vxworks no 'sh' //@ ignore-fuchsia no 'sh' +//@ ignore-ios no 'sh' +//@ ignore-tvos no 'sh' +//@ ignore-watchos no 'sh' +//@ ignore-visionos no 'sh' //@ needs-threads //@ only-unix SIGPIPE is a unix feature diff --git a/tests/ui/process/process-spawn-failure.rs b/tests/ui/process/process-spawn-failure.rs index 0950b044c97ca..ac2c34bc7836d 100644 --- a/tests/ui/process/process-spawn-failure.rs +++ b/tests/ui/process/process-spawn-failure.rs @@ -9,6 +9,10 @@ //@ ignore-vxworks no 'ps' //@ ignore-fuchsia no 'ps' //@ ignore-nto no 'ps' +//@ ignore-ios no 'ps' +//@ ignore-tvos no 'ps' +//@ ignore-watchos no 'ps' +//@ ignore-visionos no 'ps' #![feature(rustc_private)] diff --git a/tests/ui/process/win-inherit-handles.rs b/tests/ui/process/win-inherit-handles.rs new file mode 100644 index 0000000000000..5750a4b40f055 --- /dev/null +++ b/tests/ui/process/win-inherit-handles.rs @@ -0,0 +1,81 @@ +// Tests `inherit_handles` by spawning a child process and checking its handle +// count to be greater than when not setting the option. + +//@ run-pass +//@ only-windows +//@ needs-subprocess +//@ edition: 2024 + +#![feature(windows_process_extensions_inherit_handles)] + +use std::os::windows::io::AsRawHandle; +use std::os::windows::process::CommandExt; +use std::process::{Command, Stdio}; +use std::time::Duration; +use std::{env, io, thread}; + +fn main() { + if std::env::args().skip(1).any(|s| s == "--child") { + child(); + } else { + parent(); + } +} + +fn parent() { + let with_inherit_count = child_handle_count(true); + let without_inherit_count = child_handle_count(false); + // Only compare the two values instead of only expecting a hard 1 for + // robustness, although only 1 has ever been observed here. + assert!( + with_inherit_count > without_inherit_count, + "Child process handle count unexpectedly smaller when inheriting handles compared to when \ + not: {} <= {}", + with_inherit_count, + without_inherit_count, + ); +} + +/// Spawns the current program as a child process and returns its handle count. +fn child_handle_count(inherit_handles: bool) -> u32 { + let mut child_proc = Command::new(&env::current_exe().unwrap()) + .arg("--child") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .inherit_handles(inherit_handles) + .spawn() + .unwrap(); + + let mut handle_count = 0; + let ret = unsafe { GetProcessHandleCount(child_proc.as_raw_handle(), &raw mut handle_count) }; + assert_ne!( + ret, + 0, + "GetProcessHandleCount failed: {:?}", + io::Error::last_os_error(), + ); + + // Cleanup. + child_proc.kill().unwrap(); + child_proc.wait().unwrap(); + + handle_count +} + +/// A process that stays running until killed. +fn child() { + // Don't wait forever if something goes wrong. + thread::sleep(Duration::from_secs(10)); +} + +// Windows API +mod winapi { + use std::os::windows::raw::HANDLE; + + #[link(name = "kernel32")] + unsafe extern "system" { + pub fn GetProcessHandleCount(hprocess: HANDLE, pdwhandlecount: *mut u32) -> i32; + } +} +use winapi::*; diff --git a/tests/ui/reborrow/custom_mut.rs b/tests/ui/reborrow/custom_mut.rs new file mode 100644 index 0000000000000..1e7c469323822 --- /dev/null +++ b/tests/ui/reborrow/custom_mut.rs @@ -0,0 +1,13 @@ +#![feature(reborrow)] +use std::ops::Reborrow; + +struct CustomMut<'a, T>(&'a mut T); +impl<'a, T> Reborrow for CustomMut<'a, T> {} + +fn method(a: CustomMut<'_, ()>) {} + +fn main() { + let a = CustomMut(&mut ()); + let _ = method(a); + let _ = method(a); //~ERROR use of moved value: `a` +} diff --git a/tests/ui/reborrow/custom_mut.stderr b/tests/ui/reborrow/custom_mut.stderr new file mode 100644 index 0000000000000..3b3f47b62d6fa --- /dev/null +++ b/tests/ui/reborrow/custom_mut.stderr @@ -0,0 +1,29 @@ +error[E0382]: use of moved value: `a` + --> $DIR/custom_mut.rs:12:20 + | +LL | let a = CustomMut(&mut ()); + | - move occurs because `a` has type `CustomMut<'_, ()>`, which does not implement the `Copy` trait +LL | let _ = method(a); + | - value moved here +LL | let _ = method(a); + | ^ value used here after move + | +note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary + --> $DIR/custom_mut.rs:7:14 + | +LL | fn method(a: CustomMut<'_, ()>) {} + | ------ ^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value + | | + | in this function +note: if `CustomMut<'_, ()>` implemented `Clone`, you could clone the value + --> $DIR/custom_mut.rs:4:1 + | +LL | struct CustomMut<'a, T>(&'a mut T); + | ^^^^^^^^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type +... +LL | let _ = method(a); + | - you could clone this value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.rs b/tests/ui/reborrow/custom_mut_coerce_shared.rs new file mode 100644 index 0000000000000..e2d25835c093a --- /dev/null +++ b/tests/ui/reborrow/custom_mut_coerce_shared.rs @@ -0,0 +1,28 @@ +#![feature(reborrow)] +use std::ops::{CoerceShared, Reborrow}; + +struct CustomMut<'a, T>(&'a mut T); +impl<'a, T> Reborrow for CustomMut<'a, T> {} +impl<'a, T> CoerceShared for CustomMut<'a, T> { + type Target = CustomRef<'a, T>; +} + +struct CustomRef<'a, T>(&'a T); + +impl<'a, T> Clone for CustomRef<'a, T> { + fn clone(&self) -> Self { + Self(self.0) + } +} +impl<'a, T> Copy for CustomRef<'a, T> {} + +fn method(a: CustomRef<'_, ()>) {} //~NOTE function defined here + +fn main() { + let a = CustomMut(&mut ()); + method(a); + //~^ ERROR mismatched types + //~| NOTE expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>` + //~| NOTE arguments to this function are incorrect + //~| NOTE expected struct `CustomRef<'_, ()>` +} diff --git a/tests/ui/reborrow/custom_mut_coerce_shared.stderr b/tests/ui/reborrow/custom_mut_coerce_shared.stderr new file mode 100644 index 0000000000000..508651badc0a4 --- /dev/null +++ b/tests/ui/reborrow/custom_mut_coerce_shared.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/custom_mut_coerce_shared.rs:23:12 + | +LL | method(a); + | ------ ^ expected `CustomRef<'_, ()>`, found `CustomMut<'_, ()>` + | | + | arguments to this function are incorrect + | + = note: expected struct `CustomRef<'_, ()>` + found struct `CustomMut<'_, ()>` +note: function defined here + --> $DIR/custom_mut_coerce_shared.rs:19:4 + | +LL | fn method(a: CustomRef<'_, ()>) {} + | ^^^^^^ -------------------- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/reborrow/option_mut.rs b/tests/ui/reborrow/option_mut.rs new file mode 100644 index 0000000000000..04d8301772de9 --- /dev/null +++ b/tests/ui/reborrow/option_mut.rs @@ -0,0 +1,7 @@ +fn method(a: Option<&mut ()>) {} + +fn main() { + let a = Some(&mut ()); + let _ = method(a); + let _ = method(a); //~ERROR use of moved value: `a` +} diff --git a/tests/ui/reborrow/option_mut.stderr b/tests/ui/reborrow/option_mut.stderr new file mode 100644 index 0000000000000..d665e266079ea --- /dev/null +++ b/tests/ui/reborrow/option_mut.stderr @@ -0,0 +1,21 @@ +error[E0382]: use of moved value: `a` + --> $DIR/option_mut.rs:6:20 + | +LL | let a = Some(&mut ()); + | - move occurs because `a` has type `Option<&mut ()>`, which does not implement the `Copy` trait +LL | let _ = method(a); + | - value moved here +LL | let _ = method(a); + | ^ value used here after move + | +note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary + --> $DIR/option_mut.rs:1:14 + | +LL | fn method(a: Option<&mut ()>) {} + | ------ ^^^^^^^^^^^^^^^ this parameter takes ownership of the value + | | + | in this function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/reborrow/option_mut_coerce_shared.rs b/tests/ui/reborrow/option_mut_coerce_shared.rs new file mode 100644 index 0000000000000..95d33ed94dd71 --- /dev/null +++ b/tests/ui/reborrow/option_mut_coerce_shared.rs @@ -0,0 +1,11 @@ +fn method(a: Option<&()>) {} //~NOTE function defined here + +fn main() { + let a = Some(&mut ()); + method(a); + //~^ ERROR mismatched types + //~| NOTE arguments to this function are incorrect + //~| NOTE types differ in mutability + //~| NOTE expected enum `Option<&()>` + //~| NOTE found enum `Option<&mut ()>` +} diff --git a/tests/ui/reborrow/option_mut_coerce_shared.stderr b/tests/ui/reborrow/option_mut_coerce_shared.stderr new file mode 100644 index 0000000000000..6ca1a2374610e --- /dev/null +++ b/tests/ui/reborrow/option_mut_coerce_shared.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/option_mut_coerce_shared.rs:5:12 + | +LL | method(a); + | ------ ^ types differ in mutability + | | + | arguments to this function are incorrect + | + = note: expected enum `Option<&()>` + found enum `Option<&mut ()>` +note: function defined here + --> $DIR/option_mut_coerce_shared.rs:1:4 + | +LL | fn method(a: Option<&()>) {} + | ^^^^^^ -------------- +help: try using `.as_deref()` to convert `Option<&mut ()>` to `Option<&()>` + | +LL | method(a.as_deref()); + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/reborrow/pin_mut.rs b/tests/ui/reborrow/pin_mut.rs new file mode 100644 index 0000000000000..959cb14f8c9ad --- /dev/null +++ b/tests/ui/reborrow/pin_mut.rs @@ -0,0 +1,10 @@ +use std::pin::Pin; + +fn method(a: Pin<&mut ()>) {} + +fn main() { + let a = &mut (); + let a = Pin::new(a); + let _ = method(a); + let _ = method(a); //~ERROR use of moved value: `a` +} diff --git a/tests/ui/reborrow/pin_mut.stderr b/tests/ui/reborrow/pin_mut.stderr new file mode 100644 index 0000000000000..64e3f603e1110 --- /dev/null +++ b/tests/ui/reborrow/pin_mut.stderr @@ -0,0 +1,21 @@ +error[E0382]: use of moved value: `a` + --> $DIR/pin_mut.rs:9:20 + | +LL | let a = Pin::new(a); + | - move occurs because `a` has type `Pin<&mut ()>`, which does not implement the `Copy` trait +LL | let _ = method(a); + | - value moved here +LL | let _ = method(a); + | ^ value used here after move + | +note: consider changing this parameter type in function `method` to borrow instead if owning the value isn't necessary + --> $DIR/pin_mut.rs:3:14 + | +LL | fn method(a: Pin<&mut ()>) {} + | ------ ^^^^^^^^^^^^ this parameter takes ownership of the value + | | + | in this function + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.rs b/tests/ui/reborrow/pin_mut_coerce_shared.rs new file mode 100644 index 0000000000000..06af0b765d046 --- /dev/null +++ b/tests/ui/reborrow/pin_mut_coerce_shared.rs @@ -0,0 +1,13 @@ +use std::pin::Pin; + +fn method(a: Pin<&()>) {} //~NOTE function defined here + +fn main() { + let a = &mut (); + let a = Pin::new(a); + method(a); + //~^ ERROR mismatched types + //~| NOTE arguments to this function are incorrect + //~| NOTE types differ in mutability + //~| NOTE expected struct `Pin<&()>` +} diff --git a/tests/ui/reborrow/pin_mut_coerce_shared.stderr b/tests/ui/reborrow/pin_mut_coerce_shared.stderr new file mode 100644 index 0000000000000..74ecf4de4c785 --- /dev/null +++ b/tests/ui/reborrow/pin_mut_coerce_shared.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/pin_mut_coerce_shared.rs:8:12 + | +LL | method(a); + | ------ ^ types differ in mutability + | | + | arguments to this function are incorrect + | + = note: expected struct `Pin<&()>` + found struct `Pin<&mut ()>` +note: function defined here + --> $DIR/pin_mut_coerce_shared.rs:3:4 + | +LL | fn method(a: Pin<&()>) {} + | ^^^^^^ ----------- + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.rs b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs new file mode 100644 index 0000000000000..720cd1cf6eecb --- /dev/null +++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.rs @@ -0,0 +1,11 @@ +fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {} +//~^ NOTE: requirements that the value outlives `'b` introduced here + +fn foo<'b>() { //~ NOTE: lifetime `'b` defined here + outlives_indir::<'_, 'b, _>(&mut 1u32); //~ ERROR: temporary value dropped while borrowed + //~^ NOTE: argument requires that borrow lasts for `'b` + //~| NOTE: creates a temporary value which is freed while still in use + //~| NOTE: temporary value is freed at the end of this statement +} + +fn main() {} diff --git a/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr new file mode 100644 index 0000000000000..4cdaf950e155c --- /dev/null +++ b/tests/ui/regions/multiple-sources-for-outlives-requirement.stderr @@ -0,0 +1,20 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/multiple-sources-for-outlives-requirement.rs:5:38 + | +LL | fn foo<'b>() { + | -- lifetime `'b` defined here +LL | outlives_indir::<'_, 'b, _>(&mut 1u32); + | ---------------------------------^^^^-- temporary value is freed at the end of this statement + | | | + | | creates a temporary value which is freed while still in use + | argument requires that borrow lasts for `'b` + | +note: requirements that the value outlives `'b` introduced here + --> $DIR/multiple-sources-for-outlives-requirement.rs:1:23 + | +LL | fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {} + | ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/regions/regions-infer-proc-static-upvar.stderr b/tests/ui/regions/regions-infer-proc-static-upvar.stderr index 919fcffdc531e..158d74ed06d94 100644 --- a/tests/ui/regions/regions-infer-proc-static-upvar.stderr +++ b/tests/ui/regions/regions-infer-proc-static-upvar.stderr @@ -11,6 +11,12 @@ LL | | }); | |______- argument requires that `x` is borrowed for `'static` LL | } | - `x` dropped here while still borrowed + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/regions-infer-proc-static-upvar.rs:4:19 + | +LL | fn foo(_p: F) { } + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr index 1d3d5e831c39c..a8fd827bc6951 100644 --- a/tests/ui/regions/regions-pattern-typing-issue-19552.stderr +++ b/tests/ui/regions/regions-pattern-typing-issue-19552.stderr @@ -10,6 +10,12 @@ LL | [ word ] => { assert_static(word); } LL | } LL | } | - `line` dropped here while still borrowed + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/regions-pattern-typing-issue-19552.rs:1:21 + | +LL | fn assert_static(_t: T) {} + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr index ba44beb76dbb7..c98b9bb38fdb0 100644 --- a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr +++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.stderr @@ -7,7 +7,7 @@ LL | LL | extract(x).max(2); | ---------- type must be known at this point | -help: consider giving `x` an explicit type, where the type for type parameter `T` is specified +help: consider giving `x` an explicit type, where the placeholders `_` are specified | LL | let x: [Foo; 2] = [Foo(PhantomData); 2]; | +++++++++++++ diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs index d4d5a086dcc00..b0f402554b81b 100644 --- a/tests/ui/repr/16-bit-repr-c-enum.rs +++ b/tests/ui/repr/16-bit-repr-c-enum.rs @@ -6,7 +6,8 @@ //@ [avr] compile-flags: --target=avr-none -C target-cpu=atmega328p --crate-type=rlib //@ [msp430] needs-llvm-components: msp430 //@ [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib -#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)] +//@ ignore-backends: gcc +#![feature(no_core, intrinsics, staged_api, rustc_attrs)] #![no_core] #![crate_type = "lib"] #![stable(feature = "intrinsics_for_test", since = "3.3.3")] diff --git a/tests/ui/repr/attr-usage-repr.rs b/tests/ui/repr/attr-usage-repr.rs index ca63ac564fc57..10256a7619e51 100644 --- a/tests/ui/repr/attr-usage-repr.rs +++ b/tests/ui/repr/attr-usage-repr.rs @@ -46,9 +46,11 @@ enum EInt { } #[repr()] //~ ERROR attribute should be applied to a struct, enum, or union [E0517] +//~^ WARN unused attribute type SirThisIsAType = i32; #[repr()] +//~^ WARN unused attribute struct EmptyReprArgumentList(i32); fn main() {} diff --git a/tests/ui/repr/attr-usage-repr.stderr b/tests/ui/repr/attr-usage-repr.stderr index a62992c597a2e..33aa3c2f9f21a 100644 --- a/tests/ui/repr/attr-usage-repr.stderr +++ b/tests/ui/repr/attr-usage-repr.stderr @@ -41,9 +41,27 @@ error[E0517]: attribute should be applied to a struct, enum, or union | LL | #[repr()] | ^^^^^^^^^ +LL | LL | type SirThisIsAType = i32; | -------------------------- not a struct, enum, or union -error: aborting due to 5 previous errors +warning: unused attribute + --> $DIR/attr-usage-repr.rs:48:1 + | +LL | #[repr()] + | ^^^^^^^^^ help: remove this attribute + | + = note: using `repr` with an empty list has no effect + = note: requested on the command line with `-W unused-attributes` + +warning: unused attribute + --> $DIR/attr-usage-repr.rs:52:1 + | +LL | #[repr()] + | ^^^^^^^^^ help: remove this attribute + | + = note: using `repr` with an empty list has no effect + +error: aborting due to 5 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/issues/auxiliary/issue-73112.rs b/tests/ui/repr/auxiliary/aux-73112.rs similarity index 100% rename from tests/ui/issues/auxiliary/issue-73112.rs rename to tests/ui/repr/auxiliary/aux-73112.rs diff --git a/tests/ui/repr/invalid-repr-on-structs-74082.rs b/tests/ui/repr/invalid-repr-on-structs-74082.rs new file mode 100644 index 0000000000000..8b9807fad8ce2 --- /dev/null +++ b/tests/ui/repr/invalid-repr-on-structs-74082.rs @@ -0,0 +1,10 @@ +// https://github.com/rust-lang/rust/issues/74082 +#![allow(dead_code)] + +#[repr(i128)] //~ ERROR: attribute should be applied to an enum +struct Foo; + +#[repr(u128)] //~ ERROR: attribute should be applied to an enum +struct Bar; + +fn main() {} diff --git a/tests/ui/repr/invalid-repr-on-structs-74082.stderr b/tests/ui/repr/invalid-repr-on-structs-74082.stderr new file mode 100644 index 0000000000000..e11beb811fbff --- /dev/null +++ b/tests/ui/repr/invalid-repr-on-structs-74082.stderr @@ -0,0 +1,19 @@ +error[E0517]: attribute should be applied to an enum + --> $DIR/invalid-repr-on-structs-74082.rs:4:8 + | +LL | #[repr(i128)] + | ^^^^ +LL | struct Foo; + | ----------- not an enum + +error[E0517]: attribute should be applied to an enum + --> $DIR/invalid-repr-on-structs-74082.rs:7:8 + | +LL | #[repr(u128)] + | ^^^^ +LL | struct Bar; + | ----------- not an enum + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/repr/packed-struct-contains-aligned-type-73112.rs b/tests/ui/repr/packed-struct-contains-aligned-type-73112.rs new file mode 100644 index 0000000000000..baeb75beb0aa1 --- /dev/null +++ b/tests/ui/repr/packed-struct-contains-aligned-type-73112.rs @@ -0,0 +1,14 @@ +// https://github.com/rust-lang/rust/issues/73112 +//@ aux-build:aux-73112.rs + +extern crate aux_73112; + +fn main() { + use aux_73112::PageTable; + + #[repr(C, packed)] + struct SomeStruct { + //~^ ERROR packed type cannot transitively contain a `#[repr(align)]` type [E0588] + page_table: PageTable, + } +} diff --git a/tests/ui/repr/packed-struct-contains-aligned-type-73112.stderr b/tests/ui/repr/packed-struct-contains-aligned-type-73112.stderr new file mode 100644 index 0000000000000..237c357db22ba --- /dev/null +++ b/tests/ui/repr/packed-struct-contains-aligned-type-73112.stderr @@ -0,0 +1,15 @@ +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/packed-struct-contains-aligned-type-73112.rs:10:5 + | +LL | struct SomeStruct { + | ^^^^^^^^^^^^^^^^^ + | +note: `PageTable` has a `#[repr(align)]` attribute + --> $DIR/auxiliary/aux-73112.rs:8:1 + | +LL | pub struct PageTable { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0588`. diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 63d685951d981..1a1929c530ff4 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -79,7 +79,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:43:1 + --> $DIR/repr-c-dead-variants.rs:44:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:50:1 + --> $DIR/repr-c-dead-variants.rs:51:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -319,7 +319,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:62:1 + --> $DIR/repr-c-dead-variants.rs:63:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 555471be0271d..67729e9fcef9c 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -79,7 +79,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:43:1 + --> $DIR/repr-c-dead-variants.rs:44:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:50:1 + --> $DIR/repr-c-dead-variants.rs:51:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -319,7 +319,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:62:1 + --> $DIR/repr-c-dead-variants.rs:63:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 63d685951d981..1a1929c530ff4 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -79,7 +79,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:43:1 + --> $DIR/repr-c-dead-variants.rs:44:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:50:1 + --> $DIR/repr-c-dead-variants.rs:51:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -319,7 +319,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:62:1 + --> $DIR/repr-c-dead-variants.rs:63:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-c-dead-variants.rs b/tests/ui/repr/repr-c-dead-variants.rs index 7f27430856231..048e74c177ca3 100644 --- a/tests/ui/repr/repr-c-dead-variants.rs +++ b/tests/ui/repr/repr-c-dead-variants.rs @@ -1,4 +1,4 @@ -#![feature(no_core, rustc_attrs, lang_items)] +#![feature(no_core, rustc_attrs)] #![allow(dead_code)] #![crate_type = "lib"] #![no_std] @@ -33,6 +33,7 @@ use minicore::*; //@ revisions: armebv7r-none-eabi //@[armebv7r-none-eabi] compile-flags: --target armebv7r-none-eabi //@[armebv7r-none-eabi] needs-llvm-components: arm +//@ ignore-backends: gcc // A simple uninhabited type. enum Void {} diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 63d685951d981..1a1929c530ff4 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -79,7 +79,7 @@ error: layout_of(Univariant) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:43:1 + --> $DIR/repr-c-dead-variants.rs:44:1 | LL | enum Univariant { | ^^^^^^^^^^^^^^^ @@ -214,7 +214,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:50:1 + --> $DIR/repr-c-dead-variants.rs:51:1 | LL | enum TwoVariants { | ^^^^^^^^^^^^^^^^ @@ -319,7 +319,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, } - --> $DIR/repr-c-dead-variants.rs:62:1 + --> $DIR/repr-c-dead-variants.rs:63:1 | LL | enum DeadBranchHasOtherField { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/repr/repr-empty-packed.stderr b/tests/ui/repr/repr-empty-packed.stderr index 6565b2e8c1dca..adf32c9552967 100644 --- a/tests/ui/repr/repr-empty-packed.stderr +++ b/tests/ui/repr/repr-empty-packed.stderr @@ -15,6 +15,7 @@ error: unused attribute LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | + = note: using `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/repr-empty-packed.rs:2:9 | diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.rs b/tests/ui/repr/repr-transparent-non-exhaustive.rs index 9894b89e8e418..38bab0163b4c5 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.rs +++ b/tests/ui/repr/repr-transparent-non-exhaustive.rs @@ -24,6 +24,13 @@ pub struct InternalIndirection { pub type Sized = i32; +pub trait Trait { + type Assoc; +} +impl Trait for i32 { + type Assoc = NonExhaustive; +} + #[repr(transparent)] pub struct T1(Sized, InternalPrivate); #[repr(transparent)] @@ -43,6 +50,11 @@ pub struct T6(Sized, NonExhaustive); //~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler +#[repr(transparent)] +pub struct T6a(Sized, ::Assoc); // normalizes to `NonExhaustive` +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + #[repr(transparent)] pub struct T7(Sized, NonExhaustiveEnum); //~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.stderr b/tests/ui/repr/repr-transparent-non-exhaustive.stderr index 808b9bc986d91..27ba6e82a539a 100644 --- a/tests/ui/repr/repr-transparent-non-exhaustive.stderr +++ b/tests/ui/repr/repr-transparent-non-exhaustive.stderr @@ -1,5 +1,5 @@ error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:37:22 + --> $DIR/repr-transparent-non-exhaustive.rs:44:22 | LL | pub struct T5(Sized, Private); | ^^^^^^^ @@ -14,7 +14,7 @@ LL | #![deny(repr_transparent_external_private_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:42:22 + --> $DIR/repr-transparent-non-exhaustive.rs:49:22 | LL | pub struct T6(Sized, NonExhaustive); | ^^^^^^^^^^^^^ @@ -24,7 +24,17 @@ LL | pub struct T6(Sized, NonExhaustive); = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:47:22 + --> $DIR/repr-transparent-non-exhaustive.rs:54:23 + | +LL | pub struct T6a(Sized, ::Assoc); // normalizes to `NonExhaustive` + | ^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:59:22 | LL | pub struct T7(Sized, NonExhaustiveEnum); | ^^^^^^^^^^^^^^^^^ @@ -34,7 +44,7 @@ LL | pub struct T7(Sized, NonExhaustiveEnum); = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:52:22 + --> $DIR/repr-transparent-non-exhaustive.rs:64:22 | LL | pub struct T8(Sized, NonExhaustiveVariant); | ^^^^^^^^^^^^^^^^^^^^ @@ -44,7 +54,7 @@ LL | pub struct T8(Sized, NonExhaustiveVariant); = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:57:22 + --> $DIR/repr-transparent-non-exhaustive.rs:69:22 | LL | pub struct T9(Sized, InternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -54,7 +64,7 @@ LL | pub struct T9(Sized, InternalIndirection); = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:62:23 + --> $DIR/repr-transparent-non-exhaustive.rs:74:23 | LL | pub struct T10(Sized, InternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -64,7 +74,7 @@ LL | pub struct T10(Sized, InternalIndirection); = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:67:23 + --> $DIR/repr-transparent-non-exhaustive.rs:79:23 | LL | pub struct T11(Sized, InternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -74,7 +84,7 @@ LL | pub struct T11(Sized, InternalIndirection); = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:72:23 + --> $DIR/repr-transparent-non-exhaustive.rs:84:23 | LL | pub struct T12(Sized, InternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +94,7 @@ LL | pub struct T12(Sized, InternalIndirection); = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:77:23 + --> $DIR/repr-transparent-non-exhaustive.rs:89:23 | LL | pub struct T13(Sized, ExternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -94,7 +104,7 @@ LL | pub struct T13(Sized, ExternalIndirection); = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:82:23 + --> $DIR/repr-transparent-non-exhaustive.rs:94:23 | LL | pub struct T14(Sized, ExternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,7 +114,7 @@ LL | pub struct T14(Sized, ExternalIndirection); = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:87:23 + --> $DIR/repr-transparent-non-exhaustive.rs:99:23 | LL | pub struct T15(Sized, ExternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -114,7 +124,7 @@ LL | pub struct T15(Sized, ExternalIndirection); = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:92:23 + --> $DIR/repr-transparent-non-exhaustive.rs:104:23 | LL | pub struct T16(Sized, ExternalIndirection); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -124,7 +134,7 @@ LL | pub struct T16(Sized, ExternalIndirection); = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:97:16 + --> $DIR/repr-transparent-non-exhaustive.rs:109:16 | LL | pub struct T17(NonExhaustive, Sized); | ^^^^^^^^^^^^^ @@ -134,7 +144,7 @@ LL | pub struct T17(NonExhaustive, Sized); = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:102:31 + --> $DIR/repr-transparent-non-exhaustive.rs:114:31 | LL | pub struct T18(NonExhaustive, NonExhaustive); | ^^^^^^^^^^^^^ @@ -144,7 +154,7 @@ LL | pub struct T18(NonExhaustive, NonExhaustive); = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:107:31 + --> $DIR/repr-transparent-non-exhaustive.rs:119:31 | LL | pub struct T19(NonExhaustive, Private); | ^^^^^^^ @@ -154,7 +164,7 @@ LL | pub struct T19(NonExhaustive, Private); = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types - --> $DIR/repr-transparent-non-exhaustive.rs:112:32 + --> $DIR/repr-transparent-non-exhaustive.rs:124:32 | LL | pub struct T19Flipped(Private, NonExhaustive); | ^^^^^^^^^^^^^ @@ -163,5 +173,5 @@ LL | pub struct T19Flipped(Private, NonExhaustive); = note: for more information, see issue #78586 = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: aborting due to 16 previous errors +error: aborting due to 17 previous errors diff --git a/tests/ui/repr/repr_align_greater_usize.rs b/tests/ui/repr/repr_align_greater_usize.rs index 7499e242d5970..7bbf0b29b2eb1 100644 --- a/tests/ui/repr/repr_align_greater_usize.rs +++ b/tests/ui/repr/repr_align_greater_usize.rs @@ -9,7 +9,7 @@ // We should fail to compute alignment for types aligned higher than usize::MAX. // We can't handle alignments that require all 32 bits, so this only affects 16-bit. -#![feature(lang_items, no_core)] +#![feature(no_core)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/resolve/function-module-ambiguity-error-71406.rs b/tests/ui/resolve/function-module-ambiguity-error-71406.rs new file mode 100644 index 0000000000000..a7964de9ba5e2 --- /dev/null +++ b/tests/ui/resolve/function-module-ambiguity-error-71406.rs @@ -0,0 +1,7 @@ +// https://github.com/rust-lang/rust/issues/71406 +use std::sync::mpsc; + +fn main() { + let (tx, rx) = mpsc::channel::new(1); + //~^ ERROR expected type, found function `channel` in `mpsc` +} diff --git a/tests/ui/resolve/function-module-ambiguity-error-71406.stderr b/tests/ui/resolve/function-module-ambiguity-error-71406.stderr new file mode 100644 index 0000000000000..c25bafa0a5ddb --- /dev/null +++ b/tests/ui/resolve/function-module-ambiguity-error-71406.stderr @@ -0,0 +1,9 @@ +error[E0433]: failed to resolve: expected type, found function `channel` in `mpsc` + --> $DIR/function-module-ambiguity-error-71406.rs:5:26 + | +LL | let (tx, rx) = mpsc::channel::new(1); + | ^^^^^^^ expected type, found function `channel` in `mpsc` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/resolve/prelude-order.rs b/tests/ui/resolve/prelude-order.rs index a3f194270d483..c6683bdff22a6 100644 --- a/tests/ui/resolve/prelude-order.rs +++ b/tests/ui/resolve/prelude-order.rs @@ -1,5 +1,6 @@ //@ proc-macro:macro_helpers.rs //@ compile-flags: --crate-type=lib +//@ ignore-backends: gcc /* There are 5 preludes and 3 namespaces. Test the order in which they are resolved. * See https://doc.rust-lang.org/nightly/reference/names/preludes.html. diff --git a/tests/ui/resolve/prelude-order.stderr b/tests/ui/resolve/prelude-order.stderr index 1b9cc94285aa5..4dad39fb6d240 100644 --- a/tests/ui/resolve/prelude-order.stderr +++ b/tests/ui/resolve/prelude-order.stderr @@ -1,17 +1,17 @@ error[E0433]: failed to resolve: could not find `inner` in `type_ns` - --> $DIR/prelude-order.rs:61:12 + --> $DIR/prelude-order.rs:62:12 | LL | #[type_ns::inner] | ^^^^^ could not find `inner` in `type_ns` error[E0433]: failed to resolve: could not find `inner` in `usize` - --> $DIR/prelude-order.rs:73:10 + --> $DIR/prelude-order.rs:74:10 | LL | #[usize::inner] | ^^^^^ could not find `inner` in `usize` error[E0573]: expected type, found crate `Option` - --> $DIR/prelude-order.rs:79:12 + --> $DIR/prelude-order.rs:80:12 | LL | fn e2() -> Option { None } | ^^^^^^^^^^^ not a type @@ -22,7 +22,7 @@ LL + use std::option::Option; | error[E0308]: mismatched types - --> $DIR/prelude-order.rs:82:1 + --> $DIR/prelude-order.rs:83:1 | LL | #[test] | ^^^^^^^- help: try adding a return type: `-> &'static str` @@ -32,7 +32,7 @@ LL | #[test] = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0308]: mismatched types - --> $DIR/prelude-order.rs:86:1 + --> $DIR/prelude-order.rs:87:1 | LL | #[global_allocator] | ^^^^^^^^^^^^^^^^^^^- help: try adding a return type: `-> &'static str` diff --git a/tests/ui/resolve/unused-macro-import.rs b/tests/ui/resolve/unused-macro-import.rs new file mode 100644 index 0000000000000..e85f7a43993f4 --- /dev/null +++ b/tests/ui/resolve/unused-macro-import.rs @@ -0,0 +1,13 @@ +//@ check-pass + +#![warn(unused_imports)] + +#[macro_export] +macro_rules! mac { () => {} } + +fn main() { + // Unused, `mac` as `macro_rules!` is already in scope and has higher priority. + use crate::mac; //~ WARN unused import: `crate::mac` + + mac!(); +} diff --git a/tests/ui/resolve/unused-macro-import.stderr b/tests/ui/resolve/unused-macro-import.stderr new file mode 100644 index 0000000000000..5f9813808a0aa --- /dev/null +++ b/tests/ui/resolve/unused-macro-import.stderr @@ -0,0 +1,14 @@ +warning: unused import: `crate::mac` + --> $DIR/unused-macro-import.rs:10:9 + | +LL | use crate::mac; + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-macro-import.rs:3:9 + | +LL | #![warn(unused_imports)] + | ^^^^^^^^^^^^^^ + +warning: 1 warning emitted + diff --git a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr index 8b7c5e1681ad1..839e4265e031c 100644 --- a/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr +++ b/tests/ui/return/infer-return-ty-for-fn-sig-issue-125488.stderr @@ -2,37 +2,49 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:8:24 | LL | fn f1(s: S<'_>) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `S<'_>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn f1(s: S<'_>) -> _ { +LL + fn f1(s: S<'_>) -> S<'_> { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:13:24 | LL | fn f2(s: S<'_>) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `S<'_>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn f2(s: S<'_>) -> _ { +LL + fn f2(s: S<'_>) -> S<'_> { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:23:24 | LL | fn f3(s: S<'_>) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `S<'_>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn f3(s: S<'_>) -> _ { +LL + fn f3(s: S<'_>) -> S<'_> { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/infer-return-ty-for-fn-sig-issue-125488.rs:28:24 | LL | fn f4(s: S<'_>) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `S<'_>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn f4(s: S<'_>) -> _ { +LL + fn f4(s: S<'_>) -> S<'_> { + | error: aborting due to 4 previous errors diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs index 3090f68c72b77..b3dc9e5842334 100644 --- a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.rs @@ -58,6 +58,7 @@ fn match_with_or() { fn nested_mixed() { match (&Some(5), &Some(6)) { (Some(a), &Some(mut b)) => { + //~^ WARN value assigned to `b` is never read // Here, the `a` will be `&i32`, because in the first half of the tuple // we hit a non-reference pattern and shift into `ref` mode. // diff --git a/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr new file mode 100644 index 0000000000000..a953e85844943 --- /dev/null +++ b/tests/ui/rfcs/rfc-2005-default-binding-mode/general.stderr @@ -0,0 +1,11 @@ +warning: value assigned to `b` is never read + --> $DIR/general.rs:60:25 + | +LL | (Some(a), &Some(mut b)) => { + | ^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs index 7902f40b09bdb..698492966adf3 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/file-is-nul-terminated.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(file_with_nul)] #[track_caller] const fn assert_file_has_trailing_zero() { diff --git a/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.rs b/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.rs index f003e40fa55f5..053af255e0411 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.rs @@ -2,6 +2,8 @@ // See https://github.com/rust-lang/rust/issues/95151 #[track_caller] +//~^ WARN attribute cannot be used on macro defs +//~| WARN previously accepted macro_rules! _foo { () => {}; } diff --git a/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.stderr b/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.stderr new file mode 100644 index 0000000000000..0a0e49177551e --- /dev/null +++ b/tests/ui/rfcs/rfc-2091-track-caller/macro-declaration.stderr @@ -0,0 +1,12 @@ +warning: `#[track_caller]` attribute cannot be used on macro defs + --> $DIR/macro-declaration.rs:4:1 + | +LL | #[track_caller] + | ^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[track_caller]` can only be applied to functions + = note: requested on the command line with `-W unused-attributes` + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2091-track-caller/shim-does-not-modify-symbol.rs b/tests/ui/rfcs/rfc-2091-track-caller/shim-does-not-modify-symbol.rs new file mode 100644 index 0000000000000..255e2c159f119 --- /dev/null +++ b/tests/ui/rfcs/rfc-2091-track-caller/shim-does-not-modify-symbol.rs @@ -0,0 +1,26 @@ +//@ run-pass +#![feature(rustc_attrs)] + +// The shim that is generated for a function annotated with `#[track_caller]` should not inherit +// attributes that modify its symbol name. Failing to remove these attributes from the shim +// leads to errors like `symbol `foo` is already defined`. +// +// See also https://github.com/rust-lang/rust/issues/143162. + +#[unsafe(no_mangle)] +#[track_caller] +pub fn foo() {} + +#[unsafe(export_name = "bar")] +#[track_caller] +pub fn bar() {} + +#[rustc_std_internal_symbol] +#[track_caller] +pub fn baz() {} + +fn main() { + let _a = foo as fn(); + let _b = bar as fn(); + let _c = baz as fn(); +} diff --git a/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.default.stderr b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.default.stderr new file mode 100644 index 0000000000000..259a2e2c5e73b --- /dev/null +++ b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.default.stderr @@ -0,0 +1,11 @@ +warning: value assigned to `small` is never read + --> $DIR/std-panic-locations.rs:47:31 + | +LL | assert_panicked(move || { small[1] += 1; }); + | ^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.mir-opt.stderr b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.mir-opt.stderr new file mode 100644 index 0000000000000..259a2e2c5e73b --- /dev/null +++ b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.mir-opt.stderr @@ -0,0 +1,11 @@ +warning: value assigned to `small` is never read + --> $DIR/std-panic-locations.rs:47:31 + | +LL | assert_panicked(move || { small[1] += 1; }); + | ^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs index b1df1b191bcf1..b365e786fd050 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/std-panic-locations.rs @@ -45,6 +45,7 @@ fn main() { assert_panicked(move || { small[1]; }); assert_panicked(move || { small.index_mut(1); }); assert_panicked(move || { small[1] += 1; }); + //~^ WARN value assigned to `small` is never read let sorted: BTreeMap = Default::default(); assert_panicked(|| { sorted.index(&false); }); diff --git a/tests/ui/rfcs/rfc-2091-track-caller/track-caller-ffi.rs b/tests/ui/rfcs/rfc-2091-track-caller/track-caller-ffi.rs index ee8be90d14d9a..d82bd12e90a28 100644 --- a/tests/ui/rfcs/rfc-2091-track-caller/track-caller-ffi.rs +++ b/tests/ui/rfcs/rfc-2091-track-caller/track-caller-ffi.rs @@ -2,14 +2,14 @@ use std::panic::Location; -extern "Rust" { +unsafe extern "Rust" { #[track_caller] - fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>; - fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static>; + safe fn rust_track_caller_ffi_test_tracked() -> &'static Location<'static>; + safe fn rust_track_caller_ffi_test_untracked() -> &'static Location<'static>; } fn rust_track_caller_ffi_test_nested_tracked() -> &'static Location<'static> { - unsafe { rust_track_caller_ffi_test_tracked() } + rust_track_caller_ffi_test_tracked() } mod provides { @@ -31,12 +31,12 @@ fn main() { assert_eq!(location.line(), 29); assert_eq!(location.column(), 20); - let tracked = unsafe { rust_track_caller_ffi_test_tracked() }; + let tracked = rust_track_caller_ffi_test_tracked(); assert_eq!(tracked.file(), file!()); assert_eq!(tracked.line(), 34); - assert_eq!(tracked.column(), 28); + assert_eq!(tracked.column(), 19); - let untracked = unsafe { rust_track_caller_ffi_test_untracked() }; + let untracked = rust_track_caller_ffi_test_untracked(); assert_eq!(untracked.file(), file!()); assert_eq!(untracked.line(), 24); assert_eq!(untracked.column(), 9); @@ -44,5 +44,10 @@ fn main() { let contained = rust_track_caller_ffi_test_nested_tracked(); assert_eq!(contained.file(), file!()); assert_eq!(contained.line(), 12); - assert_eq!(contained.column(), 14); + assert_eq!(contained.column(), 5); + + let indirect = (rust_track_caller_ffi_test_tracked as fn() -> &'static Location<'static>)(); + assert_eq!(indirect.file(), file!()); + assert_eq!(indirect.line(), 7); + assert_eq!(indirect.column(), 5); } diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs index 151659e35c0d6..bb6e7705a29d6 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs @@ -39,10 +39,14 @@ pub fn foo( //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} struct SelfStruct {} @@ -59,10 +63,14 @@ impl SelfStruct { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} fn issue_64682_associated_fn( @@ -74,10 +82,14 @@ impl SelfStruct { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} } @@ -95,10 +107,14 @@ impl RefStruct { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} } trait RefTrait { @@ -114,10 +130,14 @@ trait RefTrait { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} fn issue_64682_associated_fn( @@ -129,10 +149,14 @@ trait RefTrait { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} } @@ -149,10 +173,14 @@ impl RefTrait for RefStruct { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Qux //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32, //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted ) {} } @@ -166,9 +194,13 @@ fn main() { //~^ ERROR documentation comments cannot be applied to function #[must_use] //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted /// Baz //~^ ERROR documentation comments cannot be applied to function #[no_mangle] b: i32 //~^ ERROR allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + //~| WARN attribute cannot be used on + //~| WARN previously accepted | {}; } diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr index 7573e39d8eb0c..cc08307a18d04 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr @@ -17,43 +17,43 @@ LL | #[test] a: u32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:56:11 + --> $DIR/param-attrs-builtin-attrs.rs:60:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:71:11 + --> $DIR/param-attrs-builtin-attrs.rs:79:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:92:11 + --> $DIR/param-attrs-builtin-attrs.rs:104:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:111:11 + --> $DIR/param-attrs-builtin-attrs.rs:127:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:126:11 + --> $DIR/param-attrs-builtin-attrs.rs:146:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:146:11 + --> $DIR/param-attrs-builtin-attrs.rs:170:11 | LL | #[test] a: i32, | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/param-attrs-builtin-attrs.rs:163:11 + --> $DIR/param-attrs-builtin-attrs.rs:191:11 | LL | #[test] a: u32, | ^^^^ not a non-macro attribute @@ -137,250 +137,395 @@ LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:42:5 + --> $DIR/param-attrs-builtin-attrs.rs:44:5 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:44:5 + --> $DIR/param-attrs-builtin-attrs.rs:46:5 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:51:9 + --> $DIR/param-attrs-builtin-attrs.rs:55:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:54:9 + --> $DIR/param-attrs-builtin-attrs.rs:58:9 | LL | /// Bar | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:58:9 + --> $DIR/param-attrs-builtin-attrs.rs:62:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:60:9 + --> $DIR/param-attrs-builtin-attrs.rs:64:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:62:9 + --> $DIR/param-attrs-builtin-attrs.rs:68:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:64:9 + --> $DIR/param-attrs-builtin-attrs.rs:70:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:69:9 + --> $DIR/param-attrs-builtin-attrs.rs:77:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:73:9 + --> $DIR/param-attrs-builtin-attrs.rs:81:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:75:9 + --> $DIR/param-attrs-builtin-attrs.rs:83:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:77:9 + --> $DIR/param-attrs-builtin-attrs.rs:87:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:79:9 + --> $DIR/param-attrs-builtin-attrs.rs:89:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:87:9 + --> $DIR/param-attrs-builtin-attrs.rs:99:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:90:9 + --> $DIR/param-attrs-builtin-attrs.rs:102:9 | LL | /// Bar | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:94:9 + --> $DIR/param-attrs-builtin-attrs.rs:106:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:96:9 + --> $DIR/param-attrs-builtin-attrs.rs:108:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:98:9 + --> $DIR/param-attrs-builtin-attrs.rs:112:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:100:9 + --> $DIR/param-attrs-builtin-attrs.rs:114:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:106:9 + --> $DIR/param-attrs-builtin-attrs.rs:122:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:109:9 + --> $DIR/param-attrs-builtin-attrs.rs:125:9 | LL | /// Bar | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:113:9 + --> $DIR/param-attrs-builtin-attrs.rs:129:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:115:9 + --> $DIR/param-attrs-builtin-attrs.rs:131:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:117:9 + --> $DIR/param-attrs-builtin-attrs.rs:135:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:119:9 + --> $DIR/param-attrs-builtin-attrs.rs:137:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:124:9 + --> $DIR/param-attrs-builtin-attrs.rs:144:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:128:9 + --> $DIR/param-attrs-builtin-attrs.rs:148:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:130:9 + --> $DIR/param-attrs-builtin-attrs.rs:150:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:132:9 + --> $DIR/param-attrs-builtin-attrs.rs:154:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:134:9 + --> $DIR/param-attrs-builtin-attrs.rs:156:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:141:9 + --> $DIR/param-attrs-builtin-attrs.rs:165:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:144:9 + --> $DIR/param-attrs-builtin-attrs.rs:168:9 | LL | /// Bar | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:148:9 + --> $DIR/param-attrs-builtin-attrs.rs:172:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:150:9 + --> $DIR/param-attrs-builtin-attrs.rs:174:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:152:9 + --> $DIR/param-attrs-builtin-attrs.rs:178:9 | LL | /// Qux | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:154:9 + --> $DIR/param-attrs-builtin-attrs.rs:180:9 | LL | #[no_mangle] b: i32, | ^^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:161:9 + --> $DIR/param-attrs-builtin-attrs.rs:189:9 | LL | /// Foo | ^^^^^^^ doc comments are not allowed here error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:165:9 + --> $DIR/param-attrs-builtin-attrs.rs:193:9 | LL | /// Bar | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:167:9 + --> $DIR/param-attrs-builtin-attrs.rs:195:9 | LL | #[must_use] | ^^^^^^^^^^^ error: documentation comments cannot be applied to function parameters - --> $DIR/param-attrs-builtin-attrs.rs:169:9 + --> $DIR/param-attrs-builtin-attrs.rs:199:9 | LL | /// Baz | ^^^^^^^ doc comments are not allowed here error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - --> $DIR/param-attrs-builtin-attrs.rs:171:9 + --> $DIR/param-attrs-builtin-attrs.rs:201:9 | LL | #[no_mangle] b: i32 | ^^^^^^^^^^^^ -error: aborting due to 64 previous errors +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:40:5 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + = note: requested on the command line with `-W unused-attributes` + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:46:5 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:64:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:70:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:83:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:89:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:108:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:114:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:131:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:137:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:150:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:156:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:174:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:180:9 + | +LL | #[no_mangle] b: i32, + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +warning: `#[must_use]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:195:9 + | +LL | #[must_use] + | ^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[must_use]` can be applied to data types, functions, traits, and unions + +warning: `#[no_mangle]` attribute cannot be used on function params + --> $DIR/param-attrs-builtin-attrs.rs:201:9 + | +LL | #[no_mangle] b: i32 + | ^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = help: `#[no_mangle]` can be applied to functions and statics + +error: aborting due to 64 previous errors; 16 warnings emitted diff --git a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr index ba92bc4a71d85..90282793fa284 100644 --- a/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfcs/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -10,18 +10,6 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ -error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:40:27 - | -LL | #[cfg(something)] a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - -error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:106:27 - | -LL | #[cfg(something)] a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:29:23 | @@ -34,6 +22,12 @@ error: unused variable: `c` LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:40:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:47:27 | @@ -118,5 +112,11 @@ error: unused variable: `c` LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:106:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: aborting due to 19 previous errors diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs index 414d5518e1fb0..2387dfb2bc575 100644 --- a/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs +++ b/tests/ui/rfcs/rfc-3348-c-string-literals/edition-spans.rs @@ -7,6 +7,7 @@ //@ check-pass //@ proc-macro: count.rs +//@ ignore-backends: gcc extern crate count; const _: () = { diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs index 5fb9943d6c3c4..d3b4d057e6d0f 100644 --- a/tests/ui/runtime/backtrace-debuginfo.rs +++ b/tests/ui/runtime/backtrace-debuginfo.rs @@ -11,10 +11,15 @@ //@ compile-flags:-Cstrip=none //@ needs-subprocess //@ ignore-fuchsia Backtrace not symbolized, trace different line alignment +//@ ignore-ios needs the `.dSYM` files to be moved to the device +//@ ignore-tvos needs the `.dSYM` files to be moved to the device +//@ ignore-watchos needs the `.dSYM` files to be moved to the device +//@ ignore-visionos needs the `.dSYM` files to be moved to the device // FIXME(#117097): backtrace (possibly unwinding mechanism) seems to be different on at least // `i686-mingw` (32-bit windows-gnu)? cc #128911. //@ ignore-windows-gnu +//@ ignore-backends: gcc use std::env; diff --git a/tests/ui/runtime/on-broken-pipe/child-processes.rs b/tests/ui/runtime/on-broken-pipe/child-processes.rs index c0c8ad4e2f5e6..b7022e1b09d90 100644 --- a/tests/ui/runtime/on-broken-pipe/child-processes.rs +++ b/tests/ui/runtime/on-broken-pipe/child-processes.rs @@ -1,5 +1,6 @@ //@ revisions: default error kill inherit //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ only-unix because SIGPIPE is a unix thing //@ ignore-backends: gcc //@ run-pass diff --git a/tests/ui/runtime/on-broken-pipe/inherit.rs b/tests/ui/runtime/on-broken-pipe/inherit.rs index f3c8140eaaef1..e99c7c7a0fe4f 100644 --- a/tests/ui/runtime/on-broken-pipe/inherit.rs +++ b/tests/ui/runtime/on-broken-pipe/inherit.rs @@ -1,4 +1,5 @@ //@ ignore-cross-compile because aux-bin does not yet support it +//@ ignore-remote because aux-bin does not yet support it //@ only-unix because SIGPIPE is a unix thing //@ aux-bin: assert-inherit-sig_dfl.rs //@ aux-bin: assert-inherit-sig_ign.rs diff --git a/tests/ui/runtime/out-of-stack.rs b/tests/ui/runtime/out-of-stack.rs index 913d3637c8f2b..3e092728f2929 100644 --- a/tests/ui/runtime/out-of-stack.rs +++ b/tests/ui/runtime/out-of-stack.rs @@ -10,6 +10,7 @@ //@ ignore-tvos stack overflow handlers aren't enabled //@ ignore-watchos stack overflow handlers aren't enabled //@ ignore-visionos stack overflow handlers aren't enabled +//@ ignore-backends: gcc #![feature(rustc_private)] diff --git a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.fixed b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.fixed index 028f86eb0a3ed..b4b47dc886bef 100644 --- a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.fixed +++ b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.fixed @@ -1,6 +1,7 @@ //@ edition:2018 //@ aux-build: remove-extern-crate.rs //@ run-rustfix +//@ rustfix-only-machine-applicable #![warn(rust_2018_idioms)] diff --git a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.rs b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.rs index 1acf531a66196..f3c591a656adc 100644 --- a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.rs +++ b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.rs @@ -1,6 +1,7 @@ //@ edition:2018 //@ aux-build: remove-extern-crate.rs //@ run-rustfix +//@ rustfix-only-machine-applicable #![warn(rust_2018_idioms)] diff --git a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.stderr b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.stderr index 632ecd6232213..fc6afa500cdae 100644 --- a/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.stderr +++ b/tests/ui/rust-2018/removing-extern-crate-malformed-cfg.stderr @@ -1,29 +1,33 @@ error: expected identifier, found `"macro_use"` - --> $DIR/removing-extern-crate-malformed-cfg.rs:7:18 + --> $DIR/removing-extern-crate-malformed-cfg.rs:8:18 | LL | #[cfg_attr(test, "macro_use")] - | ^^^^^^^^^^^ expected identifier + | -----------------^^^^^^^^^^^-- + | | | + | | expected identifier + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit error: expected one of `(`, `,`, `::`, or `=`, found `` - --> $DIR/removing-extern-crate-malformed-cfg.rs:12:16 + --> $DIR/removing-extern-crate-malformed-cfg.rs:13:16 | LL | #[cfg_attr(test)] - | ^^^^ expected one of `(`, `,`, `::`, or `=` + | -----------^^^^-- + | | | + | | expected one of `(`, `,`, `::`, or `=` + | help: must be of the form: `#[cfg_attr(predicate, attr1, attr2, ...)]` | - = help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]` = note: for more information, visit warning: unused extern crate - --> $DIR/removing-extern-crate-malformed-cfg.rs:8:1 + --> $DIR/removing-extern-crate-malformed-cfg.rs:9:1 | LL | extern crate remove_extern_crate as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unused | note: the lint level is defined here - --> $DIR/removing-extern-crate-malformed-cfg.rs:5:9 + --> $DIR/removing-extern-crate-malformed-cfg.rs:6:9 | LL | #![warn(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ @@ -36,7 +40,7 @@ LL + | warning: unused extern crate - --> $DIR/removing-extern-crate-malformed-cfg.rs:9:1 + --> $DIR/removing-extern-crate-malformed-cfg.rs:10:1 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ unused @@ -48,7 +52,7 @@ LL + | warning: unused extern crate - --> $DIR/removing-extern-crate-malformed-cfg.rs:13:5 + --> $DIR/removing-extern-crate-malformed-cfg.rs:14:5 | LL | extern crate remove_extern_crate as foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unused @@ -61,7 +65,7 @@ LL + | warning: unused extern crate - --> $DIR/removing-extern-crate-malformed-cfg.rs:14:5 + --> $DIR/removing-extern-crate-malformed-cfg.rs:15:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ unused diff --git a/tests/ui/rust-2018/suggestions-not-always-applicable.fixed b/tests/ui/rust-2018/suggestions-not-always-applicable.fixed index e3070ba150b6d..3a42434494d84 100644 --- a/tests/ui/rust-2018/suggestions-not-always-applicable.fixed +++ b/tests/ui/rust-2018/suggestions-not-always-applicable.fixed @@ -3,6 +3,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ check-pass +//@ ignore-backends: gcc #![warn(rust_2018_compatibility)] diff --git a/tests/ui/rust-2018/suggestions-not-always-applicable.rs b/tests/ui/rust-2018/suggestions-not-always-applicable.rs index e3070ba150b6d..3a42434494d84 100644 --- a/tests/ui/rust-2018/suggestions-not-always-applicable.rs +++ b/tests/ui/rust-2018/suggestions-not-always-applicable.rs @@ -3,6 +3,7 @@ //@ run-rustfix //@ rustfix-only-machine-applicable //@ check-pass +//@ ignore-backends: gcc #![warn(rust_2018_compatibility)] diff --git a/tests/ui/rust-2021/reserved-prefixes-via-macro.rs b/tests/ui/rust-2021/reserved-prefixes-via-macro.rs index eec1b859c2033..456649f23ca67 100644 --- a/tests/ui/rust-2021/reserved-prefixes-via-macro.rs +++ b/tests/ui/rust-2021/reserved-prefixes-via-macro.rs @@ -1,6 +1,7 @@ //@ run-pass //@ edition:2021 //@ proc-macro: reserved-prefixes-macro-2018.rs +//@ ignore-backends: gcc extern crate reserved_prefixes_macro_2018 as m2018; diff --git a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs index ead2ab40b77ac..ddb32c2671739 100644 --- a/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs +++ b/tests/ui/rust-2024/reserved-guarded-strings-via-macro.rs @@ -1,6 +1,7 @@ //@ run-pass //@ edition:2024 //@ proc-macro: reserved-guarded-strings-macro-2021.rs +//@ ignore-backends: gcc extern crate reserved_guarded_strings_macro_2021 as m2021; diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs index e2c504e708c55..8b7073649b7a2 100644 --- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs +++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-from-pm.rs @@ -6,6 +6,7 @@ //@[edition2021] edition:2021 //@[edition2024] edition:2024 //@ proc-macro: unsafe-attributes-pm.rs +//@ ignore-backends: gcc unsafe_attributes_pm::missing_unsafe!(); diff --git a/tests/ui/rustc_public-ir-print/async-closure.rs b/tests/ui/rustc_public-ir-print/async-closure.rs index 80f96e09cfc78..bd8c7e888a37c 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.rs +++ b/tests/ui/rustc_public-ir-print/async-closure.rs @@ -1,6 +1,6 @@ //@ compile-flags: -Z unpretty=stable-mir --crate-type lib -C panic=abort -Zmir-opt-level=0 //@ check-pass -//@ only-x86_64 +//@ only-64bit //@ edition: 2024 //@ needs-unwind unwind edges are different with panic=abort diff --git a/tests/ui/rustc_public-ir-print/async-closure.stdout b/tests/ui/rustc_public-ir-print/async-closure.stdout index 73e9b8fc097ab..550f0512569d7 100644 --- a/tests/ui/rustc_public-ir-print/async-closure.stdout +++ b/tests/ui/rustc_public-ir-print/async-closure.stdout @@ -28,7 +28,7 @@ fn foo::{closure#0}(_1: &{async closure@$DIR/async-closure.rs:9:13: 9:21}) -> {a debug y => (*((*_1).0: &i32)); bb0: { StorageLive(_2); - _3 = CopyForDeref(((*_1).0: &i32)); + _3 = ((*_1).0: &i32); _2 = &(*_3); _0 = {coroutine@$DIR/async-closure.rs:9:22: 11:6}(move _2); StorageDead(_2); @@ -40,30 +40,28 @@ fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-clo let _3: i32; let mut _4: &i32; let mut _5: (); - let mut _6: &mut Context<'_>; - let mut _7: u32; + let mut _6: u32; + let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; let mut _9: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - let mut _10: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - debug _task_context => _6; + debug _task_context => _2; debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32)); debug y => _3; bb0: { - _8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _7 = discriminant((*_8)); - switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3]; + _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _6 = discriminant((*_7)); + switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { - _6 = move _2; StorageLive(_3); - _9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _4 = CopyForDeref(((*_9).0: &i32)); + _8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _4 = ((*_8).0: &i32); _3 = (*_4); _5 = (); StorageDead(_3); _0 = std::task::Poll::Ready(move _5); - _10 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - discriminant((*_10)) = 1; + _9 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + discriminant((*_9)) = 1; return; } bb2: { @@ -78,30 +76,28 @@ fn foo::{closure#0}::{synthetic#0}(_1: Pin<&mut {async closure body@$DIR/async-c let _3: i32; let mut _4: &i32; let mut _5: (); - let mut _6: &mut Context<'_>; - let mut _7: u32; + let mut _6: u32; + let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; let mut _9: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - let mut _10: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}; - debug _task_context => _6; + debug _task_context => _2; debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32)); debug y => _3; bb0: { - _8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _7 = discriminant((*_8)); - switchInt(move _7) -> [0: bb1, 1: bb2, otherwise: bb3]; + _7 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _6 = discriminant((*_7)); + switchInt(move _6) -> [0: bb1, 1: bb2, otherwise: bb3]; } bb1: { - _6 = move _2; StorageLive(_3); - _9 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - _4 = CopyForDeref(((*_9).0: &i32)); + _8 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + _4 = ((*_8).0: &i32); _3 = (*_4); _5 = (); StorageDead(_3); _0 = std::task::Poll::Ready(move _5); - _10 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})); - discriminant((*_10)) = 1; + _9 = (_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}); + discriminant((*_9)) = 1; return; } bb2: { diff --git a/tests/ui/sanitizer/address.rs b/tests/ui/sanitizer/address.rs index 1688f46c2d556..b4e7d8f254ca9 100644 --- a/tests/ui/sanitizer/address.rs +++ b/tests/ui/sanitizer/address.rs @@ -6,7 +6,8 @@ // //@ run-fail-or-crash //@ error-pattern: AddressSanitizer: stack-buffer-overflow -//@ error-pattern: 'xs' (line 14) <== Memory access at offset +//@ error-pattern: 'xs' (line 15) <== Memory access at offset +//@ ignore-backends: gcc use std::hint::black_box; diff --git a/tests/ui/sanitizer/cfg-kasan.rs b/tests/ui/sanitizer/cfg-kasan.rs index ba0abf605707a..0f4560888935f 100644 --- a/tests/ui/sanitizer/cfg-kasan.rs +++ b/tests/ui/sanitizer/cfg-kasan.rs @@ -13,9 +13,10 @@ //@[riscv64gc] needs-llvm-components: riscv //@[x86_64] compile-flags: --target x86_64-unknown-none //@[x86_64] needs-llvm-components: x86 +//@ ignore-backends: gcc #![crate_type = "rlib"] -#![feature(cfg_sanitize, no_core, lang_items)] +#![feature(cfg_sanitize, no_core)] #![no_core] extern crate minicore; diff --git a/tests/ui/sanitizer/cfg.rs b/tests/ui/sanitizer/cfg.rs index a43813c04469f..42b1d3c5e1f97 100644 --- a/tests/ui/sanitizer/cfg.rs +++ b/tests/ui/sanitizer/cfg.rs @@ -19,8 +19,9 @@ //@[memory]compile-flags: -Zsanitizer=memory //@[thread]needs-sanitizer-thread //@[thread]compile-flags: -Zsanitizer=thread +//@ ignore-backends: gcc -#![feature(cfg_sanitize, no_core, lang_items)] +#![feature(cfg_sanitize, no_core)] #![crate_type="lib"] #![no_core] diff --git a/tests/ui/sanitizer/cfi/is-incompatible-with-kcfi.rs b/tests/ui/sanitizer/cfi/is-incompatible-with-kcfi.rs index db8d11616440d..71cae90743078 100644 --- a/tests/ui/sanitizer/cfi/is-incompatible-with-kcfi.rs +++ b/tests/ui/sanitizer/cfi/is-incompatible-with-kcfi.rs @@ -6,6 +6,7 @@ //@ [x86_64] compile-flags: --target x86_64-unknown-none //@ [x86_64] needs-llvm-components: x86 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer=kcfi +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/sanitizer/cfi/transparent-has-regions.rs b/tests/ui/sanitizer/cfi/transparent-has-regions.rs index b82850133c100..3e9893df23c92 100644 --- a/tests/ui/sanitizer/cfi/transparent-has-regions.rs +++ b/tests/ui/sanitizer/cfi/transparent-has-regions.rs @@ -3,6 +3,7 @@ //@ no-prefer-dynamic //@ only-x86_64-unknown-linux-gnu //@ build-pass +//@ ignore-backends: gcc pub trait Trait {} diff --git a/tests/ui/sanitizer/dataflow-abilist.txt b/tests/ui/sanitizer/dataflow-abilist.txt index 3d32397a175d4..b6fdfe3cbf6e7 100644 --- a/tests/ui/sanitizer/dataflow-abilist.txt +++ b/tests/ui/sanitizer/dataflow-abilist.txt @@ -490,16 +490,6 @@ fun:__dfso_*=uninstrumented fun:__dfso_*=discard # Rust functions. -fun:__rdl_alloc=uninstrumented -fun:__rdl_alloc_zeroed=uninstrumented -fun:__rdl_dealloc=uninstrumented -fun:__rdl_realloc=uninstrumented -fun:__rg_oom=uninstrumented -fun:__rust_alloc=uninstrumented -fun:__rust_alloc_error_handler=uninstrumented -fun:__rust_alloc_zeroed=uninstrumented -fun:__rust_dealloc=uninstrumented -fun:__rust_realloc=uninstrumented fun:_ZN4core*=uninstrumented fun:_ZN3std*=uninstrumented fun:rust_eh_personality=uninstrumented diff --git a/tests/ui/sanitizer/dataflow.rs b/tests/ui/sanitizer/dataflow.rs index d99a1a6ac2479..e3e03fee08c30 100644 --- a/tests/ui/sanitizer/dataflow.rs +++ b/tests/ui/sanitizer/dataflow.rs @@ -5,6 +5,7 @@ //@ needs-sanitizer-dataflow //@ run-pass //@ compile-flags: -Zsanitizer=dataflow -Zsanitizer-dataflow-abilist={{src-base}}/sanitizer/dataflow-abilist.txt -C unsafe-allow-abi-mismatch=sanitizer +//@ ignore-backends: gcc use std::mem::size_of; use std::os::raw::{c_int, c_long, c_void}; diff --git a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs index be81c7bd0cac1..ac2b95b639820 100644 --- a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs +++ b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs @@ -7,6 +7,7 @@ //@ no-prefer-dynamic //@ only-x86_64-unknown-linux-gnu //@ build-pass +//@ ignore-backends: gcc use std::future::Future; diff --git a/tests/ui/sanitizer/kcfi-c-variadic.rs b/tests/ui/sanitizer/kcfi-c-variadic.rs new file mode 100644 index 0000000000000..45d00a4524ebf --- /dev/null +++ b/tests/ui/sanitizer/kcfi-c-variadic.rs @@ -0,0 +1,20 @@ +//@ needs-sanitizer-kcfi +//@ no-prefer-dynamic +//@ compile-flags: -Zsanitizer=kcfi -Cpanic=abort -Cunsafe-allow-abi-mismatch=sanitizer +//@ ignore-backends: gcc +//@ run-pass + +#![feature(c_variadic)] + +trait Trait { + unsafe extern "C" fn foo(x: i32, y: i32, mut ap: ...) -> i32 { + x + y + ap.arg::() + ap.arg::() + } +} + +impl Trait for i32 {} + +fn main() { + let f = i32::foo as unsafe extern "C" fn(i32, i32, ...) -> i32; + assert_eq!(unsafe { f(1, 2, 3, 4) }, 1 + 2 + 3 + 4); +} diff --git a/tests/ui/sanitizer/memory-eager.rs b/tests/ui/sanitizer/memory-eager.rs index 9498336abb7d0..59ad6eec0e329 100644 --- a/tests/ui/sanitizer/memory-eager.rs +++ b/tests/ui/sanitizer/memory-eager.rs @@ -12,6 +12,7 @@ //@ error-pattern: MemorySanitizer: use-of-uninitialized-value //@ [optimized]error-pattern: Uninitialized value was created by an allocation //@ [optimized]error-pattern: in the stack frame +//@ ignore-backends: gcc // // FIXME the unoptimized case actually has that text in the output too, per // diff --git a/tests/ui/sanitizer/memory.rs b/tests/ui/sanitizer/memory.rs index 1566637acd222..764d8b4432bf2 100644 --- a/tests/ui/sanitizer/memory.rs +++ b/tests/ui/sanitizer/memory.rs @@ -12,6 +12,7 @@ //@ error-pattern: MemorySanitizer: use-of-uninitialized-value //@ error-pattern: Uninitialized value was created by an allocation //@ error-pattern: in the stack frame +//@ ignore-backends: gcc // // This test case intentionally limits the usage of the std, // since it will be linked with an uninstrumented version of it. diff --git a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs index b66568474277e..deeee694a1cf9 100644 --- a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs +++ b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs @@ -15,6 +15,7 @@ //@[opt1]compile-flags: -Copt-level=1 //@ run-fail-or-crash //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope +//@ ignore-backends: gcc static mut P: *mut usize = std::ptr::null_mut(); diff --git a/tests/ui/sanitizer/thread.rs b/tests/ui/sanitizer/thread.rs index 8f72b1b41a84c..7ed21dce9f3e9 100644 --- a/tests/ui/sanitizer/thread.rs +++ b/tests/ui/sanitizer/thread.rs @@ -19,6 +19,7 @@ //@ error-pattern: WARNING: ThreadSanitizer: data race //@ error-pattern: Location is heap block of size 4 //@ error-pattern: allocated by main thread +//@ ignore-backends: gcc #![feature(rustc_private)] extern crate libc; diff --git a/tests/ui/sanitizer/unsupported-target.rs b/tests/ui/sanitizer/unsupported-target.rs index 14925548e9271..0776c769e0796 100644 --- a/tests/ui/sanitizer/unsupported-target.rs +++ b/tests/ui/sanitizer/unsupported-target.rs @@ -1,5 +1,6 @@ //@ compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu //@ needs-llvm-components: x86 +//@ ignore-backends: gcc #![feature(no_core)] #![no_core] diff --git a/tests/ui/sanitizer/use-after-scope.rs b/tests/ui/sanitizer/use-after-scope.rs index 1c477d0be14b8..523b35869074c 100644 --- a/tests/ui/sanitizer/use-after-scope.rs +++ b/tests/ui/sanitizer/use-after-scope.rs @@ -5,6 +5,7 @@ //@ compile-flags: -Zsanitizer=address -C unsafe-allow-abi-mismatch=sanitizer //@ run-fail-or-crash //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope +//@ ignore-backends: gcc static mut P: *mut usize = std::ptr::null_mut(); diff --git a/tests/ui/sepcomp/sepcomp-lib-lto.rs b/tests/ui/sepcomp/sepcomp-lib-lto.rs index 2166a8fd031ff..f47ea25a4fc58 100644 --- a/tests/ui/sepcomp/sepcomp-lib-lto.rs +++ b/tests/ui/sepcomp/sepcomp-lib-lto.rs @@ -5,6 +5,7 @@ //@ aux-build:sepcomp_lib.rs //@ compile-flags: -C lto -g //@ no-prefer-dynamic +//@ ignore-backends: gcc extern crate sepcomp_lib; use sepcomp_lib::a::one; diff --git a/tests/ui/sepcomp/sepcomp-unwind.rs b/tests/ui/sepcomp/sepcomp-unwind.rs index 95591676b5eed..0038e887c4ee6 100644 --- a/tests/ui/sepcomp/sepcomp-unwind.rs +++ b/tests/ui/sepcomp/sepcomp-unwind.rs @@ -3,6 +3,7 @@ #![allow(dead_code)] //@ compile-flags: -C codegen-units=3 //@ needs-threads +//@ ignore-backends: gcc // Test unwinding through multiple compilation units. diff --git a/tests/ui/simd/auxiliary/simd-lane-limit.rs b/tests/ui/simd/auxiliary/simd-lane-limit.rs new file mode 100644 index 0000000000000..dde6b880c62ec --- /dev/null +++ b/tests/ui/simd/auxiliary/simd-lane-limit.rs @@ -0,0 +1,5 @@ +#![feature(rustc_attrs, repr_simd)] + +#[repr(simd, packed)] +#[rustc_simd_monomorphize_lane_limit = "8"] +pub struct Simd(pub [T; N]); diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs index caec607d6fe79..d67ff6b33b79b 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs +++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ ignore-backends: gcc #![feature(repr_simd, core_intrinsics)] #![allow(non_camel_case_types)] diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr index a27a8d721fb05..a2646c8e84872 100644 --- a/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr +++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.stderr @@ -1,167 +1,167 @@ error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:68:9 + --> $DIR/generic-arithmetic-2.rs:69:9 | LL | simd_add(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_sub` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:70:9 + --> $DIR/generic-arithmetic-2.rs:71:9 | LL | simd_sub(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_mul` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:72:9 + --> $DIR/generic-arithmetic-2.rs:73:9 | LL | simd_mul(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_div` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:74:9 + --> $DIR/generic-arithmetic-2.rs:75:9 | LL | simd_div(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shl` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:76:9 + --> $DIR/generic-arithmetic-2.rs:77:9 | LL | simd_shl(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shr` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:78:9 + --> $DIR/generic-arithmetic-2.rs:79:9 | LL | simd_shr(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:80:9 + --> $DIR/generic-arithmetic-2.rs:81:9 | LL | simd_funnel_shl(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:82:9 + --> $DIR/generic-arithmetic-2.rs:83:9 | LL | simd_funnel_shr(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_and` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:84:9 + --> $DIR/generic-arithmetic-2.rs:85:9 | LL | simd_and(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_or` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:86:9 + --> $DIR/generic-arithmetic-2.rs:87:9 | LL | simd_or(0, 0); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_xor` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:88:9 + --> $DIR/generic-arithmetic-2.rs:89:9 | LL | simd_xor(0, 0); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_neg` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:91:9 + --> $DIR/generic-arithmetic-2.rs:92:9 | LL | simd_neg(0); | ^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:93:9 + --> $DIR/generic-arithmetic-2.rs:94:9 | LL | simd_bswap(0); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:95:9 + --> $DIR/generic-arithmetic-2.rs:96:9 | LL | simd_bitreverse(0); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:97:9 + --> $DIR/generic-arithmetic-2.rs:98:9 | LL | simd_ctlz(0); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-arithmetic-2.rs:99:9 + --> $DIR/generic-arithmetic-2.rs:100:9 | LL | simd_cttz(0); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shl` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:102:9 + --> $DIR/generic-arithmetic-2.rs:103:9 | LL | simd_shl(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shr` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:104:9 + --> $DIR/generic-arithmetic-2.rs:105:9 | LL | simd_shr(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_funnel_shl` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:106:9 + --> $DIR/generic-arithmetic-2.rs:107:9 | LL | simd_funnel_shl(z, z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_funnel_shr` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:108:9 + --> $DIR/generic-arithmetic-2.rs:109:9 | LL | simd_funnel_shr(z, z, z); | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_and` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:110:9 + --> $DIR/generic-arithmetic-2.rs:111:9 | LL | simd_and(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_or` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:112:9 + --> $DIR/generic-arithmetic-2.rs:113:9 | LL | simd_or(z, z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_xor` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:114:9 + --> $DIR/generic-arithmetic-2.rs:115:9 | LL | simd_xor(z, z); | ^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bswap` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:116:9 + --> $DIR/generic-arithmetic-2.rs:117:9 | LL | simd_bswap(z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_bitreverse` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:118:9 + --> $DIR/generic-arithmetic-2.rs:119:9 | LL | simd_bitreverse(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctlz` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:120:9 + --> $DIR/generic-arithmetic-2.rs:121:9 | LL | simd_ctlz(z); | ^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_ctpop` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:122:9 + --> $DIR/generic-arithmetic-2.rs:123:9 | LL | simd_ctpop(z); | ^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_cttz` intrinsic: unsupported operation on `f32x4` with element `f32` - --> $DIR/generic-arithmetic-2.rs:124:9 + --> $DIR/generic-arithmetic-2.rs:125:9 | LL | simd_cttz(z); | ^^^^^^^^^^^^ diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs index 905299a928971..08d1e3ce944d9 100644 --- a/tests/ui/simd/intrinsic/generic-elements.rs +++ b/tests/ui/simd/intrinsic/generic-elements.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ ignore-backends: gcc #![feature( repr_simd, diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr index 3779aa86cee19..a32a923633b4c 100644 --- a/tests/ui/simd/intrinsic/generic-elements.stderr +++ b/tests/ui/simd/intrinsic/generic-elements.stderr @@ -1,125 +1,125 @@ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:51:9 + --> $DIR/generic-elements.rs:52:9 | LL | simd_insert(0, 0, 0); | ^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64` - --> $DIR/generic-elements.rs:53:9 + --> $DIR/generic-elements.rs:54:9 | LL | simd_insert(x, 0, 1.0); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32` - --> $DIR/generic-elements.rs:55:9 + --> $DIR/generic-elements.rs:56:9 | LL | simd_extract::<_, f32>(x, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:59:9 + --> $DIR/generic-elements.rs:60:9 | LL | simd_shuffle::(0, 0, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:62:9 + --> $DIR/generic-elements.rs:63:9 | LL | simd_shuffle::(0, 0, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:65:9 + --> $DIR/generic-elements.rs:66:9 | LL | simd_shuffle::(0, 0, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:68:9 + --> $DIR/generic-elements.rs:69:9 | LL | simd_shuffle::<_, _, f32x2>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:70:9 + --> $DIR/generic-elements.rs:71:9 | LL | simd_shuffle::<_, _, f32x4>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:72:9 + --> $DIR/generic-elements.rs:73:9 | LL | simd_shuffle::<_, _, f32x8>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:75:9 + --> $DIR/generic-elements.rs:76:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX2); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:77:9 + --> $DIR/generic-elements.rs:78:9 | LL | simd_shuffle::<_, _, i32x8>(x, x, IDX4); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:79:9 + --> $DIR/generic-elements.rs:80:9 | LL | simd_shuffle::<_, _, i32x2>(x, x, IDX8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:83:9 + --> $DIR/generic-elements.rs:84:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:86:9 + --> $DIR/generic-elements.rs:87:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected SIMD input type, found non-SIMD `i32` - --> $DIR/generic-elements.rs:89:9 + --> $DIR/generic-elements.rs:90:9 | LL | simd_shuffle_const_generic::(0, 0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32` - --> $DIR/generic-elements.rs:92:9 + --> $DIR/generic-elements.rs:93:9 | LL | simd_shuffle_const_generic::<_, f32x2, I2>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32` - --> $DIR/generic-elements.rs:94:9 + --> $DIR/generic-elements.rs:95:9 | LL | simd_shuffle_const_generic::<_, f32x4, I4>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32` - --> $DIR/generic-elements.rs:96:9 + --> $DIR/generic-elements.rs:97:9 | LL | simd_shuffle_const_generic::<_, f32x8, I8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:99:9 + --> $DIR/generic-elements.rs:100:9 | LL | simd_shuffle_const_generic::<_, i32x8, I2>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8 - --> $DIR/generic-elements.rs:101:9 + --> $DIR/generic-elements.rs:102:9 | LL | simd_shuffle_const_generic::<_, i32x8, I4>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_shuffle_const_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2 - --> $DIR/generic-elements.rs:103:9 + --> $DIR/generic-elements.rs:104:9 | LL | simd_shuffle_const_generic::<_, i32x2, I8>(x, x); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/masked-load-store-build-fail.rs b/tests/ui/simd/masked-load-store-build-fail.rs index 4b6cc17683c2c..c711b6dfd9770 100644 --- a/tests/ui/simd/masked-load-store-build-fail.rs +++ b/tests/ui/simd/masked-load-store-build-fail.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ ignore-backends: gcc #![feature(repr_simd, core_intrinsics)] use std::intrinsics::simd::{simd_masked_load, simd_masked_store}; diff --git a/tests/ui/simd/masked-load-store-build-fail.stderr b/tests/ui/simd/masked-load-store-build-fail.stderr index 7f09841b59710..b9158f46ea9aa 100644 --- a/tests/ui/simd/masked-load-store-build-fail.stderr +++ b/tests/ui/simd/masked-load-store-build-fail.stderr @@ -1,47 +1,47 @@ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected third argument with length 8 (same as input type `Simd`), found `Simd` with length 4 - --> $DIR/masked-load-store-build-fail.rs:15:9 + --> $DIR/masked-load-store-build-fail.rs:16:9 | LL | simd_masked_load(Simd::([-1, 0, -1, -1, 0, 0, 0, 0]), arr.as_ptr(), default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u8` of second argument `*const i8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*_ u8` - --> $DIR/masked-load-store-build-fail.rs:18:9 + --> $DIR/masked-load-store-build-fail.rs:19:9 | LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr() as *const i8, default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*_ u32` - --> $DIR/masked-load-store-build-fail.rs:21:9 + --> $DIR/masked-load-store-build-fail.rs:22:9 | LL | simd_masked_load(Simd::([-1, 0, -1, -1]), arr.as_ptr(), Simd::([9; 4])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_load` intrinsic: expected mask element type to be an integer, found `f32` - --> $DIR/masked-load-store-build-fail.rs:24:9 + --> $DIR/masked-load-store-build-fail.rs:25:9 | LL | simd_masked_load(Simd::([1.0, 0.0, 1.0, 1.0]), arr.as_ptr(), default); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u32` of second argument `*const u8` to be a pointer to the element type `u32` of the first argument `Simd`, found `u32` != `*mut u32` - --> $DIR/masked-load-store-build-fail.rs:27:9 + --> $DIR/masked-load-store-build-fail.rs:28:9 | LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u32; 4])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected element type `u8` of second argument `*const u8` to be a pointer to the element type `u8` of the first argument `Simd`, found `u8` != `*mut u8` - --> $DIR/masked-load-store-build-fail.rs:30:9 + --> $DIR/masked-load-store-build-fail.rs:31:9 | LL | simd_masked_store(Simd([-1i8; 4]), arr.as_ptr(), Simd([5u8; 4])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected third argument with length 4 (same as input type `Simd`), found `Simd` with length 2 - --> $DIR/masked-load-store-build-fail.rs:33:9 + --> $DIR/masked-load-store-build-fail.rs:34:9 | LL | simd_masked_store(Simd([-1i8; 4]), arr.as_mut_ptr(), Simd([5u8; 2])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_masked_store` intrinsic: expected mask element type to be an integer, found `f32` - --> $DIR/masked-load-store-build-fail.rs:36:9 + --> $DIR/masked-load-store-build-fail.rs:37:9 | LL | simd_masked_store(Simd([1f32; 4]), arr.as_mut_ptr(), Simd([5u8; 4])); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr index b0742bc5ef806..c82adbf8d4c58 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr +++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr @@ -1,5 +1,5 @@ error: overly complex generic constant - --> $DIR/monomorphize-shuffle-index.rs:36:51 + --> $DIR/monomorphize-shuffle-index.rs:37:51 | LL | return simd_shuffle_const_generic::<_, _, { &Self::I.0 }>(a, b); | ^^----------^^ diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs index 1490f8e2319f0..ba952cdb0dc60 100644 --- a/tests/ui/simd/monomorphize-shuffle-index.rs +++ b/tests/ui/simd/monomorphize-shuffle-index.rs @@ -1,6 +1,7 @@ //@ revisions: old generic generic_with_fn //@[old]run-pass //@[generic_with_fn]run-pass +//@ ignore-backends: gcc #![feature( repr_simd, core_intrinsics, diff --git a/tests/ui/simd/monomorphize-too-long.rs b/tests/ui/simd/monomorphize-too-long.rs index 4fac987b0b5aa..9c83741519178 100644 --- a/tests/ui/simd/monomorphize-too-long.rs +++ b/tests/ui/simd/monomorphize-too-long.rs @@ -6,7 +6,5 @@ struct Simd([T; N]); fn main() { - let _too_big = Simd([1_u16; 54321]); + let _too_big = Simd([1_u16; 54321]); //~ ERROR the SIMD type `Simd` has more elements than the limit 32768 } - -//~? ERROR monomorphising SIMD type `Simd` of length greater than 32768 diff --git a/tests/ui/simd/monomorphize-too-long.stderr b/tests/ui/simd/monomorphize-too-long.stderr index 978eef307abd1..71bc78ef5c955 100644 --- a/tests/ui/simd/monomorphize-too-long.stderr +++ b/tests/ui/simd/monomorphize-too-long.stderr @@ -1,4 +1,8 @@ -error: monomorphising SIMD type `Simd` of length greater than 32768 +error: the SIMD type `Simd` has more elements than the limit 32768 + --> $DIR/monomorphize-too-long.rs:9:9 + | +LL | let _too_big = Simd([1_u16; 54321]); + | ^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/simd/monomorphize-zero-length.rs b/tests/ui/simd/monomorphize-zero-length.rs index d38870c572d97..f956197a61cf0 100644 --- a/tests/ui/simd/monomorphize-zero-length.rs +++ b/tests/ui/simd/monomorphize-zero-length.rs @@ -6,7 +6,5 @@ struct Simd([T; N]); fn main() { - let _empty = Simd([1.0; 0]); + let _empty = Simd([1.0; 0]); //~ ERROR the SIMD type `Simd` has zero elements } - -//~? ERROR monomorphising SIMD type `Simd` of zero length diff --git a/tests/ui/simd/monomorphize-zero-length.stderr b/tests/ui/simd/monomorphize-zero-length.stderr index 738c20fe51a46..66f26d95c9d97 100644 --- a/tests/ui/simd/monomorphize-zero-length.stderr +++ b/tests/ui/simd/monomorphize-zero-length.stderr @@ -1,4 +1,8 @@ -error: monomorphising SIMD type `Simd` of zero length +error: the SIMD type `Simd` has zero elements + --> $DIR/monomorphize-zero-length.rs:9:9 + | +LL | let _empty = Simd([1.0; 0]); + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/simd/not-out-of-bounds.rs b/tests/ui/simd/not-out-of-bounds.rs index 4bd2a69edbf5e..c80c90e3ab9bd 100644 --- a/tests/ui/simd/not-out-of-bounds.rs +++ b/tests/ui/simd/not-out-of-bounds.rs @@ -1,4 +1,5 @@ //@ build-fail +//@ ignore-backends: gcc #![allow(non_camel_case_types)] #![feature(repr_simd, core_intrinsics)] diff --git a/tests/ui/simd/not-out-of-bounds.stderr b/tests/ui/simd/not-out-of-bounds.stderr index 4b6bda93e4561..d5bcd15d97d6c 100644 --- a/tests/ui/simd/not-out-of-bounds.stderr +++ b/tests/ui/simd/not-out-of-bounds.stderr @@ -1,5 +1,5 @@ error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | test_shuffle_lanes!(2, u8x2, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 8) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | test_shuffle_lanes!(4, u8x4, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 16) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | test_shuffle_lanes!(8, u8x8, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 32) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ LL | test_shuffle_lanes!(16, u8x16, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 64) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -54,7 +54,7 @@ LL | test_shuffle_lanes!(32, u8x32, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 128) - --> $DIR/not-out-of-bounds.rs:52:21 + --> $DIR/not-out-of-bounds.rs:53:21 | LL | $y(vec1, vec2, IDX) | ^^^^^^^^^^^^^^^^^^^ @@ -65,22 +65,22 @@ LL | test_shuffle_lanes!(64, u8x64, simd_shuffle); = note: this error originates in the macro `test_shuffle_lanes` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: SIMD index #0 is out of bounds (limit 4) - --> $DIR/not-out-of-bounds.rs:77:23 + --> $DIR/not-out-of-bounds.rs:78:23 | LL | let _: u8x2 = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_insert` intrinsic: SIMD index #1 is out of bounds (limit 2) - --> $DIR/not-out-of-bounds.rs:83:9 + --> $DIR/not-out-of-bounds.rs:84:9 | LL | simd_insert(v, 2, 0u8); | ^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_extract` intrinsic: SIMD index #1 is out of bounds (limit 2) - --> $DIR/not-out-of-bounds.rs:84:24 + --> $DIR/not-out-of-bounds.rs:85:24 | -LL | let _val: u8 = simd_extract(v, 2); - | ^^^^^^^^^^^^^^^^^^ +LL | ... let _val: u8 = simd_extract(v, 2); + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 9 previous errors diff --git a/tests/ui/simd/simd-lane-limit-err-npow2.rs b/tests/ui/simd/simd-lane-limit-err-npow2.rs new file mode 100644 index 0000000000000..d5c5c92e953db --- /dev/null +++ b/tests/ui/simd/simd-lane-limit-err-npow2.rs @@ -0,0 +1,12 @@ +//@ build-fail +//@ aux-crate:simd=simd-lane-limit.rs + +extern crate simd; + +use simd::Simd; + +fn main() { + // test non-power-of-two, since #[repr(simd, packed)] has unusual layout + let _x: Simd = Simd([0; 24]); + //~^ ERROR the SIMD type `simd::Simd` has more elements than the limit 8 +} diff --git a/tests/ui/simd/simd-lane-limit-err-npow2.stderr b/tests/ui/simd/simd-lane-limit-err-npow2.stderr new file mode 100644 index 0000000000000..fff26c4c1c1b0 --- /dev/null +++ b/tests/ui/simd/simd-lane-limit-err-npow2.stderr @@ -0,0 +1,8 @@ +error: the SIMD type `simd::Simd` has more elements than the limit 8 + --> $DIR/simd-lane-limit-err-npow2.rs:10:9 + | +LL | let _x: Simd = Simd([0; 24]); + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/simd/simd-lane-limit-err.rs b/tests/ui/simd/simd-lane-limit-err.rs new file mode 100644 index 0000000000000..00390bdbdafac --- /dev/null +++ b/tests/ui/simd/simd-lane-limit-err.rs @@ -0,0 +1,11 @@ +//@ build-fail +//@ aux-crate:simd=simd-lane-limit.rs + +extern crate simd; + +use simd::Simd; + +fn main() { + let _x: Simd = Simd([0; 16]); + //~^ ERROR the SIMD type `simd::Simd` has more elements than the limit 8 +} diff --git a/tests/ui/simd/simd-lane-limit-err.stderr b/tests/ui/simd/simd-lane-limit-err.stderr new file mode 100644 index 0000000000000..3f2eaeda2d415 --- /dev/null +++ b/tests/ui/simd/simd-lane-limit-err.stderr @@ -0,0 +1,8 @@ +error: the SIMD type `simd::Simd` has more elements than the limit 8 + --> $DIR/simd-lane-limit-err.rs:9:9 + | +LL | let _x: Simd = Simd([0; 16]); + | ^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/simd/simd-lane-limit-ok.rs b/tests/ui/simd/simd-lane-limit-ok.rs new file mode 100644 index 0000000000000..52fd3158440ad --- /dev/null +++ b/tests/ui/simd/simd-lane-limit-ok.rs @@ -0,0 +1,14 @@ +//@ build-pass +//@ aux-crate:simd=simd-lane-limit.rs + +extern crate simd; + +use simd::Simd; + +fn main() { + let _x: Simd = Simd([0; 4]); + let _y: Simd = Simd([0; 8]); + + // test non-power-of-two, since #[repr(simd, packed)] has unusual layout + let _z: Simd = Simd([0; 6]); +} diff --git a/tests/ui/simd/target-feature-mixup.rs b/tests/ui/simd/target-feature-mixup.rs index 82902891b97f2..014a9966f5cbd 100644 --- a/tests/ui/simd/target-feature-mixup.rs +++ b/tests/ui/simd/target-feature-mixup.rs @@ -5,6 +5,7 @@ //@ needs-subprocess //@ ignore-fuchsia must translate zircon signal to SIGILL, FIXME (#58590) +//@ ignore-backends: gcc #![feature(repr_simd, target_feature, cfg_target_feature)] diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.rs b/tests/ui/simd/type-generic-monomorphisation-empty.rs index c08dc9fe3df2f..7c43b8914da63 100644 --- a/tests/ui/simd/type-generic-monomorphisation-empty.rs +++ b/tests/ui/simd/type-generic-monomorphisation-empty.rs @@ -6,7 +6,5 @@ struct Simd([f32; N]); fn main() { - let _ = Simd::<0>([]); + let _empty = Simd::<0>([]); //~ ERROR the SIMD type `Simd<0>` has zero elements } - -//~? ERROR monomorphising SIMD type `Simd<0>` of zero length diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.stderr b/tests/ui/simd/type-generic-monomorphisation-empty.stderr index fc294607ae310..450db7e47db03 100644 --- a/tests/ui/simd/type-generic-monomorphisation-empty.stderr +++ b/tests/ui/simd/type-generic-monomorphisation-empty.stderr @@ -1,4 +1,8 @@ -error: monomorphising SIMD type `Simd<0>` of zero length +error: the SIMD type `Simd<0>` has zero elements + --> $DIR/type-generic-monomorphisation-empty.rs:9:9 + | +LL | let _empty = Simd::<0>([]); + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.rs b/tests/ui/simd/type-generic-monomorphisation-oversized.rs index efe3480317c9e..73a1f00e8c7f0 100644 --- a/tests/ui/simd/type-generic-monomorphisation-oversized.rs +++ b/tests/ui/simd/type-generic-monomorphisation-oversized.rs @@ -6,7 +6,6 @@ struct Simd([f32; N]); fn main() { - let _ = Simd::<65536>([0.; 65536]); + let _x = Simd::<65536>([0.; 65536]); + //~^ ERROR the SIMD type `Simd<65536>` has more elements than the limit 32768 } - -//~? ERROR monomorphising SIMD type `Simd<65536>` of length greater than 32768 diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.stderr b/tests/ui/simd/type-generic-monomorphisation-oversized.stderr index 39ff36799cc92..0065049abd68d 100644 --- a/tests/ui/simd/type-generic-monomorphisation-oversized.stderr +++ b/tests/ui/simd/type-generic-monomorphisation-oversized.stderr @@ -1,4 +1,8 @@ -error: monomorphising SIMD type `Simd<65536>` of length greater than 32768 +error: the SIMD type `Simd<65536>` has more elements than the limit 32768 + --> $DIR/type-generic-monomorphisation-oversized.rs:9:9 + | +LL | let _x = Simd::<65536>([0.; 65536]); + | ^^ error: aborting due to 1 previous error diff --git a/tests/ui/sized-hierarchy/bound-on-assoc-type-projection-1.rs b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection-1.rs new file mode 100644 index 0000000000000..4a20ed2cafb16 --- /dev/null +++ b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection-1.rs @@ -0,0 +1,21 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: old next +//@[next] compile-flags: -Znext-solver + +use std::marker::PhantomData; + +pub trait ZeroMapKV<'a> { + type Container; +} + +pub trait ZeroFrom<'zf, C: ?Sized> {} + +pub struct ZeroMap<'a, K: ZeroMapKV<'a>>(PhantomData<&'a K>); + +impl<'zf, 's, K> ZeroFrom<'zf, ZeroMap<'s, K>> for ZeroMap<'zf, K> +where + K: for<'b> ZeroMapKV<'b>, + >::Container: ZeroFrom<'zf, >::Container>, +{ +} diff --git a/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs new file mode 100644 index 0000000000000..48d17ac9a3af5 --- /dev/null +++ b/tests/ui/sized-hierarchy/bound-on-assoc-type-projection.rs @@ -0,0 +1,18 @@ +//@ check-pass +#![crate_type = "lib"] +#![feature(sized_hierarchy)] + +// Tests that a bound on an associated type projection, of a trait with a sizedness bound, will be +// elaborated. + +trait FalseDeref { + type Target: std::marker::PointeeSized; +} + +trait Bar {} + +fn foo() +where + T::Target: Bar, +{ +} diff --git a/tests/ui/sized-hierarchy/default-supertrait.rs b/tests/ui/sized-hierarchy/default-supertrait.rs index ab3b28e84db5a..b13f9d90081cd 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.rs +++ b/tests/ui/sized-hierarchy/default-supertrait.rs @@ -12,12 +12,17 @@ trait MetaSized_: MetaSized { } trait NegMetaSized: ?MetaSized { } //~^ ERROR relaxed bounds are not permitted in supertrait bounds - +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` trait PointeeSized_: PointeeSized { } trait NegPointeeSized: ?PointeeSized { } //~^ ERROR relaxed bounds are not permitted in supertrait bounds +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` +//~| ERROR bound modifier `?` can only be applied to `Sized` trait Bare {} @@ -47,14 +52,11 @@ fn with_pointeesized_supertrait() { requires_pointeesized::(); } -// `T` won't inherit the `const MetaSized` implicit supertrait of `Bare`, so there is an error on -// the bound, which is expected. +// `T` inherits the `const MetaSized` implicit supertrait of `Bare`. fn with_bare_trait() { -//~^ ERROR the size for values of type `T` cannot be known requires_sized::(); //~^ ERROR the size for values of type `T` cannot be known requires_metasized::(); - //~^ ERROR the size for values of type `T` cannot be known requires_pointeesized::(); } diff --git a/tests/ui/sized-hierarchy/default-supertrait.stderr b/tests/ui/sized-hierarchy/default-supertrait.stderr index f5589d6e279cc..35875163774d4 100644 --- a/tests/ui/sized-hierarchy/default-supertrait.stderr +++ b/tests/ui/sized-hierarchy/default-supertrait.stderr @@ -4,7 +4,7 @@ error: relaxed bounds are not permitted in supertrait bounds LL | trait NegSized: ?Sized { } | ^^^^^^ | - = note: traits are `?Sized` by default + = note: traits are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in supertrait bounds --> $DIR/default-supertrait.rs:13:21 @@ -13,29 +13,57 @@ LL | trait NegMetaSized: ?MetaSized { } | ^^^^^^^^^^ error: relaxed bounds are not permitted in supertrait bounds - --> $DIR/default-supertrait.rs:19:24 + --> $DIR/default-supertrait.rs:21:24 | LL | trait NegPointeeSized: ?PointeeSized { } | ^^^^^^^^^^^^^ -error[E0277]: the size for values of type `T` cannot be known - --> $DIR/default-supertrait.rs:52:38 +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:13:21 | -LL | fn with_bare_trait() { - | ^^^^ doesn't have a known size +LL | trait NegMetaSized: ?MetaSized { } + | ^^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:13:21 | -note: required by a bound in `Bare` - --> $DIR/default-supertrait.rs:22:1 +LL | trait NegMetaSized: ?MetaSized { } + | ^^^^^^^^^^ | -LL | trait Bare {} - | ^^^^^^^^^^^^^ required by this bound in `Bare` -help: consider further restricting type parameter `T` with unstable trait `MetaSized` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:13:21 + | +LL | trait NegMetaSized: ?MetaSized { } + | ^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:21:24 | -LL | fn with_bare_trait() { - | ++++++++++++++++++++++++ +LL | trait NegPointeeSized: ?PointeeSized { } + | ^^^^^^^^^^^^^ + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:21:24 + | +LL | trait NegPointeeSized: ?PointeeSized { } + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/default-supertrait.rs:21:24 + | +LL | trait NegPointeeSized: ?PointeeSized { } + | ^^^^^^^^^^^^^ + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/default-supertrait.rs:35:22 + --> $DIR/default-supertrait.rs:40:22 | LL | fn with_metasized_supertrait() { | - this type parameter needs to be `Sized` @@ -43,13 +71,13 @@ LL | requires_sized::(); | ^ doesn't have a size known at compile-time | note: required by a bound in `requires_sized` - --> $DIR/default-supertrait.rs:24:22 + --> $DIR/default-supertrait.rs:29:22 | LL | fn requires_sized() {} | ^^^^^ required by this bound in `requires_sized` error[E0277]: the size for values of type `T` cannot be known at compilation time - --> $DIR/default-supertrait.rs:43:22 + --> $DIR/default-supertrait.rs:48:22 | LL | fn with_pointeesized_supertrait() { | - this type parameter needs to be `Sized` @@ -57,19 +85,19 @@ LL | requires_sized::(); | ^ doesn't have a size known at compile-time | note: required by a bound in `requires_sized` - --> $DIR/default-supertrait.rs:24:22 + --> $DIR/default-supertrait.rs:29:22 | LL | fn requires_sized() {} | ^^^^^ required by this bound in `requires_sized` error[E0277]: the size for values of type `T` cannot be known - --> $DIR/default-supertrait.rs:45:26 + --> $DIR/default-supertrait.rs:50:26 | LL | requires_metasized::(); | ^ doesn't have a known size | note: required by a bound in `requires_metasized` - --> $DIR/default-supertrait.rs:25:26 + --> $DIR/default-supertrait.rs:30:26 | LL | fn requires_metasized() {} | ^^^^^^^^^ required by this bound in `requires_metasized` @@ -79,36 +107,19 @@ LL | fn with_pointeesized_supertrait $DIR/default-supertrait.rs:54:22 + --> $DIR/default-supertrait.rs:57:22 | LL | fn with_bare_trait() { | - this type parameter needs to be `Sized` -LL | LL | requires_sized::(); | ^ doesn't have a size known at compile-time | note: required by a bound in `requires_sized` - --> $DIR/default-supertrait.rs:24:22 + --> $DIR/default-supertrait.rs:29:22 | LL | fn requires_sized() {} | ^^^^^ required by this bound in `requires_sized` -error[E0277]: the size for values of type `T` cannot be known - --> $DIR/default-supertrait.rs:56:26 - | -LL | requires_metasized::(); - | ^ doesn't have a known size - | -note: required by a bound in `requires_metasized` - --> $DIR/default-supertrait.rs:25:26 - | -LL | fn requires_metasized() {} - | ^^^^^^^^^ required by this bound in `requires_metasized` -help: consider further restricting type parameter `T` with unstable trait `MetaSized` - | -LL | fn with_bare_trait() { - | ++++++++++++++++++++++++ - -error: aborting due to 9 previous errors +error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/sized-hierarchy/elaboration-simple.rs b/tests/ui/sized-hierarchy/elaboration-simple.rs new file mode 100644 index 0000000000000..87e100166a298 --- /dev/null +++ b/tests/ui/sized-hierarchy/elaboration-simple.rs @@ -0,0 +1,13 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +#![feature(sized_hierarchy)] + +// Test demonstrating that elaboration of sizedness bounds works in the simplest cases. + +trait Trait {} + +fn f() { + require_metasized::(); +} + +fn require_metasized() {} diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr deleted file mode 100644 index b904b784df735..0000000000000 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.current_sized_hierarchy.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/incomplete-inference-issue-143992.rs:30:28 - | -LL | let _x = T::Assoc::new(()); - | ------------- ^^ expected `[u32; 1]`, found `()` - | | - | arguments to this function are incorrect - | -note: associated function defined here - --> $DIR/incomplete-inference-issue-143992.rs:21:8 - | -LL | fn new(r: R) -> R { - | ^^^ ---- - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr deleted file mode 100644 index b904b784df735..0000000000000 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.next_sized_hierarchy.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/incomplete-inference-issue-143992.rs:30:28 - | -LL | let _x = T::Assoc::new(()); - | ------------- ^^ expected `[u32; 1]`, found `()` - | | - | arguments to this function are incorrect - | -note: associated function defined here - --> $DIR/incomplete-inference-issue-143992.rs:21:8 - | -LL | fn new(r: R) -> R { - | ^^^ ---- - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs index b9e65ed283935..44453b65e7cd1 100644 --- a/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs +++ b/tests/ui/sized-hierarchy/incomplete-inference-issue-143992.rs @@ -1,12 +1,8 @@ +//@ check-pass //@ compile-flags: --crate-type=lib -//@ revisions: current next current_sized_hierarchy next_sized_hierarchy +//@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-pass -//@[next] check-pass //@[next] compile-flags: -Znext-solver -//@[next_sized_hierarchy] compile-flags: -Znext-solver - -#![cfg_attr(any(current_sized_hierarchy, next_sized_hierarchy), feature(sized_hierarchy))] // Test that we avoid incomplete inference when normalizing. Without this, // `Trait`'s implicit `MetaSized` supertrait requires proving `T::Assoc<_>: MetaSized` @@ -28,6 +24,4 @@ where T::Assoc<[u32; 1]>: Clone, { let _x = T::Assoc::new(()); - //[next_sized_hierarchy]~^ ERROR mismatched types - //[current_sized_hierarchy]~^^ ERROR mismatched types } diff --git a/tests/ui/sized-hierarchy/overflow.current.stderr b/tests/ui/sized-hierarchy/overflow.current.stderr new file mode 100644 index 0000000000000..da58a6d2f7bf6 --- /dev/null +++ b/tests/ui/sized-hierarchy/overflow.current.stderr @@ -0,0 +1,45 @@ +error[E0275]: overflow evaluating the requirement `Element: MetaSized` + --> $DIR/overflow.rs:17:16 + | +LL | struct Element(> as ParseTokens>::Output); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: required for `Box` to implement `ParseTokens` + --> $DIR/overflow.rs:13:31 + | +LL | impl ParseTokens for Box { + | - ^^^^^^^^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here + = note: 1 redundant requirement hidden + = note: required for `Box>` to implement `ParseTokens` + +error[E0275]: overflow evaluating the requirement `Box: ParseTokens` + --> $DIR/overflow.rs:19:22 + | +LL | impl ParseTokens for Element { + | ^^^^^^^ + | +note: required for `Box>` to implement `ParseTokens` + --> $DIR/overflow.rs:13:31 + | +LL | impl ParseTokens for Box { + | ----------- ^^^^^^^^^^^ ^^^^^^ + | | + | unsatisfied trait bound introduced here +note: required because it appears within the type `Element` + --> $DIR/overflow.rs:17:8 + | +LL | struct Element(> as ParseTokens>::Output); + | ^^^^^^^ +note: required by a bound in `ParseTokens` + --> $DIR/overflow.rs:10:1 + | +LL | / trait ParseTokens { +LL | | type Output; +LL | | } + | |_^ required by this bound in `ParseTokens` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/sized-hierarchy/overflow.rs b/tests/ui/sized-hierarchy/overflow.rs index f8e5dd5d4029b..31c2ca8a49171 100644 --- a/tests/ui/sized-hierarchy/overflow.rs +++ b/tests/ui/sized-hierarchy/overflow.rs @@ -1,13 +1,10 @@ //@ compile-flags: --crate-type=lib //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[current] check-pass +//@[current] check-fail //@[next] check-pass //@[next] compile-flags: -Znext-solver -// FIXME(sized_hierarchy): this is expected to fail in the old solver when there -// isn't a temporary revert of the `sized_hierarchy` feature - use std::marker::PhantomData; trait ParseTokens { @@ -18,6 +15,8 @@ impl ParseTokens for Box { } struct Element(> as ParseTokens>::Output); +//[current]~^ ERROR: overflow impl ParseTokens for Element { +//[current]~^ ERROR: overflow type Output = (); } diff --git a/tests/ui/sized-hierarchy/prefer-non-nested-alias-bound.rs b/tests/ui/sized-hierarchy/prefer-non-nested-alias-bound.rs new file mode 100644 index 0000000000000..affef2e61482e --- /dev/null +++ b/tests/ui/sized-hierarchy/prefer-non-nested-alias-bound.rs @@ -0,0 +1,30 @@ +//@ check-pass +//@ compile-flags: --crate-type=lib +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +// Since #120752, also get alias-bound candidates from a nested self-type, so prefering +// alias-bound over where-bound candidates can be incorrect. This test checks that case and that +// we prefer non-nested alias-bound candidates over where-bound candidates over nested alias-bound +// candidates. + +trait OtherTrait<'a> { + type Assoc: ?Sized; +} + +trait Trait +where + >::Assoc: Sized, +{ + type Assoc: for<'a> OtherTrait<'a>; +} + +fn impls_sized() {} +fn foo<'a, T>() +where + T: Trait, + for<'hr> >::Assoc: Sized, +{ + impls_sized::<>::Assoc>(); +} diff --git a/tests/ui/sized-hierarchy/trait-alias-elaboration.rs b/tests/ui/sized-hierarchy/trait-alias-elaboration.rs new file mode 100644 index 0000000000000..a5b4443ffddd3 --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-alias-elaboration.rs @@ -0,0 +1,16 @@ +#![feature(sized_hierarchy, trait_alias)] +use std::marker::MetaSized; + +// Trait aliases also have implicit `MetaSized` bounds, like traits. These are filtered out during +// elaboration of trait aliases when lowering `dyn TraitAlias` - however, if the user explicitly +// wrote `MetaSized` in the `dyn Trait` then that should still be an error so as not to accidentally +// accept this going forwards. + +trait Qux = Clone; + +type Foo = dyn Qux + MetaSized; +//~^ ERROR: only auto traits can be used as additional traits in a trait object + +type Bar = dyn Qux; + +fn main() {} diff --git a/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr b/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr new file mode 100644 index 0000000000000..394aae6f8e32f --- /dev/null +++ b/tests/ui/sized-hierarchy/trait-alias-elaboration.stderr @@ -0,0 +1,17 @@ +error[E0225]: only auto traits can be used as additional traits in a trait object + --> $DIR/trait-alias-elaboration.rs:11:16 + | +LL | trait Qux = Clone; + | ------------------ additional non-auto trait +LL | +LL | type Foo = dyn Qux + MetaSized; + | ^^^ --------- first non-auto trait + | | + | second non-auto trait comes from this alias + | + = help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: MetaSized + MetaSized + Clone {}` + = note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0225`. diff --git a/tests/ui/sized-hierarchy/trait-aliases.rs b/tests/ui/sized-hierarchy/trait-aliases.rs deleted file mode 100644 index ffec302adaa5c..0000000000000 --- a/tests/ui/sized-hierarchy/trait-aliases.rs +++ /dev/null @@ -1,9 +0,0 @@ -//@ check-pass -//@ compile-flags: --crate-type=lib -#![feature(trait_alias)] - -// Checks that `?Sized` in a trait alias doesn't trigger an ICE. - -use std::ops::{Index, IndexMut}; - -pub trait SlicePrereq = ?Sized + IndexMut>::Output>; diff --git a/tests/ui/sized/relaxing-default-bound-error-37534.rs b/tests/ui/sized/relaxing-default-bound-error-37534.rs index d30e9f92ce9fb..5aca030908bfa 100644 --- a/tests/ui/sized/relaxing-default-bound-error-37534.rs +++ b/tests/ui/sized/relaxing-default-bound-error-37534.rs @@ -1,7 +1,5 @@ -struct Foo {} -//~^ ERROR expected trait, found derive macro `Hash` -//~| ERROR bound modifier `?` can only be applied to `Sized` +// issue: -fn main() {} +struct Foo {} //~ ERROR expected trait, found derive macro `Hash` -// https://github.com/rust-lang/rust/issues/37534 +fn main() {} diff --git a/tests/ui/sized/relaxing-default-bound-error-37534.stderr b/tests/ui/sized/relaxing-default-bound-error-37534.stderr index 8b9597f33e307..5de82206d2692 100644 --- a/tests/ui/sized/relaxing-default-bound-error-37534.stderr +++ b/tests/ui/sized/relaxing-default-bound-error-37534.stderr @@ -1,5 +1,5 @@ error[E0404]: expected trait, found derive macro `Hash` - --> $DIR/relaxing-default-bound-error-37534.rs:1:16 + --> $DIR/relaxing-default-bound-error-37534.rs:3:16 | LL | struct Foo {} | ^^^^ not a trait @@ -9,12 +9,6 @@ help: consider importing this trait instead LL + use std::hash::Hash; | -error: bound modifier `?` can only be applied to `Sized` - --> $DIR/relaxing-default-bound-error-37534.rs:1:15 - | -LL | struct Foo {} - | ^^^^^ - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/span/suggestion-non-ascii.stderr b/tests/ui/span/suggestion-non-ascii.stderr index 6e6e31a5698b8..361f744ee8eb6 100644 --- a/tests/ui/span/suggestion-non-ascii.stderr +++ b/tests/ui/span/suggestion-non-ascii.stderr @@ -2,7 +2,9 @@ error[E0608]: cannot index into a value of type `({integer},)` --> $DIR/suggestion-non-ascii.rs:3:24 | LL | println!("☃{}", tup[0]); - | ^^^ help: to access tuple elements, use: `.0` + | ^^^ help: to access tuple element `0`, use: `.0` + | + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error: aborting due to 1 previous error diff --git a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs index a635976c8427b..9e0e126dabe66 100644 --- a/tests/ui/stack-protector/warn-stack-protector-unsupported.rs +++ b/tests/ui/stack-protector/warn-stack-protector-unsupported.rs @@ -5,6 +5,7 @@ //@ [all] compile-flags: -Z stack-protector=all //@ [strong] compile-flags: -Z stack-protector=strong //@ [basic] compile-flags: -Z stack-protector=basic +//@ ignore-backends: gcc #![crate_type = "lib"] #![feature(no_core, lang_items)] diff --git a/tests/ui/static/static-align.rs b/tests/ui/static/static-align.rs index 93241db09f949..e2db7c01adf29 100644 --- a/tests/ui/static/static-align.rs +++ b/tests/ui/static/static-align.rs @@ -1,10 +1,14 @@ //@ run-pass +//@ compile-flags: --cfg FOURTY_TWO="42" --cfg TRUE --check-cfg=cfg(FOURTY_TWO,values("42")) --check-cfg=cfg(TRUE) #![feature(static_align)] +#![deny(non_upper_case_globals)] + +use std::cell::Cell; #[rustc_align_static(64)] static A: u8 = 0; -#[rustc_align_static(64)] +#[rustc_align_static(4096)] static B: u8 = 0; #[rustc_align_static(128)] @@ -17,10 +21,86 @@ unsafe extern "C" { static C: u64; } +struct HasDrop(*const HasDrop); + +impl Drop for HasDrop { + fn drop(&mut self) { + assert_eq!(core::ptr::from_mut(self).cast_const(), self.0); + } +} + +thread_local! { + #[rustc_align_static(4096)] + static LOCAL: u64 = 0; + + #[allow(unused_mut, reason = "test attribute handling")] + #[cfg_attr(true, rustc_align_static(4096))] + static CONST_LOCAL: u64 = const { 0 }; + + #[cfg_attr(any(true), cfg_attr(true, rustc_align_static(4096)))] + #[allow(unused_mut, reason = "test attribute handling")] + static HASDROP_LOCAL: Cell = Cell::new(HasDrop(core::ptr::null())); + + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + #[allow(unused_mut, reason = "test attribute handling")] + #[cfg_attr(TRUE, + cfg_attr(FOURTY_TWO = "42", + cfg_attr(all(), + cfg_attr(any(true), + cfg_attr(true, rustc_align_static(4096))))))] + #[allow(unused_mut, reason = "test attribute handling")] + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + /// I love doc comments. + static HASDROP_CONST_LOCAL: Cell = const { Cell::new(HasDrop(core::ptr::null())) }; + + #[cfg_attr(TRUE,)] + #[cfg_attr(true,)] + #[cfg_attr(false,)] + #[cfg_attr( + TRUE, + rustc_align_static(32), + cfg_attr(true, allow(non_upper_case_globals, reason = "test attribute handling")), + cfg_attr(false,) + )] + #[cfg_attr(false, rustc_align_static(0))] + static more_attr_testing: u64 = 0; +} + +fn thread_local_ptr(key: &'static std::thread::LocalKey) -> *const T { + key.with(|local| core::ptr::from_ref::(local)) +} + fn main() { assert!(core::ptr::from_ref(&A).addr().is_multiple_of(64)); - assert!(core::ptr::from_ref(&B).addr().is_multiple_of(64)); + assert!(core::ptr::from_ref(&B).addr().is_multiple_of(4096)); assert!(core::ptr::from_ref(&EXPORTED).addr().is_multiple_of(128)); unsafe { assert!(core::ptr::from_ref(&C).addr().is_multiple_of(128)) }; + + assert!(thread_local_ptr(&LOCAL).addr().is_multiple_of(4096)); + assert!(thread_local_ptr(&CONST_LOCAL).addr().is_multiple_of(4096)); + assert!(thread_local_ptr(&HASDROP_LOCAL).addr().is_multiple_of(4096)); + assert!(thread_local_ptr(&HASDROP_CONST_LOCAL).addr().is_multiple_of(4096)); + assert!(thread_local_ptr(&more_attr_testing).addr().is_multiple_of(32)); + + // Test that address (and therefore alignment) is maintained during drop + let hasdrop_ptr = thread_local_ptr(&HASDROP_LOCAL); + core::mem::forget(HASDROP_LOCAL.replace(HasDrop(hasdrop_ptr.cast()))); + let hasdrop_const_ptr = thread_local_ptr(&HASDROP_CONST_LOCAL); + core::mem::forget(HASDROP_CONST_LOCAL.replace(HasDrop(hasdrop_const_ptr.cast()))); } diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr index 8b0d3a0bf4cf4..51be79be5db8a 100644 --- a/tests/ui/static/static-lifetime-bound.stderr +++ b/tests/ui/static/static-lifetime-bound.stderr @@ -10,6 +10,12 @@ LL | f(&x); | argument requires that `x` is borrowed for `'static` LL | } | - `x` dropped here while still borrowed + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/static-lifetime-bound.rs:1:10 + | +LL | fn f<'a: 'static>(_: &'a i32) {} + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/static/static-region-bound.stderr b/tests/ui/static/static-region-bound.stderr index a47c94571022d..8472738daa49c 100644 --- a/tests/ui/static/static-region-bound.stderr +++ b/tests/ui/static/static-region-bound.stderr @@ -7,6 +7,12 @@ LL | f(x); | ---- argument requires that borrow lasts for `'static` LL | } | - temporary value is freed at the end of this statement + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/static-region-bound.rs:3:8 + | +LL | fn f(_: T) {} + | ^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/static/static_sized_requirement.rs b/tests/ui/static/static_sized_requirement.rs index 25e1359607c9b..a0f4759112ca0 100644 --- a/tests/ui/static/static_sized_requirement.rs +++ b/tests/ui/static/static_sized_requirement.rs @@ -1,7 +1,7 @@ //@ add-core-stubs //@ check-pass -#![feature(no_core, lang_items)] +#![feature(no_core)] #![no_core] #![crate_type = "lib"] diff --git a/tests/ui/structs-enums/unit-like-struct-drop-run.rs b/tests/ui/structs-enums/unit-like-struct-drop-run.rs index 3d00871837cf8..5e3fc5931bdc5 100644 --- a/tests/ui/structs-enums/unit-like-struct-drop-run.rs +++ b/tests/ui/structs-enums/unit-like-struct-drop-run.rs @@ -1,6 +1,7 @@ //@ run-pass //@ needs-unwind //@ needs-threads +//@ ignore-backends: gcc // Make sure the destructor is run for unit-like structs. diff --git a/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs b/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs new file mode 100644 index 0000000000000..fc68060a96271 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-fields-ice-147325.rs @@ -0,0 +1,11 @@ +// ICE #147325: When the user mistakenly uses struct syntax to construct an enum, +// the field_idents and field_defaults functions will trigger an error + +mod m { + struct Priv1; +} + +fn main() { + Option { field1: m::Priv1 } //~ ERROR expected struct, variant or union type, found enum + //~^ ERROR unit struct `Priv1` is private +} diff --git a/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr b/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr new file mode 100644 index 0000000000000..7193a7112b445 --- /dev/null +++ b/tests/ui/structs/default-field-values/struct-fields-ice-147325.stderr @@ -0,0 +1,22 @@ +error[E0574]: expected struct, variant or union type, found enum `Option` + --> $DIR/struct-fields-ice-147325.rs:9:5 + | +LL | Option { field1: m::Priv1 } + | ^^^^^^ not a struct, variant or union type + +error[E0603]: unit struct `Priv1` is private + --> $DIR/struct-fields-ice-147325.rs:9:25 + | +LL | Option { field1: m::Priv1 } + | ^^^^^ private unit struct + | +note: the unit struct `Priv1` is defined here + --> $DIR/struct-fields-ice-147325.rs:5:5 + | +LL | struct Priv1; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0574, E0603. +For more information about an error, try `rustc --explain E0574`. diff --git a/tests/ui/suggestions/apitit-unimplemented-method.rs b/tests/ui/suggestions/apitit-unimplemented-method.rs index b182e1939b3e3..c0cd709e2300a 100644 --- a/tests/ui/suggestions/apitit-unimplemented-method.rs +++ b/tests/ui/suggestions/apitit-unimplemented-method.rs @@ -4,9 +4,12 @@ extern crate dep; use dep::*; struct Local; + impl Trait for Local {} //~^ ERROR not all trait items implemented //~| HELP implement the missing item: `fn foo(_: impl Sized) { todo!() }` -//~| HELP implement the missing item: `fn bar(_: impl Sized) { todo!() }` +//~| HELP implement the missing item: `fn bar(_: impl Sized) where Foo: MetaSized { todo!() }` +//~| HELP implement the missing item: `fn baz() { todo!() }` +//~| HELP implement the missing item: `fn quux<'a: 'b, 'b, T>() where T: ?Sized { todo!() }` fn main() {} diff --git a/tests/ui/suggestions/apitit-unimplemented-method.stderr b/tests/ui/suggestions/apitit-unimplemented-method.stderr index b309a64e95829..1f2e0ea2cad94 100644 --- a/tests/ui/suggestions/apitit-unimplemented-method.stderr +++ b/tests/ui/suggestions/apitit-unimplemented-method.stderr @@ -1,11 +1,13 @@ -error[E0046]: not all trait items implemented, missing: `foo`, `bar` - --> $DIR/apitit-unimplemented-method.rs:7:1 +error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `baz`, `quux` + --> $DIR/apitit-unimplemented-method.rs:8:1 | LL | impl Trait for Local {} - | ^^^^^^^^^^^^^^^^^^^^ missing `foo`, `bar` in implementation + | ^^^^^^^^^^^^^^^^^^^^ missing `foo`, `bar`, `baz`, `quux` in implementation | = help: implement the missing item: `fn foo(_: impl Sized) { todo!() }` - = help: implement the missing item: `fn bar(_: impl Sized) { todo!() }` + = help: implement the missing item: `fn bar(_: impl Sized) where Foo: MetaSized { todo!() }` + = help: implement the missing item: `fn baz() { todo!() }` + = help: implement the missing item: `fn quux<'a: 'b, 'b, T>() where T: ?Sized { todo!() }` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/auxiliary/dep.rs b/tests/ui/suggestions/auxiliary/dep.rs index ac0de418313c0..c28c8b8a52f51 100644 --- a/tests/ui/suggestions/auxiliary/dep.rs +++ b/tests/ui/suggestions/auxiliary/dep.rs @@ -1,4 +1,16 @@ +#![feature(sized_hierarchy)] + +use std::marker::MetaSized; + +pub struct Foo { + inner: T, +} + pub trait Trait { fn foo(_: impl Sized); - fn bar(_: impl Sized); + fn bar(_: impl Sized) + where + Foo: MetaSized; + fn baz<'a, const N: usize>(); + fn quux<'a: 'b, 'b, T: ?Sized>(); } diff --git a/tests/ui/suggestions/auxiliary/hidden-struct.rs b/tests/ui/suggestions/auxiliary/hidden-struct.rs index 30d69acac2097..ee24389bebd7c 100644 --- a/tests/ui/suggestions/auxiliary/hidden-struct.rs +++ b/tests/ui/suggestions/auxiliary/hidden-struct.rs @@ -1,3 +1,5 @@ +// `Foo` and `Bar` should not be suggested in diagnostics of dependents + #[doc(hidden)] pub mod hidden { pub struct Foo; @@ -5,13 +7,32 @@ pub mod hidden { pub mod hidden1 { #[doc(hidden)] - pub struct Foo; + pub struct Bar; } +// `Baz` and `Quux` *should* be suggested in diagnostics of dependents #[doc(hidden)] -pub(crate) mod hidden2 { - pub struct Bar; +pub mod hidden2 { + pub struct Baz; +} + +pub use hidden2::Baz; + +#[doc(hidden)] +pub(crate) mod hidden3 { + pub struct Quux; } -pub use hidden2::Bar; +pub use hidden3::Quux; + +pub trait Marker {} + +impl Marker for Option {} +impl Marker for hidden::Foo {} +impl Marker for hidden1::Bar {} +impl Marker for Baz {} +impl Marker for Quux {} + + +pub use crate as library; diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs index 281975dcc2f3b..0716e4e2e143b 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.rs @@ -1,5 +1,4 @@ //@ aux-build:hidden-struct.rs -//@ compile-flags: --crate-type lib extern crate hidden_struct; @@ -9,7 +8,25 @@ mod local { } pub fn test(_: Foo) {} -//~^ ERROR cannot find type `Foo` in this scope +//~^ ERROR [E0412] pub fn test2(_: Bar) {} -//~^ ERROR cannot find type `Bar` in this scope +//~^ ERROR [E0412] + +pub fn test3(_: Baz) {} +//~^ ERROR [E0412] + +pub fn test4(_: Quux) {} +//~^ ERROR [E0412] + +fn test5() {} + +fn test6() {} + +fn main() { + test5::(); + //~^ ERROR [E0277] + + test6::(); + //~^ ERROR [E0277] +} diff --git a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr index 7fb4d95ff9bf5..21ab7441d43c1 100644 --- a/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr +++ b/tests/ui/suggestions/dont-suggest-foreign-doc-hidden.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `Foo` in this scope - --> $DIR/dont-suggest-foreign-doc-hidden.rs:11:16 + --> $DIR/dont-suggest-foreign-doc-hidden.rs:10:16 | LL | pub fn test(_: Foo) {} | ^^^ not found in this scope @@ -10,16 +10,66 @@ LL + use local::Foo; | error[E0412]: cannot find type `Bar` in this scope - --> $DIR/dont-suggest-foreign-doc-hidden.rs:14:17 + --> $DIR/dont-suggest-foreign-doc-hidden.rs:13:17 | LL | pub fn test2(_: Bar) {} | ^^^ not found in this scope + +error[E0412]: cannot find type `Baz` in this scope + --> $DIR/dont-suggest-foreign-doc-hidden.rs:16:17 + | +LL | pub fn test3(_: Baz) {} + | ^^^ not found in this scope + | +help: consider importing this struct + | +LL + use hidden_struct::Baz; + | + +error[E0412]: cannot find type `Quux` in this scope + --> $DIR/dont-suggest-foreign-doc-hidden.rs:19:17 + | +LL | pub fn test4(_: Quux) {} + | ^^^^ not found in this scope | help: consider importing this struct | -LL + use hidden_struct::Bar; +LL + use hidden_struct::Quux; + | + +error[E0277]: the trait bound `i32: Marker` is not satisfied + --> $DIR/dont-suggest-foreign-doc-hidden.rs:27:13 + | +LL | test5::(); + | ^^^ the trait `Marker` is not implemented for `i32` + | + = help: the following other types implement trait `Marker`: + Baz + Option + Quux +note: required by a bound in `test5` + --> $DIR/dont-suggest-foreign-doc-hidden.rs:22:13 + | +LL | fn test5() {} + | ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test5` + +error[E0277]: the trait bound `i32: Marker` is not satisfied + --> $DIR/dont-suggest-foreign-doc-hidden.rs:30:13 + | +LL | test6::(); + | ^^^ the trait `Marker` is not implemented for `i32` + | + = help: the following other types implement trait `Marker`: + Baz + Option + Quux +note: required by a bound in `test6` + --> $DIR/dont-suggest-foreign-doc-hidden.rs:24:13 | +LL | fn test6() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test6` -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0412`. +Some errors have detailed explanations: E0277, E0412. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/incorrect-variant-literal.svg b/tests/ui/suggestions/incorrect-variant-literal.svg index 2cab1f4b60f64..d2c1f6c95ca58 100644 --- a/tests/ui/suggestions/incorrect-variant-literal.svg +++ b/tests/ui/suggestions/incorrect-variant-literal.svg @@ -1,11 +1,11 @@ ())); + | +++++ + +error[E0283]: type annotations needed + --> $DIR/projection-predicate-not-satisfied-69455.rs:29:41 + | +LL | println!("{}", 23u64.test(xs.iter().sum())); + | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` + | | + | required by a bound introduced by this call + | +note: multiple `impl`s satisfying `u64: Test<_>` found + --> $DIR/projection-predicate-not-satisfied-69455.rs:11:1 + | +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl Test for u64 { + | ^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the generic argument + | +LL | println!("{}", 23u64.test(xs.iter().sum::())); + | +++++ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0284. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr b/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr deleted file mode 100644 index 16223676c067e..0000000000000 --- a/tests/ui/trait-bounds/relaxed-bounds-assumed-unsized-87199.stderr +++ /dev/null @@ -1,46 +0,0 @@ -error: bound modifier `?` can only be applied to `Sized` - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:9:11 - | -LL | fn arg(_: T) {} - | ^^^^^ - -error: bound modifier `?` can only be applied to `Sized` - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:11:15 - | -LL | fn ref_arg(_: &T) {} - | ^^^^^ - -error: bound modifier `?` can only be applied to `Sized` - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:13:40 - | -LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } - | ^^^^^ - -error: bound modifier `?` can only be applied to `Sized` - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:13:40 - | -LL | fn ret() -> impl Iterator + ?Send { std::iter::empty() } - | ^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0277]: the size for values of type `[i32]` cannot be known at compilation time - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:20:15 - | -LL | ref_arg::<[i32]>(&[5]); - | ^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `[i32]` -note: required by an implicit `Sized` bound in `ref_arg` - --> $DIR/relaxed-bounds-assumed-unsized-87199.rs:11:12 - | -LL | fn ref_arg(_: &T) {} - | ^ required by the implicit `Sized` requirement on this type parameter in `ref_arg` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn ref_arg(_: &T) {} - | ++++++++ - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/alias/effectively-empty-trait-object-type.rs b/tests/ui/traits/alias/effectively-empty-trait-object-type.rs new file mode 100644 index 0000000000000..f7e8daa88e7c2 --- /dev/null +++ b/tests/ui/traits/alias/effectively-empty-trait-object-type.rs @@ -0,0 +1,20 @@ +// Test that we reject trait object types that effectively (i.e., after trait alias expansion) +// don't contain any bounds. + +#![feature(trait_alias)] + +trait Empty0 =; + +// Nest a couple of levels deep: +trait Empty1 = Empty0; +trait Empty2 = Empty1; + +// Straight list expansion: +type Type0 = dyn Empty2; //~ ERROR at least one trait is required for an object type [E0224] + +// Twice: +trait Empty3 = Empty2 + Empty2; + +type Type1 = dyn Empty3; //~ ERROR at least one trait is required for an object type [E0224] + +fn main() {} diff --git a/tests/ui/traits/alias/effectively-empty-trait-object-type.stderr b/tests/ui/traits/alias/effectively-empty-trait-object-type.stderr new file mode 100644 index 0000000000000..dbef9c3b5b31b --- /dev/null +++ b/tests/ui/traits/alias/effectively-empty-trait-object-type.stderr @@ -0,0 +1,21 @@ +error[E0224]: at least one trait is required for an object type + --> $DIR/effectively-empty-trait-object-type.rs:13:14 + | +LL | trait Empty2 = Empty1; + | ------------ this alias does not contain a trait +... +LL | type Type0 = dyn Empty2; + | ^^^^^^^^^^ + +error[E0224]: at least one trait is required for an object type + --> $DIR/effectively-empty-trait-object-type.rs:18:14 + | +LL | trait Empty3 = Empty2 + Empty2; + | ------------ this alias does not contain a trait +LL | +LL | type Type1 = dyn Empty3; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/traits/alias/empty.rs b/tests/ui/traits/alias/empty.rs new file mode 100644 index 0000000000000..68d642f485395 --- /dev/null +++ b/tests/ui/traits/alias/empty.rs @@ -0,0 +1,17 @@ +// Ensure that there are straightforward ways to define "empty" / "trivial" / "unit" trait aliases +// which don't impose any constraints when used as a bound (since they expand to nothing). +//@ check-pass +#![feature(trait_alias)] + +trait Empty =; + +trait Trivial = where; + +trait Unit = where Self:; + +fn check() {} + +fn main() { + check::<()>(); // OK. "`(): Empty`" is trivially satisfied + check::(); // OK. `Empty` is truly empty and isn't implicitly bounded by `Sized`. +} diff --git a/tests/ui/traits/alias/maybe-bound.rs b/tests/ui/traits/alias/maybe-bound.rs deleted file mode 100644 index 9fdeb714d5e75..0000000000000 --- a/tests/ui/traits/alias/maybe-bound.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ build-pass (FIXME(62277): could be check-pass?) - -// Test that `dyn ... + ?Sized + ...` resulting from the expansion of trait aliases is okay. - -#![feature(trait_alias)] - -trait Foo {} - -trait S = ?Sized; - -// Nest a couple of levels deep: -trait _0 = S; -trait _1 = _0; - -// Straight list expansion: -type _T0 = dyn _1 + Foo; - -// In second position: -type _T1 = dyn Foo + _1; - -// ... and with an auto trait: -type _T2 = dyn Foo + Send + _1; - -// Twice: -trait _2 = _1 + _1; - -type _T3 = dyn _2 + Foo; - -fn main() {} diff --git a/tests/ui/traits/alias/only-maybe-bound.rs b/tests/ui/traits/alias/only-maybe-bound.rs deleted file mode 100644 index e4abf314e0a96..0000000000000 --- a/tests/ui/traits/alias/only-maybe-bound.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed, when just -// `?Sized` results from trait alias expansion. - -#![feature(trait_alias)] - -trait S = ?Sized; - -// Nest a couple of levels deep: -trait _0 = S; -trait _1 = _0; - -// Straight list expansion: -type _T0 = dyn _1; -//~^ ERROR at least one trait is required for an object type [E0224] - -// Twice: -trait _2 = _1 + _1; - -type _T1 = dyn _2; -//~^ ERROR at least one trait is required for an object type [E0224] - -fn main() {} diff --git a/tests/ui/traits/alias/only-maybe-bound.stderr b/tests/ui/traits/alias/only-maybe-bound.stderr deleted file mode 100644 index 175ec8120ecc6..0000000000000 --- a/tests/ui/traits/alias/only-maybe-bound.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0224]: at least one trait is required for an object type - --> $DIR/only-maybe-bound.rs:13:12 - | -LL | trait _1 = _0; - | -------- this alias does not contain a trait -... -LL | type _T0 = dyn _1; - | ^^^^^^ - -error[E0224]: at least one trait is required for an object type - --> $DIR/only-maybe-bound.rs:19:12 - | -LL | trait _2 = _1 + _1; - | -------- this alias does not contain a trait -LL | -LL | type _T1 = dyn _2; - | ^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/traits/alias/relaxed-bounds.rs b/tests/ui/traits/alias/relaxed-bounds.rs new file mode 100644 index 0000000000000..88e092c631622 --- /dev/null +++ b/tests/ui/traits/alias/relaxed-bounds.rs @@ -0,0 +1,19 @@ +#![feature(trait_alias)] + +// Ensure that relaxed bounds are not permitted in the `Self` bounds of trait aliases because trait +// aliases (like traits) aren't implicitly bounded by `Sized` so there's nothing to relax. + +trait Alias0 = ?Sized; //~ ERROR relaxed bounds are not permitted in trait alias bounds +trait Alias1 = where Self: ?Sized; //~ ERROR this relaxed bound is not permitted here + +trait Alias2 =; // OK +trait Alias3 = where T: ?Sized; // OK + +// Make sure that we don't permit "relaxing" trait aliases since we don't want to expand trait +// aliases during sized elaboration for simplicity as we'd need to handle relaxing arbitrary bounds +// (e.g., ones with modifiers, outlives-bounds, …) and where-clauses. + +trait SizedAlias = Sized; +fn take() {} //~ ERROR bound modifier `?` can only be applied to `Sized` + +fn main() {} diff --git a/tests/ui/traits/alias/relaxed-bounds.stderr b/tests/ui/traits/alias/relaxed-bounds.stderr new file mode 100644 index 0000000000000..d7782b723a305 --- /dev/null +++ b/tests/ui/traits/alias/relaxed-bounds.stderr @@ -0,0 +1,24 @@ +error: relaxed bounds are not permitted in trait alias bounds + --> $DIR/relaxed-bounds.rs:6:16 + | +LL | trait Alias0 = ?Sized; + | ^^^^^^ + | + = note: trait aliases are not implicitly bounded by `Sized`, so there is nothing to relax + +error: this relaxed bound is not permitted here + --> $DIR/relaxed-bounds.rs:7:28 + | +LL | trait Alias1 = where Self: ?Sized; + | ^^^^^^ + | + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item + +error: bound modifier `?` can only be applied to `Sized` + --> $DIR/relaxed-bounds.rs:17:12 + | +LL | fn take() {} + | ^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/traits/associated_type_bound/assoc-type-via-another-trait-issue-19479.rs b/tests/ui/traits/associated_type_bound/assoc-type-via-another-trait-issue-19479.rs new file mode 100644 index 0000000000000..f17a89bcb5f42 --- /dev/null +++ b/tests/ui/traits/associated_type_bound/assoc-type-via-another-trait-issue-19479.rs @@ -0,0 +1,24 @@ +//@ check-pass + +//! Tests that it's possible to define an associated type in a trait +//! using an associated type from type parameter bound trait in a blanket implementation. +//! +//! # Context +//! Original issue: https://github.com/rust-lang/rust/issues/19479 + +trait Base { + fn dummy(&self) { } +} +trait AssocA { + type X: Base; + fn dummy(&self) { } +} +trait AssocB { + type Y: Base; + fn dummy(&self) { } +} +impl AssocB for T { + type Y = ::X; +} + +fn main() {} diff --git a/tests/ui/traits/callback-trait-implementation-73229.rs b/tests/ui/traits/callback-trait-implementation-73229.rs new file mode 100644 index 0000000000000..56bcf7acdcdf5 --- /dev/null +++ b/tests/ui/traits/callback-trait-implementation-73229.rs @@ -0,0 +1,34 @@ +// https://github.com/rust-lang/rust/issues/73229 +//@ check-pass + +fn any() -> T { + loop {} +} + +trait Foo { + type V; +} + +trait Callback: Fn(&T, &T::V) {} +impl Callback for F {} + +struct Bar { + callback: Box>, +} + +impl Bar { + fn event(&self) { + (self.callback)(any(), any()); + } +} + +struct A; +struct B; +impl Foo for A { + type V = B; +} + +fn main() { + let foo = Bar:: { callback: Box::new(|_: &A, _: &B| ()) }; + foo.event(); +} diff --git a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs new file mode 100644 index 0000000000000..3c3815054502f --- /dev/null +++ b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs @@ -0,0 +1,19 @@ +//! Tests that compiler yields error E0191 when value with existing trait implementation +//! is cast as same `dyn` trait without specifying associated type at the cast. +//! +//! # Context +//! Original issue: https://github.com/rust-lang/rust/issues/21950 + +trait Add { + type Output; +} + +impl Add for i32 { + type Output = i32; +} + +fn main() { + let x = &10 as &dyn Add; //OK + let x = &10 as &dyn Add; + //~^ ERROR E0191 +} diff --git a/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr new file mode 100644 index 0000000000000..5f4974e6f237d --- /dev/null +++ b/tests/ui/traits/cast-as-dyn-trait-wo-assoc-type-issue-21950.stderr @@ -0,0 +1,12 @@ +error[E0191]: the value of the associated type `Output` in `Add` must be specified + --> $DIR/cast-as-dyn-trait-wo-assoc-type-issue-21950.rs:17:25 + | +LL | type Output; + | ----------- `Output` defined here +... +LL | let x = &10 as &dyn Add; + | ^^^ help: specify the associated type: `Add` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/traits/clone-unwind-rc-cleanup.rs b/tests/ui/traits/clone-unwind-rc-cleanup.rs index cd02050ea2746..dab48a1b4c6cf 100644 --- a/tests/ui/traits/clone-unwind-rc-cleanup.rs +++ b/tests/ui/traits/clone-unwind-rc-cleanup.rs @@ -2,6 +2,7 @@ //@ run-pass //@ needs-unwind +//@ ignore-backends: gcc #![allow(unused_variables)] #![allow(unused_imports)] diff --git a/tests/ui/traits/const-traits/parse-const-unsafe-trait.rs b/tests/ui/traits/const-traits/parse-const-unsafe-trait.rs new file mode 100644 index 0000000000000..3d62405d9ae20 --- /dev/null +++ b/tests/ui/traits/const-traits/parse-const-unsafe-trait.rs @@ -0,0 +1,13 @@ +// Test that `const unsafe trait` and `const unsafe auto trait` works. + +//@ check-pass + +#![feature(const_trait_impl)] +#![feature(auto_traits)] + +pub const unsafe trait Owo {} +const unsafe trait OwO {} +pub const unsafe auto trait UwU {} +const unsafe auto trait Uwu {} + +fn main() {} diff --git a/tests/ui/traits/core-marker-name-shadowing-issue-2284.rs b/tests/ui/traits/core-marker-name-shadowing-issue-2284.rs new file mode 100644 index 0000000000000..e5d083ac8c3fb --- /dev/null +++ b/tests/ui/traits/core-marker-name-shadowing-issue-2284.rs @@ -0,0 +1,21 @@ +//@ run-pass +#![allow(dead_code)] + +//! Tests that user-defined trait is prioritized in compile time over +//! the core::marker trait with the same name, allowing shadowing core traits. +//! +//! # Context +//! Original issue: https://github.com/rust-lang/rust/issues/2284 +//! Original fix pull request: https://github.com/rust-lang/rust/pull/3792 + + +trait Send { + fn f(&self); +} + +fn f(t: T) { + t.f(); +} + +pub fn main() { +} diff --git a/tests/ui/generics/duplicate-generic-parameter-error-86756.rs b/tests/ui/traits/duplicate-generic-parameter-error-86756.rs similarity index 100% rename from tests/ui/generics/duplicate-generic-parameter-error-86756.rs rename to tests/ui/traits/duplicate-generic-parameter-error-86756.rs diff --git a/tests/ui/generics/duplicate-generic-parameter-error-86756.stderr b/tests/ui/traits/duplicate-generic-parameter-error-86756.stderr similarity index 100% rename from tests/ui/generics/duplicate-generic-parameter-error-86756.stderr rename to tests/ui/traits/duplicate-generic-parameter-error-86756.stderr diff --git a/tests/ui/traits/generic-cow-inference-regression.rs b/tests/ui/traits/generic-cow-inference-regression.rs new file mode 100644 index 0000000000000..6fd4715f85bbd --- /dev/null +++ b/tests/ui/traits/generic-cow-inference-regression.rs @@ -0,0 +1,20 @@ +//@ run-pass + +// regression test for #147964: +// constification of these traits resulted in inference errors due to additional where clauses + +use std::borrow::{Cow, Borrow}; + +pub fn generic_deref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = &cow; +} + +pub fn generic_borrow<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.borrow(); +} + +pub fn generic_as_ref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.as_ref(); +} + +fn main() {} diff --git a/tests/ui/traits/inheritance/supertrait-operator-issue-18088.rs b/tests/ui/traits/inheritance/supertrait-operator-issue-18088.rs new file mode 100644 index 0000000000000..8bd45cd54a445 --- /dev/null +++ b/tests/ui/traits/inheritance/supertrait-operator-issue-18088.rs @@ -0,0 +1,13 @@ +//@ check-pass + +//! Tests that operators from supertrait are available directly on `self` for an inheritor trait. +//! +//! # Context +//! Original issue: https://github.com/rust-lang/rust/issues/18088 + +pub trait Indexable: std::ops::Index { + fn index2(&self, i: usize) -> &T { + &self[i] + } +} +fn main() {} diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.rs b/tests/ui/traits/next-solver/alias-bound-unsound.rs index 0236826c3ed29..57fc88d87cf65 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.rs +++ b/tests/ui/traits/next-solver/alias-bound-unsound.rs @@ -4,6 +4,10 @@ #![feature(trivial_bounds)] +// we use identity instead of drop because the presence of [const] Destruct means that there +// are additional bounds on the function, which result in additional errors +use std::convert::identity; + trait Foo { type Item: Copy where @@ -21,7 +25,7 @@ impl Foo for () { fn main() { let x = String::from("hello, world"); - drop(<() as Foo>::copy_me(&x)); + let _ = identity(<() as Foo>::copy_me(&x)); //~^ ERROR overflow evaluating the requirement `String <: <() as Foo>::Item` //~| ERROR overflow evaluating the requirement `<() as Foo>::Item well-formed` //~| ERROR overflow evaluating the requirement `&<() as Foo>::Item well-formed` diff --git a/tests/ui/traits/next-solver/alias-bound-unsound.stderr b/tests/ui/traits/next-solver/alias-bound-unsound.stderr index 7e3737d120bf4..1079c27fa815f 100644 --- a/tests/ui/traits/next-solver/alias-bound-unsound.stderr +++ b/tests/ui/traits/next-solver/alias-bound-unsound.stderr @@ -1,11 +1,11 @@ error[E0275]: overflow evaluating the requirement `String: Copy` - --> $DIR/alias-bound-unsound.rs:18:38 + --> $DIR/alias-bound-unsound.rs:22:38 | LL | type Item = String where String: Copy; | ^^^^ | note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type - --> $DIR/alias-bound-unsound.rs:8:10 + --> $DIR/alias-bound-unsound.rs:12:10 | LL | trait Foo { | --- in this trait @@ -13,50 +13,50 @@ LL | type Item: Copy | ^^^^ this trait's associated type doesn't have the requirement `String: Copy` error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item` - --> $DIR/alias-bound-unsound.rs:24:31 + --> $DIR/alias-bound-unsound.rs:28:43 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` - --> $DIR/alias-bound-unsound.rs:24:10 + --> $DIR/alias-bound-unsound.rs:28:22 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` - --> $DIR/alias-bound-unsound.rs:24:10 + --> $DIR/alias-bound-unsound.rs:28:22 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed` - --> $DIR/alias-bound-unsound.rs:24:31 + --> $DIR/alias-bound-unsound.rs:28:43 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed` - --> $DIR/alias-bound-unsound.rs:24:10 + --> $DIR/alias-bound-unsound.rs:28:22 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` - --> $DIR/alias-bound-unsound.rs:24:10 + --> $DIR/alias-bound-unsound.rs:28:22 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` - --> $DIR/alias-bound-unsound.rs:24:31 + --> $DIR/alias-bound-unsound.rs:28:43 | -LL | drop(<() as Foo>::copy_me(&x)); - | ^^ +LL | let _ = identity(<() as Foo>::copy_me(&x)); + | ^^ error: aborting due to 8 previous errors diff --git a/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.rs b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.rs new file mode 100644 index 0000000000000..aa5893d621cdb --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -Znext-solver +#![feature(rustc_attrs)] +#![rustc_no_implicit_bounds] + +// A regression test making sure that when forcing dependent +// provisional cache entries to ambiguous, we use the `MaybeCause` +// of the cycle head. We ended up trying to use the current result +// of the provisional cache entry, which is incorrect and caused an +// ICE when trying to unwrap it. + +struct Root(T); +struct Head(T); +struct Error(T); +struct NotImplemented(T); + +#[rustc_coinductive] +trait Trait {} +impl Trait for Root +where + Head: Trait, +{} + +impl Trait for Head +where + Root: Trait, + T: Trait, // ambiguous +{} + +impl Trait for Head +where + Error: Trait, + NotImplemented: Trait, +{} + +impl Trait for Error +where + Head: Trait, + NotImplemented: Trait, +{} + +fn impls_trait() {} +fn main() { + impls_trait::>() //~ ERROR type annotations needed +} diff --git a/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr new file mode 100644 index 0000000000000..dd4049a66d0b4 --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/forced_ambiguity-use-head-maybe-cause.stderr @@ -0,0 +1,27 @@ +error[E0283]: type annotations needed + --> $DIR/forced_ambiguity-use-head-maybe-cause.rs:43:19 + | +LL | impls_trait::>() + | ^^^^^^^ cannot infer type for struct `Head<_>` + | + = note: cannot satisfy `Head<_>: Trait` + = help: the trait `Trait` is implemented for `Head` +note: required for `Root<_>` to implement `Trait` + --> $DIR/forced_ambiguity-use-head-maybe-cause.rs:18:9 + | +LL | impl Trait for Root + | ^^^^^ ^^^^^^^ +LL | where +LL | Head: Trait, + | ----- unsatisfied trait bound introduced here + = note: 8 redundant requirements hidden + = note: required for `Root<_>` to implement `Trait` +note: required by a bound in `impls_trait` + --> $DIR/forced_ambiguity-use-head-maybe-cause.rs:41:19 + | +LL | fn impls_trait() {} + | ^^^^^ required by this bound in `impls_trait` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs b/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs new file mode 100644 index 0000000000000..9a33ae536442f --- /dev/null +++ b/tests/ui/traits/next-solver/cycles/ignore-head-usages-provisional-cache.rs @@ -0,0 +1,55 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// A regression test for trait-system-refactor-initiative#232. We've +// previously incorrectly rebased provisional cache entries even if +// the cycle head didn't reach a fixpoint as it did not depend on any +// cycles itself. +// +// Just because the result of a goal does not depend on its own provisional +// result, it does not mean its nested goals don't depend on its result. +struct B; +struct C; +struct D; + +pub trait Trait { + type Output; +} +macro_rules! k { + ($t:ty) => { + <$t as Trait>::Output + }; +} + +trait CallB { + type Output; + type Return; +} + +trait CallC { + type Output; + type Return; +} + +trait CallD { + type Output; +} + +fn foo() +where + X: Trait, + Y: Trait, + D: CallD, + C: CallC<>::Output>, + >::Output>>::Output: Trait, + B: CallB< + >::Output>>::Return, + >::Output>>::Output, + >, + >::Output>>::Return, + >::Output>>::Output, + >>::Output: Trait, +{ +} +fn main() {} diff --git a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr index 4934d8bf6fa07..4a87aa3e2f128 100644 --- a/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr +++ b/tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.stderr @@ -17,6 +17,13 @@ LL | impl Trait for T { | ----- ^^^^^^^^ ^ | | | unsatisfied trait bound introduced here +note: required by a bound in `Bound` + --> $DIR/normalizes-to-is-not-productive.rs:8:1 + | +LL | / trait Bound { +LL | | fn method(); +LL | | } + | |_^ required by this bound in `Bound` error[E0277]: the trait bound `Foo: Bound` is not satisfied --> $DIR/normalizes-to-is-not-productive.rs:47:19 diff --git a/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs b/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs new file mode 100644 index 0000000000000..679d6b1fb165a --- /dev/null +++ b/tests/ui/traits/next-solver/forced-ambiguity-typenum-ice.rs @@ -0,0 +1,60 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#105. We previously encountered +// an ICE in typenum as `forced_ambiguity` failed. While this test no longer causes +// `forced_ambiguity` to error, we still want to use it as a regression test. + +pub struct UInt { + _msb: U, + _lsb: B, +} +pub struct B1; +pub trait Sub { + type Output; +} +impl Sub for UInt, B1> { + type Output = (); +} +impl Sub for UInt +where + U: Sub, + U::Output: Send, +{ + type Output = (); +} + +pub trait Op { + fn op(&self) { + unimplemented!() + } +} +trait OpIf {} + +impl Op, I> for () +where + N: Sub, + (): OpIf, N::Output>, I>, +{ +} +impl OpIf> for () +where + UInt: Sub, + (): Op as Sub>::Output>, +{ +} +impl OpIf for () where R: Sub {} + +pub trait Compute { + type Output; +} + +pub fn repro() +where + UInt: Compute, + as Compute>::Output: Sub, + (): Op, (), ()>, +{ + ().op(); +} +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/hidden-types-equate-before-fallback.rs b/tests/ui/traits/next-solver/opaques/hidden-types-equate-before-fallback.rs new file mode 100644 index 0000000000000..0bd01e66b02b8 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/hidden-types-equate-before-fallback.rs @@ -0,0 +1,44 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#240. Hidden types should +// equate *before* inference var fallback, otherwise we can get mismatched types. + +#[derive(Clone, Copy)] +struct FileSystem; +impl FileSystem { + fn build(self, commands: T) -> Option { + match false { + true => Some(commands), + false => { + drop(match self.build::<_>(commands) { + Some(x) => x, + None => return None, + }); + panic!() + }, + } + } +} + +fn build2() -> impl Sized { + if false { + build2::() + } else { + loop {} + }; + 1u32 +} + +fn build3<'a>() -> impl Sized + use<'a> { + if false { + build3() + } else { + loop {} + }; + 1u32 +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs new file mode 100644 index 0000000000000..e35e48dfcecbd --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-1.rs @@ -0,0 +1,25 @@ +//@ ignore-compare-mode-next-solver +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#220. Builtin `Fn`-trait +// candidates required `for<'latebound> Output<'latebound>: Sized` which ended +// up resulting in overflow if the return type is an opaque in the defining scope. +// +// We now eagerly instantiate the binder of the function definition which avoids +// that overflow by relating the lifetime of the opaque to something from the +// input. +fn flat_map(_: F, _: G) +where + F: FnOnce(T) -> I, + I: Iterator, + G: Fn(::Item) -> usize, +{ +} + +fn rarw<'a>(_: &'a ()) -> impl Iterator { + flat_map(rarw, |x| x.len()); + std::iter::empty() +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs new file mode 100644 index 0000000000000..1d64e422d8938 --- /dev/null +++ b/tests/ui/traits/next-solver/opaques/overflow-hr-fn-trait-sized-2.rs @@ -0,0 +1,14 @@ +//@ ignore-compare-mode-next-solver +//@ compile-flags: -Znext-solver +//@ check-pass + +// Regression test for trait-system-refactor-initiative#204, see +// the sibling test for more details. + +fn constrain<'a, F: FnOnce(&'a ())>(_: F) {} +fn foo<'a>(_: &'a ()) -> impl Sized + use<'a> { + constrain(foo); + () +} + +fn main() {} diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs index 6567f2752404a..2f108daf1e5ab 100644 --- a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs +++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs @@ -1,7 +1,7 @@ //@ compile-flags: -Znext-solver //@ check-pass -// Fixes a regression in icu_provider_adaptors where we weren't normalizing the +// Fixes a regression in icu_provider_adapters where we weren't normalizing the // return type of a function type before performing a `Ty::builtin_deref` call, // leading to an ICE. diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr index 5294a072d3123..d79e465b3e387 100644 --- a/tests/ui/traits/next-solver/well-formed-in-relate.stderr +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -12,6 +12,8 @@ LL | x = unconstrained_map(); where A: Tuple, F: Fn, F: ?Sized; - impl Fn for Box where Args: Tuple, F: Fn, A: Allocator, F: ?Sized; + - impl Fn for Exclusive + where F: Sync, F: Fn, Args: Tuple; note: required by a bound in `unconstrained_map` --> $DIR/well-formed-in-relate.rs:21:25 | diff --git a/tests/ui/traits/next-solver/writeback-predicate-bound-region.rs b/tests/ui/traits/next-solver/writeback-predicate-bound-region.rs new file mode 100644 index 0000000000000..a7ed5dbcf086d --- /dev/null +++ b/tests/ui/traits/next-solver/writeback-predicate-bound-region.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ check-pass +//@ compile-flags: -Znext-solver + +// This previously ICE'd during writeback when resolving +// the stalled coroutine predicate due to its bound lifetime. + +trait Trait<'a> {} +impl<'a, T: Send> Trait<'a> for T {} + +fn is_trait Trait<'a>>(_: T) {} +fn main() { + is_trait(async {}) +} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.rs b/tests/ui/traits/resolve-impl-before-constrain-check.rs index 87f9c241e402b..00005a7209363 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.rs +++ b/tests/ui/traits/resolve-impl-before-constrain-check.rs @@ -15,6 +15,7 @@ use foo::*; fn test() -> impl Sized { <() as Callable>::call() +//~^ ERROR type annotations needed } fn main() {} diff --git a/tests/ui/traits/resolve-impl-before-constrain-check.stderr b/tests/ui/traits/resolve-impl-before-constrain-check.stderr index e8e569ba625ee..13fbfdb855cbf 100644 --- a/tests/ui/traits/resolve-impl-before-constrain-check.stderr +++ b/tests/ui/traits/resolve-impl-before-constrain-check.stderr @@ -4,6 +4,13 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self LL | impl Callable for () { | ^ unconstrained type parameter -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/resolve-impl-before-constrain-check.rs:17:6 + | +LL | <() as Callable>::call() + | ^^ cannot infer type for type parameter `V` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0282. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs index 723179302e30a..c5c2c27b28267 100644 --- a/tests/ui/traits/solver-cycles/129541-recursive-struct.rs +++ b/tests/ui/traits/solver-cycles/129541-recursive-struct.rs @@ -1,3 +1,4 @@ +//~ ERROR reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` // Regression test for #129541 //@ revisions: unique_curr unique_next multiple_curr multiple_next @@ -24,5 +25,3 @@ struct Hello { } fn main() {} - -//~? ERROR reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc` diff --git a/tests/ui/traits/trait-implementation-ambiguity-69602.rs b/tests/ui/traits/trait-implementation-ambiguity-69602.rs new file mode 100644 index 0000000000000..74198b97fd80b --- /dev/null +++ b/tests/ui/traits/trait-implementation-ambiguity-69602.rs @@ -0,0 +1,23 @@ +// https://github.com/rust-lang/rust/issues/69602 +trait TraitA { + const VALUE: usize; +} + +struct A; +impl TraitA for A { + const VALUE: usize = 0; +} + +trait TraitB { + type MyA: TraitA; + const VALUE: usize = Self::MyA::VALUE; +} + +struct B; +impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA` + type M = A; //~ ERROR type `M` is not a member of trait `TraitB` +} + +fn main() { + let _ = [0; B::VALUE]; +} diff --git a/tests/ui/traits/trait-implementation-ambiguity-69602.stderr b/tests/ui/traits/trait-implementation-ambiguity-69602.stderr new file mode 100644 index 0000000000000..c771740bec415 --- /dev/null +++ b/tests/ui/traits/trait-implementation-ambiguity-69602.stderr @@ -0,0 +1,19 @@ +error[E0437]: type `M` is not a member of trait `TraitB` + --> $DIR/trait-implementation-ambiguity-69602.rs:18:5 + | +LL | type M = A; + | ^^^^^^^^^^^^^ not a member of trait `TraitB` + +error[E0046]: not all trait items implemented, missing: `MyA` + --> $DIR/trait-implementation-ambiguity-69602.rs:17:1 + | +LL | type MyA: TraitA; + | ---------------- `MyA` from trait +... +LL | impl TraitB for B { + | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0046, E0437. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/traits/trait-implementation-for-non-local-types-67535.rs b/tests/ui/traits/trait-implementation-for-non-local-types-67535.rs new file mode 100644 index 0000000000000..198576ba5357d --- /dev/null +++ b/tests/ui/traits/trait-implementation-for-non-local-types-67535.rs @@ -0,0 +1,23 @@ +// https://github.com/rust-lang/rust/issues/67535 +fn main() {} + +impl std::ops::AddAssign for () { + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + fn add_assign(&self, other: ()) -> () { + () + } +} + +impl std::ops::AddAssign for [(); 1] { + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + fn add_assign(&self, other: [(); 1]) -> [(); 1] { + [()] + } +} + +impl std::ops::AddAssign for &[u8] { + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + fn add_assign(&self, other: &[u8]) -> &[u8] { + self + } +} diff --git a/tests/ui/traits/trait-implementation-for-non-local-types-67535.stderr b/tests/ui/traits/trait-implementation-for-non-local-types-67535.stderr new file mode 100644 index 0000000000000..ef20f0c60ce19 --- /dev/null +++ b/tests/ui/traits/trait-implementation-for-non-local-types-67535.stderr @@ -0,0 +1,42 @@ +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/trait-implementation-for-non-local-types-67535.rs:4:1 + | +LL | impl std::ops::AddAssign for () { + | ^^^^^-------------------^^^^^-- + | | | + | | this is not defined in the current crate because tuples are always foreign + | this is not defined in the current crate because this is a foreign trait + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/trait-implementation-for-non-local-types-67535.rs:11:1 + | +LL | impl std::ops::AddAssign for [(); 1] { + | ^^^^^-------------------^^^^^------- + | | | + | | this is not defined in the current crate because arrays are always foreign + | this is not defined in the current crate because this is a foreign trait + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types + --> $DIR/trait-implementation-for-non-local-types-67535.rs:18:1 + | +LL | impl std::ops::AddAssign for &[u8] { + | ^^^^^-------------------^^^^^----- + | | | + | | this is not defined in the current crate because slices are always foreign + | this is not defined in the current crate because this is a foreign trait + | + = note: impl doesn't have any local type before any uncovered type parameters + = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules + = note: define and implement a trait or new type instead + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0117`. diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs index 2760c1696b56d..f603ff1ec80ec 100644 --- a/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs +++ b/tests/ui/traits/trait-upcasting/illegal-upcast-to-impl-opaque.rs @@ -1,12 +1,5 @@ //@ revisions: current next //@[next] compile-flags: -Znext-solver -//@[next] failure-status: 101 -//@[next] known-bug: unknown -//@[next] normalize-stderr: "note: .*\n\n" -> "" -//@[next] normalize-stderr: "thread 'rustc' panicked.*\n.*\n" -> "" -//@[next] normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[next] normalize-stderr: "delayed at .*" -> "" -//@[next] rustc-env:RUST_BACKTRACE=0 //@ check-pass trait Super { diff --git a/tests/ui/traits/wf-object/only-maybe-bound.rs b/tests/ui/traits/wf-object/only-maybe-bound.rs deleted file mode 100644 index 96360e0331cdb..0000000000000 --- a/tests/ui/traits/wf-object/only-maybe-bound.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Test that `dyn ?Sized` (i.e., a trait object with only a maybe buond) is not allowed. - -type _0 = dyn ?Sized; -//~^ ERROR at least one trait is required for an object type [E0224] -//~| ERROR relaxed bounds are not permitted in trait object types - -fn main() {} diff --git a/tests/ui/traits/wf-object/only-maybe-bound.stderr b/tests/ui/traits/wf-object/only-maybe-bound.stderr deleted file mode 100644 index 6ae4568c699a7..0000000000000 --- a/tests/ui/traits/wf-object/only-maybe-bound.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: relaxed bounds are not permitted in trait object types - --> $DIR/only-maybe-bound.rs:3:15 - | -LL | type _0 = dyn ?Sized; - | ^^^^^^ - -error[E0224]: at least one trait is required for an object type - --> $DIR/only-maybe-bound.rs:3:11 - | -LL | type _0 = dyn ?Sized; - | ^^^^^^^^^^ - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr index 7b69820a3c6df..164c57a362442 100644 --- a/tests/ui/transmutability/alignment/align-fail.stderr +++ b/tests/ui/transmutability/alignment/align-fail.stderr @@ -1,8 +1,8 @@ error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` --> $DIR/align-fail.rs:21:55 | -LL | ...tatic [u8; 0], &'static [u16; 0]>(); - | ^^^^^^^^^^^^^^^^^ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) +LL | ...ic [u8; 0], &'static [u16; 0]>(); + | ^^^^^^^^^^^^^^^^^ the minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2) | note: required by a bound in `is_maybe_transmutable` --> $DIR/align-fail.rs:9:14 diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr index c0f197ec48c37..222edfb90a7b3 100644 --- a/tests/ui/type-alias-impl-trait/issue-77179.stderr +++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr @@ -11,10 +11,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/issue-77179.rs:8:22 | LL | fn test() -> Pointer<_> { - | --------^- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `Pointer` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test() -> Pointer<_> { +LL + fn test() -> Pointer { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/issue-77179.rs:19:25 diff --git a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr index bbdd3923821ff..37bde4b18a45b 100644 --- a/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr +++ b/tests/ui/type-alias-impl-trait/method_resolution_trait_method_from_opaque.next.stderr @@ -1,8 +1,14 @@ error[E0282]: type annotations needed - --> $DIR/method_resolution_trait_method_from_opaque.rs:28:9 + --> $DIR/method_resolution_trait_method_from_opaque.rs:28:18 | LL | self.bar.next().unwrap(); - | ^^^^^^^^ cannot infer type + | ^^^^ + | +help: try using a fully qualified path to specify the expected types + | +LL - self.bar.next().unwrap(); +LL + <_ as Iterator>::next(&mut self.bar).unwrap(); + | error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs new file mode 100644 index 0000000000000..5541c5267f39a --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.rs @@ -0,0 +1,19 @@ +//! Regression test for ICE #139556 + +#![feature(type_alias_impl_trait)] + +trait T {} + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S {} + +#[define_opaque(Alias)] +fn with_positive(fun: impl Fn(Alias<'_>)) { +//~^ WARN: function cannot return without recursing + with_positive(|&n| ()); + //~^ ERROR: cannot move out of a shared reference +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr new file mode 100644 index 0000000000000..e1fdd222ee147 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration-2.stderr @@ -0,0 +1,30 @@ +warning: function cannot return without recursing + --> $DIR/recursive-drop-elaboration-2.rs:13:1 + | +LL | fn with_positive(fun: impl Fn(Alias<'_>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | with_positive(|&n| ()); + | ---------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error[E0507]: cannot move out of a shared reference + --> $DIR/recursive-drop-elaboration-2.rs:15:20 + | +LL | with_positive(|&n| ()); + | ^- + | | + | data moved here + | move occurs because `n` has type `S`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - with_positive(|&n| ()); +LL + with_positive(|n| ()); + | + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs new file mode 100644 index 0000000000000..dd28732ebb281 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.rs @@ -0,0 +1,24 @@ +//! Regression test for #122904. + +#![feature(type_alias_impl_trait)] + +trait T {} + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S {} + +#[define_opaque(Alias)] +fn with_positive(fun: impl Fn(Alias<'_>)) { +//~^ WARN: function cannot return without recursing + with_positive(|&n| ()); + //~^ ERROR: cannot move out of a shared reference +} + +#[define_opaque(Alias)] +fn main(_: Alias<'_>) { +//~^ ERROR: `main` function has wrong type [E0580] + with_positive(|&a| ()); + //~^ ERROR: cannot move out of a shared reference +} diff --git a/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr new file mode 100644 index 0000000000000..8b5dc950afdde --- /dev/null +++ b/tests/ui/type-alias-impl-trait/recursive-drop-elaboration.stderr @@ -0,0 +1,58 @@ +warning: function cannot return without recursing + --> $DIR/recursive-drop-elaboration.rs:13:1 + | +LL | fn with_positive(fun: impl Fn(Alias<'_>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | with_positive(|&n| ()); + | ---------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error[E0507]: cannot move out of a shared reference + --> $DIR/recursive-drop-elaboration.rs:15:20 + | +LL | with_positive(|&n| ()); + | ^- + | | + | data moved here + | move occurs because `n` has type `S`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - with_positive(|&n| ()); +LL + with_positive(|n| ()); + | + +error[E0507]: cannot move out of a shared reference + --> $DIR/recursive-drop-elaboration.rs:22:20 + | +LL | with_positive(|&a| ()); + | ^- + | | + | data moved here + | move occurs because `a` has type `S`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - with_positive(|&a| ()); +LL + with_positive(|a| ()); + | + +error[E0580]: `main` function has wrong type + --> $DIR/recursive-drop-elaboration.rs:20:1 + | +LL | type Alias<'a> = impl T; + | ------ the found opaque type +... +LL | fn main(_: Alias<'_>) { + | ^^^^^^^^^^^^^^^^^^^^^ incorrect number of function parameters + | + = note: expected signature `fn()` + found signature `for<'a> fn(Alias<'a>)` + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0507, E0580. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs new file mode 100644 index 0000000000000..c0fb9007865a5 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.rs @@ -0,0 +1,27 @@ +//! Regression test for #125185 +//@ compile-flags: -Zvalidate-mir + +#![feature(type_alias_impl_trait)] + +type Foo = impl Send; + +struct A; + +#[define_opaque(Foo)] +const fn foo() -> Foo { + value() + //~^ ERROR: cannot find function `value` in this scope +} + +const VALUE: Foo = foo(); + +#[define_opaque(Foo)] +fn test(foo: Foo, f: impl for<'b> FnMut()) { + match VALUE { + 0 | 0 => {} + + _ => (), + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr new file mode 100644 index 0000000000000..1cb33eabd902e --- /dev/null +++ b/tests/ui/type-alias-impl-trait/type-error-drop-elaboration.stderr @@ -0,0 +1,12 @@ +error[E0425]: cannot find function `value` in this scope + --> $DIR/type-error-drop-elaboration.rs:12:5 + | +LL | value() + | ^^^^^ help: a constant with a similar name exists: `VALUE` +... +LL | const VALUE: Foo = foo(); + | ------------------------- similarly named constant `VALUE` defined here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/type-inference/box_has_sigdrop.rs b/tests/ui/type-inference/box_has_sigdrop.rs new file mode 100644 index 0000000000000..3e801197a78e6 --- /dev/null +++ b/tests/ui/type-inference/box_has_sigdrop.rs @@ -0,0 +1,9 @@ +//@ should-fail +//@ compile-flags: -Wrust-2021-incompatible-closure-captures +// Inference, canonicalization, and significant drops should work nicely together. +// Related issue: #86868 + +fn main() { + let mut state = 0; + Box::new(move || state) +} diff --git a/tests/ui/type-inference/box_has_sigdrop.stderr b/tests/ui/type-inference/box_has_sigdrop.stderr new file mode 100644 index 0000000000000..b61b6322c107f --- /dev/null +++ b/tests/ui/type-inference/box_has_sigdrop.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/box_has_sigdrop.rs:8:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | let mut state = 0; +LL | Box::new(move || state) + | ^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` + | | + | expected `()`, found `Box<{closure@box_has_sigdrop.rs:8:14}>` + | + = note: expected unit type `()` + found struct `Box<{closure@$DIR/box_has_sigdrop.rs:8:14: 8:21}>` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-inference/dropper_has_sigdrop.rs b/tests/ui/type-inference/dropper_has_sigdrop.rs new file mode 100644 index 0000000000000..c3d835cfe16f8 --- /dev/null +++ b/tests/ui/type-inference/dropper_has_sigdrop.rs @@ -0,0 +1,18 @@ +//@ run-pass +// Inference, canonicalization, and significant drops should work nicely together. +// Related issue: #86868 + +#[clippy::has_significant_drop] +struct DropGuy {} + +fn creator() -> DropGuy { + DropGuy {} +} + +fn dropper() { + let _ = creator(); +} + +fn main() { + dropper(); +} diff --git a/tests/ui/type/issue-100584.stderr b/tests/ui/type/issue-100584.stderr index 1523bdda7614b..29b567eb74405 100644 --- a/tests/ui/type/issue-100584.stderr +++ b/tests/ui/type/issue-100584.stderr @@ -2,7 +2,7 @@ error: unused variable: `xyza` --> $DIR/issue-100584.rs:2:8 | LL | fn foo(xyza: &str) { - | ^^^^ unused variable + | ^^^^ LL | LL | let _ = "{xyza}"; | -------- you might have meant to use string interpolation in this string literal @@ -26,7 +26,7 @@ error: unused variable: `xyza` --> $DIR/issue-100584.rs:7:9 | LL | fn foo3(xyza: &str) { - | ^^^^ unused variable + | ^^^^ LL | LL | let _ = "aaa{xyza}bbb"; | -------------- you might have meant to use string interpolation in this string literal diff --git a/tests/ui/type/pattern_types/bad_pat.rs b/tests/ui/type/pattern_types/bad_pat.rs index 549b0d11dd187..7e2b4cb996f27 100644 --- a/tests/ui/type/pattern_types/bad_pat.rs +++ b/tests/ui/type/pattern_types/bad_pat.rs @@ -10,4 +10,15 @@ type Positive2 = pattern_type!(i32 is 0..=); type Wild = pattern_type!(() is _); //~^ ERROR: pattern not supported in pattern types +// FIXME: confusing diagnostic because `not` can be a binding +type NonNull = pattern_type!(*const () is not null); +//~^ ERROR: expected one of `@` or `|`, found `null` +//~| ERROR: pattern not supported in pattern types + +type NonNull2 = pattern_type!(*const () is !nil); +//~^ ERROR: expected `null`, found `nil` + +// FIXME: reject with a type mismatch +type Mismatch2 = pattern_type!(() is !null); + fn main() {} diff --git a/tests/ui/type/pattern_types/bad_pat.stderr b/tests/ui/type/pattern_types/bad_pat.stderr index d2a5a20bf89b6..e72279542280c 100644 --- a/tests/ui/type/pattern_types/bad_pat.stderr +++ b/tests/ui/type/pattern_types/bad_pat.stderr @@ -30,6 +30,24 @@ error: pattern not supported in pattern types LL | type Wild = pattern_type!(() is _); | ^ -error: aborting due to 3 previous errors +error: pattern not supported in pattern types + --> $DIR/bad_pat.rs:14:43 + | +LL | type NonNull = pattern_type!(*const () is not null); + | ^^^ + +error: expected one of `@` or `|`, found `null` + --> $DIR/bad_pat.rs:14:47 + | +LL | type NonNull = pattern_type!(*const () is not null); + | ^^^^ expected one of `@` or `|` + +error: expected `null`, found `nil` + --> $DIR/bad_pat.rs:18:45 + | +LL | type NonNull2 = pattern_type!(*const () is !nil); + | ^^^ expected `null` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0586`. diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs index 79d46c010d733..f5eb90e94d4fd 100644 --- a/tests/ui/type/pattern_types/const_generics.rs +++ b/tests/ui/type/pattern_types/const_generics.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(pattern_types, generic_pattern_types, pattern_type_macro)] #![expect(incomplete_features)] diff --git a/tests/ui/type/pattern_types/non_null.rs b/tests/ui/type/pattern_types/non_null.rs new file mode 100644 index 0000000000000..7e86b8b684d17 --- /dev/null +++ b/tests/ui/type/pattern_types/non_null.rs @@ -0,0 +1,21 @@ +//! Show that pattern-types non-null is the same as libstd's + +//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED" +//@ only-64bit + +#![feature(pattern_type_macro, pattern_types, rustc_attrs)] + +use std::pat::pattern_type; + +#[rustc_layout(debug)] +type NonNull = pattern_type!(*const T is !null); //~ ERROR layout_of + +#[rustc_layout(debug)] +type Test = Option>; //~ ERROR layout_of + +#[rustc_layout(debug)] +type Wide = pattern_type!(*const [u8] is !null); //~ ERROR layout_of + +const _: () = assert!(size_of::>() == size_of::>>()); + +fn main() {} diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr new file mode 100644 index 0000000000000..ad61e9a591473 --- /dev/null +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -0,0 +1,218 @@ +error: layout_of((*const T) is !null) = Layout { + size: Size(8 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Scalar( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + } + --> $DIR/non_null.rs:11:1 + | +LL | type NonNull = pattern_type!(*const T is !null); + | ^^^^^^^^^^^^^^^ + +error: layout_of(Option<(*const ()) is !null>) = Layout { + size: Size(8 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Scalar( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: (..=0) | (1..), + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: None, + uninhabited: false, + variants: Multiple { + tag: Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: (..=0) | (1..), + }, + tag_encoding: Niche { + untagged_variant: 1, + niche_variants: 0..=0, + niche_start: 0, + }, + tag_field: 0, + variants: [ + Layout { + size: Size(0 bytes), + align: AbiAlign { + abi: Align(1 bytes), + }, + backend_repr: Memory { + sized: true, + }, + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + largest_niche: None, + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(1 bytes), + randomization_seed: $SEED, + }, + Layout { + size: Size(8 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: Scalar( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + ), + uninhabited: false, + variants: Single { + index: 1, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + }, + ], + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + } + --> $DIR/non_null.rs:14:1 + | +LL | type Test = Option>; + | ^^^^^^^^^ + +error: layout_of((*const [u8]) is !null) = Layout { + size: Size(16 bytes), + align: AbiAlign { + abi: Align(8 bytes), + }, + backend_repr: ScalarPair( + Initialized { + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + Initialized { + value: Int( + I64, + false, + ), + valid_range: 0..=18446744073709551615, + }, + ), + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, + largest_niche: Some( + Niche { + offset: Size(0 bytes), + value: Pointer( + AddressSpace( + 0, + ), + ), + valid_range: 1..=18446744073709551615, + }, + ), + uninhabited: false, + variants: Single { + index: 0, + }, + max_repr_align: None, + unadjusted_abi_align: Align(8 bytes), + randomization_seed: $SEED, + } + --> $DIR/non_null.rs:17:1 + | +LL | type Wide = pattern_type!(*const [u8] is !null); + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/type/pattern_types/or_patterns.stderr b/tests/ui/type/pattern_types/or_patterns.stderr index a417e502e3562..adc7320829b95 100644 --- a/tests/ui/type/pattern_types/or_patterns.stderr +++ b/tests/ui/type/pattern_types/or_patterns.stderr @@ -53,7 +53,14 @@ error: layout_of((i8) is (i8::MIN..=-1 | 1..)) = Layout { valid_range: 1..=255, }, ), - fields: Primitive, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, largest_niche: Some( Niche { offset: Size(0 bytes), @@ -91,7 +98,14 @@ error: layout_of((i8) is (i8::MIN..=-2 | 0..)) = Layout { valid_range: 0..=254, }, ), - fields: Primitive, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, largest_niche: Some( Niche { offset: Size(0 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index abd8b87fffc6f..c9a846e22f581 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -57,7 +57,14 @@ error: layout_of((u32) is 1..) = Layout { valid_range: 1..=4294967295, }, ), - fields: Primitive, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, largest_niche: Some( Niche { offset: Size(0 bytes), @@ -390,7 +397,14 @@ error: layout_of((i8) is -10..=10) = Layout { valid_range: (..=10) | (246..), }, ), - fields: Primitive, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, largest_niche: Some( Niche { offset: Size(0 bytes), @@ -428,7 +442,14 @@ error: layout_of((i8) is i8::MIN..=0) = Layout { valid_range: (..=0) | (128..), }, ), - fields: Primitive, + fields: Arbitrary { + offsets: [ + Size(0 bytes), + ], + memory_index: [ + 0, + ], + }, largest_niche: Some( Niche { offset: Size(0 bytes), diff --git a/tests/ui/type/pattern_types/transmute.current.stderr b/tests/ui/type/pattern_types/transmute.current.stderr new file mode 100644 index 0000000000000..edec542e5e151 --- /dev/null +++ b/tests/ui/type/pattern_types/transmute.current.stderr @@ -0,0 +1,21 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:23:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `u32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:31:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `Option` (64 bits) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/type/pattern_types/transmute.next.stderr b/tests/ui/type/pattern_types/transmute.next.stderr new file mode 100644 index 0000000000000..edec542e5e151 --- /dev/null +++ b/tests/ui/type/pattern_types/transmute.next.stderr @@ -0,0 +1,21 @@ +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:23:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `u32` (32 bits) + +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/transmute.rs:31:14 + | +LL | unsafe { std::mem::transmute(x) } + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) + = note: target type: `Option` (64 bits) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/type/pattern_types/transmute.rs b/tests/ui/type/pattern_types/transmute.rs index 43dd62a19e706..4e686245f9375 100644 --- a/tests/ui/type/pattern_types/transmute.rs +++ b/tests/ui/type/pattern_types/transmute.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(pattern_types, pattern_type_macro, generic_pattern_types)] #![expect(incomplete_features)] diff --git a/tests/ui/type/pattern_types/transmute.stderr b/tests/ui/type/pattern_types/transmute.stderr deleted file mode 100644 index 578549b515c10..0000000000000 --- a/tests/ui/type/pattern_types/transmute.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:20:14 - | -LL | unsafe { std::mem::transmute(x) } - | ^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) - = note: target type: `u32` (32 bits) - -error[E0512]: cannot transmute between types of different sizes, or dependently-sized types - --> $DIR/transmute.rs:28:14 - | -LL | unsafe { std::mem::transmute(x) } - | ^^^^^^^^^^^^^^^^^^^ - | - = note: source type: `Option<(u32) is S..=E>` (size can vary because of u32) - = note: target type: `Option` (64 bits) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0512`. diff --git a/tests/ui/type/pattern_types/unsize.rs b/tests/ui/type/pattern_types/unsize.rs new file mode 100644 index 0000000000000..1020dd8c21544 --- /dev/null +++ b/tests/ui/type/pattern_types/unsize.rs @@ -0,0 +1,18 @@ +//! Show that pattern-types with pointer base types can be part of unsizing coercions + +//@ check-pass + +#![feature(pattern_type_macro, pattern_types)] + +use std::pat::pattern_type; + +type NonNull = pattern_type!(*const T is !null); + +trait Trait {} +impl Trait for u32 {} +impl Trait for i32 {} + +fn main() { + let x: NonNull = unsafe { std::mem::transmute(std::ptr::dangling::()) }; + let x: NonNull = x; +} diff --git a/tests/ui/type/type-ascription.rs b/tests/ui/type/type-ascription.rs index 76d6d923affc2..3649c707f3046 100644 --- a/tests/ui/type/type-ascription.rs +++ b/tests/ui/type/type-ascription.rs @@ -1,9 +1,8 @@ //@ run-pass -#![allow(dead_code)] -#![allow(unused_variables)] -// Type ascription doesn't lead to unsoundness +#![allow(dead_code, unused_variables, unused_assignments)] +// Type ascription doesn't lead to unsoundness #![feature(type_ascription)] use std::mem; diff --git a/tests/ui/typeck/associated-type-ice-recovery-66353.rs b/tests/ui/typeck/associated-type-ice-recovery-66353.rs new file mode 100644 index 0000000000000..472bc11108231 --- /dev/null +++ b/tests/ui/typeck/associated-type-ice-recovery-66353.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/66353 +// #66353: ICE when trying to recover from incorrect associated type + +trait _Func { + fn func(_: Self); +} + +trait _A { + type AssocT; +} + +fn main() { + _Func::< <() as _A>::AssocT >::func(()); + //~^ ERROR the trait bound `(): _A` is not satisfied + //~| ERROR the trait bound `(): _Func<_>` is not satisfied +} diff --git a/tests/ui/typeck/associated-type-ice-recovery-66353.stderr b/tests/ui/typeck/associated-type-ice-recovery-66353.stderr new file mode 100644 index 0000000000000..30740f66dcd90 --- /dev/null +++ b/tests/ui/typeck/associated-type-ice-recovery-66353.stderr @@ -0,0 +1,29 @@ +error[E0277]: the trait bound `(): _A` is not satisfied + --> $DIR/associated-type-ice-recovery-66353.rs:13:15 + | +LL | _Func::< <() as _A>::AssocT >::func(()); + | ^^ the trait `_A` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-type-ice-recovery-66353.rs:8:1 + | +LL | trait _A { + | ^^^^^^^^ + +error[E0277]: the trait bound `(): _Func<_>` is not satisfied + --> $DIR/associated-type-ice-recovery-66353.rs:13:41 + | +LL | _Func::< <() as _A>::AssocT >::func(()); + | ----------------------------------- ^^ the trait `_Func<_>` is not implemented for `()` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/associated-type-ice-recovery-66353.rs:4:1 + | +LL | trait _Func { + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/auxiliary/extern-macro-issue-139050.rs b/tests/ui/typeck/auxiliary/extern-macro-issue-139050.rs new file mode 100644 index 0000000000000..9e20c86adabce --- /dev/null +++ b/tests/ui/typeck/auxiliary/extern-macro-issue-139050.rs @@ -0,0 +1,15 @@ +#[macro_export] +macro_rules! eq { + (assert $a:expr, $b:expr) => { + match (&$a, &$b) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + panic!( + "assertion failed: `(left == right)`\n left: `{:?}`,\n right: `{:?}`", + left_val, right_val + ); + } + } + } + }; +} diff --git a/tests/ui/typeck/coercion-check-for-indexing-expression-issue-40861.stderr b/tests/ui/typeck/coercion-check-for-indexing-expression-issue-40861.stderr index 13bc0cd94f37c..ef5f1786801a1 100644 --- a/tests/ui/typeck/coercion-check-for-indexing-expression-issue-40861.stderr +++ b/tests/ui/typeck/coercion-check-for-indexing-expression-issue-40861.stderr @@ -4,7 +4,7 @@ error[E0608]: cannot index into a value of type `()` LL | ()[f(&[1.0])]; | ^^^^^^^^^^^ | - = help: to access tuple elements, use tuple indexing syntax (e.g., `tuple.0`) + = help: tuples are indexed with a dot and a literal index: `tuple.0`, `tuple.1`, etc. error: aborting due to 1 previous error diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs index c08030fc5c150..81c2d778b057f 100644 --- a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.rs @@ -1,4 +1,5 @@ //@ proc-macro: derive-demo-issue-136343.rs +//@ ignore-backends: gcc #[macro_use] extern crate derive_demo_issue_136343; diff --git a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr index 0b9c1d9123aab..d69eaae533551 100644 --- a/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr +++ b/tests/ui/typeck/invalid-sugg-for-derive-macro-issue-136343.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/invalid-sugg-for-derive-macro-issue-136343.rs:6:10 + --> $DIR/invalid-sugg-for-derive-macro-issue-136343.rs:7:10 | LL | #[derive(Sample)] | ^^^^^^ diff --git a/tests/ui/typeck/issue-13853.rs b/tests/ui/typeck/issue-13853.rs index ac9886d2e7249..ed44d5062614f 100644 --- a/tests/ui/typeck/issue-13853.rs +++ b/tests/ui/typeck/issue-13853.rs @@ -25,7 +25,7 @@ impl Node for Stuff { fn iterate>(graph: &G) { for node in graph.iter() { //~ ERROR no method named `iter` found - node.zomg(); + node.zomg(); //~ ERROR type annotations needed } } diff --git a/tests/ui/typeck/issue-13853.stderr b/tests/ui/typeck/issue-13853.stderr index 45363c87d29df..4a39b404770d0 100644 --- a/tests/ui/typeck/issue-13853.stderr +++ b/tests/ui/typeck/issue-13853.stderr @@ -17,6 +17,12 @@ error[E0599]: no method named `iter` found for reference `&G` in the current sco LL | for node in graph.iter() { | ^^^^ method not found in `&G` +error[E0282]: type annotations needed + --> $DIR/issue-13853.rs:28:9 + | +LL | node.zomg(); + | ^^^^ cannot infer type + error[E0308]: mismatched types --> $DIR/issue-13853.rs:37:13 | @@ -37,7 +43,7 @@ help: consider borrowing here LL | iterate(&graph); | + -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0308, E0599. -For more information about an error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0282, E0308, E0599. +For more information about an error, try `rustc --explain E0282`. diff --git a/tests/ui/typeck/issue-80779.stderr b/tests/ui/typeck/issue-80779.stderr index 2261ba616545f..90c80fa2ea6fd 100644 --- a/tests/ui/typeck/issue-80779.stderr +++ b/tests/ui/typeck/issue-80779.stderr @@ -2,19 +2,25 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/issue-80779.rs:10:28 | LL | pub fn g(_: T<'static>) -> _ {} - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `()` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - pub fn g(_: T<'static>) -> _ {} +LL + pub fn g(_: T<'static>) -> () {} + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/issue-80779.rs:5:29 | LL | pub fn f<'a>(val: T<'a>) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `()` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - pub fn f<'a>(val: T<'a>) -> _ { +LL + pub fn f<'a>(val: T<'a>) -> () { + | error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-98260.stderr b/tests/ui/typeck/issue-98260.stderr index b7debd335b0fb..f380db55cdffc 100644 --- a/tests/ui/typeck/issue-98260.stderr +++ b/tests/ui/typeck/issue-98260.stderr @@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/issue-98260.rs:3:27 | LL | fn a(aa: B) -> Result<_, B> { - | -------^---- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `Result<(), B>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn a(aa: B) -> Result<_, B> { +LL + fn a(aa: B) -> Result<(), B> { + | error: aborting due to 1 previous error diff --git a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs index f3ece563f5403..e8c3bbba1e458 100644 --- a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs +++ b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs @@ -1,5 +1,4 @@ -//@ check-pass -//@ known-bug: #85099 +//@ check-fail // Should fail. Can coerce `Pin` into `Pin` where // `T: Deref` and `U: Deref`, using the @@ -43,6 +42,7 @@ impl<'a, Fut: Future> SomeTrait<'a, Fut> for Fut { } impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> { +//~^ ERROR: conflicting implementations of trait `DerefMut` fn deref_mut<'c>( self: &'c mut Pin<&'b dyn SomeTrait<'a, Fut>>, ) -> &'c mut (dyn SomeTrait<'a, Fut> + 'b) { diff --git a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr new file mode 100644 index 0000000000000..2bcd92b76a09d --- /dev/null +++ b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.stderr @@ -0,0 +1,14 @@ +error[E0119]: conflicting implementations of trait `DerefMut` for type `Pin<&dyn SomeTrait<'_, _>>` + --> $DIR/pin-unsound-issue-85099-derefmut.rs:44:1 + | +LL | impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl DerefMut for Pin + where as pin::helper::PinDerefMutHelper>::Target == as Deref>::Target, Ptr: Deref, pin::helper::PinHelper: pin::helper::PinDerefMutHelper, pin::helper::PinHelper: ?Sized; + = note: upstream crates may add a new impl of trait `std::pin::helper::PinDerefMutHelper` for type `std::pin::helper::PinHelper<&dyn SomeTrait<'_, _>>` in future versions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/typeck/return-unsized-coercion.rs b/tests/ui/typeck/return-unsized-coercion.rs new file mode 100644 index 0000000000000..17706ea8dd287 --- /dev/null +++ b/tests/ui/typeck/return-unsized-coercion.rs @@ -0,0 +1,8 @@ +// Regression test for issue + +fn digit() -> str { + //~^ ERROR the size for values of type `str` cannot be known at compilation time + return { i32::MIN }; +} + +fn main() {} diff --git a/tests/ui/typeck/return-unsized-coercion.stderr b/tests/ui/typeck/return-unsized-coercion.stderr new file mode 100644 index 0000000000000..9736d26592636 --- /dev/null +++ b/tests/ui/typeck/return-unsized-coercion.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/return-unsized-coercion.rs:3:15 + | +LL | fn digit() -> str { + | ^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `str` + = note: the return type of a function must have a statically known size + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.rs b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.rs new file mode 100644 index 0000000000000..5aa2bd7fddeb1 --- /dev/null +++ b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.rs @@ -0,0 +1,34 @@ +// if we use lhs == rhs in a macro, we should not suggest to swap the equality +// because the origin span of lhs and rhs can not be found. See issue #139050 + +//@ aux-build:extern-macro-issue-139050.rs +//@ aux-crate:ext=extern-macro-issue-139050.rs + +extern crate ext; + +use std::fmt::Debug; + +macro_rules! eq_local { + (assert $a:expr, $b:expr) => { + match (&$a, &$b) { + (left_val, right_val) => { + if !(*left_val == *right_val) { + //~^ ERROR mismatched types [E0308] + panic!( + "assertion failed: `(left == right)`\n left: `{:?}`,\n right: `{:?}`", + left_val, right_val + ); + } + } + } + }; +} + +pub fn foo(mut iter: I, value: &I::Item) +where + Item: Eq + Debug, //~ ERROR cannot find type `Item` in this scope [E0412] +{ + ext::eq!(assert iter.next(), Some(value)); //~ ERROR mismatched types [E0308] + eq_local!(assert iter.next(), Some(value)); +} +fn main() {} diff --git a/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr new file mode 100644 index 0000000000000..96a3bc65dfdc9 --- /dev/null +++ b/tests/ui/typeck/sugg-swap-equality-in-macro-issue-139050.stderr @@ -0,0 +1,39 @@ +error[E0412]: cannot find type `Item` in this scope + --> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:29:5 + | +LL | Item: Eq + Debug, + | ^^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:31:5 + | +LL | ext::eq!(assert iter.next(), Some(value)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<::Item>`, found `Option<&::Item>` + | + = note: expected enum `Option<_>` + found enum `Option<&_>` + = note: this error originates in the macro `ext::eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/sugg-swap-equality-in-macro-issue-139050.rs:15:35 + | +LL | if !(*left_val == *right_val) { + | ^^^^^^^^^^ expected `Option<::Item>`, found `Option<&::Item>` +... +LL | eq_local!(assert iter.next(), Some(value)); + | ------------------------------------------ in this macro invocation + | + = note: expected enum `Option<_>` + found enum `Option<&_>` + = note: `Option<&::Item>` implements `PartialEq::Item>>` + = note: this error originates in the macro `eq_local` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider swapping the equality + | +LL - if !(*left_val == *right_val) { +LL + if !(*right_val == *left_val) { + | + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/typeck/type-arguments-on-local-variable-60989.rs b/tests/ui/typeck/type-arguments-on-local-variable-60989.rs new file mode 100644 index 0000000000000..134188754b4ce --- /dev/null +++ b/tests/ui/typeck/type-arguments-on-local-variable-60989.rs @@ -0,0 +1,19 @@ +// https://github.com/rust-lang/rust/issues/60989 +struct A {} +struct B {} + +impl From for B { + fn from(a: A) -> B { + B{} + } +} + +fn main() { + let c1 = (); + c1::<()>; + //~^ ERROR type arguments are not allowed on local variable + + let c1 = A {}; + c1::>; + //~^ ERROR type arguments are not allowed on local variable +} diff --git a/tests/ui/typeck/type-arguments-on-local-variable-60989.stderr b/tests/ui/typeck/type-arguments-on-local-variable-60989.stderr new file mode 100644 index 0000000000000..20cb4752079a2 --- /dev/null +++ b/tests/ui/typeck/type-arguments-on-local-variable-60989.stderr @@ -0,0 +1,19 @@ +error[E0109]: type arguments are not allowed on local variable + --> $DIR/type-arguments-on-local-variable-60989.rs:13:10 + | +LL | c1::<()>; + | -- ^^ type argument not allowed + | | + | not allowed on local variable + +error[E0109]: type arguments are not allowed on local variable + --> $DIR/type-arguments-on-local-variable-60989.rs:17:10 + | +LL | c1::>; + | -- ^^^^^^^^^^^ type argument not allowed + | | + | not allowed on local variable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0109`. diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.rs b/tests/ui/typeck/type-inference-for-associated-types-69683.rs new file mode 100644 index 0000000000000..f18adcae23b05 --- /dev/null +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.rs @@ -0,0 +1,34 @@ +// https://github.com/rust-lang/rust/issues/69683 +pub trait Element { + type Array; +} + +impl Element<()> for T { + type Array = T; +} + +impl, S> Element<[S; 3]> for T { + type Array = [T::Array; 3]; +} + +trait Foo +where + u8: Element, +{ + fn foo(self, x: >::Array); +} + +impl Foo for u16 +where + u8: Element, +{ + fn foo(self, _: >::Array) {} +} + +fn main() { + let b: [u8; 3] = [0u8; 3]; + + 0u16.foo(b); //~ ERROR type annotations needed + //~^ ERROR type annotations needed + //>::foo(0u16, b); +} diff --git a/tests/ui/typeck/type-inference-for-associated-types-69683.stderr b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr new file mode 100644 index 0000000000000..5d49d442c55d0 --- /dev/null +++ b/tests/ui/typeck/type-inference-for-associated-types-69683.stderr @@ -0,0 +1,45 @@ +error[E0284]: type annotations needed + --> $DIR/type-inference-for-associated-types-69683.rs:31:10 + | +LL | 0u16.foo(b); + | ^^^ + | + = note: cannot satisfy `>::Array == [u8; 3]` +help: try using a fully qualified path to specify the expected types + | +LL - 0u16.foo(b); +LL + >::foo(0u16, b); + | + +error[E0283]: type annotations needed + --> $DIR/type-inference-for-associated-types-69683.rs:31:10 + | +LL | 0u16.foo(b); + | ^^^ + | +note: multiple `impl`s satisfying `u8: Element<_>` found + --> $DIR/type-inference-for-associated-types-69683.rs:6:1 + | +LL | impl Element<()> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl, S> Element<[S; 3]> for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `Foo::foo` + --> $DIR/type-inference-for-associated-types-69683.rs:16:9 + | +LL | u8: Element, + | ^^^^^^^^^^ required by this bound in `Foo::foo` +LL | { +LL | fn foo(self, x: >::Array); + | --- required by a bound in this associated function +help: try using a fully qualified path to specify the expected types + | +LL - 0u16.foo(b); +LL + >::foo(0u16, b); + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0283, E0284. +For more information about an error, try `rustc --explain E0283`. diff --git a/tests/ui/typeck/type-name-intrinsic-usage-61894.rs b/tests/ui/typeck/type-name-intrinsic-usage-61894.rs new file mode 100644 index 0000000000000..8131bb273909d --- /dev/null +++ b/tests/ui/typeck/type-name-intrinsic-usage-61894.rs @@ -0,0 +1,22 @@ +// https://github.com/rust-lang/rust/issues/61894 +//@ run-pass + +#![feature(core_intrinsics)] + +use std::any::type_name; + +struct Bar(#[allow(dead_code)] M); + +impl Bar { + fn foo(&self) -> &'static str { + fn f() {} + fn type_name_of(_: T) -> &'static str { + type_name::() + } + type_name_of(f) + } +} + +fn main() { + assert_eq!(Bar(()).foo(), "type_name_intrinsic_usage_61894::Bar<_>::foo::f"); +} diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index 87750ee6dc140..240dc1ae8ab9e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -48,20 +48,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:7:14 | LL | fn test() -> _ { 5 } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `i32` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test() -> _ { 5 } +LL + fn test() -> i32 { 5 } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:10:16 | LL | fn test2() -> (_, _) { (5, 5) } - | -^--^- - | || | - | || not allowed in type signatures - | |not allowed in type signatures - | help: replace with the correct return type: `(i32, i32)` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test2() -> (_, _) { (5, 5) } +LL + fn test2() -> (i32, i32) { (5, 5) } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:13:15 @@ -189,19 +196,25 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:47:26 | LL | fn test11(x: &usize) -> &_ { - | -^ - | || - | |not allowed in type signatures - | help: replace with the correct return type: `&&usize` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test11(x: &usize) -> &_ { +LL + fn test11(x: &usize) -> &&usize { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:52:52 | LL | unsafe fn test12(x: *const usize) -> *const *const _ { - | --------------^ - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `*const *const usize` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - unsafe fn test12(x: *const usize) -> *const *const _ { +LL + unsafe fn test12(x: *const usize) -> *const *const usize { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods --> $DIR/typeck_type_placeholder_item.rs:58:24 @@ -261,20 +274,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:80:21 | LL | fn fn_test() -> _ { 5 } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `i32` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn fn_test() -> _ { 5 } +LL + fn fn_test() -> i32 { 5 } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:83:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } - | -^--^- - | || | - | || not allowed in type signatures - | |not allowed in type signatures - | help: replace with the correct return type: `(i32, i32)` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn fn_test2() -> (_, _) { (5, 5) } +LL + fn fn_test2() -> (i32, i32) { (5, 5) } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/typeck_type_placeholder_item.rs:86:22 @@ -374,20 +394,27 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:134:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } - | -^--^- - | || | - | || not allowed in type signatures - | |not allowed in type signatures - | help: replace with the correct return type: `(i32, i32)` + | ^ ^ not allowed in type signatures + | | + | not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn fn_test12(x: i32) -> (_, _) { (x, x) } +LL + fn fn_test12(x: i32) -> (i32, i32) { (x, x) } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:137:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } - | ------^- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `(i32, i32)` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn fn_test13(x: _) -> (i32, _) { (x, x) } +LL + fn fn_test13(x: _) -> (i32, i32) { (x, x) } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods --> $DIR/typeck_type_placeholder_item.rs:142:31 @@ -528,10 +555,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:226:31 | LL | fn value() -> Option<&'static _> { - | ----------------^- - | | | - | | not allowed in type signatures - | help: replace with the correct return type: `Option<&'static u8>` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn value() -> Option<&'static _> { +LL + fn value() -> Option<&'static u8> { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item.rs:231:17 @@ -549,10 +579,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:235:31 | LL | fn evens_squared(n: usize) -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with an appropriate return type: `impl Iterator` + | ^ not allowed in type signatures + | +help: replace with an appropriate return type + | +LL - fn evens_squared(n: usize) -> _ { +LL + fn evens_squared(n: usize) -> impl Iterator { + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item.rs:240:10 @@ -570,10 +603,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:40:24 | LL | fn test9(&self) -> _ { () } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `()` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test9(&self) -> _ { () } +LL + fn test9(&self) -> () { () } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods --> $DIR/typeck_type_placeholder_item.rs:43:27 @@ -585,10 +621,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item.rs:107:31 | LL | fn fn_test9(&self) -> _ { () } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `()` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn fn_test9(&self) -> _ { () } +LL + fn fn_test9(&self) -> () { () } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for methods --> $DIR/typeck_type_placeholder_item.rs:110:34 diff --git a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr index 2fce00e7a8e9f..3f21ff6d4ec9f 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item_help.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item_help.stderr @@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/typeck_type_placeholder_item_help.rs:4:15 | LL | fn test1() -> _ { Some(42) } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `Option` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - fn test1() -> _ { Some(42) } +LL + fn test1() -> Option { Some(42) } + | error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/typeck_type_placeholder_item_help.rs:7:14 diff --git a/tests/ui/unboxed-closures/callback-trait-prediction-70746.rs b/tests/ui/unboxed-closures/callback-trait-prediction-70746.rs new file mode 100644 index 0000000000000..c0f0eb541e843 --- /dev/null +++ b/tests/ui/unboxed-closures/callback-trait-prediction-70746.rs @@ -0,0 +1,30 @@ +// https://github.com/rust-lang/rust/issues/70746 +//@ check-pass + +pub trait Trait1 { + type C; +} + +struct T1; +impl Trait1 for T1 { + type C = usize; +} +pub trait Callback: FnMut(::C) {} +impl::C)> Callback for F {} + +pub struct State { + callback: Option>>, +} +impl State { + fn new() -> Self { + Self { callback: None } + } + fn test_cb(&mut self, d: ::C) { + (self.callback.as_mut().unwrap())(d) + } +} + +fn main() { + let mut s = State::::new(); + s.test_cb(1); +} diff --git a/tests/ui/unboxed-closures/unboxed-closures-all-traits.rs b/tests/ui/unboxed-closures/unboxed-closures-all-traits.rs index 0ca4de56d744c..c1020a0d468a0 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-all-traits.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-all-traits.rs @@ -1,5 +1,4 @@ //@ run-pass -#![feature(lang_items)] fn a isize>(f: F) -> isize { f(1, 2) diff --git a/tests/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs b/tests/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs index 1cf4863bfa999..805af283d1a82 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-blanket-fn-mut.rs @@ -2,8 +2,6 @@ #![allow(unused_variables)] // Test that you can supply `&F` where `F: FnMut()`. -#![feature(lang_items)] - fn a i32>(mut f: F) -> i32 { f() } diff --git a/tests/ui/unboxed-closures/unboxed-closures-blanket-fn.rs b/tests/ui/unboxed-closures/unboxed-closures-blanket-fn.rs index 921bd94ee626c..c31e85eacee91 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-blanket-fn.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-blanket-fn.rs @@ -2,8 +2,6 @@ #![allow(unused_variables)] // Test that you can supply `&F` where `F: Fn()`. -#![feature(lang_items)] - fn a i32>(f: F) -> i32 { f() } diff --git a/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs b/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs index 42287ac50701b..ee425abfd1e27 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.rs @@ -21,8 +21,9 @@ fn main() { call(move || { // this mutates a moved copy, and hence doesn't affect original - counter += 1; //~ WARN value assigned to `counter` is never read - //~| WARN unused variable: `counter` + counter += 1; + //~^ WARN value captured by `counter` is never read + //~| WARN value assigned to `counter` is never read }); assert_eq!(counter, 88); } diff --git a/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr b/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr index 190ef0f472463..3afb032747734 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr @@ -1,27 +1,27 @@ -warning: unused variable: `item` - --> $DIR/unboxed-closures-counter-not-moved.rs:15:13 +warning: value captured by `counter` is never read + --> $DIR/unboxed-closures-counter-not-moved.rs:24:9 | -LL | for item in y { - | ^^^^ help: if this is intentional, prefix it with an underscore: `_item` +LL | counter += 1; + | ^^^^^^^ | - = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default + = help: did you mean to capture by reference instead? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default warning: value assigned to `counter` is never read --> $DIR/unboxed-closures-counter-not-moved.rs:24:9 | LL | counter += 1; - | ^^^^^^^ + | ^^^^^^^^^^^^ | = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default -warning: unused variable: `counter` - --> $DIR/unboxed-closures-counter-not-moved.rs:24:9 +warning: unused variable: `item` + --> $DIR/unboxed-closures-counter-not-moved.rs:15:13 | -LL | counter += 1; - | ^^^^^^^ +LL | for item in y { + | ^^^^ help: if this is intentional, prefix it with an underscore: `_item` | - = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default warning: 3 warnings emitted diff --git a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr index 058dbb1e220f6..739182e120b4f 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-failed-recursive-fn-2.stderr @@ -5,7 +5,7 @@ LL | let mut closure0 = None; | ^^^^^^^^^^^^ ... LL | return c(); - | --- type must be known at this point + | - type must be known at this point | help: consider giving `closure0` an explicit type, where the placeholders `_` are specified | diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs index f27461808c390..5710998cda799 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs +++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.rs @@ -13,11 +13,17 @@ fn set(x: &mut usize) { *x = 42; } fn main() { { let mut x = 0_usize; - move || x += 1; //~ WARN unused variable: `x` + //~^ WARN unused variable: `x` + move || x += 1; + //~^ WARN value captured by `x` is never read + //~| WARN value assigned to `x` is never read } { let mut x = 0_usize; - move || x += 1; //~ WARN unused variable: `x` + //~^ WARN unused variable: `x` + move || x += 1; + //~^ WARN value captured by `x` is never read + //~| WARN value assigned to `x` is never read } { let mut x = 0_usize; diff --git a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr index 24590128107b3..70c48b596c0ec 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-move-mutable.stderr @@ -1,19 +1,49 @@ -warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:16:17 +warning: value captured by `x` is never read + --> $DIR/unboxed-closures-move-mutable.rs:24:17 | LL | move || x += 1; | ^ | = help: did you mean to capture by reference instead? - = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default -warning: unused variable: `x` - --> $DIR/unboxed-closures-move-mutable.rs:20:17 +warning: value assigned to `x` is never read + --> $DIR/unboxed-closures-move-mutable.rs:24:17 + | +LL | move || x += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: value captured by `x` is never read + --> $DIR/unboxed-closures-move-mutable.rs:17:17 | LL | move || x += 1; | ^ | = help: did you mean to capture by reference instead? -warning: 2 warnings emitted +warning: value assigned to `x` is never read + --> $DIR/unboxed-closures-move-mutable.rs:17:17 + | +LL | move || x += 1; + | ^^^^^^ + | + = help: maybe it is overwritten before being read? + +warning: unused variable: `x` + --> $DIR/unboxed-closures-move-mutable.rs:15:13 + | +LL | let mut x = 0_usize; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default + +warning: unused variable: `x` + --> $DIR/unboxed-closures-move-mutable.rs:22:13 + | +LL | let mut x = 0_usize; + | ^^^^^ help: if this is intentional, prefix it with an underscore: `_x` + +warning: 6 warnings emitted diff --git a/tests/ui/uninhabited/void-branch.rs b/tests/ui/uninhabited/void-branch.rs new file mode 100644 index 0000000000000..e000f946dc156 --- /dev/null +++ b/tests/ui/uninhabited/void-branch.rs @@ -0,0 +1,30 @@ +#![deny(unreachable_code)] +#![allow(deprecated, invalid_value)] + +enum Void {} + +fn with_void() { + if false { + unsafe { + //~^ ERROR unreachable expression + std::mem::uninitialized::(); + } + } + + println!(); +} + +fn infallible() -> std::convert::Infallible { + loop {} +} + +fn with_infallible() { + if false { + //~^ ERROR unreachable expression + infallible(); + } + + println!() +} + +fn main() {} diff --git a/tests/ui/uninhabited/void-branch.stderr b/tests/ui/uninhabited/void-branch.stderr new file mode 100644 index 0000000000000..7bbcb763ddf7c --- /dev/null +++ b/tests/ui/uninhabited/void-branch.stderr @@ -0,0 +1,40 @@ +error: unreachable expression + --> $DIR/void-branch.rs:8:9 + | +LL | / unsafe { +LL | | +LL | | std::mem::uninitialized::(); + | | --------------------------------- any code following this expression is unreachable +LL | | } + | |_________^ unreachable expression + | +note: this expression has type `Void`, which is uninhabited + --> $DIR/void-branch.rs:10:13 + | +LL | std::mem::uninitialized::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/void-branch.rs:1:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + +error: unreachable expression + --> $DIR/void-branch.rs:22:14 + | +LL | if false { + | ______________^ +LL | | +LL | | infallible(); + | | ------------ any code following this expression is unreachable +LL | | } + | |_____^ unreachable expression + | +note: this expression has type `Infallible`, which is uninhabited + --> $DIR/void-branch.rs:24:9 + | +LL | infallible(); + | ^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/union/union-field-access-error-65462.rs b/tests/ui/union/union-field-access-error-65462.rs new file mode 100644 index 0000000000000..ead403bc526cd --- /dev/null +++ b/tests/ui/union/union-field-access-error-65462.rs @@ -0,0 +1,16 @@ +// https://github.com/rust-lang/rust/issues/65462 +//@ build-pass + +enum Empty {} +enum Enum { + Empty( Empty ) +} + +fn foobar() -> Option< Enum > { + let value: Option< Empty > = None; + Some( Enum::Empty( value? ) ) +} + +fn main() { + foobar(); +} diff --git a/tests/ui/union/union-unsafe.rs b/tests/ui/union/union-unsafe.rs index bd3946686be36..beb074f4e8ebc 100644 --- a/tests/ui/union/union-unsafe.rs +++ b/tests/ui/union/union-unsafe.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::mem::ManuallyDrop; +use std::ops::Deref; union U1 { a: u8, @@ -17,6 +18,10 @@ union U4 { a: T, } +union U5 { + a: usize, +} + union URef { p: &'static mut i32, } @@ -31,6 +36,20 @@ fn deref_union_field(mut u: URef) { *(u.p) = 13; //~ ERROR access to union field is unsafe } +union A { + a: usize, + b: &'static &'static B, +} + +union B { + c: usize, +} + +fn raw_deref_union_field(mut u: URef) { + // This is unsafe because we first dereference u.p (reading uninitialized memory) + let _p = &raw const *(u.p); //~ ERROR access to union field is unsafe +} + fn assign_noncopy_union_field(mut u: URefCell) { u.a = (ManuallyDrop::new(RefCell::new(0)), 1); // OK (assignment does not drop) u.a.0 = ManuallyDrop::new(RefCell::new(0)); // OK (assignment does not drop) @@ -57,6 +76,20 @@ fn main() { let a = u1.a; //~ ERROR access to union field is unsafe u1.a = 11; // OK + let mut u2 = U1 { a: 10 }; + let a = &raw mut u2.a; // OK + unsafe { *a = 3 }; + + let mut u3 = U1 { a: 10 }; + let a = std::ptr::addr_of_mut!(u3.a); // OK + unsafe { *a = 14 }; + + let u4 = U5 { a: 2 }; + let vec = vec![1, 2, 3]; + // This is unsafe because we read u4.a (potentially uninitialized memory) + // to use as an array index + let _a = &raw const vec[u4.a]; //~ ERROR access to union field is unsafe + let U1 { a } = u1; //~ ERROR access to union field is unsafe if let U1 { a: 12 } = u1 {} //~ ERROR access to union field is unsafe if let Some(U1 { a: 13 }) = Some(u1) {} //~ ERROR access to union field is unsafe @@ -73,4 +106,44 @@ fn main() { let mut u3 = U3 { a: ManuallyDrop::new(String::from("old")) }; // OK u3.a = ManuallyDrop::new(String::from("new")); // OK (assignment does not drop) *u3.a = String::from("new"); //~ ERROR access to union field is unsafe + + let mut unions = [U1 { a: 1 }, U1 { a: 2 }]; + + // Array indexing + union field raw borrow - should be OK + let ptr = &raw mut unions[0].a; // OK + let ptr2 = &raw const unions[1].a; // OK + + let a = A { a: 0 }; + let _p = &raw const (**a.b).c; //~ ERROR access to union field is unsafe + + arbitrary_deref(); +} + +// regression test for https://github.com/rust-lang/rust/pull/141469#discussion_r2312546218 +fn arbitrary_deref() { + use std::ops::Deref; + + union A { + a: usize, + b: B, + } + + #[derive(Copy, Clone)] + struct B(&'static str); + + impl Deref for B { + type Target = C; + + fn deref(&self) -> &C { + println!("{:?}", self.0); + &C { c: 0 } + } + } + + union C { + c: usize, + } + + let a = A { a: 0 }; + let _p = &raw const (*a.b).c; //~ ERROR access to union field is unsafe } diff --git a/tests/ui/union/union-unsafe.stderr b/tests/ui/union/union-unsafe.stderr index 82b3f897167c7..01f4d95eb649d 100644 --- a/tests/ui/union/union-unsafe.stderr +++ b/tests/ui/union/union-unsafe.stderr @@ -1,5 +1,5 @@ error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:31:6 + --> $DIR/union-unsafe.rs:36:6 | LL | *(u.p) = 13; | ^^^^^ access to union field @@ -7,7 +7,15 @@ LL | *(u.p) = 13; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:43:6 + --> $DIR/union-unsafe.rs:50:26 + | +LL | let _p = &raw const *(u.p); + | ^^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:62:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -15,7 +23,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:49:6 + --> $DIR/union-unsafe.rs:68:6 | LL | *u3.a = T::default(); | ^^^^ access to union field @@ -23,7 +31,7 @@ LL | *u3.a = T::default(); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:57:13 + --> $DIR/union-unsafe.rs:76:13 | LL | let a = u1.a; | ^^^^ access to union field @@ -31,7 +39,15 @@ LL | let a = u1.a; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:60:14 + --> $DIR/union-unsafe.rs:91:29 + | +LL | let _a = &raw const vec[u4.a]; + | ^^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:93:14 | LL | let U1 { a } = u1; | ^ access to union field @@ -39,7 +55,7 @@ LL | let U1 { a } = u1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:61:20 + --> $DIR/union-unsafe.rs:94:20 | LL | if let U1 { a: 12 } = u1 {} | ^^ access to union field @@ -47,7 +63,7 @@ LL | if let U1 { a: 12 } = u1 {} = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:62:25 + --> $DIR/union-unsafe.rs:95:25 | LL | if let Some(U1 { a: 13 }) = Some(u1) {} | ^^ access to union field @@ -55,7 +71,7 @@ LL | if let Some(U1 { a: 13 }) = Some(u1) {} = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:67:6 + --> $DIR/union-unsafe.rs:100:6 | LL | *u2.a = String::from("new"); | ^^^^ access to union field @@ -63,7 +79,7 @@ LL | *u2.a = String::from("new"); = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:71:6 + --> $DIR/union-unsafe.rs:104:6 | LL | *u3.a = 1; | ^^^^ access to union field @@ -71,13 +87,29 @@ LL | *u3.a = 1; = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior error[E0133]: access to union field is unsafe and requires unsafe function or block - --> $DIR/union-unsafe.rs:75:6 + --> $DIR/union-unsafe.rs:108:6 | LL | *u3.a = String::from("new"); | ^^^^ access to union field | = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior -error: aborting due to 10 previous errors +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:117:28 + | +LL | let _p = &raw const (**a.b).c; + | ^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error[E0133]: access to union field is unsafe and requires unsafe function or block + --> $DIR/union-unsafe.rs:148:27 + | +LL | let _p = &raw const (*a.b).c; + | ^^^ access to union field + | + = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior + +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout index 96d85d1e7c14f..27cba6560300a 100644 --- a/tests/ui/unpretty/exhaustive.hir.stdout +++ b/tests/ui/unpretty/exhaustive.hir.stdout @@ -398,7 +398,8 @@ mod expressions { let expr; format_arguments::new_const(&[]); { - super let args = [format_argument::new_display(&expr)]; + super let args = (&expr,); + super let args = [format_argument::new_display(args.0)]; format_arguments::new_v1(&[""], &args) }; } diff --git a/tests/ui/unpretty/flattened-format-args.stdout b/tests/ui/unpretty/flattened-format-args.stdout index 0792dc10e946b..233c9f1c91bd7 100644 --- a/tests/ui/unpretty/flattened-format-args.stdout +++ b/tests/ui/unpretty/flattened-format-args.stdout @@ -11,7 +11,8 @@ fn main() { // Should flatten to println!("a 123 b {x} xyz\n"): { ::std::io::_print({ - super let args = [format_argument::new_display(&x)]; + super let args = (&x,); + super let args = [format_argument::new_display(args.0)]; format_arguments::new_v1(&["a 123 b ", " xyz\n"], &args) }); }; diff --git a/tests/ui/thir-print/break-outside-loop-error-83048.rs b/tests/ui/unpretty/thir-tree-break-outside-loop-83048.rs similarity index 100% rename from tests/ui/thir-print/break-outside-loop-error-83048.rs rename to tests/ui/unpretty/thir-tree-break-outside-loop-83048.rs diff --git a/tests/ui/unpretty/thir-tree-break-outside-loop-83048.stderr b/tests/ui/unpretty/thir-tree-break-outside-loop-83048.stderr new file mode 100644 index 0000000000000..72ae6ae2725cc --- /dev/null +++ b/tests/ui/unpretty/thir-tree-break-outside-loop-83048.stderr @@ -0,0 +1,9 @@ +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/thir-tree-break-outside-loop-83048.rs:5:5 + | +LL | break; + | ^^^^^ cannot `break` outside of a loop or labeled block + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0268`. diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.rs b/tests/ui/unsized/relaxed-bounds-invalid-places.rs index 4c1f242a01cef..5aa1dbb9a094e 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.rs +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.rs @@ -30,6 +30,9 @@ trait Tr: ?Sized {} //~ ERROR relaxed bounds are not permitted in supertrait bou // Test that relaxed `Sized` bounds are rejected in trait object types: +type O0 = dyn ?Sized; +//~^ ERROR relaxed bounds are not permitted in trait object types +//~| ERROR at least one trait is required for an object type [E0224] type O1 = dyn Tr + ?Sized; //~ ERROR relaxed bounds are not permitted in trait object types type O2 = dyn ?Sized + ?Sized + Tr; //~^ ERROR relaxed bounds are not permitted in trait object types diff --git a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr index d3f0535e2f0cb..7f54d045a1ce8 100644 --- a/tests/ui/unsized/relaxed-bounds-invalid-places.stderr +++ b/tests/ui/unsized/relaxed-bounds-invalid-places.stderr @@ -4,7 +4,7 @@ error: this relaxed bound is not permitted here LL | struct S1(T) where (T): ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:8:27 @@ -12,7 +12,7 @@ error: this relaxed bound is not permitted here LL | struct S2(T) where u8: ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:10:35 @@ -20,7 +20,7 @@ error: this relaxed bound is not permitted here LL | struct S3(T) where &'static T: ?Sized; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:14:34 @@ -28,7 +28,7 @@ error: this relaxed bound is not permitted here LL | struct S4(T) where for<'a> T: ?Trait<'a>; | ^^^^^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:22:21 @@ -36,7 +36,7 @@ error: this relaxed bound is not permitted here LL | fn f() where T: ?Sized {} | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: this relaxed bound is not permitted here --> $DIR/relaxed-bounds-invalid-places.rs:27:41 @@ -44,7 +44,7 @@ error: this relaxed bound is not permitted here LL | struct S6(T) where T: Iterator; | ^^^^^^ | - = note: in this context, relaxed bounds are only allowed on type parameters defined by the closest item + = note: in this context, relaxed bounds are only allowed on type parameters defined on the closest item error: relaxed bounds are not permitted in supertrait bounds --> $DIR/relaxed-bounds-invalid-places.rs:29:11 @@ -52,25 +52,39 @@ error: relaxed bounds are not permitted in supertrait bounds LL | trait Tr: ?Sized {} | ^^^^^^ | - = note: traits are `?Sized` by default + = note: traits are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:33:20 + --> $DIR/relaxed-bounds-invalid-places.rs:33:15 + | +LL | type O0 = dyn ?Sized; + | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax + +error: relaxed bounds are not permitted in trait object types + --> $DIR/relaxed-bounds-invalid-places.rs:36:20 | LL | type O1 = dyn Tr + ?Sized; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:34:15 + --> $DIR/relaxed-bounds-invalid-places.rs:37:15 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: relaxed bounds are not permitted in trait object types - --> $DIR/relaxed-bounds-invalid-places.rs:34:24 + --> $DIR/relaxed-bounds-invalid-places.rs:37:24 | LL | type O2 = dyn ?Sized + ?Sized + Tr; | ^^^^^^ + | + = note: trait object types are not implicitly bounded by `Sized`, so there is nothing to relax error: bound modifier `?` can only be applied to `Sized` --> $DIR/relaxed-bounds-invalid-places.rs:14:34 @@ -84,5 +98,12 @@ error: bound modifier `?` can only be applied to `Sized` LL | struct S5(*const T) where T: ?Trait<'static> + ?Sized; | ^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error[E0224]: at least one trait is required for an object type + --> $DIR/relaxed-bounds-invalid-places.rs:33:11 + | +LL | type O0 = dyn ?Sized; + | ^^^^^^^^^^ + +error: aborting due to 14 previous errors +For more information about this error, try `rustc --explain E0224`. diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr index c3147558b03f9..afef024e1b9c1 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.disabled.stderr @@ -6,7 +6,7 @@ LL | impl aux::Trait for LocalTy {} | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - impl Trait for T - where unstable feature: `foo`; + where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr index c3147558b03f9..afef024e1b9c1 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_coherence.enabled.stderr @@ -6,7 +6,7 @@ LL | impl aux::Trait for LocalTy {} | = note: conflicting implementation in crate `unstable_impl_coherence_aux`: - impl Trait for T - where unstable feature: `foo`; + where feature(foo) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr index c2bb10f043b2e..840af730154d9 100644 --- a/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr +++ b/tests/ui/unstable-feature-bound/unstable_impl_method_selection.stderr @@ -7,7 +7,7 @@ LL | vec![].foo(); = note: multiple `impl`s satisfying `Vec<_>: Trait` found in the `unstable_impl_method_selection_aux` crate: - impl Trait for Vec; - impl Trait for Vec - where unstable feature: `bar`; + where feature(bar) is enabled; error: aborting due to 1 previous error diff --git a/tests/ui/variance/leaking-unnameables.stderr b/tests/ui/variance/leaking-unnameables.stderr index 92afe952801d0..59bdc33040de7 100644 --- a/tests/ui/variance/leaking-unnameables.stderr +++ b/tests/ui/variance/leaking-unnameables.stderr @@ -2,10 +2,13 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures --> $DIR/leaking-unnameables.rs:8:18 | LL | pub fn f() -> _ { - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `fn()` + | ^ not allowed in type signatures + | +help: replace with the correct return type + | +LL - pub fn f() -> _ { +LL + pub fn f() -> fn() { + | error: aborting due to 1 previous error diff --git a/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs b/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs new file mode 100644 index 0000000000000..69d508518597e --- /dev/null +++ b/tests/ui/wasm/auxiliary/link-name-in-foreign-crate.rs @@ -0,0 +1,7 @@ +#![no_std] + +#[link(wasm_import_module = "test")] +unsafe extern "C" { + #[link_name = "close"] + pub fn close(x: u32) -> u32; +} diff --git a/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs b/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs new file mode 100644 index 0000000000000..e2ceeb8ae13e2 --- /dev/null +++ b/tests/ui/wasm/wasm-link-name-in-foreign-crate-respected.rs @@ -0,0 +1,22 @@ +//@ only-wasm32 +//@ aux-build:link-name-in-foreign-crate.rs +//@ compile-flags: --crate-type cdylib +//@ build-pass +//@ no-prefer-dynamic + +extern crate link_name_in_foreign_crate; + +// This test that the definition of a function named `close`, which collides +// with the `close` function in libc in theory, is handled correctly in +// cross-crate situations. The `link_name_in_foreign_crate` dependency declares +// `close` from a non-`env` wasm import module and then this crate attempts to +// use the symbol. This should properly ensure that the wasm module name is +// tagged as `test` and the `close` symbol, to LLD, is mangled, to avoid +// colliding with the `close` symbol in libc itself. + +#[unsafe(no_mangle)] +pub extern "C" fn foo() { + unsafe { + link_name_in_foreign_crate::close(1); + } +} diff --git a/tests/ui/wf/wf-in-where-clause-static.current.stderr b/tests/ui/wf/wf-in-where-clause-static.current.stderr index d0bb89884c68a..788fe2c3faa07 100644 --- a/tests/ui/wf/wf-in-where-clause-static.current.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.current.stderr @@ -6,6 +6,12 @@ LL | let s = foo(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/wf-in-where-clause-static.rs:12:17 + | +LL | &'static S: Static, + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/wf/wf-in-where-clause-static.next.stderr b/tests/ui/wf/wf-in-where-clause-static.next.stderr index d0bb89884c68a..788fe2c3faa07 100644 --- a/tests/ui/wf/wf-in-where-clause-static.next.stderr +++ b/tests/ui/wf/wf-in-where-clause-static.next.stderr @@ -6,6 +6,12 @@ LL | let s = foo(&String::from("blah blah blah")); | | | | | creates a temporary value which is freed while still in use | argument requires that borrow lasts for `'static` + | +note: requirement that the value outlives `'static` introduced here + --> $DIR/wf-in-where-clause-static.rs:12:17 + | +LL | &'static S: Static, + | ^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs new file mode 100644 index 0000000000000..5d13e6e253a4e --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-1.rs @@ -0,0 +1,14 @@ +//@ check-pass + +#![feature(associated_type_defaults, where_clause_attrs)] +#![allow(deprecated_where_clause_location)] + +trait A { + type F + where + #[cfg(false)] + T: TraitB, + = T; +} + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs new file mode 100644 index 0000000000000..cf84bf3ee3559 --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.rs @@ -0,0 +1,27 @@ +#![feature(where_clause_attrs, lazy_type_alias)] +#![expect(incomplete_features)] + +struct Foo; +trait Trait {} + +impl Trait for Foo {} + +type MixedWhereBounds1 +where + //~^ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(true)] + Foo: Trait, += Foo +where + (): Sized; + +type MixedWhereBounds2 +where + //~^ ERROR: where clauses are not allowed before the type for type aliases + #[cfg(false)] + Foo: Trait, += Foo +where + (): Sized; + +fn main() {} diff --git a/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr new file mode 100644 index 0000000000000..f59ce0fa1acaa --- /dev/null +++ b/tests/ui/where-clauses/cfg-attr-issue-138010-2.stderr @@ -0,0 +1,31 @@ +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:10:1 + | +LL | / where +LL | | +LL | | #[cfg(true)] +LL | | Foo: Trait, + | |_______________^ + | + = note: see issue #89122 for more information +help: move it to the end of the type declaration + | +LL + +LL | = Foo +LL | where +LL ~ (): Sized, Foo: Trait; + | + +error: where clauses are not allowed before the type for type aliases + --> $DIR/cfg-attr-issue-138010-2.rs:19:1 + | +LL | / where +LL | | +LL | | #[cfg(false)] +LL | | Foo: Trait, + | |_______________^ help: remove this `where` + | + = note: see issue #89122 for more information + +error: aborting due to 2 previous errors + diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr index 42a8a1350d2b5..9ebc14c40a145 100644 --- a/tests/ui/where-clauses/unsupported_attribute.stderr +++ b/tests/ui/where-clauses/unsupported_attribute.stderr @@ -48,7 +48,7 @@ error: `#[macro_use]` attribute cannot be used on where predicates LL | #[macro_use] T: Trait, | ^^^^^^^^^^^^ | - = help: `#[macro_use]` can be applied to modules, extern crates, and crates + = help: `#[macro_use]` can be applied to crates, extern crates, and modules error: `#[macro_use]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:21:5 @@ -56,7 +56,7 @@ error: `#[macro_use]` attribute cannot be used on where predicates LL | #[macro_use] 'a: 'static, | ^^^^^^^^^^^^ | - = help: `#[macro_use]` can be applied to modules, extern crates, and crates + = help: `#[macro_use]` can be applied to crates, extern crates, and modules error: `#[deprecated]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:24:5 @@ -64,7 +64,7 @@ error: `#[deprecated]` attribute cannot be used on where predicates LL | #[deprecated] T: Trait, | ^^^^^^^^^^^^^ | - = help: `#[deprecated]` can be applied to functions, data types, modules, unions, constants, statics, macro defs, type aliases, use statements, foreign statics, struct fields, traits, associated types, associated consts, enum variants, inherent impl blocks, and crates + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements error: `#[deprecated]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:25:5 @@ -72,7 +72,7 @@ error: `#[deprecated]` attribute cannot be used on where predicates LL | #[deprecated] 'a: 'static, | ^^^^^^^^^^^^^ | - = help: `#[deprecated]` can be applied to functions, data types, modules, unions, constants, statics, macro defs, type aliases, use statements, foreign statics, struct fields, traits, associated types, associated consts, enum variants, inherent impl blocks, and crates + = help: `#[deprecated]` can be applied to associated consts, associated types, constants, crates, data types, enum variants, foreign statics, functions, inherent impl blocks, macro defs, modules, statics, struct fields, traits, type aliases, unions, and use statements error: `#[automatically_derived]` attribute cannot be used on where predicates --> $DIR/unsupported_attribute.rs:26:5 diff --git a/triagebot.toml b/triagebot.toml index 2d58c616bc278..b6edc229f9a29 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -61,10 +61,6 @@ required-issue-label = "regression-from-stable-to-beta" # if the above conditions matches, the PR will receive these labels add-labels = ["beta-nominated"] -[backport.t-compiler-stable-backport] -required-pr-labels = ["T-compiler"] -required-issue-label = "regression-from-stable-to-stable" -add-labels = ["stable-nominated"] # ------------------------------------------------------------------------------ # Ping groups @@ -742,13 +738,15 @@ message_on_reopen = "PR #{number} has been reopened. Pinging @*T-rustdoc*." [notify-zulip."beta-nominated".compiler] required_labels = ["T-compiler"] zulip_stream = 474880 # #t-compiler/backports -topic = "#{number}: beta-nominated" +topic = "#{number}: beta-backport nomination" message_on_add = [ """\ -@**channel** PR #{number} "{title}" has been nominated for beta backport. +PR #{number} "{title}" fixes a regression. +{recipients}, please evaluate nominating this PR for backport. +The following poll is a vibe-check and not binding. """, """\ -/poll Approve beta backport of #{number}? +/poll Should #{number} be beta backported? approve decline don't know @@ -1052,6 +1050,12 @@ cc = ["@rust-lang/clippy"] [mentions."src/tools/compiletest"] cc = ["@jieyouxu"] +[mentions."src/tools/compiletest/src/directives"] +message = """ +`compiletest` directives have been modified. Please add or update docs for the +new or modified directive in `src/doc/rustc-dev-guide/`. +""" + [mentions."src/tools/miri"] message = "The Miri subtree was changed" cc = ["@rust-lang/miri"] @@ -1366,7 +1370,9 @@ compiler = [ "@jackh726", "@jieyouxu", "@jdonszelmann", + "@JonathanBrouwer", "@lcnr", + "@madsmtm", "@Nadrieril", "@nnethercote", "@oli-obk", @@ -1382,6 +1388,7 @@ libs = [ "@tgross35", "@thomcc", "@ibraheemdev", + "@joboet", ] infra-ci = [ "@Mark-Simulacrum", @@ -1401,6 +1408,7 @@ docs = [ ] codegen = [ "@dianqk", + "@madsmtm", "@saethlin", "@workingjubilee", "@WaffleLapkin", @@ -1597,7 +1605,7 @@ labels = ["has-merge-commits", "S-waiting-on-author"] format = "rustc" project-name = "Rust" changelog-path = "RELEASES.md" -changelog-branch = "master" +changelog-branch = "main" [shortcut] diff --git a/typos.toml b/typos.toml index b0ff48f8fa28b..758239ffe751c 100644 --- a/typos.toml +++ b/typos.toml @@ -1,11 +1,11 @@ [files] extend-exclude = [ # exclude git (sub)modules and generated content - "compiler/rustc_codegen_gcc", - "compiler/rustc_codegen_cranelift", "compiler/rustc_baked_icu_data", - "library/compiler-builtins", + "compiler/rustc_codegen_cranelift", + "compiler/rustc_codegen_gcc", "library/backtrace", + "library/compiler-builtins", "library/stdarch", # generated lorem ipsum texts "library/alloctests/benches/str.rs", @@ -16,24 +16,25 @@ extend-exclude = [ # Add exclusions here, lines should be like `x = "x"`, where `x` is excluded word. # # Also see docs: https://github.com/crate-ci/typos/blob/v1.28.2/docs/reference.md -rplace = "rplace" arange = "arange" -unstalled = "unstalled" -taits = "taits" +childs = "childs" +clonable = "clonable" Datas = "Datas" -splitted = "splitted" +filetimes = "filetimes" leafs = "leafs" makro = "makro" +misformed = "misformed" +moreso = "moreso" optin = "optin" -unparseable = "unparseable" +publically = "publically" +rplace = "rplace" smove = "smove" -childs = "childs" -filetimes = "filetimes" -misformed = "misformed" +splitted = "splitted" +taits = "taits" targetting = "targetting" -publically = "publically" -clonable = "clonable" -moreso = "moreso" +unparseable = "unparseable" +unstability = "unstability" +unstalled = "unstalled" # this can be valid word, depends on dictionary edition #matcheable = "matcheable" @@ -46,12 +47,19 @@ moreso = "moreso" # I.e. you don't want (or can't) fix some constant name, like # `DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME` but actually # want to see `INVAILD` typo fixed in other places. -ERROR_FILENAME_EXCED_RANGE = "ERROR_FILENAME_EXCED_RANGE" +debug_aranges = "debug_aranges" DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME = "DNS_ERROR_INVAILD_VIRTUALIZATION_INSTANCE_NAME" +EnzymeTypeTreeShiftIndiciesEq = "EnzymeTypeTreeShiftIndiciesEq" +ERRNO_ACCES = "ERRNO_ACCES" ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS = "ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS" ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC = "ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC" +ERROR_FILENAME_EXCED_RANGE = "ERROR_FILENAME_EXCED_RANGE" ERROR_MCA_OCCURED = "ERROR_MCA_OCCURED" -ERRNO_ACCES = "ERRNO_ACCES" +ERROR_REQ_NOT_ACCEP = "ERROR_REQ_NOT_ACCEP" +Oppen = "Oppen" +# typos treats this as two different camelcase words (`SETTIN` and `Gs`) +# Tracked in: https://github.com/crate-ci/typos/issues/745 +SETTINGs = "SETTINGs" tolen = "tolen" [default] @@ -61,6 +69,8 @@ extend-ignore-words-re = [ ] extend-ignore-re = [ + # allow turning off spell checking + "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on", # ignore these intentional typo examples "/// 1 \\| #\\[cfg\\(widnows\\)\\]", "/// warning: unexpected `cfg` condition name: `widnows`", @@ -70,5 +80,5 @@ extend-ignore-re = [ "\"core::iter::adapters::Copie\"", "-Ccontrol-flow-guard", "concat!\\(\"CURRENT_RUSTC_VERSIO\", \"N\"\\)", - "\\*\\*v\\*\\*ariable" + "\\*\\*v\\*\\*ariable", ] diff --git a/x b/x index 551cfe6efbf33..4fce0be219e7c 100755 --- a/x +++ b/x @@ -15,7 +15,8 @@ realpath() { if [ -L "$path" ]; then readlink -f "$path" elif [ -d "$path" ]; then - (cd -P "$path" && pwd) + # "cd" is not always silent (e.g. when CDPATH is set), so discard its output. + (cd -P "$path" >/dev/null && pwd) else echo "$(realpath "$(dirname "$path")")/$(basename "$path")" fi