diff options
2134 files changed, 19276 insertions, 13311 deletions
diff --git a/.editorconfig b/.editorconfig index 03aab32bfc6..d065fa46469 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,6 @@ trim_trailing_whitespace = false [*.yml] indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 353bfcb6ac1..4c445f635d7 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -12,3 +12,5 @@ a06baa56b95674fc626b3c3fd680d6a65357fe60 c34fbfaad38cf5829ef5cfe780dc9d58480adeaa # move tests cf2dff2b1e3fa55fa5415d524200070d0d7aacfe +# Run rustfmt on bootstrap +b39a1d6f1a30ba29f25d7141038b9a5bf0126e36 diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md index 91c06402ca1..934312662be 100644 --- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/library_tracking_issue.md @@ -12,7 +12,7 @@ Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that -case, you can use use `issue = "none"` in your initial implementation PR. The +case, you can use `issue = "none"` in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be added without an RFC. --> @@ -65,7 +65,7 @@ the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final comment period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in -that period of 10 days, a stabilzation PR can be opened by anyone. +that period of 10 days, a stabilization PR can be opened by anyone. --> ### Unresolved Questions diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bce88472f96..dacf929278a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -292,6 +292,10 @@ jobs: - name: x86_64-gnu-distcheck os: ubuntu-20.04-8core-32gb env: {} + - name: x86_64-gnu-llvm-16 + env: + RUST_BACKTRACE: 1 + os: ubuntu-20.04-8core-32gb - name: x86_64-gnu-llvm-15 env: RUST_BACKTRACE: 1 diff --git a/Cargo.lock b/Cargo.lock index 12be36ef861..c58147ad757 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,12 +4,12 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.27.2", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] @@ -42,7 +42,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" dependencies = [ "cfg-if", - "getrandom", "once_cell", "version_check", ] @@ -80,6 +79,15 @@ dependencies = [ ] [[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] name = "annotate-snippets" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -108,7 +116,7 @@ dependencies = [ "anstyle-parse", "anstyle-wincon", "concolor-override", - "concolor-query 0.3.3", + "concolor-query", "is-terminal", "utf8parse", ] @@ -150,16 +158,10 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0639441fd17a3197d1cbca8dc8768cc172a63b64b4bb6c372e8f41ed0acc9bb" dependencies = [ - "object 0.30.1", + "object", ] [[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - -[[package]] name = "array_tool" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -167,12 +169,6 @@ checksum = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271" [[package]] name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a2f58b0bb10c380af2b26e57212856b8c9a59e0925b4c20f4a174a49734eaf7" @@ -228,38 +224,20 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.29.0", + "object", "rustc-demangle", ] [[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base64" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" - -[[package]] -name = "base64ct" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" - -[[package]] name = "basic-toml" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -275,15 +253,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bitmaps" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" -dependencies = [ - "typenum", -] - -[[package]] name = "block-buffer" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -316,15 +285,6 @@ dependencies = [ ] [[package]] -name = "btoi" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" -dependencies = [ - "num-traits", -] - -[[package]] name = "build-manifest" version = "0.1.0" dependencies = [ @@ -336,7 +296,7 @@ dependencies = [ "serde_json", "sha2", "tar", - "toml 0.5.7", + "toml", ] [[package]] @@ -352,14 +312,14 @@ dependencies = [ "indexmap", "serde", "serde_json", - "toml 0.5.7", + "toml", ] [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bytecount" @@ -377,12 +337,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" [[package]] -name = "bytesize" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a18687293a1546b67c246452202bbbf143d239cb43494cc163da14979082da" - -[[package]] name = "camino" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -392,108 +346,6 @@ dependencies = [ ] [[package]] -name = "cargo" -version = "0.71.0" -dependencies = [ - "anyhow", - "base64", - "bytesize", - "cargo-platform 0.1.2", - "cargo-test-macro", - "cargo-test-support", - "cargo-util", - "clap 4.2.1", - "crates-io", - "curl", - "curl-sys", - "env_logger 0.10.0", - "filetime", - "flate2", - "fwdansi", - "git2", - "git2-curl", - "gix", - "gix-features", - "glob", - "hex", - "hmac", - "home", - "http-auth", - "humantime 2.0.1", - "ignore", - "im-rc", - "indexmap", - "is-terminal", - "itertools", - "jobserver", - "lazy_static", - "lazycell", - "libc", - "libgit2-sys", - "log", - "memchr", - "opener", - "openssl", - "os_info", - "pasetors", - "pathdiff", - "pretty_env_logger", - "rand", - "rustc-workspace-hack", - "rustfix", - "same-file", - "semver", - "serde", - "serde-value", - "serde_ignored", - "serde_json", - "sha1", - "shell-escape", - "snapbox", - "strip-ansi-escapes", - "tar", - "tempfile", - "termcolor", - "time 0.3.17", - "toml 0.7.2", - "toml_edit", - "unicode-width", - "unicode-xid", - "url", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "cargo-credential" -version = "0.2.0" - -[[package]] -name = "cargo-credential-1password" -version = "0.2.0" -dependencies = [ - "cargo-credential", - "serde", - "serde_json", -] - -[[package]] -name = "cargo-credential-macos-keychain" -version = "0.2.0" -dependencies = [ - "cargo-credential", - "security-framework", -] - -[[package]] -name = "cargo-credential-wincred" -version = "0.2.0" -dependencies = [ - "cargo-credential", - "windows-sys 0.45.0", -] - -[[package]] name = "cargo-miri" version = "0.1.0" dependencies = [ @@ -510,13 +362,6 @@ dependencies = [ [[package]] name = "cargo-platform" version = "0.1.2" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ @@ -524,63 +369,13 @@ dependencies = [ ] [[package]] -name = "cargo-test-macro" -version = "0.1.0" - -[[package]] -name = "cargo-test-support" -version = "0.1.0" -dependencies = [ - "anyhow", - "cargo-test-macro", - "cargo-util", - "crates-io", - "filetime", - "flate2", - "git2", - "glob", - "itertools", - "lazy_static", - "pasetors", - "serde", - "serde_json", - "snapbox", - "tar", - "termcolor", - "time 0.3.17", - "toml 0.7.2", - "url", - "windows-sys 0.45.0", -] - -[[package]] -name = "cargo-util" -version = "0.2.4" -dependencies = [ - "anyhow", - "core-foundation", - "filetime", - "hex", - "jobserver", - "libc", - "log", - "miow 0.5.0", - "same-file", - "sha2", - "shell-escape", - "tempfile", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] name = "cargo_metadata" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c297bd3135f558552f99a0daa180876984ea2c4ffa7470314540dff8c654109a" dependencies = [ "camino", - "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo-platform", "semver", "serde", "serde_json", @@ -593,7 +388,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08a1ec454bc3eead8719cb56e15dbbfecdbc14e4b3a3ae4936cc6e31f5fc0d07" dependencies = [ "camino", - "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo-platform", "semver", "serde", "serde_json", @@ -609,9 +404,6 @@ name = "cc" version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" -dependencies = [ - "jobserver", -] [[package]] name = "cfg-if" @@ -679,15 +471,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "libc", + "iana-time-zone", "num-integer", "num-traits", "serde", - "time 0.1.43", "winapi", ] @@ -802,14 +593,13 @@ dependencies = [ "rustc-semver", "rustc-workspace-hack", "rustc_tools_util", - "semver", "serde", - "syn 1.0.102", + "syn 2.0.8", "tempfile", "termize", "tester", "tokio", - "toml 0.5.7", + "toml", "walkdir", ] @@ -830,7 +620,7 @@ dependencies = [ name = "clippy_lints" version = "0.1.70" dependencies = [ - "arrayvec 0.7.0", + "arrayvec", "cargo_metadata 0.15.3", "clippy_utils", "declare_clippy_lint", @@ -844,7 +634,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "toml 0.5.7", + "toml", "unicode-normalization", "unicode-script", "url", @@ -854,17 +644,21 @@ dependencies = [ name = "clippy_utils" version = "0.1.70" dependencies = [ - "arrayvec 0.7.0", + "arrayvec", "if_chain", "itertools", "rustc-semver", ] [[package]] -name = "clru" -version = "0.6.1" +name = "codespan-reporting" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] [[package]] name = "collect-license-metadata" @@ -951,9 +745,9 @@ dependencies = [ [[package]] name = "compiletest_rs" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70489bbb718aea4f92e5f48f2e3b5be670c2051de30e57cb6e5377b4aa08b372" +checksum = "e2731272cf25196735df1b52ab5bcba22cf9f99455626c4c8dc092bd5f7f66d0" dependencies = [ "diff", "filetime", @@ -973,17 +767,6 @@ dependencies = [ ] [[package]] -name = "concolor" -version = "0.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37" -dependencies = [ - "atty", - "bitflags", - "concolor-query 0.1.0", -] - -[[package]] name = "concolor-override" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -991,12 +774,6 @@ checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" [[package]] name = "concolor-query" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" - -[[package]] -name = "concolor-query" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" @@ -1005,21 +782,6 @@ dependencies = [ ] [[package]] -name = "const-oid" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" - -[[package]] -name = "content_inspector" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38" -dependencies = [ - "memchr", -] - -[[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1034,20 +796,10 @@ dependencies = [ ] [[package]] -name = "core-foundation" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5ed8e7e76c45974e15e41bfa8d5b0483cd90191639e01d8f5f1e606299d3fb" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] name = "core-foundation-sys" -version = "0.8.0" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a21fa21941700a3cd8fcb4091f361a6a712fac632f85d9f487cc892045d55c6" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "coverage_test_macros" @@ -1063,18 +815,6 @@ dependencies = [ ] [[package]] -name = "crates-io" -version = "0.36.0" -dependencies = [ - "anyhow", - "curl", - "percent-encoding", - "serde", - "serde_json", - "url", -] - -[[package]] name = "crc32fast" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1127,18 +867,6 @@ dependencies = [ ] [[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - -[[package]] name = "crypto-common" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1159,22 +887,6 @@ dependencies = [ ] [[package]] -name = "ct-codecs" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" - -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn 1.0.102", -] - -[[package]] name = "curl" version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1197,7 +909,6 @@ checksum = "14d05c10f541ae6f3bc5b3d923c20001f47db7d5f0b2bc6ad16490133842db79" dependencies = [ "cc", "libc", - "libnghttp2-sys", "libz-sys", "openssl-sys", "pkg-config", @@ -1206,6 +917,50 @@ dependencies = [ ] [[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.8", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.8", +] + +[[package]] name = "datafrog" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1217,18 +972,7 @@ version = "0.1.70" dependencies = [ "itertools", "quote", - "syn 1.0.102", -] - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", + "syn 2.0.8", ] [[package]] @@ -1269,7 +1013,6 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer", "crypto-common", - "subtle", ] [[package]] @@ -1351,33 +1094,6 @@ dependencies = [ ] [[package]] -name = "dunce" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", -] - -[[package]] -name = "ed25519-compact" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" -dependencies = [ - "getrandom", -] - -[[package]] name = "either" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1396,28 +1112,6 @@ dependencies = [ ] [[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct", - "crypto-bigint", - "der", - "digest", - "ff", - "generic-array", - "group", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core", - "sec1", - "subtle", - "zeroize", -] - -[[package]] name = "elsa" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1476,13 +1170,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1547,22 +1241,6 @@ dependencies = [ ] [[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a214f5bb88731d436478f3ae1f8a277b62124089ba9fb67f4f93fb100ef73c90" - -[[package]] name = "filetime" version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1582,14 +1260,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ - "cfg-if", "crc32fast", - "libc", - "libz-sys", "miniz_oxide", ] @@ -1634,21 +1309,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] name = "form_urlencoded" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1774,16 +1434,6 @@ dependencies = [ ] [[package]] -name = "fwdansi" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c1f5787fe85505d1f7777268db5103d80a7a374d2316a7ce262e57baf8f208" -dependencies = [ - "memchr", - "termcolor", -] - -[[package]] name = "generate-copyright" version = "0.1.0" dependencies = [ @@ -1820,10 +1470,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -1832,592 +1480,20 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ - "compiler_builtins", "fallible-iterator", "indexmap", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", "stable_deref_trait", ] [[package]] -name = "git2" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89511277159354bea13ae1e53e0c9ab85ba1b20d7e91618fa30e6bc5566857fb" -dependencies = [ - "bitflags", - "libc", - "libgit2-sys", - "log", - "openssl-probe", - "openssl-sys", - "url", -] - -[[package]] -name = "git2-curl" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f8b7432b72928cff76f69e59ed5327f94a52763731e71274960dee72fe5f8c" -dependencies = [ - "curl", - "git2", - "log", - "url", -] - -[[package]] -name = "gix" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabfac58aecb4a38cdd2568de66eb1f0d968fd6726f5a80cb8bea7944ef10cc0" -dependencies = [ - "gix-actor", - "gix-attributes", - "gix-config", - "gix-credentials", - "gix-date", - "gix-diff", - "gix-discover", - "gix-features", - "gix-glob", - "gix-hash", - "gix-hashtable", - "gix-index", - "gix-lock", - "gix-mailmap", - "gix-object", - "gix-odb", - "gix-pack", - "gix-path", - "gix-prompt", - "gix-protocol", - "gix-ref", - "gix-refspec", - "gix-revision", - "gix-sec", - "gix-tempfile", - "gix-transport", - "gix-traverse", - "gix-url", - "gix-validate", - "gix-worktree", - "log", - "once_cell", - "prodash", - "signal-hook", - "smallvec", - "thiserror", - "unicode-normalization", -] - -[[package]] -name = "gix-actor" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc22b0cdc52237667c301dd7cdc6ead8f8f73c9f824e9942c8ebd6b764f6c0bf" -dependencies = [ - "bstr 1.3.0", - "btoi", - "gix-date", - "itoa", - "nom", - "thiserror", -] - -[[package]] -name = "gix-attributes" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2231a25934a240d0a4b6f4478401c73ee81d8be52de0293eedbc172334abf3e1" -dependencies = [ - "bstr 1.3.0", - "gix-features", - "gix-glob", - "gix-path", - "gix-quote", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-bitmap" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "024bca0c7187517bda5ea24ab148c9ca8208dd0c3e2bea88cdb2008f91791a6d" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-chunk" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d39583cab06464b8bf73b3f1707458270f0e7383cb24c3c9c1a16e6f792978" -dependencies = [ - "thiserror", -] - -[[package]] -name = "gix-command" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2c6f75c1e0f924de39e750880a6e21307194bb1ab773efe3c7d2d787277f8ab" -dependencies = [ - "bstr 1.3.0", -] - -[[package]] -name = "gix-config" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c62e26ce11f607712e4f49a0a192ed87675d30187fd61be070abbd607d12f1" -dependencies = [ - "bstr 1.3.0", - "gix-config-value", - "gix-features", - "gix-glob", - "gix-path", - "gix-ref", - "gix-sec", - "memchr", - "nom", - "once_cell", - "smallvec", - "thiserror", - "unicode-bom", -] - -[[package]] -name = "gix-config-value" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d4a4ba0531e46fe558459557a5b29fb86c3e4b2666c1c0861d93c7c678331" -dependencies = [ - "bitflags", - "bstr 1.3.0", - "gix-path", - "libc", - "thiserror", -] - -[[package]] -name = "gix-credentials" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be32b5fe339a31b8e53fa854081dc914c45020dcb64637f3c21baf69c96fc1b" -dependencies = [ - "bstr 1.3.0", - "gix-command", - "gix-config-value", - "gix-path", - "gix-prompt", - "gix-sec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-date" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96271912ce39822501616f177dea7218784e6c63be90d5f36322ff3a722aae2" -dependencies = [ - "bstr 1.3.0", - "itoa", - "thiserror", - "time 0.3.17", -] - -[[package]] -name = "gix-diff" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585b0834d4b6791a848637c4e109545fda9b0f29b591ba55edb33ceda6e7856b" -dependencies = [ - "gix-hash", - "gix-object", - "imara-diff", - "thiserror", -] - -[[package]] -name = "gix-discover" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c204adba5ebd211c74735cbb65817d277e154486bac0dffa3701f163b80350" -dependencies = [ - "bstr 1.3.0", - "dunce", - "gix-hash", - "gix-path", - "gix-ref", - "gix-sec", - "thiserror", -] - -[[package]] -name = "gix-features" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6a9dfa7b3c1a99315203e8b97f8f99f3bd95731590607abeaa5ca31bc41fe3" -dependencies = [ - "bytes", - "crc32fast", - "crossbeam-channel", - "flate2", - "gix-hash", - "libc", - "once_cell", - "parking_lot 0.12.1", - "prodash", - "sha1_smol", - "thiserror", - "walkdir", -] - -[[package]] -name = "gix-glob" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93e43efd776bc543f46f0fd0ca3d920c37af71a764a16f2aebd89765e9ff2993" -dependencies = [ - "bitflags", - "bstr 1.3.0", -] - -[[package]] -name = "gix-hash" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0c5a9f4d621d4f4ea046bb331df5c746ca735b8cae5b234cc2be70ee4dbef0" -dependencies = [ - "hex", - "thiserror", -] - -[[package]] -name = "gix-hashtable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9609c1b8f36f12968e6a6098f7cdb52004f7d42d570f47a2d6d7c16612f19acb" -dependencies = [ - "gix-hash", - "hashbrown 0.13.1", - "parking_lot 0.12.1", -] - -[[package]] -name = "gix-index" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12caf7886c7ba06f2b28835cdc2be1dca86bd047d00299d2d49e707ce1c2616" -dependencies = [ - "bitflags", - "bstr 1.3.0", - "btoi", - "filetime", - "gix-bitmap", - "gix-features", - "gix-hash", - "gix-lock", - "gix-object", - "gix-traverse", - "itoa", - "memmap2 0.5.10", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-lock" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66119ff8a4a395d0ea033fef718bc85f8b4f0855874f4ce1e005fc16cfe1f66e" -dependencies = [ - "fastrand", - "gix-tempfile", - "thiserror", -] - -[[package]] -name = "gix-mailmap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b66aea5e52875cd4915f4957a6f4b75831a36981e2ec3f5fad9e370e444fe1a" -dependencies = [ - "bstr 1.3.0", - "gix-actor", - "thiserror", -] - -[[package]] -name = "gix-object" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df068db9180ee935fbb70504848369e270bdcb576b05c0faa8b9fd3b86fc017" -dependencies = [ - "bstr 1.3.0", - "btoi", - "gix-actor", - "gix-features", - "gix-hash", - "gix-validate", - "hex", - "itoa", - "nom", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-odb" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9a5f9e1afbd509761977a2ea02869cedaaba500b4e783deb2e4de5179a55a80" -dependencies = [ - "arc-swap", - "gix-features", - "gix-hash", - "gix-object", - "gix-pack", - "gix-path", - "gix-quote", - "parking_lot 0.12.1", - "tempfile", - "thiserror", -] - -[[package]] -name = "gix-pack" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51db84e1459a8022e518d40a8778028d793dbb28e4d35c9a5eaf92658fb0775" -dependencies = [ - "clru", - "gix-chunk", - "gix-diff", - "gix-features", - "gix-hash", - "gix-hashtable", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-traverse", - "memmap2 0.5.10", - "parking_lot 0.12.1", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-packetline" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63e5e5a9a92d4fc6b63ff9d94954d25c779ce25c98d5bbe2e4399aa42f7073c" -dependencies = [ - "bstr 1.3.0", - "hex", - "thiserror", -] - -[[package]] -name = "gix-path" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6c104a66dec149cb8f7aaafc6ab797654cf82d67f050fd0cb7e7294e328354b" -dependencies = [ - "bstr 1.3.0", - "thiserror", -] - -[[package]] -name = "gix-prompt" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20cebf73229debaa82574c4fd20dcaf00fa8d4bfce823a862c4e990d7a0b5b4" -dependencies = [ - "gix-command", - "gix-config-value", - "nix", - "parking_lot 0.12.1", - "thiserror", -] - -[[package]] -name = "gix-protocol" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d372ab11d5d28ac21800e3f1a6603a67c1ead57f6f5fab07e1e73e960f331c1" -dependencies = [ - "bstr 1.3.0", - "btoi", - "gix-credentials", - "gix-features", - "gix-hash", - "gix-transport", - "maybe-async", - "nom", - "thiserror", -] - -[[package]] -name = "gix-quote" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a282f5a8d9ee0b09ec47390ac727350c48f2f5c76d803cd8da6b3e7ad56e0bcb" -dependencies = [ - "bstr 1.3.0", - "btoi", - "thiserror", -] - -[[package]] -name = "gix-ref" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a0ed29e581f04b904ecd0c32b11f33b8209b5a0af9c43f415249a4f2fba632" -dependencies = [ - "gix-actor", - "gix-features", - "gix-hash", - "gix-lock", - "gix-object", - "gix-path", - "gix-tempfile", - "gix-validate", - "memmap2 0.5.10", - "nom", - "thiserror", -] - -[[package]] -name = "gix-refspec" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba332462bda2e8efeae4302b39a6ed01ad56ef772fd5b7ef197cf2798294d65" -dependencies = [ - "bstr 1.3.0", - "gix-hash", - "gix-revision", - "gix-validate", - "smallvec", - "thiserror", -] - -[[package]] -name = "gix-revision" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed98e4a0254953c64bc913bd23146a1de662067d5cf974cbdde396958b39e5b0" -dependencies = [ - "bstr 1.3.0", - "gix-date", - "gix-hash", - "gix-hashtable", - "gix-object", - "thiserror", -] - -[[package]] -name = "gix-sec" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ffa5bf0772f9b01de501c035b6b084cf9b8bb07dec41e3afc6a17336a65f47" -dependencies = [ - "bitflags", - "dirs", - "gix-path", - "libc", - "windows 0.43.0", -] - -[[package]] -name = "gix-tempfile" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88751f247234b1f73c8e8056fd835a0999b04e596e052302cb71186005dc4b27" -dependencies = [ - "libc", - "once_cell", - "parking_lot 0.12.1", - "signal-hook", - "signal-hook-registry", - "tempfile", -] - -[[package]] -name = "gix-transport" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d633947b36a2fbbc089195bdc71621158f1660c2ff2a6b12b0279c16e2f764bc" -dependencies = [ - "base64", - "bstr 1.3.0", - "curl", - "gix-command", - "gix-credentials", - "gix-features", - "gix-packetline", - "gix-quote", - "gix-sec", - "gix-url", - "thiserror", -] - -[[package]] -name = "gix-traverse" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd9a4a07bb22168dc79c60e1a6a41919d198187ca83d8a5940ad8d7122a45df3" -dependencies = [ - "gix-hash", - "gix-hashtable", - "gix-object", - "thiserror", -] - -[[package]] -name = "gix-url" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044072b7ce8601b62dcec841b92129f5cc677072823324121b395d766ac5f528" -dependencies = [ - "bstr 1.3.0", - "gix-features", - "gix-path", - "home", - "thiserror", - "url", -] - -[[package]] -name = "gix-validate" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69ddb780ea1465255e66818d75b7098371c58dbc9560da4488a44b9f5c7e443" -dependencies = [ - "bstr 1.3.0", - "thiserror", -] - -[[package]] -name = "gix-worktree" -version = "0.14.0" +name = "gimli" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cb9af6e56152953d8fe113c4f9d7cf60cf7a982362711e9200a255579b49cb" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" dependencies = [ - "bstr 1.3.0", - "gix-attributes", - "gix-features", - "gix-glob", - "gix-hash", - "gix-index", - "gix-object", - "gix-path", - "io-close", - "thiserror", + "compiler_builtins", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -2440,17 +1516,6 @@ dependencies = [ ] [[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff", - "rand_core", - "subtle", -] - -[[package]] name = "gsgdt" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2461,21 +1526,6 @@ dependencies = [ [[package]] name = "handlebars" -version = "3.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3" -dependencies = [ - "log", - "pest", - "pest_derive", - "quick-error 2.0.1", - "serde", - "serde_json", - "walkdir", -] - -[[package]] -name = "handlebars" version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "360d9740069b2f6cbb63ce2dbaa71a20d3185350cbb990d7bebeb9318415eb17" @@ -2542,33 +1592,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" [[package]] -name = "hkdf" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" -dependencies = [ - "winapi", -] - -[[package]] name = "html-checker" version = "0.1.0" dependencies = [ @@ -2591,21 +1614,12 @@ dependencies = [ ] [[package]] -name = "http-auth" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b40b39d66c28829a0cf4d09f7e139ff8201f7500a5083732848ed3b4b4d850" -dependencies = [ - "memchr", -] - -[[package]] name = "humantime" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" dependencies = [ - "quick-error 1.2.3", + "quick-error", ] [[package]] @@ -2615,6 +1629,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] name = "icu_list" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2715,30 +1753,6 @@ dependencies = [ ] [[package]] -name = "im-rc" -version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" -dependencies = [ - "bitmaps", - "rand_core", - "rand_xoshiro", - "sized-chunks", - "typenum", - "version_check", -] - -[[package]] -name = "imara-diff" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" -dependencies = [ - "ahash 0.8.2", - "hashbrown 0.12.3", -] - -[[package]] name = "indenter" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2806,16 +1820,6 @@ dependencies = [ ] [[package]] -name = "io-close" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" -dependencies = [ - "libc", - "winapi", -] - -[[package]] name = "io-lifetimes" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2827,14 +1831,14 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.0", "io-lifetimes", "rustix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -2873,9 +1877,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -2960,20 +1964,6 @@ dependencies = [ ] [[package]] -name = "libgit2-sys" -version = "0.15.0+1.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "032e537ae4dd4e50c877f258dc55fcd0657b5021f454094a425bb6bcc9edea4c" -dependencies = [ - "cc", - "libc", - "libssh2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", -] - -[[package]] name = "libloading" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2990,39 +1980,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] -name = "libnghttp2-sys" -version = "0.1.4+1.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03624ec6df166e79e139a2310ca213283d6b3c30810c54844f307086d4488df1" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "libssh2-sys" -version = "0.3.0" +name = "libz-sys" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ "cc", "libc", - "libz-sys", - "openssl-sys", "pkg-config", "vcpkg", ] [[package]] -name = "libz-sys" -version = "1.1.3" +name = "link-cplusplus" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" dependencies = [ "cc", - "libc", - "pkg-config", - "vcpkg", ] [[package]] @@ -3050,9 +2025,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "litemap" @@ -3136,17 +2111,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] -name = "maybe-async" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.102", -] - -[[package]] name = "md-5" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3168,7 +2132,7 @@ dependencies = [ "clap_complete", "elasticlunr-rs", "env_logger 0.10.0", - "handlebars 4.3.3", + "handlebars", "log", "memchr", "once_cell", @@ -3179,31 +2143,18 @@ dependencies = [ "serde_json", "shlex", "tempfile", - "toml 0.5.7", + "toml", "topological-sort", ] [[package]] -name = "mdman" -version = "0.1.0" -dependencies = [ - "anyhow", - "handlebars 3.5.5", - "pretty_assertions", - "pulldown-cmark", - "same-file", - "serde_json", - "url", -] - -[[package]] name = "measureme" version = "10.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbdc226fa10994e8f66a4d2f6f000148bc563a1c671b6dcd2135737018033d8a" dependencies = [ "log", - "memmap2 0.2.1", + "memmap2", "parking_lot 0.11.2", "perf-event-open-sys", "rustc-hash", @@ -3230,15 +2181,6 @@ dependencies = [ ] [[package]] -name = "memmap2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] - -[[package]] name = "memoffset" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3277,9 +2219,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", "compiler_builtins", @@ -3340,18 +2282,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" [[package]] -name = "nix" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" -dependencies = [ - "bitflags", - "cfg-if", - "libc", - "static_assertions", -] - -[[package]] name = "nom" version = "7.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3363,21 +2293,6 @@ dependencies = [ ] [[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] name = "num-integer" version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3407,37 +2322,19 @@ dependencies = [ ] [[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - -[[package]] -name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "compiler_builtins", - "memchr", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", -] - -[[package]] name = "object" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d864c91689fdc196779b98dba0aceac6118594c2df6ee5d943eb6a8df4d107a" dependencies = [ + "compiler_builtins", "crc32fast", "flate2", "hashbrown 0.13.1", "indexmap", "memchr", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -3466,47 +2363,12 @@ dependencies = [ ] [[package]] -name = "openssl" -version = "0.10.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.8", -] - -[[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] -name = "openssl-src" -version = "111.25.0+1.1.1t" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3173cd3626c43e3854b1b727422a276e568d9ec5fe8cec197822cf52cfb743d6" -dependencies = [ - "cc", -] - -[[package]] name = "openssl-sys" version = "0.9.84" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3514,75 +2376,23 @@ checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] [[package]] -name = "ordered-float" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" -dependencies = [ - "num-traits", -] - -[[package]] -name = "orion" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2baf7fd2e326e3895c681176788dd227fcd8369350e53c570592d8563fecbb6" -dependencies = [ - "fiat-crypto", - "subtle", - "zeroize", -] - -[[package]] -name = "os_info" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5209b2162b2c140df493a93689e04f8deab3a67634f5bc7a553c0a98e5b8d399" -dependencies = [ - "log", - "serde", - "winapi", -] - -[[package]] name = "os_str_bytes" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" [[package]] -name = "output_vt100" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66" -dependencies = [ - "winapi", -] - -[[package]] name = "owo-colors" version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] -name = "p384" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" -dependencies = [ - "ecdsa", - "elliptic-curve", - "sha2", -] - -[[package]] name = "packed_simd_2" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3664,42 +2474,12 @@ dependencies = [ ] [[package]] -name = "pasetors" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed20c4c21d893414f42e0cbfebe8a8036b5ae9b0264611fb6504e395eda6ceec" -dependencies = [ - "ct-codecs", - "ed25519-compact", - "getrandom", - "orion", - "p384", - "rand_core", - "regex", - "serde", - "serde_json", - "sha2", - "subtle", - "time 0.3.17", - "zeroize", -] - -[[package]] name = "pathdiff" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] -name = "pem-rfc7468" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" -dependencies = [ - "base64ct", -] - -[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3819,16 +2599,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der", - "spki", -] - -[[package]] name = "pkg-config" version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3858,28 +2628,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] -name = "pretty_assertions" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" -dependencies = [ - "ctor", - "diff", - "output_vt100", - "yansi", -] - -[[package]] -name = "pretty_env_logger" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" -dependencies = [ - "env_logger 0.7.1", - "log", -] - -[[package]] name = "proc-macro-error" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3927,15 +2675,6 @@ dependencies = [ ] [[package]] -name = "prodash" -version = "23.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d73c6b64cb5b99eb63ca97d378685712617ec0172ff5c04cd47a489d3e2c51f8" -dependencies = [ - "parking_lot 0.12.1", -] - -[[package]] name = "profiler_builtins" version = "0.0.0" dependencies = [ @@ -3977,12 +2716,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - -[[package]] name = "quine-mc_cluskey" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4149,21 +2882,9 @@ dependencies = [ ] [[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint", - "hmac", - "zeroize", -] - -[[package]] name = "rls" version = "2.0.0" dependencies = [ - "rustc-workspace-hack", "serde", "serde_json", ] @@ -4275,22 +2996,8 @@ dependencies = [ [[package]] name = "rustc-workspace-hack" version = "1.0.0" -dependencies = [ - "bstr 0.2.17", - "clap 3.2.20", - "getrandom", - "hashbrown 0.12.3", - "libc", - "libz-sys", - "once_cell", - "rand", - "regex", - "serde_json", - "smallvec", - "syn 1.0.102", - "url", - "winapi", -] +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" [[package]] name = "rustc_abi" @@ -4346,6 +3053,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -4369,6 +3077,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_macros", "rustc_parse", "rustc_session", @@ -4396,6 +3105,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_macros", "rustc_serialize", @@ -4421,9 +3131,9 @@ dependencies = [ "either", "itertools", "polonius-engine", - "rustc_const_eval", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -4453,6 +3163,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_lint_defs", "rustc_macros", @@ -4474,13 +3185,14 @@ dependencies = [ "cstr", "libc", "measureme", - "object 0.30.1", + "object", "rustc-demangle", "rustc_ast", "rustc_attr", "rustc_codegen_ssa", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_index", @@ -4496,7 +3208,6 @@ dependencies = [ "serde", "serde_json", "smallvec", - "tempfile", "tracing", ] @@ -4510,7 +3221,7 @@ dependencies = [ "itertools", "jobserver", "libc", - "object 0.30.1", + "object", "pathdiff", "regex", "rustc_arena", @@ -4518,6 +3229,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_incremental", @@ -4550,6 +3262,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -4568,7 +3281,7 @@ dependencies = [ name = "rustc_data_structures" version = "0.0.0" dependencies = [ - "arrayvec 0.7.0", + "arrayvec", "bitflags", "cfg-if", "elsa", @@ -4578,7 +3291,7 @@ dependencies = [ "jobserver", "libc", "measureme", - "memmap2 0.2.1", + "memmap2", "parking_lot 0.11.2", "rustc-hash", "rustc-rayon", @@ -4587,9 +3300,7 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", - "serde_json", "smallvec", - "stable_deref_trait", "stacker", "tempfile", "thin-vec", @@ -4624,6 +3335,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", @@ -4672,6 +3384,7 @@ dependencies = [ "intl-memoizer", "rustc_baked_icu_data", "rustc_data_structures", + "rustc_fluent_macro", "rustc_macros", "rustc_serialize", "rustc_span", @@ -4688,6 +3401,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_error_messages", + "rustc_fluent_macro", "rustc_hir", "rustc_lint_defs", "rustc_macros", @@ -4716,6 +3430,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_lint_defs", "rustc_macros", @@ -4737,6 +3452,19 @@ dependencies = [ ] [[package]] +name = "rustc_fluent_macro" +version = "0.1.0" +dependencies = [ + "annotate-snippets", + "fluent-bundle", + "fluent-syntax", + "proc-macro2", + "quote", + "syn 2.0.8", + "unic-langid", +] + +[[package]] name = "rustc_fs_util" version = "0.0.0" @@ -4772,10 +3500,11 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", - "rustc_lint", + "rustc_lint_defs", "rustc_macros", "rustc_middle", "rustc_session", @@ -4784,7 +3513,6 @@ dependencies = [ "rustc_trait_selection", "rustc_type_ir", "smallvec", - "thin-vec", "tracing", ] @@ -4806,6 +3534,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_hir_analysis", @@ -4833,6 +3562,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_graphviz", "rustc_hir", @@ -4849,7 +3579,7 @@ dependencies = [ name = "rustc_index" version = "0.0.0" dependencies = [ - "arrayvec 0.7.0", + "arrayvec", "rustc_macros", "rustc_serialize", "smallvec", @@ -4861,6 +3591,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -4891,6 +3622,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_expand", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_analysis", @@ -4917,7 +3649,6 @@ dependencies = [ "rustc_trait_selection", "rustc_traits", "rustc_ty_utils", - "smallvec", "tracing", ] @@ -4940,6 +3671,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -4993,14 +3725,10 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ - "annotate-snippets", - "fluent-bundle", - "fluent-syntax", "proc-macro2", "quote", "syn 2.0.8", "synstructure 0.13.0", - "unic-langid", ] [[package]] @@ -5016,6 +3744,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_pretty", @@ -5027,7 +3756,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_type_ir", - "smallvec", "snap", "tempfile", "tracing", @@ -5053,6 +3781,7 @@ dependencies = [ "rustc_error_messages", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -5078,6 +3807,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -5101,6 +3831,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -5144,6 +3875,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -5153,7 +3885,6 @@ dependencies = [ "rustc_target", "serde", "serde_json", - "smallvec", "tracing", ] @@ -5167,6 +3898,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_macros", "rustc_session", @@ -5197,6 +3929,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_lexer", @@ -5217,6 +3950,7 @@ dependencies = [ "libloading", "rustc_ast", "rustc_errors", + "rustc_fluent_macro", "rustc_lint", "rustc_macros", "rustc_metadata", @@ -5232,6 +3966,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_hir_analysis", "rustc_macros", @@ -5268,11 +4003,11 @@ version = "0.0.0" dependencies = [ "parking_lot 0.11.2", "rustc-rayon-core", - "rustc_arena", "rustc_ast", "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -5300,6 +4035,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -5333,9 +4069,9 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", - "rustc_index", "rustc_lint_defs", "rustc_macros", "rustc_serialize", @@ -5384,6 +4120,7 @@ dependencies = [ "rustc-demangle", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_macros", "rustc_middle", @@ -5403,7 +4140,6 @@ dependencies = [ "rustc_data_structures", "rustc_feature", "rustc_fs_util", - "rustc_index", "rustc_macros", "rustc_serialize", "rustc_span", @@ -5421,11 +4157,11 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f" name = "rustc_trait_selection" version = "0.0.0" dependencies = [ - "itertools", "rustc_ast", "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -5452,7 +4188,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_hir", - "rustc_index", "rustc_infer", "rustc_middle", "rustc_span", @@ -5483,6 +4218,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -5521,7 +4257,7 @@ dependencies = [ name = "rustdoc" version = "0.0.0" dependencies = [ - "arrayvec 0.7.0", + "arrayvec", "askama", "expect-test", "itertools", @@ -5606,7 +4342,7 @@ dependencies = [ "serde_json", "term", "thiserror", - "toml 0.5.7", + "toml", "unicode-segmentation", "unicode-width", "unicode_categories", @@ -5614,16 +4350,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.5" +version = "0.37.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -5670,41 +4406,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.0.0" +name = "scratch" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" [[package]] name = "self_cell" @@ -5731,16 +4436,6 @@ dependencies = [ ] [[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - -[[package]] name = "serde_derive" version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5752,15 +4447,6 @@ dependencies = [ ] [[package]] -name = "serde_ignored" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2c7d39d14f2f2ea82239de71594782f186fd03501ac81f0ce08e674819ff2f" -dependencies = [ - "serde", -] - -[[package]] name = "serde_json" version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5773,15 +4459,6 @@ dependencies = [ ] [[package]] -name = "serde_spanned" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" -dependencies = [ - "serde", -] - -[[package]] name = "sha1" version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5793,12 +4470,6 @@ dependencies = [ ] [[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - -[[package]] name = "sha2" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5831,57 +4502,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d" [[package]] -name = "signal-hook" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest", - "rand_core", -] - -[[package]] -name = "similar" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" - -[[package]] name = "siphasher" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" [[package]] -name = "sized-chunks" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e65d6a9f13cd78f361ea5a2cf53a45d67cdda421ba0316b9be101560f3d207" -dependencies = [ - "bitmaps", - "typenum", -] - -[[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5900,30 +4526,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" [[package]] -name = "snapbox" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293" -dependencies = [ - "concolor", - "content_inspector", - "dunce", - "filetime", - "normalize-line-endings", - "similar", - "snapbox-macros", - "tempfile", - "walkdir", - "yansi", -] - -[[package]] -name = "snapbox-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a253e6f894cfa440cba00600a249fa90869d8e0ec45ab274a456e043a0ce8f2" - -[[package]] name = "socket2" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5947,9 +4549,9 @@ dependencies = [ [[package]] name = "spdx-rs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c02f6eb7e7b4100c272f685a9ccaccaab302324e8c7ec3e2ee72340fb29ff3" +checksum = "6b1ec09829bf2d82c175c121b20de11ffab2def83bd55979002099b1f9956c9b" dependencies = [ "chrono", "log", @@ -5963,16 +4565,6 @@ dependencies = [ ] [[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der", -] - -[[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6012,7 +4604,7 @@ dependencies = [ "hermit-abi 0.3.0", "libc", "miniz_oxide", - "object 0.29.0", + "object", "panic_abort", "panic_unwind", "profiler_builtins", @@ -6062,15 +4654,6 @@ dependencies = [ ] [[package]] -name = "strip-ansi-escapes" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011cbb39cf7c1f62871aea3cc46e5817b0937b49e9447370c93cacbe93a766d8" -dependencies = [ - "vte", -] - -[[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6096,12 +4679,6 @@ dependencies = [ ] [[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] name = "suggest-tests" version = "0.1.0" dependencies = [ @@ -6214,12 +4791,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ "rustix", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -6295,9 +4872,9 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da8fbf660a019b6bf11ea95762041464aa9099cc293b6a66d77cea5107619671" dependencies = [ - "gimli", + "gimli 0.26.2", "hashbrown 0.12.3", - "object 0.30.1", + "object", "tracing", ] @@ -6323,7 +4900,7 @@ dependencies = [ name = "tidy" version = "0.1.0" dependencies = [ - "cargo-platform 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cargo-platform", "cargo_metadata 0.15.3", "ignore", "lazy_static", @@ -6339,45 +4916,6 @@ name = "tier-check" version = "0.1.0" [[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" -dependencies = [ - "itoa", - "libc", - "num_threads", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - -[[package]] -name = "time-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" -dependencies = [ - "time-core", -] - -[[package]] name = "tinystr" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6424,40 +4962,6 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5" -dependencies = [ - "indexmap", - "nom8", - "serde", - "serde_spanned", - "toml_datetime", -] - -[[package]] name = "topological-sort" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6721,12 +5225,6 @@ dependencies = [ ] [[package]] -name = "unicode-bom" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63ec69f541d875b783ca40184d655f2927c95f0bffd486faa83cd3ac3529ec32" - -[[package]] name = "unicode-ident" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6841,9 +5339,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "0.8.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" dependencies = [ "getrandom", ] @@ -6867,27 +5365,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] -name = "vte" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cbce692ab4ca2f1f3047fcf732430249c0e971bfdd2b234cf2c47ad93af5983" -dependencies = [ - "arrayvec 0.5.2", - "utf8parse", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ff" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] name = "walkdir" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6911,9 +5388,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6921,9 +5398,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -6936,9 +5413,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6946,9 +5423,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -6959,9 +5436,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "winapi" @@ -6996,26 +5473,20 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.43.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04662ed0e3e5630dfa9b26e4cb823b817f1a9addda855d973a9458c236556244" +checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets 0.42.2", ] [[package]] name = "windows" -version = "0.46.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -7024,13 +5495,13 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -7039,7 +5510,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -7048,13 +5528,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -7064,42 +5559,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] name = "writeable" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7144,12 +5681,6 @@ dependencies = [ ] [[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - -[[package]] name = "yansi-term" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7204,12 +5735,6 @@ dependencies = [ ] [[package]] -name = "zeroize" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" - -[[package]] name = "zerovec" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml index 1fcaaf6ddc4..a497d7321e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,12 +22,6 @@ members = [ "src/tools/remote-test-server", "src/tools/rust-installer", "src/tools/rust-demangler", - "src/tools/cargo", - "src/tools/cargo/crates/credential/cargo-credential-1password", - "src/tools/cargo/crates/credential/cargo-credential-macos-keychain", - "src/tools/cargo/crates/credential/cargo-credential-wincred", - "src/tools/cargo/crates/mdman", - # "src/tools/cargo/crates/resolver-tests", "src/tools/rustdoc", "src/tools/rls", "src/tools/rustfmt", @@ -106,10 +100,6 @@ miniz_oxide.debug = 0 object.debug = 0 [patch.crates-io] -# See comments in `src/tools/rustc-workspace-hack/README.md` for what's going on -# here -rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' } - # See comments in `library/rustc-std-workspace-core/README.md` for what's going on # here rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' } diff --git a/README.md b/README.md index c19e129a920..41b135972af 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Read ["Installation"] from [The Book]. The Rust build system uses a Python script called `x.py` to build the compiler, which manages the bootstrapping process. It lives at the root of the project. +It also uses a file named `config.toml` to determine various configuration settings for the build. +You can see a full list of options in `config.example.toml`. The `x.py` command can be run directly on most Unix systems in the following format: @@ -85,6 +87,8 @@ See [the rustc-dev-guide for more info][sysllvm]. ### Building on a Unix-like system +#### Build steps + 1. Clone the [source] with `git`: ```sh @@ -96,18 +100,13 @@ See [the rustc-dev-guide for more info][sysllvm]. 2. Configure the build settings: - The Rust build system uses a file named `config.toml` in the root of the - source tree to determine various configuration settings for the build. - Set up the defaults intended for distros to get started. You can see a full - list of options in `config.example.toml`. - ```sh - printf 'profile = "user" \nchangelog-seen = 2 \n' > config.toml + ./configure ``` If you plan to use `x.py install` to create an installation, it is recommended that you set the `prefix` value in the `[install]` section to a - directory. + directory: `./configure --set install.prefix=<path>` 3. Build and install: @@ -117,12 +116,25 @@ See [the rustc-dev-guide for more info][sysllvm]. When complete, `./x.py install` will place several programs into `$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the - API-documentation tool. If you've set `profile = "user"` or - `build.extended = true`, it will also include [Cargo], Rust's package - manager. + API-documentation tool. By default, it will also include [Cargo], Rust's package manager. + You can disable this behavior by passing `--set build.extended=false` to `./configure`. [Cargo]: https://github.com/rust-lang/cargo +#### Configure and Make + +This project provides a configure script and makefile (the latter of which just invokes `x.py`). +`./configure` is the recommended way to programatically generate a `config.toml`. `make` is not +recommended (we suggest using `x.py` directly), but it is supported and we try not to break it +unnecessarily. + +```sh +./configure +make && sudo make install +``` + +`configure` generates a `config.toml` which can also be used with normal `x.py` invocations. + ### Building on Windows On Windows, we suggest using [winget] to install dependencies by running the @@ -186,7 +198,7 @@ toolchain. 4. Navigate to Rust's source code (or clone it), then build it: ```sh - ./x.py build && ./x.py install + python x.py setup user && python x.py build && python x.py install ``` #### MSVC @@ -204,6 +216,7 @@ With these dependencies installed, you can build the compiler in a `cmd.exe` shell with: ```sh +python x.py setup user python x.py build ``` @@ -232,21 +245,7 @@ Windows build triples are: The build triple can be specified by either specifying `--build=<triple>` when invoking `x.py` commands, or by creating a `config.toml` file (as described in -[Installing from Source](#installing-from-source)), and modifying the `build` -option under the `[build]` section. - -### Configure and Make - -While it's not the recommended build system, this project also provides a -configure script and makefile (the latter of which just invokes `x.py`). - -```sh -./configure -make && sudo make install -``` - -`configure` generates a `config.toml` which can also be used with normal `x.py` -invocations. +[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing `--set build.build=<triple>` to `./configure`. ## Building Documentation diff --git a/RELEASES.md b/RELEASES.md index b89178a6f68..e72905c15bd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -88,7 +88,11 @@ Compatibility Notes - [When `default-features` is set to false of a workspace dependency, and an inherited dependency of a member has `default-features = true`, Cargo will enable default features of that dependency.](https://github.com/rust-lang/cargo/pull/11409/) - [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/) - [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/) - +- [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886) + If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By + default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the + list. + <a id="1.69.0-Internal-Changes"></a> Internal Changes @@ -963,7 +967,7 @@ Compatibility Notes - [rustdoc: doctests are now run on unexported `macro_rules!` macros, matching other private items][96630] - [rustdoc: Remove .woff font files][96279] - [Enforce Copy bounds for repeat elements while considering lifetimes][95819] -- [Windows: Fix potentinal unsoundness by aborting if `File` reads or writes cannot +- [Windows: Fix potential unsoundness by aborting if `File` reads or writes cannot complete synchronously][95469]. Internal Changes @@ -1794,10 +1798,10 @@ Libraries - [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744] - [`impl From<[(K, V); N]>` for all collections.][rust#84111] - [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363] -- [Treat invalid environment variable names as non-existent.][rust#86183] +- [Treat invalid environment variable names as nonexistent.][rust#86183] Previously, the environment functions would panic if given a variable name with an internal null character or equal sign (`=`). Now, these functions will - just treat such names as non-existent variables, since the OS cannot represent + just treat such names as nonexistent variables, since the OS cannot represent the existence of a variable with such a name. Stabilised APIs @@ -1990,7 +1994,7 @@ Compatibility Notes kinds of errors could be categorised [into newer more specific `ErrorKind` variants][79965], and that they do not represent a user error. - [Using environment variable names with `process::Command` on Windows now - behaves as expected.][85270] Previously using envionment variables with + behaves as expected.][85270] Previously using environment variables with `Command` would cause them to be ASCII-uppercased. - [Rustdoc will now warn on using rustdoc lints that aren't prefixed with `rustdoc::`][86849] @@ -6367,7 +6371,7 @@ eg. `static MINUTE: Duration = Duration::from_secs(60);` Cargo ----- -- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] +- [`cargo new` no longer removes `rust` or `rs` prefixes/suffixes.][cargo/5013] - [`cargo new` now defaults to creating a binary crate, instead of a library crate.][cargo/5029] diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index c863acde7b0..f3af031ade4 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -79,7 +79,8 @@ pub trait LayoutCalculator { { // `ReprOptions.layout_seed` is a deterministic seed that we can use to // randomize field ordering with - let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed); + let mut rng = + Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed.as_u64()); // Shuffle the ordering of the fields optimizing.shuffle(&mut rng); @@ -461,8 +462,8 @@ pub trait LayoutCalculator { let all_indices = variants.indices(); let needs_disc = |index: VariantIdx| index != largest_variant_index && !absent(&variants[index]); - let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap().index() - ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap().index(); + let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap() + ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap(); let count = niche_variants.size_hint().1.unwrap() as u128; @@ -560,8 +561,7 @@ pub trait LayoutCalculator { tag: niche_scalar, tag_encoding: TagEncoding::Niche { untagged_variant: largest_variant_index, - niche_variants: (VariantIdx::new(*niche_variants.start()) - ..=VariantIdx::new(*niche_variants.end())), + niche_variants, niche_start, }, tag_field: 0, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index b0c0ee942ea..d01a9b00304 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -9,9 +9,10 @@ use std::str::FromStr; use bitflags::bitflags; use rustc_data_structures::intern::Interned; +use rustc_data_structures::stable_hasher::Hash64; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::HashStable_Generic; #[cfg(feature = "nightly")] @@ -77,12 +78,12 @@ pub struct ReprOptions { pub flags: ReprFlags, /// The seed to be used for randomizing a type's layout /// - /// Note: This could technically be a `[u8; 16]` (a `u128`) which would + /// Note: This could technically be a `Hash128` which would /// be the "most accurate" hash as it'd encompass the item and crate /// hash without loss, but it does pay the price of being larger. - /// Everything's a tradeoff, a `u64` seed should be sufficient for our + /// Everything's a tradeoff, a 64-bit seed should be sufficient for our /// purposes (primarily `-Z randomize-layout`) - pub field_shuffle_seed: u64, + pub field_shuffle_seed: Hash64, } impl ReprOptions { @@ -665,15 +666,12 @@ impl Align { format!("`{}` is too large", align) } - let mut bytes = align; - let mut pow2: u8 = 0; - while (bytes & 1) == 0 { - pow2 += 1; - bytes >>= 1; - } - if bytes != 1 { + let tz = align.trailing_zeros(); + if align != (1 << tz) { return Err(not_power_of_2(align)); } + + let pow2 = tz as u8; if pow2 > Self::MAX.pow2 { return Err(too_large(align)); } diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index df1a716755b..1e4d3ba47f4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1271,6 +1271,7 @@ impl Expr { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf, ExprKind::MacCall(..) => ExprPrecedence::Mac, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, @@ -1298,17 +1299,17 @@ impl Expr { /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { - match &self.peel_parens().kind { + matches!( + &self.peel_parens().kind, ExprKind::Array(_) - | ExprKind::Call(_, _) - | ExprKind::Tup(_) - | ExprKind::Lit(_) - | ExprKind::Range(_, _, _) - | ExprKind::Underscore - | ExprKind::Path(_, _) - | ExprKind::Struct(_) => true, - _ => false, - } + | ExprKind::Call(_, _) + | ExprKind::Tup(_) + | ExprKind::Lit(_) + | ExprKind::Range(_, _, _) + | ExprKind::Underscore + | ExprKind::Path(_, _) + | ExprKind::Struct(_) + ) } } @@ -1469,6 +1470,9 @@ pub enum ExprKind { /// Output of the `asm!()` macro. InlineAsm(P<InlineAsm>), + /// Output of the `offset_of!()` macro. + OffsetOf(P<Ty>, P<[Ident]>), + /// A macro invocation; pre-expansion. MacCall(P<MacCall>), diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 23c32fa96ca..b07ed1d1c74 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -10,7 +10,6 @@ )] #![feature(associated_type_bounds)] #![feature(box_patterns)] -#![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 694d31d8f1f..99f1f4bd968 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1456,6 +1456,12 @@ pub fn noop_visit_expr<T: MutVisitor>( } ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), + ExprKind::OffsetOf(container, fields) => { + vis.visit_ty(container); + for field in fields.iter_mut() { + vis.visit_ident(field); + } + } ExprKind::MacCall(mac) => vis.visit_mac_call(mac), ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = se.deref_mut(); diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs index daa82996b3d..d16741757d1 100644 --- a/compiler/rustc_ast/src/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs @@ -9,14 +9,14 @@ rustc_index::newtype_index! { /// /// [`DefId`]: rustc_span::def_id::DefId #[debug_format = "NodeId({})"] - pub struct NodeId {} + pub struct NodeId { + /// The [`NodeId`] used to represent the root of the crate. + const CRATE_NODE_ID = 0; + } } rustc_data_structures::define_id_collections!(NodeMap, NodeSet, NodeMapEntry, NodeId); -/// The [`NodeId`] used to represent the root of the crate. -pub const CRATE_NODE_ID: NodeId = NodeId::from_u32(0); - /// When parsing and at the beginning of doing expansions, we initially give all AST nodes /// this dummy AST [`NodeId`]. Then, during a later phase of expansion, we renumber them /// to have small, positive IDs. diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 4b2850336a0..0140fb752bf 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -126,7 +126,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> { } impl<T> P<[T]> { - pub const fn new() -> P<[T]> { + // FIXME(const-hack) make this const again + pub fn new() -> P<[T]> { P { ptr: Box::default() } } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 3893875e9a4..24b4bd8623f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -269,6 +269,7 @@ pub enum ExprPrecedence { Index, Try, InlineAsm, + OffsetOf, Mac, FormatArgs, @@ -335,7 +336,8 @@ impl ExprPrecedence { | ExprPrecedence::Try | ExprPrecedence::InlineAsm | ExprPrecedence::Mac - | ExprPrecedence::FormatArgs => PREC_POSTFIX, + | ExprPrecedence::FormatArgs + | ExprPrecedence::OffsetOf => PREC_POSTFIX, // Never need parens ExprPrecedence::Array diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ac9b321b71c..8a6b5d5c905 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -909,6 +909,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression), ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm), ExprKind::FormatArgs(f) => visitor.visit_format_args(f), + ExprKind::OffsetOf(container, fields) => { + visitor.visit_ty(container); + for &field in fields { + visitor.visit_ident(field); + } + } ExprKind::Yield(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index eb2e82d7988..6b0da256505 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 1b1c4765bc0..6863100d9ba 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -121,12 +121,16 @@ impl<'hir> LoweringContext<'_, 'hir> { LitKind::Err } }; - hir::ExprKind::Lit(respan(self.lower_span(e.span), lit_kind)) + let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind)); + hir::ExprKind::Lit(lit) + } + ExprKind::IncludedBytes(bytes) => { + let lit = self.arena.alloc(respan( + self.lower_span(e.span), + LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), + )); + hir::ExprKind::Lit(lit) } - ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan( - self.lower_span(e.span), - LitKind::ByteStr(bytes.clone(), StrStyle::Cooked), - )), ExprKind::Cast(expr, ty) => { let expr = self.lower_expr(expr); let ty = @@ -285,6 +289,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm)) } ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt), + ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf( + self.lower_ty( + container, + &mut ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf), + ), + self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))), + ), ExprKind::Struct(se) => { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), @@ -1746,40 +1757,31 @@ impl<'hir> LoweringContext<'_, 'hir> { } pub(super) fn expr_usize(&mut self, sp: Span, value: usize) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Int( - value as u128, - ast::LitIntType::Unsigned(ast::UintTy::Usize), - ), - }), - ) + let lit = self.arena.alloc(hir::Lit { + span: sp, + node: ast::LitKind::Int(value as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), + }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_u32(&mut self, sp: Span, value: u32) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)), - }), - ) + let lit = self.arena.alloc(hir::Lit { + span: sp, + node: ast::LitKind::Int(value.into(), ast::LitIntType::Unsigned(ast::UintTy::U32)), + }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> { - self.expr(sp, hir::ExprKind::Lit(hir::Lit { span: sp, node: ast::LitKind::Char(value) })) + let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> { - self.expr( - sp, - hir::ExprKind::Lit(hir::Lit { - span: sp, - node: ast::LitKind::Str(value, ast::StrStyle::Cooked), - }), - ) + let lit = self + .arena + .alloc(hir::Lit { span: sp, node: ast::LitKind::Str(value, ast::StrStyle::Cooked) }); + self.expr(sp, hir::ExprKind::Lit(lit)) } pub(super) fn expr_call_mut( diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index c41bdc44093..ccf481cb9b3 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -220,19 +220,19 @@ fn make_argument<'hir>( /// Generates: /// /// ```text -/// <core::fmt::rt::v1::Count>::Is(…) +/// <core::fmt::rt::Count>::Is(…) /// ``` /// /// or /// /// ```text -/// <core::fmt::rt::v1::Count>::Param(…) +/// <core::fmt::rt::Count>::Param(…) /// ``` /// /// or /// /// ```text -/// <core::fmt::rt::v1::Count>::Implied +/// <core::fmt::rt::Count>::Implied /// ``` fn make_count<'hir>( ctx: &mut LoweringContext<'_, 'hir>, @@ -278,13 +278,13 @@ fn make_count<'hir>( /// Generates /// /// ```text -/// <core::fmt::rt::v1::Argument::new( +/// <core::fmt::rt::Placeholder::new( /// …usize, // position /// '…', // fill -/// <core::fmt::rt::v1::Alignment>::…, // alignment +/// <core::fmt::rt::Alignment>::…, // alignment /// …u32, // flags -/// <core::fmt::rt::v1::Count::…>, // width -/// <core::fmt::rt::v1::Count::…>, // precision +/// <core::fmt::rt::Count::…>, // width +/// <core::fmt::rt::Count::…>, // precision /// ) /// ``` fn make_format_spec<'hir>( diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index f7fe0d771a1..2e66c81eb0d 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::definitions; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::*; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::span_bug; use rustc_session::Session; use rustc_span::source_map::SourceMap; diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f89e254a2f5..a9fd8db281b 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::PredicateOrigin; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::source_map::DesugaringKind; @@ -89,9 +89,9 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { lctx.with_hir_id_owner(owner, |lctx| f(lctx)); for (def_id, info) in lctx.children { - self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); - debug_assert!(matches!(self.owners[def_id], hir::MaybeOwner::Phantom)); - self.owners[def_id] = info; + let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); + debug_assert!(matches!(owner, hir::MaybeOwner::Phantom)); + *owner = info; } } @@ -99,8 +99,8 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { &mut self, def_id: LocalDefId, ) -> hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>> { - self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); - if let hir::MaybeOwner::Phantom = self.owners[def_id] { + let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); + if let hir::MaybeOwner::Phantom = owner { let node = self.ast_index[def_id]; match node { AstOwner::NonOwner => {} @@ -138,12 +138,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // Evaluate with the lifetimes in `params` in-scope. // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - match parent_hir.node().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { - lctx.is_in_trait_impl = of_trait.is_some(); - } - _ => {} - }; + + if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind { + lctx.is_in_trait_impl = impl_.of_trait.is_some(); + } match ctxt { AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)), @@ -445,7 +443,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacroDef(MacroDef { body, macro_rules }) => { let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); - hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind) + let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); + hir::ItemKind::Macro(macro_def, macro_kind) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f7ae96b7c4a..d07355a4154 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,13 +55,13 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{ DiagnosticArgFromDisplay, DiagnosticMessage, Handler, StashKey, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; -use rustc_macros::fluent_messages; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::{ span_bug, ty::{ResolverAstLowering, TyCtxt}, @@ -283,6 +283,7 @@ enum ImplTraitPosition { FieldTy, Cast, ImplSelf, + OffsetOf, } impl std::fmt::Display for ImplTraitPosition { @@ -313,6 +314,7 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::FieldTy => "field types", ImplTraitPosition::Cast => "cast types", ImplTraitPosition::ImplSelf => "impl headers", + ImplTraitPosition::OffsetOf => "`offset_of!` params", }; write!(f, "{name}") @@ -332,10 +334,7 @@ enum FnDeclKind { impl FnDeclKind { fn param_impl_trait_allowed(&self) -> bool { - match self { - FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => true, - _ => false, - } + matches!(self, FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait) } fn return_impl_trait_allowed(&self, tcx: TyCtxt<'_>) -> bool { @@ -371,8 +370,8 @@ fn index_crate<'a>( krate: &'a Crate, ) -> IndexVec<LocalDefId, AstOwner<'a>> { let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() }; - indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner); - indexer.index[CRATE_DEF_ID] = AstOwner::Crate(krate); + *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = + AstOwner::Crate(krate); visit::walk_crate(&mut indexer, krate); return indexer.index; @@ -389,22 +388,21 @@ fn index_crate<'a>( fn visit_item(&mut self, item: &'a ast::Item) { let def_id = self.node_id_to_def_id[&item.id]; - self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); - self.index[def_id] = AstOwner::Item(item); + *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); visit::walk_item(self, item) } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { let def_id = self.node_id_to_def_id[&item.id]; - self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); - self.index[def_id] = AstOwner::AssocItem(item, ctxt); + *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = + AstOwner::AssocItem(item, ctxt); visit::walk_assoc_item(self, item, ctxt); } fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { let def_id = self.node_id_to_def_id[&item.id]; - self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner); - self.index[def_id] = AstOwner::ForeignItem(item); + *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = + AstOwner::ForeignItem(item); visit::walk_foreign_item(self, item); } } diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 8bd212073a6..eb736123520 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -12,6 +12,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index a349fe6a3c4..ffca37ae9d5 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -231,7 +231,7 @@ ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$chann .suggestion = remove the attribute .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable -ast_passes_incompatbile_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed +ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed .help = remove one of these features ast_passes_show_span = {$msg} diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 27bbd237961..1732865f0bb 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -677,7 +677,7 @@ impl AddToDiagnostic for StableFeature { } #[derive(Diagnostic)] -#[diag(ast_passes_incompatbile_features)] +#[diag(ast_passes_incompatible_features)] #[help] pub struct IncompatibleFeatures { #[primary_span] diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index e2c666604b3..7db413c5bbd 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -13,7 +13,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod ast_validation; mod errors; diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 776bf54244e..aeb0c762020 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -549,6 +549,26 @@ impl<'a> State<'a> { self.end(); self.pclose(); } + ast::ExprKind::OffsetOf(container, fields) => { + // FIXME: This should have its own syntax, distinct from a macro invocation. + self.word("offset_of!"); + self.popen(); + self.rbox(0, Inconsistent); + self.print_type(container); + self.word(","); + self.space(); + + if let Some((&first, rest)) = fields.split_first() { + self.print_ident(first); + + for &field in rest { + self.word("."); + self.print_ident(field); + } + } + + self.end(); + } ast::ExprKind::MacCall(m) => self.print_mac(m), ast::ExprKind::Paren(e) => { self.popen(); diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 6349ddf31d1..2c4c3a0c263 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_serialize = { path = "../rustc_serialize" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_span = { path = "../rustc_span" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 49818c14f27..cfed2acfb3a 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -12,7 +12,7 @@ extern crate rustc_macros; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod builtin; mod session_diagnostics; diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 87c113f3e30..56a9deb6aab 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -15,12 +15,12 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_const_eval = { path = "../rustc_const_eval" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index a3b6b5e8138..0b8123c9703 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -56,18 +56,6 @@ borrowck_returned_lifetime_short = borrowck_used_impl_require_static = the used `impl` has a `'static` requirement -borrowck_capture_kind_label = - capture is {$kind_desc} because of use here - -borrowck_var_borrow_by_use_place_in_generator = - borrow occurs due to use of {$place} in closure in generator - -borrowck_var_borrow_by_use_place_in_closure = - borrow occurs due to use of {$place} in closure - -borrowck_var_borrow_by_use_place = - borrow occurs due to use of {$place} - borrowck_borrow_due_to_use_generator = borrow occurs due to use in generator @@ -101,12 +89,63 @@ borrowck_capture_mut = borrowck_capture_move = capture is moved because of use here +borrowck_var_borrow_by_use_place_in_generator = + {$is_single_var -> + *[true] borrow occurs + [false] borrows occur + } due to use of {$place} in generator + +borrowck_var_borrow_by_use_place_in_closure = + {$is_single_var -> + *[true] borrow occurs + [false] borrows occur + } due to use of {$place} in closure + +borrowck_var_borrow_by_use_in_generator = + borrow occurs due to use in generator + +borrowck_var_borrow_by_use_in_closure = + borrow occurs due to use in closure + borrowck_var_move_by_use_place_in_generator = move occurs due to use of {$place} in generator borrowck_var_move_by_use_place_in_closure = move occurs due to use of {$place} in closure +borrowck_var_move_by_use_in_generator = + move occurs due to use in generator + +borrowck_var_move_by_use_in_closure = + move occurs due to use in closure + +borrowck_partial_var_move_by_use_in_generator = + variable {$is_partial -> + [true] partially moved + *[false] moved + } due to use in generator + +borrowck_partial_var_move_by_use_in_closure = + variable {$is_partial -> + [true] partially moved + *[false] moved + } due to use in closure + +borrowck_var_first_borrow_by_use_place_in_generator = + first borrow occurs due to use of {$place} in generator + +borrowck_var_first_borrow_by_use_place_in_closure = + first borrow occurs due to use of {$place} in closure + +borrowck_var_second_borrow_by_use_place_in_generator = + second borrow occurs due to use of {$place} in generator + +borrowck_var_second_borrow_by_use_place_in_closure = + second borrow occurs due to use of {$place} in closure + +borrowck_var_mutable_borrow_by_use_place_in_closure = + mutable borrow occurs due to use of {$place} in closure + borrowck_cannot_move_when_borrowed = cannot move out of {$place -> [value] value @@ -127,3 +166,90 @@ borrowck_opaque_type_non_generic_param = [true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type *[other] this generic parameter must be used with a generic {$kind} parameter } + +borrowck_moved_due_to_call = + {$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this {$is_loop_message -> + [true] call, in previous iteration of loop + *[false] call + } + +borrowck_moved_due_to_usage_in_operator = + {$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to usage in {$is_loop_message -> + [true] operator, in previous iteration of loop + *[false] operator + } + +borrowck_moved_due_to_implicit_into_iter_call = + {$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this implicit call to {$is_loop_message -> + [true] `.into_iter()`, in previous iteration of loop + *[false] `.into_iter()` + } + +borrowck_moved_due_to_method_call = + {$place_name} {$is_partial -> + [true] partially moved + *[false] moved + } due to this method {$is_loop_message -> + [true] call, in previous iteration of loop + *[false] call + } + +borrowck_value_moved_here = + value {$is_partial -> + [true] partially moved + *[false] moved + } {$is_move_msg -> + [true] into closure here + *[false] here + }{$is_loop_message -> + [true] , in previous iteration of loop + *[false] {""} + } + +borrowck_consider_borrow_type_contents = + help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents + +borrowck_moved_a_fn_once_in_call = + this value implements `FnOnce`, which causes it to be moved when called + +borrowck_calling_operator_moves_lhs = + calling this operator moves the left-hand side + +borrowck_func_take_self_moved_place = + `{$func}` takes ownership of the receiver `self`, which moves {$place_name} + +borrowck_suggest_iterate_over_slice = + consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop + +borrowck_suggest_create_freash_reborrow = + consider reborrowing the `Pin` instead of moving it + +borrowck_value_capture_here = + value captured {$is_within -> + [true] here by generator + *[false] here + } + +borrowck_move_out_place_here = + {$place} is moved here + +borrowck_closure_invoked_twice = + closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment + +borrowck_closure_moved_twice = + closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment + +borrowck_ty_no_impl_copy = + {$is_partial_move -> + [true] partial move + *[false] move + } occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 2bbb9618dbf..acca1a1477f 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -469,6 +469,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { } #[rustc_lint_diagnostics] + #[track_caller] pub(crate) fn struct_span_err_with_code<S: Into<MultiSpan>>( &self, sp: S, diff --git a/compiler/rustc_borrowck/src/constraints/graph.rs b/compiler/rustc_borrowck/src/constraints/graph.rs index f5a34cb0561..8b7d9ec2cd6 100644 --- a/compiler/rustc_borrowck/src/constraints/graph.rs +++ b/compiler/rustc_borrowck/src/constraints/graph.rs @@ -1,5 +1,5 @@ use rustc_data_structures::graph; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{RegionVid, VarianceDiagInfo}; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index d2d9779dbea..315886bbe29 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -2,7 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::graph::scc::Sccs; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{RegionVid, VarianceDiagInfo}; use rustc_span::Span; diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index cb1a6522223..3451b7db8ca 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -3,10 +3,10 @@ //! This file provides API for compiler consumers. use rustc_hir::def_id::LocalDefId; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_middle::mir::Body; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::TyCtxt; pub use super::{ facts::{AllFacts as PoloniusInput, RustcFacts}, @@ -28,12 +28,9 @@ pub use super::{ /// that shows how to do this at `tests/run-make/obtain-borrowck/`. /// /// * Polonius is highly unstable, so expect regular changes in its signature or other details. -pub fn get_body_with_borrowck_facts( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> BodyWithBorrowckFacts<'_> { +pub fn get_body_with_borrowck_facts(tcx: TyCtxt<'_>, def: LocalDefId) -> BodyWithBorrowckFacts<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build(); + let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexSlice<_, _> = &promoted.borrow(); *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 9e9f0b4b4ad..6259722b694 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -52,12 +52,16 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) | + // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not + // contain dangling references. + PlaceContext::NonUse(NonUseContext::PlaceMention) | + PlaceContext::NonUse(NonUseContext::AscribeUserTy) | + PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) | - PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => Some(DefUse::Use), @@ -72,8 +76,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { PlaceContext::MutatingUse(MutatingUseContext::Drop) => Some(DefUse::Drop), - // This statement exists to help unsafeck. It does not require the place to be live. - PlaceContext::NonUse(NonUseContext::PlaceMention) => None, // Debug info is neither def nor use. PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 75a3dd0c0f3..5db0f72919d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,5 +1,6 @@ +use std::iter; + use either::Either; -use rustc_const_eval::util::CallKind; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ @@ -9,8 +10,8 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; +use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, @@ -18,20 +19,19 @@ use rustc_middle::mir::{ ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty}; +use rustc_middle::util::CallKind; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; use crate::borrow_set::TwoPhaseActivation; use crate::borrowck_errors; - use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead; -use crate::diagnostics::find_all_local_uses; -use crate::diagnostics::mutability_errors::mut_borrow_of_mutable_ref; +use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt}; use crate::{ borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf, InitializationRequiringAction, MirBorrowckCtxt, PrefixSet, WriteKind, @@ -183,13 +183,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let move_spans = self.move_spans(moved_place.as_ref(), move_out.source); let move_span = move_spans.args_or_use(); - let move_msg = if move_spans.for_closure() { " into closure" } else { "" }; + let is_move_msg = move_spans.for_closure(); - let loop_message = if location == move_out.source || move_site.traversed_back_edge { - ", in previous iteration of loop" - } else { - "" - }; + let is_loop_message = location == move_out.source || move_site.traversed_back_edge; if location == move_out.source { is_loop_move = true; @@ -206,17 +202,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); } + let msg_opt = CapturedMessageOpt { + is_partial_move, + is_loop_message, + is_move_msg, + is_loop_move, + maybe_reinitialized_locations_is_empty: maybe_reinitialized_locations + .is_empty(), + }; self.explain_captures( &mut err, span, move_span, move_spans, *moved_place, - partially_str, - loop_message, - move_msg, - is_loop_move, - maybe_reinitialized_locations.is_empty(), + msg_opt, ); } seen_spans.insert(move_span); @@ -282,12 +282,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } if needs_note { - let span = if let Some(local) = place.as_local() { - Some(self.body.local_decls[local].source_info.span) + if let Some(local) = place.as_local() { + let span = self.body.local_decls[local].source_info.span; + err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move, + ty, + place: ¬e_msg, + span, + }); } else { - None + err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Note { + is_partial_move, + ty, + place: ¬e_msg, + }); }; - self.note_type_does_not_implement_copy(&mut err, ¬e_msg, ty, span, partial_str); } if let UseSpans::FnSelfUse { @@ -633,11 +642,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { return false; }; - // Regions are already solved, so we must use a fresh InferCtxt, - // but the type has region variables, so erase those. - tcx.infer_ctxt() - .build() - .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env) + self.infcx + .type_implements_trait(default_trait, [ty], param_env) .must_apply_modulo_regions() }; @@ -696,7 +702,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .copied() .find_map(find_fn_kind_from_did), ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx - .bound_explicit_item_bounds(def_id) + .explicit_item_bounds(def_id) .subst_iter_copied(tcx, substs) .find_map(find_fn_kind_from_did), ty::Closure(_, substs) => match substs.as_closure().kind() { @@ -730,13 +736,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - if let Some(clone_trait_def) = tcx.lang_items().clone_trait() - && infcx + && self.infcx .type_implements_trait( clone_trait_def, - [tcx.erase_regions(ty)], + [ty], self.param_env, ) .must_apply_modulo_regions() @@ -760,12 +764,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|def_id| tcx.hir().get_generics(def_id)) else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new(&self.infcx); let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::misc(span, self.mir_def_id()); - ocx.register_bound(cause, self.param_env, infcx.tcx.erase_regions(ty), copy_did); + ocx.register_bound(cause, self.param_env, ty, copy_did); let errors = ocx.select_all_or_error(); // Only emit suggestion if all required predicates are on generic @@ -827,11 +830,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_spans.var_path_only_subdiag(&mut err, crate::InitializationRequiringAction::Borrow); - move_spans.var_span_label( - &mut err, - format!("move occurs due to use{}", move_spans.describe()), - "moved", - ); + move_spans.var_subdiag(None, &mut err, None, |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => MoveUseInGenerator { var_span }, + None => MoveUseInClosure { var_span }, + } + }); self.explain_why_borrow_contains_point(location, borrow, None) .add_explanation_to_diagnostic( @@ -868,13 +873,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_span, &self.describe_any_place(borrow.borrowed_place.as_ref()), ); - borrow_spans.var_subdiag(&mut err, Some(borrow.kind), |kind, var_span| { + borrow_spans.var_subdiag(None, &mut err, Some(borrow.kind), |kind, var_span| { use crate::session_diagnostics::CaptureVarCause::*; let place = &borrow.borrowed_place; let desc_place = self.describe_any_place(place.as_ref()); match kind { - Some(_) => BorrowUsePlaceGenerator { place: desc_place, var_span }, - None => BorrowUsePlaceClosure { place: desc_place, var_span }, + Some(_) => { + BorrowUsePlaceGenerator { place: desc_place, var_span, is_single_var: true } + } + None => BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true }, } }); @@ -946,7 +953,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &msg_borrow, None, ); - self.suggest_binding_for_closure_capture_self( + self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans); + self.suggest_using_closure_argument_instead_of_capture( &mut err, issued_borrow.borrowed_place, &issued_spans, @@ -969,6 +977,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place, issued_borrow.borrowed_place, ); + self.suggest_using_closure_argument_instead_of_capture( + &mut err, + issued_borrow.borrowed_place, + &issued_spans, + ); err } @@ -988,16 +1001,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { immutable_section_description, "mutably borrow", ); - borrow_spans.var_span_label( + borrow_spans.var_subdiag( + None, &mut err, - format!( - "borrow occurs due to use of {}{}", - desc_place, - borrow_spans.describe(), - ), - "immutable", + Some(BorrowKind::Unique), + |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => BorrowUsePlaceGenerator { + place: desc_place, + var_span, + is_single_var: true, + }, + None => BorrowUsePlaceClosure { + place: desc_place, + var_span, + is_single_var: true, + }, + } + }, ); - return err; } else { first_borrow_desc = "immutable "; @@ -1070,32 +1093,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }; if issued_spans == borrow_spans { - borrow_spans.var_span_label( - &mut err, - format!("borrows occur due to use of {}{}", desc_place, borrow_spans.describe(),), - gen_borrow_kind.describe_mutability(), - ); + borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => BorrowUsePlaceGenerator { + place: desc_place, + var_span, + is_single_var: false, + }, + None => { + BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: false } + } + } + }); } else { - let borrow_place = &issued_borrow.borrowed_place; - let borrow_place_desc = self.describe_any_place(borrow_place.as_ref()); - issued_spans.var_span_label( + issued_spans.var_subdiag( + Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic), &mut err, - format!( - "first borrow occurs due to use of {}{}", - borrow_place_desc, - issued_spans.describe(), - ), - issued_borrow.kind.describe_mutability(), + Some(issued_borrow.kind), + |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + let borrow_place = &issued_borrow.borrowed_place; + let borrow_place_desc = self.describe_any_place(borrow_place.as_ref()); + match kind { + Some(_) => { + FirstBorrowUsePlaceGenerator { place: borrow_place_desc, var_span } + } + None => FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span }, + } + }, ); - borrow_spans.var_span_label( + borrow_spans.var_subdiag( + Some(&self.infcx.tcx.sess.parse_sess.span_diagnostic), &mut err, - format!( - "second borrow occurs due to use of {}{}", - desc_place, - borrow_spans.describe(), - ), - gen_borrow_kind.describe_mutability(), + Some(gen_borrow_kind), + |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => SecondBorrowUsePlaceGenerator { place: desc_place, var_span }, + None => SecondBorrowUsePlaceClosure { place: desc_place, var_span }, + } + }, ); } @@ -1229,22 +1268,160 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn suggest_binding_for_closure_capture_self( + /// Suggest using closure argument instead of capture. + /// + /// For example: + /// ```ignore (illustrative) + /// struct S; + /// + /// impl S { + /// fn call(&mut self, f: impl Fn(&mut Self)) { /* ... */ } + /// fn x(&self) {} + /// } + /// + /// let mut v = S; + /// v.call(|this: &mut S| v.x()); + /// // ^\ ^-- help: try using the closure argument: `this` + /// // *-- error: cannot borrow `v` as mutable because it is also borrowed as immutable + /// ``` + fn suggest_using_closure_argument_instead_of_capture( &self, err: &mut Diagnostic, borrowed_place: Place<'tcx>, issued_spans: &UseSpans<'tcx>, ) { - let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; - let hir = self.infcx.tcx.hir(); + let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; + let tcx = self.infcx.tcx; + let hir = tcx.hir(); - // check whether the borrowed place is capturing `self` by mut reference + // Get the type of the local that we are trying to borrow let local = borrowed_place.local; - let Some(_) = self - .body - .local_decls - .get(local) - .map(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) else { return }; + let local_ty = self.body.local_decls[local].ty; + + // Get the body the error happens in + let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return }; + + let body_expr = hir.body(body_id).value; + + struct ClosureFinder<'hir> { + hir: rustc_middle::hir::map::Map<'hir>, + borrow_span: Span, + res: Option<(&'hir hir::Expr<'hir>, &'hir hir::Closure<'hir>)>, + /// The path expression with the `borrow_span` span + error_path: Option<(&'hir hir::Expr<'hir>, &'hir hir::QPath<'hir>)>, + } + impl<'hir> Visitor<'hir> for ClosureFinder<'hir> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.hir + } + + fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { + if let hir::ExprKind::Path(qpath) = &ex.kind + && ex.span == self.borrow_span + { + self.error_path = Some((ex, qpath)); + } + + if let hir::ExprKind::Closure(closure) = ex.kind + && ex.span.contains(self.borrow_span) + // To support cases like `|| { v.call(|this| v.get()) }` + // FIXME: actually support such cases (need to figure out how to move from the capture place to original local) + && self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span)) + { + self.res = Some((ex, closure)); + } + + hir::intravisit::walk_expr(self, ex); + } + } + + // Find the closure that most tightly wraps `capture_kind_span` + let mut finder = + ClosureFinder { hir, borrow_span: capture_kind_span, res: None, error_path: None }; + finder.visit_expr(body_expr); + let Some((closure_expr, closure)) = finder.res else { return }; + + let typeck_results = tcx.typeck(self.mir_def_id()); + + // Check that the parent of the closure is a method call, + // with receiver matching with local's type (modulo refs) + let parent = hir.parent_id(closure_expr.hir_id); + if let hir::Node::Expr(parent) = hir.get(parent) { + if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind { + let recv_ty = typeck_results.expr_ty(recv); + + if recv_ty.peel_refs() != local_ty { + return; + } + } + } + + // Get closure's arguments + let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { unreachable!() }; + let sig = substs.as_closure().sig(); + let tupled_params = + tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b)); + let ty::Tuple(params) = tupled_params.kind() else { return }; + + // Find the first argument with a matching type, get its name + let Some((_, this_name)) = params + .iter() + .zip(hir.body_param_names(closure.body)) + .find(|(param_ty, name)|{ + // FIXME: also support deref for stuff like `Rc` arguments + param_ty.peel_refs() == local_ty && name != &Ident::empty() + }) + else { return }; + + let spans; + if let Some((_path_expr, qpath)) = finder.error_path + && let hir::QPath::Resolved(_, path) = qpath + && let hir::def::Res::Local(local_id) = path.res + { + // Find all references to the problematic variable in this closure body + + struct VariableUseFinder { + local_id: hir::HirId, + spans: Vec<Span>, + } + impl<'hir> Visitor<'hir> for VariableUseFinder { + fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { + if let hir::ExprKind::Path(qpath) = &ex.kind + && let hir::QPath::Resolved(_, path) = qpath + && let hir::def::Res::Local(local_id) = path.res + && local_id == self.local_id + { + self.spans.push(ex.span); + } + + hir::intravisit::walk_expr(self, ex); + } + } + + let mut finder = VariableUseFinder { local_id, spans: Vec::new() }; + finder.visit_expr(hir.body(closure.body).value); + + spans = finder.spans; + } else { + spans = vec![capture_kind_span]; + } + + err.multipart_suggestion( + "try using the closure argument", + iter::zip(spans, iter::repeat(this_name.to_string())).collect(), + Applicability::MaybeIncorrect, + ); + } + + fn suggest_binding_for_closure_capture_self( + &self, + err: &mut Diagnostic, + issued_spans: &UseSpans<'tcx>, + ) { + let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; + let hir = self.infcx.tcx.hir(); struct ExpressionFinder<'hir> { capture_span: Span, @@ -1731,9 +1908,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(borrow_span, "borrowed value does not live long enough"); err.span_label(drop_span, format!("`{}` dropped here while still borrowed", name)); - let within = if borrow_spans.for_generator() { " by generator" } else { "" }; - - borrow_spans.args_span_label(&mut err, format!("value captured here{}", within)); + borrow_spans.args_subdiag(&mut err, |args_span| { + crate::session_diagnostics::CaptureArgLabel::Capture { + is_within: borrow_spans.for_generator(), + args_span, + } + }); explanation.add_explanation_to_diagnostic( self.infcx.tcx, @@ -1947,9 +2127,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None, ); - let within = if borrow_spans.for_generator() { " by generator" } else { "" }; - - borrow_spans.args_span_label(&mut err, format!("value captured here{}", within)); + borrow_spans.args_subdiag(&mut err, |args_span| { + crate::session_diagnostics::CaptureArgLabel::Capture { + is_within: borrow_spans.for_generator(), + args_span, + } + }); err } @@ -2029,7 +2212,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; - let return_ty = tcx.erase_regions(return_ty); // to avoid panics if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) @@ -2382,11 +2564,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { section, "assign", ); - loan_spans.var_span_label( - &mut err, - format!("borrow occurs due to use{}", loan_spans.describe()), - loan.kind.describe_mutability(), - ); + + loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => BorrowUseInGenerator { var_span }, + None => BorrowUseInClosure { var_span }, + } + }); self.buffer_error(err); @@ -2396,11 +2581,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut err = self.cannot_assign_to_borrowed(span, loan_span, &descr_place); - loan_spans.var_span_label( - &mut err, - format!("borrow occurs due to use{}", loan_spans.describe()), - loan.kind.describe_mutability(), - ); + loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| { + use crate::session_diagnostics::CaptureVarCause::*; + match kind { + Some(_) => BorrowUseInGenerator { var_span }, + None => BorrowUseInClosure { var_span }, + } + }); self.explain_why_borrow_contains_point(location, loan, None).add_explanation_to_diagnostic( self.infcx.tcx, @@ -2424,7 +2611,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some((method_did, method_substs)), ) = ( &self.body[loan.reserve_location.block].terminator, - rustc_const_eval::util::find_self_call( + rustc_middle::util::find_self_call( tcx, self.body, loan.assigned_place.local, diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 8860395e71c..f995c3165a9 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -3,7 +3,7 @@ use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::{ Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place, diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 110354a20d8..4243ec214b0 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1,13 +1,16 @@ //! Borrow checker diagnostics. +use crate::session_diagnostics::{ + CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause, + CaptureVarKind, CaptureVarPathUseCause, OnClosureNote, +}; use itertools::Itertools; -use rustc_const_eval::util::{call_kind, CallDesugaringKind}; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::GeneratorKind; -use rustc_index::vec::IndexSlice; -use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; +use rustc_index::IndexSlice; +use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, @@ -15,6 +18,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_middle::util::{call_kind, CallDesugaringKind}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; use rustc_span::def_id::LocalDefId; use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; @@ -45,7 +49,7 @@ pub(crate) use mutability_errors::AccessKind; pub(crate) use outlives_suggestion::OutlivesSuggestionBuilder; pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; pub(crate) use region_name::{RegionName, RegionNameSource}; -pub(crate) use rustc_const_eval::util::CallKind; +pub(crate) use rustc_middle::util::CallKind; pub(super) struct DescribePlaceOpt { pub including_downcast: bool, @@ -117,13 +121,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[closure].ty.kind() { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { - diag.span_note( - *span, - &format!( - "closure cannot be invoked more than once because it moves the \ - variable `{}` out of its environment", - ty::place_to_string_for_capture(self.infcx.tcx, hir_place) - ), + diag.eager_subdiagnostic( + &self.infcx.tcx.sess.parse_sess.span_diagnostic, + OnClosureNote::InvokedTwice { + place_name: &ty::place_to_string_for_capture( + self.infcx.tcx, + hir_place, + ), + span: *span, + }, ); return true; } @@ -137,13 +143,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let ty::Closure(did, _) = self.body.local_decls[target].ty.kind() { let did = did.expect_local(); if let Some((span, hir_place)) = self.infcx.tcx.closure_kind_origin(did) { - diag.span_note( - *span, - &format!( - "closure cannot be moved more than once as it is not `Copy` due to \ - moving the variable `{}` out of its environment", - ty::place_to_string_for_capture(self.infcx.tcx, hir_place) - ), + diag.eager_subdiagnostic( + &self.infcx.tcx.sess.parse_sess.span_diagnostic, + OnClosureNote::MovedTwice { + place_name: &ty::place_to_string_for_capture(self.infcx.tcx, hir_place), + span: *span, + }, ); return true; } @@ -380,25 +385,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - /// Add a note that a type does not implement `Copy` - pub(super) fn note_type_does_not_implement_copy( - &self, - err: &mut Diagnostic, - place_desc: &str, - ty: Ty<'tcx>, - span: Option<Span>, - move_prefix: &str, - ) { - let message = format!( - "{move_prefix}move occurs because {place_desc} has type `{ty}`, which does not implement the `Copy` trait", - ); - if let Some(span) = span { - err.span_label(span, message); - } else { - err.note(&message); - } - } - pub(super) fn borrowed_content_source( &self, deref_base: PlaceRef<'tcx>, @@ -582,9 +568,13 @@ impl UseSpans<'_> { } /// Add a span label to the arguments of the closure, if it exists. - pub(super) fn args_span_label(self, err: &mut Diagnostic, message: impl Into<String>) { + pub(super) fn args_subdiag( + self, + err: &mut Diagnostic, + f: impl FnOnce(Span) -> CaptureArgLabel, + ) { if let UseSpans::ClosureUse { args_span, .. } = self { - err.span_label(args_span, message); + err.subdiagnostic(f(args_span)); } } @@ -595,8 +585,8 @@ impl UseSpans<'_> { err: &mut Diagnostic, action: crate::InitializationRequiringAction, ) { - use crate::session_diagnostics::CaptureVarPathUseCause::*; use crate::InitializationRequiringAction::*; + use CaptureVarPathUseCause::*; if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self { match generator_kind { Some(_) => { @@ -619,34 +609,14 @@ impl UseSpans<'_> { } } - /// Add a span label to the use of the captured variable, if it exists. - pub(super) fn var_span_label( - self, - err: &mut Diagnostic, - message: impl Into<String>, - kind_desc: impl Into<String>, - ) { - if let UseSpans::ClosureUse { capture_kind_span, path_span, .. } = self { - if capture_kind_span == path_span { - err.span_label(capture_kind_span, message); - } else { - let capture_kind_label = - format!("capture is {} because of use here", kind_desc.into()); - let path_label = message; - err.span_label(capture_kind_span, capture_kind_label); - err.span_label(path_span, path_label); - } - } - } - /// Add a subdiagnostic to the use of the captured variable, if it exists. pub(super) fn var_subdiag( self, + handler: Option<&rustc_errors::Handler>, err: &mut Diagnostic, kind: Option<rustc_middle::mir::BorrowKind>, - f: impl Fn(Option<GeneratorKind>, Span) -> crate::session_diagnostics::CaptureVarCause, + f: impl FnOnce(Option<GeneratorKind>, Span) -> CaptureVarCause, ) { - use crate::session_diagnostics::CaptureVarKind::*; if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self { if capture_kind_span != path_span { err.subdiagnostic(match kind { @@ -654,17 +624,21 @@ impl UseSpans<'_> { rustc_middle::mir::BorrowKind::Shared | rustc_middle::mir::BorrowKind::Shallow | rustc_middle::mir::BorrowKind::Unique => { - Immute { kind_span: capture_kind_span } + CaptureVarKind::Immut { kind_span: capture_kind_span } } rustc_middle::mir::BorrowKind::Mut { .. } => { - Mut { kind_span: capture_kind_span } + CaptureVarKind::Mut { kind_span: capture_kind_span } } }, - None => Move { kind_span: capture_kind_span }, + None => CaptureVarKind::Move { kind_span: capture_kind_span }, }); }; - err.subdiagnostic(f(generator_kind, path_span)); + let diag = f(generator_kind, path_span); + match handler { + Some(hd) => err.eager_subdiagnostic(hd, diag), + None => err.subdiagnostic(diag), + }; } } @@ -684,20 +658,6 @@ impl UseSpans<'_> { } } - /// Describe the span associated with a use of a place. - pub(super) fn describe(&self) -> &str { - match *self { - UseSpans::ClosureUse { generator_kind, .. } => { - if generator_kind.is_some() { - " in generator" - } else { - " in closure" - } - } - _ => "", - } - } - pub(super) fn or_else<F>(self, if_other: F) -> Self where F: FnOnce() -> Self, @@ -788,6 +748,15 @@ impl<'tcx> BorrowedContentSource<'tcx> { } } +///helper struct for explain_captures() +struct CapturedMessageOpt { + is_partial_move: bool, + is_loop_message: bool, + is_move_msg: bool, + is_loop_move: bool, + maybe_reinitialized_locations_is_empty: bool, +} + impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Finds the spans associated to a move or copy of move_place at location. pub(super) fn move_spans( @@ -874,7 +843,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { }) = &self.body[location.block].terminator { let Some((method_did, method_substs)) = - rustc_const_eval::util::find_self_call( + rustc_middle::util::find_self_call( self.infcx.tcx, &self.body, target_temp, @@ -1027,12 +996,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { move_span: Span, move_spans: UseSpans<'tcx>, moved_place: Place<'tcx>, - partially_str: &str, - loop_message: &str, - move_msg: &str, - is_loop_move: bool, - maybe_reinitialized_locations_is_empty: bool, + msg_opt: CapturedMessageOpt, ) { + let CapturedMessageOpt { + is_partial_move: is_partial, + is_loop_message, + is_move_msg, + is_loop_move, + maybe_reinitialized_locations_is_empty, + } = msg_opt; if let UseSpans::FnSelfUse { var_span, fn_call_span, fn_span, kind } = move_spans { let place_name = self .describe_place(moved_place.as_ref()) @@ -1042,30 +1014,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { CallKind::FnCall { fn_trait_id, .. } if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() => { - err.span_label( + err.subdiagnostic(CaptureReasonLabel::Call { fn_call_span, - &format!( - "{place_name} {partially_str}moved due to this call{loop_message}", - ), - ); - err.span_note( - var_span, - "this value implements `FnOnce`, which causes it to be moved when called", - ); + place_name: &place_name, + is_partial, + is_loop_message, + }); + err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span }); } CallKind::Operator { self_arg, .. } => { let self_arg = self_arg.unwrap(); - err.span_label( + err.subdiagnostic(CaptureReasonLabel::OperatorUse { fn_call_span, - &format!( - "{place_name} {partially_str}moved due to usage in operator{loop_message}", - ), - ); + place_name: &place_name, + is_partial, + is_loop_message, + }); if self.fn_self_span_reported.insert(fn_span) { - err.span_note( - self_arg.span, - "calling this operator moves the left-hand side", - ); + err.subdiagnostic(CaptureReasonNote::LhsMoveByOperator { + span: self_arg.span, + }); } } CallKind::Normal { self_arg, desugaring, method_did, method_substs } => { @@ -1074,35 +1042,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { let ty = moved_place.ty(self.body, tcx).ty; let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { - Some(def_id) => { - let infcx = self.infcx.tcx.infer_ctxt().build(); - type_known_to_meet_bound_modulo_regions( - &infcx, - self.param_env, - tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.erase_regions(ty)), - def_id, - ) - } + Some(def_id) => type_known_to_meet_bound_modulo_regions( + &self.infcx, + self.param_env, + tcx.mk_imm_ref(tcx.lifetimes.re_erased, ty), + def_id, + ), _ => false, }; if suggest { - err.span_suggestion_verbose( - move_span.shrink_to_lo(), - &format!( - "consider iterating over a slice of the `{ty}`'s content to \ - avoid moving into the `for` loop", - ), - "&", - Applicability::MaybeIncorrect, - ); + err.subdiagnostic(CaptureReasonSuggest::IterateSlice { + ty, + span: move_span.shrink_to_lo(), + }); } - err.span_label( + err.subdiagnostic(CaptureReasonLabel::ImplicitCall { fn_call_span, - &format!( - "{place_name} {partially_str}moved due to this implicit call to `.into_iter()`{loop_message}", - ), - ); + place_name: &place_name, + is_partial, + is_loop_message, + }); // If the moved place was a `&mut` ref, then we can // suggest to reborrow it where it was moved, so it // will still be valid by the time we get to the usage. @@ -1125,34 +1085,30 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } } else { - err.span_label( + err.subdiagnostic(CaptureReasonLabel::MethodCall { fn_call_span, - &format!( - "{place_name} {partially_str}moved due to this method call{loop_message}", - ), - ); - - let infcx = tcx.infer_ctxt().build(); + place_name: &place_name, + is_partial, + is_loop_message, + }); // Erase and shadow everything that could be passed to the new infcx. - let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty); - let method_substs = tcx.erase_regions(method_substs); + let ty = moved_place.ty(self.body, tcx).ty; if let ty::Adt(def, substs) = ty.kind() && Some(def.did()) == tcx.lang_items().pin_type() && let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind() - && let self_ty = infcx.instantiate_binder_with_fresh_vars( + && let self_ty = self.infcx.instantiate_binder_with_fresh_vars( fn_call_span, LateBoundRegionConversionTime::FnCall, tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), ) - && infcx.can_eq(self.param_env, ty, self_ty) + && self.infcx.can_eq(self.param_env, ty, self_ty) { - err.span_suggestion_verbose( - fn_call_span.shrink_to_lo(), - "consider reborrowing the `Pin` instead of moving it", - "as_mut().".to_string(), - Applicability::MaybeIncorrect, - ); + err.eager_subdiagnostic( + &self.infcx.tcx.sess.parse_sess.span_diagnostic, + CaptureReasonSuggest::FreshReborrow { + span: fn_call_span.shrink_to_lo(), + }); } if let Some(clone_trait) = tcx.lang_items().clone_trait() && let trait_ref = tcx.mk_trait_ref(clone_trait, [ty]) @@ -1162,7 +1118,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.param_env, ty::Binder::dummy(trait_ref), ) - && infcx.predicate_must_hold_modulo_regions(&o) + && self.infcx.predicate_must_hold_modulo_regions(&o) { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), @@ -1177,10 +1133,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // error messages. if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span) { let func = tcx.def_path_str(method_did); - err.span_note( - self_arg.span, - &format!("`{func}` takes ownership of the receiver `self`, which moves {place_name}") - ); + err.subdiagnostic(CaptureReasonNote::FuncTakeSelf { + func, + place_name, + span: self_arg.span, + }); } let parent_did = tcx.parent(method_did); let parent_self_ty = @@ -1194,30 +1151,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result)) }); if is_option_or_result && maybe_reinitialized_locations_is_empty { - err.span_label( - var_span, - "help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents", - ); + err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span }); } } // Other desugarings takes &self, which cannot cause a move _ => {} } } else { - if move_span != span || !loop_message.is_empty() { - err.span_label( + if move_span != span || is_loop_message { + err.subdiagnostic(CaptureReasonLabel::MovedHere { move_span, - format!("value {partially_str}moved{move_msg} here{loop_message}"), - ); + is_partial, + is_move_msg, + is_loop_message, + }); } // If the move error occurs due to a loop, don't show // another message for the same span - if loop_message.is_empty() { - move_spans.var_span_label( - err, - format!("variable {partially_str}moved due to use{}", move_spans.describe()), - "moved", - ); + if !is_loop_message { + move_spans.var_subdiag(None, err, None, |kind, var_span| match kind { + Some(_) => CaptureVarCause::PartialMoveUseInGenerator { var_span, is_partial }, + None => CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial }, + }) } } } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 3662bec0c76..67af96a71e3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -6,6 +6,7 @@ use rustc_mir_dataflow::move_paths::{ }; use rustc_span::{BytePos, Span}; +use crate::diagnostics::CapturedMessageOpt; use crate::diagnostics::{DescribePlaceOpt, UseSpans}; use crate::prefixes::PrefixSet; use crate::MirBorrowckCtxt; @@ -397,10 +398,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } }; + let msg_opt = CapturedMessageOpt { + is_partial_move: false, + is_loop_message: false, + is_move_msg: false, + is_loop_move: false, + maybe_reinitialized_locations_is_empty: true, + }; if let Some(use_spans) = use_spans { - self.explain_captures( - &mut err, span, span, use_spans, move_place, "", "", "", false, true, - ); + self.explain_captures(&mut err, span, span, use_spans, move_place, msg_opt); } err } @@ -416,13 +422,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { None => "value".to_string(), }; - self.note_type_does_not_implement_copy( - err, - &place_desc, - place_ty, - Some(span), - "", - ); + err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: place_ty, + place: &place_desc, + span, + }); } else { binds_to.sort(); binds_to.dedup(); @@ -444,9 +449,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { Some(desc) => format!("`{desc}`"), None => "value".to_string(), }; - self.note_type_does_not_implement_copy(err, &place_desc, place_ty, Some(span), ""); + err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: place_ty, + place: &place_desc, + span, + }); - use_spans.args_span_label(err, format!("{place_desc} is moved here")); + use_spans.args_subdiag(err, |args_span| { + crate::session_diagnostics::CaptureArgLabel::MoveOutPlace { + place: place_desc, + args_span, + } + }); } } } @@ -534,13 +549,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } if binds_to.len() == 1 { - self.note_type_does_not_implement_copy( - err, - &format!("`{}`", self.local_names[*local].unwrap()), - bind_to.ty, - Some(binding_span), - "", - ); + let place_desc = &format!("`{}`", self.local_names[*local].unwrap()); + err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label { + is_partial_move: false, + ty: bind_to.ty, + place: &place_desc, + span: binding_span, + }); } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 9d904009650..e3d81194ac8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -15,8 +15,8 @@ use rustc_span::{sym, BytePos, Span}; use rustc_target::abi::FieldIdx; use crate::diagnostics::BorrowedContentSource; +use crate::util::FindAssignments; use crate::MirBorrowckCtxt; -use rustc_const_eval::util::collect_writes::FindAssignments; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub(crate) enum AccessKind { @@ -231,14 +231,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } } if suggest { - borrow_spans.var_span_label( - &mut err, - format!( - "mutable borrow occurs due to use of {} in closure", - self.describe_any_place(access_place.as_ref()), - ), - "mutable", - ); + borrow_spans.var_subdiag( + None, + &mut err, + Some(mir::BorrowKind::Mut { allow_two_phase_borrow: false }), + |_kind, var_span| { + let place = self.describe_any_place(access_place.as_ref()); + crate::session_diagnostics::CaptureVarCause::MutableBorrowUsePlaceClosure { + place, + var_span, + } + }, + ); } borrow_span } @@ -1143,7 +1147,7 @@ pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option< // suggest removing the `&mut`. // // Deliberately fall into this case for all implicit self types, - // so that we don't fall in to the next case with them. + // so that we don't fall into the next case with them. kind == hir::ImplicitSelfKind::MutRef } _ if Some(kw::SelfLower) == local_name => { @@ -1231,7 +1235,7 @@ fn suggest_ampmut<'tcx>( } } - let (suggestability, highlight_span) = match opt_ty_info { + let (suggestibility, highlight_span) = match opt_ty_info { // if this is a variable binding with an explicit type, // try to highlight that for the suggestion. Some(ty_span) => (true, ty_span), @@ -1252,7 +1256,7 @@ fn suggest_ampmut<'tcx>( let ty_mut = local_decl.ty.builtin_deref(true).unwrap(); assert_eq!(ty_mut.mutbl, hir::Mutability::Not); ( - suggestability, + suggestibility, highlight_span, if local_decl.ty.is_ref() { format!("&mut {}", ty_mut.ty) diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index 376415e3d32..98418e2372f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -3,7 +3,7 @@ use crate::region_infer::RegionInferenceContext; use crate::Upvar; -use rustc_index::vec::{Idx, IndexSlice}; +use rustc_index::IndexSlice; use rustc_middle::mir::{Body, Local}; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_span::source_map::Span; @@ -117,7 +117,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { argument_index: usize, ) -> (Option<Symbol>, Span) { let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); - let argument_local = Local::new(implicit_inputs + argument_index + 1); + let argument_local = Local::from_usize(implicit_inputs + argument_index + 1); debug!("get_argument_name_and_span_for_region: argument_local={argument_local:?}"); let argument_name = local_names[argument_local]; diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs index 02ffb51fbb7..87fad9a355d 100644 --- a/compiler/rustc_borrowck/src/facts.rs +++ b/compiler/rustc_borrowck/src/facts.rs @@ -4,7 +4,6 @@ use crate::location::{LocationIndex, LocationTable}; use crate::BorrowIndex; use polonius_engine::AllFacts as PoloniusFacts; use polonius_engine::Atom; -use rustc_index::vec::Idx; use rustc_middle::mir::Local; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_mir_dataflow::move_paths::MovePathIndex; @@ -93,13 +92,13 @@ impl AllFactsExt for AllFacts { impl Atom for BorrowIndex { fn index(self) -> usize { - Idx::index(self) + self.as_usize() } } impl Atom for LocationIndex { fn index(self) -> usize { - Idx::index(self) + self.as_usize() } } diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 498d254da65..06986f848bf 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -79,7 +79,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 70d0a101b4e..b57b0c9e4ba 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -20,14 +20,14 @@ extern crate tracing; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::{ DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; -use rustc_macros::fluent_messages; use rustc_middle::mir::{ traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, @@ -88,6 +88,7 @@ mod session_diagnostics; mod type_check; mod universal_regions; mod used_muts; +mod util; /// A public API provided for the Rust compiler consumers. pub mod consumers; @@ -118,24 +119,12 @@ impl<'tcx> TyCtxtConsts<'tcx> { } pub fn provide(providers: &mut Providers) { - *providers = Providers { - mir_borrowck: |tcx, did| { - if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) { - tcx.mir_borrowck_const_arg(def) - } else { - mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)) - } - }, - mir_borrowck_const_arg: |tcx, (did, param_did)| { - mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, - ..*providers - }; + *providers = Providers { mir_borrowck, ..*providers }; } -fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &BorrowCheckResult<'_> { +fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); if input_body.borrow().should_skip() { debug!("Skipping borrowck because of injected body"); @@ -149,7 +138,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor return tcx.arena.alloc(result); } - let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; + let hir_owner = tcx.hir().local_def_id_to_hir_id(def).owner; let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build(); @@ -166,19 +155,19 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor /// If `return_body_with_facts` is true, then return the body with non-erased /// region ids on which the borrow checking was performed together with Polonius /// facts. -#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")] +#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")] fn do_mir_borrowck<'tcx>( infcx: &InferCtxt<'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexSlice<Promoted, Body<'tcx>>, return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { - let def = input_body.source.with_opt_param().as_local().unwrap(); + let def = input_body.source.def_id().expect_local(); debug!(?def); let tcx = infcx.tcx; let infcx = BorrowckInferCtxt::new(infcx); - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { @@ -206,7 +195,7 @@ fn do_mir_borrowck<'tcx>( errors.set_tainted_by_errors(e); } let upvars: Vec<_> = tcx - .closure_captures(def.did) + .closure_captures(def) .iter() .map(|&captured_place| { let capture = captured_place.info.capture_kind; @@ -248,7 +237,7 @@ fn do_mir_borrowck<'tcx>( .iterate_to_fixpoint() .into_results_cursor(&body); - let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def.did).is_fn_or_closure(); + let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); let borrow_set = Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); @@ -676,7 +665,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 288b7d85be2..0e669abfd14 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -1,6 +1,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::IndexVec; use rustc_middle::mir::{BasicBlock, Body, Location}; /// Maps between a MIR Location, which identifies a particular @@ -50,19 +50,19 @@ impl LocationTable { } pub fn all_points(&self) -> impl Iterator<Item = LocationIndex> { - (0..self.num_points).map(LocationIndex::new) + (0..self.num_points).map(LocationIndex::from_usize) } pub fn start_index(&self, location: Location) -> LocationIndex { let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; - LocationIndex::new(start_index + statement_index * 2) + LocationIndex::from_usize(start_index + statement_index * 2) } pub fn mid_index(&self, location: Location) -> LocationIndex { let Location { block, statement_index } = location; let start_index = self.statements_before_block[block]; - LocationIndex::new(start_index + statement_index * 2 + 1) + LocationIndex::from_usize(start_index + statement_index * 2 + 1) } pub fn to_location(&self, index: LocationIndex) -> RichLocation { diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index f637e6a95ac..db5b8f464c8 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -2,7 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::infer::MemberConstraint; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 59a3ab3189d..5f1bcb27ea7 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -4,11 +4,11 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::LocalDefId; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere}; use rustc_middle::mir::{ - BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, - Promoted, + Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, Promoted, + START_BLOCK, }; use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; use rustc_span::symbol::sym; @@ -61,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>( body: &mut Body<'tcx>, promoted: &mut IndexSlice<Promoted, Body<'tcx>>, ) -> UniversalRegions<'tcx> { - let def = body.source.with_opt_param().as_local().unwrap(); + let def = body.source.def_id().expect_local(); debug!(?def); @@ -94,8 +94,8 @@ fn populate_polonius_move_facts( } } - let fn_entry_start = location_table - .start_index(Location { block: BasicBlock::from_u32(0u32), statement_index: 0 }); + let fn_entry_start = + location_table.start_index(Location { block: START_BLOCK, statement_index: 0 }); // initialized_at for init in move_data.inits.iter() { @@ -235,7 +235,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. - let var_origins = infcx.take_region_var_origins(); + let var_origins = infcx.get_region_var_origins(); let MirTypeckRegionConstraints { placeholder_indices, placeholder_index_to_region: _, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 729f3dbff3b..65573c71f14 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 8132800f107..193e2060115 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -4,8 +4,8 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::IntervalSet; use rustc_index::interval::SparseIntervalMatrix; -use rustc_index::vec::Idx; -use rustc_index::vec::IndexVec; +use rustc_index::Idx; +use rustc_index::IndexVec; use rustc_middle::mir::{BasicBlock, Body, Location}; use rustc_middle::ty::{self, RegionVid}; use std::fmt::Debug; diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 94ce29dfe51..22de7549e94 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,7 +1,7 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] use crate::BorrowckInferCtxt; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::Constant; diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index a3678929099..bb95101845f 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -184,7 +184,7 @@ pub(crate) enum CaptureVarPathUseCause { #[derive(Subdiagnostic)] pub(crate) enum CaptureVarKind { #[label(borrowck_capture_immute)] - Immute { + Immut { #[primary_span] kind_span: Span, }, @@ -204,16 +204,80 @@ pub(crate) enum CaptureVarKind { pub(crate) enum CaptureVarCause { #[label(borrowck_var_borrow_by_use_place_in_generator)] BorrowUsePlaceGenerator { + is_single_var: bool, place: String, #[primary_span] var_span: Span, }, #[label(borrowck_var_borrow_by_use_place_in_closure)] BorrowUsePlaceClosure { + is_single_var: bool, place: String, #[primary_span] var_span: Span, }, + #[label(borrowck_var_borrow_by_use_in_generator)] + BorrowUseInGenerator { + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_borrow_by_use_in_closure)] + BorrowUseInClosure { + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_move_by_use_in_generator)] + MoveUseInGenerator { + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_move_by_use_in_closure)] + MoveUseInClosure { + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_first_borrow_by_use_place_in_generator)] + FirstBorrowUsePlaceGenerator { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_first_borrow_by_use_place_in_closure)] + FirstBorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_second_borrow_by_use_place_in_generator)] + SecondBorrowUsePlaceGenerator { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_second_borrow_by_use_place_in_closure)] + SecondBorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_var_mutable_borrow_by_use_place_in_closure)] + MutableBorrowUsePlaceClosure { + place: String, + #[primary_span] + var_span: Span, + }, + #[label(borrowck_partial_var_move_by_use_in_generator)] + PartialMoveUseInGenerator { + #[primary_span] + var_span: Span, + is_partial: bool, + }, + #[label(borrowck_partial_var_move_by_use_in_closure)] + PartialMoveUseInClosure { + #[primary_span] + var_span: Span, + is_partial: bool, + }, } #[derive(Diagnostic)] @@ -239,3 +303,144 @@ pub(crate) struct NonGenericOpaqueTypeParam<'a, 'tcx> { #[label] pub param_span: Span, } + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureReasonLabel<'a> { + #[label(borrowck_moved_due_to_call)] + Call { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, + #[label(borrowck_moved_due_to_usage_in_operator)] + OperatorUse { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, + #[label(borrowck_moved_due_to_implicit_into_iter_call)] + ImplicitCall { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, + #[label(borrowck_moved_due_to_method_call)] + MethodCall { + #[primary_span] + fn_call_span: Span, + place_name: &'a str, + is_partial: bool, + is_loop_message: bool, + }, + #[label(borrowck_value_moved_here)] + MovedHere { + #[primary_span] + move_span: Span, + is_partial: bool, + is_move_msg: bool, + is_loop_message: bool, + }, + #[label(borrowck_consider_borrow_type_contents)] + BorrowContent { + #[primary_span] + var_span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureReasonNote { + #[note(borrowck_moved_a_fn_once_in_call)] + FnOnceMoveInCall { + #[primary_span] + var_span: Span, + }, + #[note(borrowck_calling_operator_moves_lhs)] + LhsMoveByOperator { + #[primary_span] + span: Span, + }, + #[note(borrowck_func_take_self_moved_place)] + FuncTakeSelf { + func: String, + place_name: String, + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureReasonSuggest<'tcx> { + #[suggestion( + borrowck_suggest_iterate_over_slice, + applicability = "maybe-incorrect", + code = "&", + style = "verbose" + )] + IterateSlice { + ty: Ty<'tcx>, + #[primary_span] + span: Span, + }, + #[suggestion( + borrowck_suggest_create_freash_reborrow, + applicability = "maybe-incorrect", + code = "as_mut().", + style = "verbose" + )] + FreshReborrow { + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum CaptureArgLabel { + #[label(borrowck_value_capture_here)] + Capture { + is_within: bool, + #[primary_span] + args_span: Span, + }, + #[label(borrowck_move_out_place_here)] + MoveOutPlace { + place: String, + #[primary_span] + args_span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum OnClosureNote<'a> { + #[note(borrowck_closure_invoked_twice)] + InvokedTwice { + place_name: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck_closure_moved_twice)] + MovedTwice { + place_name: &'a str, + #[primary_span] + span: Span, + }, +} + +#[derive(Subdiagnostic)] +pub(crate) enum TypeNoCopy<'a, 'tcx> { + #[label(borrowck_ty_no_impl_copy)] + Label { + is_partial_move: bool, + ty: Ty<'tcx>, + place: &'a str, + #[primary_span] + span: Span, + }, + #[note(borrowck_ty_no_impl_copy)] + Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str }, +} diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 17e702eb8c5..9250b8d3eaf 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -7,7 +7,6 @@ //! `RETURN_PLACE` the MIR arguments) are always fully normalized (and //! contain revealed `impl Trait` values). -use rustc_index::vec::Idx; use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; @@ -83,7 +82,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } // In MIR, argument N is stored in local N+1. - let local = Local::new(argument_index + 1); + let local = Local::from_usize(argument_index + 1); let mir_input_ty = body.local_decls[local].ty; diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index 2c387edfef0..a9ca9456787 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -1,5 +1,5 @@ use rustc_data_structures::vec_linked_list as vll; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{Body, Local, Location}; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 375eca1b29d..d5e50a61b03 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,7 +14,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; @@ -394,7 +394,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { self.cx.ascribe_user_type( constant.literal.ty(), UserType::TypeOf( - uv.def.did, + uv.def, UserSubsts { substs: uv.substs, user_self_ty: None }, ), locations.span(&self.cx.body), @@ -1766,7 +1766,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { let tcx = self.tcx(); - let def_id = uv.def.def_id_for_type_of(); + let def_id = uv.def; if tcx.def_kind(def_id) == DefKind::InlineConst { let def_id = def_id.expect_local(); let predicates = @@ -2306,7 +2306,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::AddressOf(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Len(..) - | Rvalue::Discriminant(..) => {} + | Rvalue::Discriminant(..) + | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 70fddb1057c..3f7f23df8d9 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -19,7 +19,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::BodyOwnerKind; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::IndexVec; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt}; @@ -226,7 +226,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// known between those regions. pub fn new( infcx: &BorrowckInferCtxt<'_, 'tcx>, - mir_def: ty::WithOptConstParam<LocalDefId>, + mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, ) -> Self { UniversalRegionsBuilder { infcx, mir_def, param_env }.build() @@ -289,7 +289,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// Returns an iterator over all the RegionVids corresponding to /// universally quantified free regions. pub fn universal_regions(&self) -> impl Iterator<Item = RegionVid> { - (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::new) + (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) } /// Returns `true` if `r` is classified as an local region. @@ -388,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> { struct UniversalRegionsBuilder<'cx, 'tcx> { infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, - mir_def: ty::WithOptConstParam<LocalDefId>, + mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, } @@ -417,12 +417,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); // If this is a 'root' body (not a closure/generator/inline const), then // there are no extern regions, so the local regions start at the same // position as the (empty) sub-list of extern regions - let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id { + let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { first_extern_index } else { // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing @@ -433,7 +433,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // } for_each_late_bound_region_in_recursive_scope( self.infcx.tcx, - self.infcx.tcx.local_parent(self.mir_def.did), + self.infcx.tcx.local_parent(self.mir_def), |r| { debug!(?r); if !indices.indices.contains_key(&r) { @@ -462,13 +462,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars( FR, - self.mir_def.did, + self.mir_def, bound_inputs_and_output, &mut indices, ); // Converse of above, if this is a function/closure then the late-bound regions declared on its // signature are local. - for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| { + for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { @@ -492,7 +492,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { let va_list_did = self.infcx.tcx.require_lang_item( LangItem::VaList, - Some(self.infcx.tcx.def_span(self.mir_def.did)), + Some(self.infcx.tcx.def_span(self.mir_def)), ); let reg_vid = self @@ -544,11 +544,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); - match tcx.hir().body_owner_kind(self.mir_def.did) { + match tcx.hir().body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { - let defining_ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); + let defining_ty = tcx.type_of(self.mir_def).subst_identity(); debug!("defining_ty (pre-replacement): {:?}", defining_ty); @@ -562,9 +562,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), _ => span_bug!( - tcx.def_span(self.mir_def.did), + tcx.def_span(self.mir_def), "expected defining type for `{:?}`: `{:?}`", - self.mir_def.did, + self.mir_def, defining_ty ), } @@ -572,10 +572,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const | BodyOwnerKind::Static(..) => { let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.did.to_def_id() == typeck_root_def_id { + if self.mir_def.to_def_id() == typeck_root_def_id { let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs); - DefiningTy::Const(self.mir_def.did.to_def_id(), substs) + DefiningTy::Const(self.mir_def.to_def_id(), substs) } else { // FIXME this line creates a dependency between borrowck and typeck. // @@ -587,15 +587,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // below), so that `type_of(inline_const_def_id).substs(substs)` uses the // proper type with NLL infer vars. let ty = tcx - .typeck(self.mir_def.did) - .node_type(tcx.local_def_id_to_hir_id(self.mir_def.did)); + .typeck(self.mir_def) + .node_type(tcx.local_def_id_to_hir_id(self.mir_def)); let substs = InlineConstSubsts::new( tcx, InlineConstSubstsParts { parent_substs: identity_substs, ty }, ) .substs; let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs); - DefiningTy::InlineConst(self.mir_def.did.to_def_id(), substs) + DefiningTy::InlineConst(self.mir_def.to_def_id(), substs) } } } @@ -611,7 +611,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); let fr_substs = match defining_ty { DefiningTy::Closure(_, substs) @@ -647,7 +647,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; match defining_ty { DefiningTy::Closure(def_id, substs) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let closure_sig = substs.as_closure().sig(); let inputs_and_output = closure_sig.inputs_and_output(); let bound_vars = tcx.mk_bound_variable_kinds_from_iter( @@ -682,7 +682,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::Generator(def_id, substs, movability) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let resume_ty = substs.as_generator().resume_ty(); let output = substs.as_generator().return_ty(); let generator_ty = tcx.mk_generator(def_id, substs, movability); @@ -700,14 +700,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::Const(def_id, _) => { // For a constant body, there are no inputs, and one // "output" (the type of the constant). - assert_eq!(self.mir_def.did.to_def_id(), def_id); - let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); + assert_eq!(self.mir_def.to_def_id(), def_id); + let ty = tcx.type_of(self.mir_def).subst_identity(); let ty = indices.fold_to_region_vids(tcx, ty); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } DefiningTy::InlineConst(def_id, substs) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let ty = substs.as_inline_const().ty(); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } diff --git a/compiler/rustc_const_eval/src/util/collect_writes.rs b/compiler/rustc_borrowck/src/util/collect_writes.rs index 8d92bb35938..8d92bb35938 100644 --- a/compiler/rustc_const_eval/src/util/collect_writes.rs +++ b/compiler/rustc_borrowck/src/util/collect_writes.rs diff --git a/compiler/rustc_borrowck/src/util/mod.rs b/compiler/rustc_borrowck/src/util/mod.rs new file mode 100644 index 00000000000..7377d4de727 --- /dev/null +++ b/compiler/rustc_borrowck/src/util/mod.rs @@ -0,0 +1,3 @@ +mod collect_writes; + +pub use collect_writes::FindAssignments; diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 336e14ef966..5f6441660e3 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -17,6 +17,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_parse_format = { path = "../rustc_parse_format" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 83dc1ac50e5..fca6012a408 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -149,3 +149,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n -> [one] argument *[more] arguments } in format string, but {$desc} +builtin_macros_offset_of_expected_field = expected field + +builtin_macros_offset_of_expected_two_args = expected 2 arguments diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index c9e3cd486f8..090e00616fb 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -301,6 +301,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::If(_, _, _) | ExprKind::IncludedBytes(..) | ExprKind::InlineAsm(_) + | ExprKind::OffsetOf(_, _) | ExprKind::Let(_, _, _) | ExprKind::Lit(_) | ExprKind::Loop(_, _, _) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index f0fc61d7c4f..f17df5b0a83 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -141,13 +141,7 @@ fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult< args: args .named_args() .iter() - .filter_map(|a| { - if let Some(ident) = a.kind.ident() { - Some((a, ident)) - } else { - None - } - }) + .filter_map(|a| a.kind.ident().map(|ident| (a, ident))) .map(|(arg, n)| n.span.to(arg.expr.span)) .collect(), }); diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 37fbd03a6a2..8f86ef44aa3 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -24,7 +24,7 @@ use crate::deriving::*; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_span::symbol::sym; mod alloc_error_handler; @@ -45,6 +45,7 @@ mod format; mod format_foreign; mod global_allocator; mod log_syntax; +mod offset_of; mod source_util; mod test; mod trace_macros; @@ -92,6 +93,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { line: source_util::expand_line, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, + offset_of: offset_of::expand_offset_of, option_env: env::expand_option_env, core_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic, diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs new file mode 100644 index 00000000000..0ef3e000e41 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/offset_of.rs @@ -0,0 +1,99 @@ +use rustc_ast as ast; +use rustc_ast::ptr::P; +use rustc_ast::token; +use rustc_ast::tokenstream::TokenStream; +use rustc_errors::PResult; +use rustc_expand::base::{self, *}; +use rustc_macros::Diagnostic; +use rustc_parse::parser::Parser; +use rustc_span::{symbol::Ident, Span}; + +#[derive(Diagnostic)] +#[diag(builtin_macros_offset_of_expected_field)] +struct ExpectedField { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_offset_of_expected_two_args)] +struct ExpectedTwoArgs { + #[primary_span] + span: Span, +} + +fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> { + let token = p.token.uninterpolate(); + let field = match token.kind { + token::Ident(name, _) => Ident::new(name, token.span), + token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => { + Ident::new(symbol, token.span) + } + _ => return Err(cx.create_err(ExpectedField { span: p.token.span })), + }; + + p.bump(); + + Ok(field) +} + +fn parse_args<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: TokenStream, +) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> { + let mut p = cx.new_parser_from_tts(tts); + + let container = p.parse_ty()?; + + p.expect(&token::Comma)?; + + if p.eat(&token::Eof) { + return Err(cx.create_err(ExpectedTwoArgs { span: sp })); + } + + let mut fields = Vec::new(); + + loop { + let field = parse_field(cx, &mut p)?; + fields.push(field); + + if p.eat(&token::Dot) { + continue; + } + + p.eat(&token::Comma); + + if !p.eat(&token::Eof) { + return Err(cx.create_err(ExpectedTwoArgs { span: sp })); + } + + break; + } + + Ok((container, fields.into())) +} + +pub fn expand_offset_of<'cx>( + cx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> Box<dyn base::MacResult + 'cx> { + match parse_args(cx, sp, tts) { + Ok((container, fields)) => { + let expr = P(ast::Expr { + id: ast::DUMMY_NODE_ID, + kind: ast::ExprKind::OffsetOf(container, fields), + span: sp, + attrs: ast::AttrVec::new(), + tokens: None, + }); + + MacEager::expr(expr) + } + Err(mut err) => { + err.emit(); + DummyResult::any(sp) + } + } +} diff --git a/compiler/rustc_codegen_cranelift/src/abi/returning.rs b/compiler/rustc_codegen_cranelift/src/abi/returning.rs index 6d3e8eda276..bd055216e36 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/returning.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/returning.rs @@ -9,7 +9,7 @@ use smallvec::{smallvec, SmallVec}; /// this adds an extra parameter pointing to where the return value needs to be stored. pub(super) fn codegen_return_param<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - ssa_analyzed: &rustc_index::vec::IndexVec<Local, crate::analyze::SsaKind>, + ssa_analyzed: &rustc_index::IndexSlice<Local, crate::analyze::SsaKind>, block_params_iter: &mut impl Iterator<Item = Value>, ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { diff --git a/compiler/rustc_codegen_cranelift/src/analyze.rs b/compiler/rustc_codegen_cranelift/src/analyze.rs index 54d5c1c2ae9..359d581c153 100644 --- a/compiler/rustc_codegen_cranelift/src/analyze.rs +++ b/compiler/rustc_codegen_cranelift/src/analyze.rs @@ -2,7 +2,7 @@ use crate::prelude::*; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::StatementKind::*; use rustc_middle::ty::Ty; diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index f5301f9f7f1..98ba23c6f57 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -1,7 +1,7 @@ //! Codegen of a single function use rustc_ast::InlineAsmOptions; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -781,12 +781,15 @@ fn codegen_stmt<'tcx>( let operand = operand.load_scalar(fx); lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); } - Rvalue::NullaryOp(null_op, ty) => { + Rvalue::NullaryOp(ref null_op, ty) => { assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all())); 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::OffsetOf(fields) => { + layout.offset_of_subfield(fx, fields.iter().map(|f| f.index())).bytes() + } }; let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into()); lval.write_cvalue(fx, val); diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index d39bf700035..528b35283d7 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -2,7 +2,7 @@ use cranelift_codegen::isa::TargetFrontendConfig; use gimli::write::FileId; use rustc_data_structures::sync::Lrc; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index e87f4e25891..aacf37bb5b7 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -91,7 +91,7 @@ pub(crate) fn eval_mir_constant<'tcx>( ), }, ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _) - if fx.tcx.is_static(def.did) => + if fx.tcx.is_static(def) => { span_bug!(constant.span, "MIR constant refers to static"); } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 8cc7f6c34b0..74d9b72b90c 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -90,7 +90,7 @@ mod prelude { pub(crate) use rustc_data_structures::fx::FxHashMap; - pub(crate) use rustc_index::vec::Idx; + pub(crate) use rustc_index::Idx; pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC}; pub(crate) use cranelift_codegen::ir::function::Function; diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 65de02b3567..738cdb6f119 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -593,6 +593,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a", InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d", @@ -667,6 +669,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl InlineAsmRegClass::Avr(_) => unimplemented!(), InlineAsmRegClass::Bpf(_) => unimplemented!(), InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(), InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(), @@ -804,6 +808,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option } } InlineAsmRegClass::Hexagon(_) => None, + InlineAsmRegClass::LoongArch(_) => None, InlineAsmRegClass::Mips(_) => None, InlineAsmRegClass::Nvptx(_) => None, InlineAsmRegClass::PowerPC(_) => None, diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 0b661505acc..1cabb05de97 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -27,6 +27,7 @@ extern crate rustc_attr; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_hir; extern crate rustc_macros; extern crate rustc_metadata; @@ -76,7 +77,7 @@ use rustc_codegen_ssa::target_features::supported_target_features; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index a7ba2f8b695..5e750d91b82 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -22,6 +22,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } @@ -35,6 +36,5 @@ rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -tempfile = "3.2.0" serde = { version = "1", features = [ "derive" ]} serde_json = "1" diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 1a3865360a3..98d5b3599d9 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -236,6 +236,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::Nvptx64 => {} InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {} InlineAsmArch::Hexagon => {} + InlineAsmArch::LoongArch64 => {} InlineAsmArch::Mips | InlineAsmArch::Mips64 => {} InlineAsmArch::S390x => {} InlineAsmArch::SpirV => {} @@ -633,6 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg) | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w", InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r", + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r", InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f", InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h", @@ -719,6 +722,7 @@ fn modifier_to_llvm( } } InlineAsmRegClass::Hexagon(_) => None, + InlineAsmRegClass::LoongArch(_) => None, InlineAsmRegClass::Mips(_) => None, InlineAsmRegClass::Nvptx(_) => None, InlineAsmRegClass::PowerPC(_) => None, @@ -803,6 +807,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' cx.type_vector(cx.type_i64(), 2) } InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(), + InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(), InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(), InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(), diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 4f8b5abd901..9127fba388b 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -10,7 +10,7 @@ use crate::value::Value; use rustc_ast::Mutability; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::*; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; use rustc_hir::def_id::DefId; use rustc_middle::bug; use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar}; @@ -261,7 +261,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let hash = self.tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); alloc.hash_stable(&mut hcx, &mut hasher); - hasher.finish::<u128>() + hasher.finish::<Hash128>() }); llvm::set_value_name(value, format!("alloc_{hash:032x}").as_bytes()); } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs index 99e4ded62f1..2f910c37d61 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs @@ -12,7 +12,7 @@ use rustc_middle::ty::{self, Instance}; use rustc_session::config::DebugInfo; use rustc_index::bit_set::BitSet; -use rustc_index::vec::Idx; +use rustc_index::Idx; /// Produces DIScope DIEs for each MIR Scope which has variables defined in it. // FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs index ff2b005d757..aaf5dbd9930 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs @@ -22,9 +22,9 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(bx: &mut Builder<'_, bx.const_bitcast(get_or_insert_gdb_debug_scripts_section_global(bx), bx.type_i8p()); // Load just the first byte as that's all that's necessary to force // LLVM to keep around the reference to the global. - let volative_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section); + let volatile_load_instruction = bx.volatile_load(bx.type_i8(), gdb_debug_scripts_section); unsafe { - llvm::LLVMSetAlignment(volative_load_instruction, 1); + llvm::LLVMSetAlignment(volatile_load_instruction, 1); } } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 21a0a60b012..25fe3cb265d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, }; @@ -1182,12 +1181,12 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( let names = get_parameter_names(cx, generics); let template_params: SmallVec<_> = iter::zip(substs, names) .filter_map(|(kind, name)| { - if let GenericArgKind::Type(ty) = kind.unpack() { + kind.as_type().map(|ty| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_di_node = type_di_node(cx, actual_type); let name = name.as_str(); - Some(unsafe { + unsafe { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), None, @@ -1195,10 +1194,8 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( name.len(), actual_type_di_node, ) - }) - } else { - None - } + } + }) }) .collect(); 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 69443b9b828..ecb0912d328 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 @@ -6,7 +6,7 @@ use rustc_codegen_ssa::{ traits::ConstMethods, }; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::{ bug, ty::{ @@ -62,7 +62,7 @@ const SINGLE_VARIANT_VIRTUAL_DISR: u64 = 0; /// In CPP-like mode, we generate a union with a field for each variant and an /// explicit tag field. The field of each variant has a struct type -/// that encodes the discrimiant of the variant and it's data layout. +/// that encodes the discriminant of the variant and it's data layout. /// The union also has a nested enumeration type that is only used for encoding /// variant names in an efficient way. Its enumerator values do _not_ correspond /// to the enum's discriminant values. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 55a217f59f9..9e0e847a155 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -3,7 +3,7 @@ use rustc_codegen_ssa::debuginfo::{ wants_c_like_enum_debuginfo, }; use rustc_hir::def::CtorKind; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::{ bug, mir::{GeneratorLayout, GeneratorSavedLocal}, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index d56c414cf65..824cffa28ba 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -21,12 +21,13 @@ use rustc_codegen_ssa::debuginfo::type_names; use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind}; use rustc_codegen_ssa::traits::*; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::Hash128; use rustc_data_structures::sync::Lrc; use rustc_hir::def_id::{DefId, DefIdMap}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; +use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; @@ -61,7 +62,7 @@ pub struct CodegenUnitDebugContext<'ll, 'tcx> { llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, - created_files: RefCell<FxHashMap<Option<(u128, SourceFileHash)>, &'ll DIFile>>, + created_files: RefCell<FxHashMap<Option<(Hash128, SourceFileHash)>, &'ll DIFile>>, type_map: metadata::TypeMap<'ll, 'tcx>, namespace_map: RefCell<DefIdMap<&'ll DIScope>>, @@ -460,12 +461,12 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let names = get_parameter_names(cx, generics); iter::zip(substs, names) .filter_map(|(kind, name)| { - if let GenericArgKind::Type(ty) = kind.unpack() { + kind.as_type().map(|ty| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_metadata = type_di_node(cx, actual_type); let name = name.as_str(); - Some(unsafe { + unsafe { Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), None, @@ -473,10 +474,8 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { name.len(), actual_type_metadata, )) - }) - } else { - None - } + } + }) }) .collect() } else { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 3f77ea77eff..8305a0a4c28 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -34,7 +34,7 @@ use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::{CodegenResults, CompiledModule}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::query::Providers; @@ -69,7 +69,7 @@ mod declare; mod errors; mod intrinsic; -// The following is a work around that replaces `pub mod llvm;` and that fixes issue 53912. +// The following is a workaround that replaces `pub mod llvm;` and that fixes issue 53912. #[path = "llvm/mod.rs"] mod llvm_; pub mod llvm { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 09f3fe02165..c95148013eb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -552,6 +552,7 @@ pub enum ArchiveKind { K_BSD, K_DARWIN, K_COFF, + K_AIXBIG, } // LLVMRustThinLTOData diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index f820e752371..4f5cc575da6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -137,6 +137,7 @@ impl FromStr for ArchiveKind { "bsd" => Ok(ArchiveKind::K_BSD), "darwin" => Ok(ArchiveKind::K_DARWIN), "coff" => Ok(ArchiveKind::K_COFF), + "aix_big" => Ok(ArchiveKind::K_AIXBIG), _ => Err(()), } } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index c55991e00d3..a421535c9b4 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -7,12 +7,11 @@ edition = "2021" test = false [dependencies] -ar_archive_writer = "0.1.1" +ar_archive_writer = "0.1.3" bitflags = "1.2.1" cc = "1.0.69" itertools = "0.10.1" tracing = "0.1" -libc = "0.2.50" jobserver = "0.1.22" tempfile = "3.2" thorin-dwp = "0.4" @@ -29,6 +28,7 @@ rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } rustc_type_ir = { path = "../rustc_type_ir" } rustc_attr = { path = "../rustc_attr" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } @@ -42,6 +42,9 @@ rustc_query_system = { path = "../rustc_query_system" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } +[target.'cfg(unix)'.dependencies] +libc = "0.2.50" + [dependencies.object] version = "0.30.1" default-features = false diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index 243be0e1f70..85a96e3e89c 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -148,7 +148,7 @@ codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` fa codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} -codegen_ssa_stripping_debu_info_failed = stripping debug info with `{$util}` failed: {$status} +codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status} .note = {$output} codegen_ssa_unable_to_run = unable to run `{$util}`: {$error} diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 66ec8f5f57d..1c464b3eca4 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -233,6 +233,7 @@ impl<'a> ArArchiveBuilder<'a> { "bsd" => ArchiveKind::Bsd, "darwin" => ArchiveKind::Darwin, "coff" => ArchiveKind::Coff, + "aix_big" => ArchiveKind::AixBig, kind => { self.sess.emit_fatal(UnknownArchiveKind { kind }); } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d0fd3cd7666..8f2f829c17c 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -333,7 +333,7 @@ fn exported_symbols_provider_local( match *mono_item { MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => { if substs.non_erasable_generics().next().is_some() { - let symbol = ExportedSymbol::Generic(def.did, substs); + let symbol = ExportedSymbol::Generic(def, substs); symbols.push(( symbol, SymbolExportInfo { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2dda4cd1694..c80347448cb 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -872,7 +872,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { let source_file = in_incr_comp_dir(&incr_comp_session_dir, saved_path); debug!( - "copying pre-existing module `{}` from {:?} to {}", + "copying preexisting module `{}` from {:?} to {}", module.name, source_file, output_path.display() diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8542bab689d..9bfe426c007 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -156,7 +156,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { None => { // Unfortunately, unconditionally using `llvm.used` causes // issues in handling `.init_array` with the gold linker, - // but using `llvm.compiler.used` caused a nontrival amount + // but using `llvm.compiler.used` caused a nontrivial amount // of unintentional ecosystem breakage -- particularly on // Mach-O targets. // diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 1ea13040072..e4da3b8de05 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -1,6 +1,6 @@ pub use super::ffi::*; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::coverage::{ CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, InjectedExpressionIndex, MappedExpressionIndex, Op, diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index f2469fde3b6..03f33d8d8aa 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -12,7 +12,7 @@ // * `"` is treated as the start of a string. use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_hir::def_id::DefId; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability}; @@ -675,8 +675,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: ty::Const<'tcx>, output: &mut S hcx.while_hashing_spans(false, |hcx| { ct.to_valtree().hash_stable(hcx, &mut hasher) }); - let hash: u64 = hasher.finish(); - hash + hasher.finish::<Hash64>() }); if cpp_like_debuginfo(tcx) { diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 66e7e314f79..44931766678 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -424,7 +424,7 @@ pub struct UnableToRunDsymutil { } #[derive(Diagnostic)] -#[diag(codegen_ssa_stripping_debu_info_failed)] +#[diag(codegen_ssa_stripping_debug_info_failed)] #[note] pub struct StrippingDebugInfoFailed<'a> { pub util: &'a str, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 0ab12314b3c..26d55618b49 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -25,8 +25,8 @@ use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def_id::CrateNum; -use rustc_macros::fluent_messages; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 2421acab471..81b49afb883 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -67,10 +67,10 @@ impl<'a, 'tcx> VirtualIndex { /// ref of the type. fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { for arg in ty.peel_refs().walk() { - if let GenericArgKind::Type(ty) = arg.unpack() { - if let ty::Dynamic(data, _, _) = ty.kind() { - return data.principal().expect("expected principal trait object"); - } + if let GenericArgKind::Type(ty) = arg.unpack() + && let ty::Dynamic(data, _, _) = ty.kind() + { + return data.principal().expect("expected principal trait object"); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 115a41050d2..0334c7ff132 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -5,7 +5,7 @@ use super::FunctionCx; use crate::traits::*; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, Location, TerminatorKind}; diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index dd86977817f..a0a8246be15 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -12,7 +12,6 @@ use crate::MemFlags; use rustc_ast as ast; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::Idx; use rustc_middle::mir::{self, AssertKind, SwitchTargets}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; @@ -369,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if self.fn_abi.c_variadic { // The `VaList` "spoofed" argument is just after all the real arguments. let va_list_arg_idx = self.fn_abi.args.len(); - match self.locals[mir::Local::new(1 + va_list_arg_idx)] { + match self.locals[mir::Local::from_usize(1 + va_list_arg_idx)] { LocalRef::Place(va_list) => { bx.va_end(va_list.llval); } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d049bafb821..4e5e2dd5d50 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -1,5 +1,5 @@ use crate::traits::*; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; @@ -494,6 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { + self.set_debug_loc(bx, var.source_info); let base = Self::spill_operand_to_stack( &operand, Some(var.name.to_string()), diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 3dadb33c969..e4f04b83d58 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -9,7 +9,7 @@ use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use self::debuginfo::{FunctionDebugContext, PerLocalVarDebugInfo}; use self::place::PlaceRef; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d88226f5db0..94de19a9c29 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::Operand; use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; +use rustc_session::config::OptLevel; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_target::abi::{self, FIRST_VARIANT}; @@ -231,10 +232,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar)) if in_scalar.size(self.cx) == out_scalar.size(self.cx) => { + let operand_bty = bx.backend_type(operand.layout); let cast_bty = bx.backend_type(cast); - Some(OperandValue::Immediate( - self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty), - )) + Some(OperandValue::Immediate(self.transmute_immediate( + bx, + imm, + in_scalar, + operand_bty, + out_scalar, + cast_bty, + ))) } _ => None, } @@ -250,11 +257,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { && in_a.size(self.cx) == out_a.size(self.cx) && in_b.size(self.cx) == out_b.size(self.cx) { + let in_a_ibty = bx.scalar_pair_element_backend_type(operand.layout, 0, false); + let in_b_ibty = bx.scalar_pair_element_backend_type(operand.layout, 1, false); let out_a_ibty = bx.scalar_pair_element_backend_type(cast, 0, false); let out_b_ibty = bx.scalar_pair_element_backend_type(cast, 1, false); Some(OperandValue::Pair( - self.transmute_immediate(bx, imm_a, in_a, out_a, out_a_ibty), - self.transmute_immediate(bx, imm_b, in_b, out_b, out_b_ibty), + self.transmute_immediate(bx, imm_a, in_a, in_a_ibty, out_a, out_a_ibty), + self.transmute_immediate(bx, imm_b, in_b, in_b_ibty, out_b, out_b_ibty), )) } else { None @@ -273,6 +282,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, mut imm: Bx::Value, from_scalar: abi::Scalar, + from_backend_ty: Bx::Type, to_scalar: abi::Scalar, to_backend_ty: Bx::Type, ) -> Bx::Value { @@ -280,6 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { use abi::Primitive::*; imm = bx.from_immediate(imm); + + // When scalars are passed by value, there's no metadata recording their + // valid ranges. For example, `char`s are passed as just `i32`, with no + // way for LLVM to know that they're 0x10FFFF at most. Thus we assume + // the range of the input value too, not just the output range. + self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty); + imm = match (from_scalar.primitive(), to_scalar.primitive()) { (Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), @@ -294,10 +311,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.bitcast(int_imm, to_backend_ty) } }; + self.assume_scalar_range(bx, imm, to_scalar, to_backend_ty); imm = bx.to_immediate_scalar(imm, to_scalar); imm } + fn assume_scalar_range( + &self, + bx: &mut Bx, + imm: Bx::Value, + scalar: abi::Scalar, + backend_ty: Bx::Type, + ) { + if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less) + // For now, the critical niches are all over `Int`eger values. + // Should floating-point values or pointers ever get more complex + // niches, then this code will probably want to handle them too. + || !matches!(scalar.primitive(), abi::Primitive::Int(..)) + || scalar.is_always_valid(self.cx) + { + return; + } + + let abi::WrappingRange { start, end } = scalar.valid_range(self.cx); + + if start <= end { + if start > 0 { + let low = bx.const_uint_big(backend_ty, start); + let cmp = bx.icmp(IntPredicate::IntUGE, imm, low); + bx.assume(cmp); + } + + let type_max = scalar.size(self.cx).unsigned_int_max(); + if end < type_max { + let high = bx.const_uint_big(backend_ty, end); + let cmp = bx.icmp(IntPredicate::IntULE, imm, high); + bx.assume(cmp); + } + } else { + let low = bx.const_uint_big(backend_ty, start); + let cmp_low = bx.icmp(IntPredicate::IntUGE, imm, low); + + let high = bx.const_uint_big(backend_ty, end); + let cmp_high = bx.icmp(IntPredicate::IntULE, imm, high); + + let or = bx.or(cmp_low, cmp_high); + bx.assume(or); + } + } + pub fn codegen_rvalue_unsized( &mut self, bx: &mut Bx, @@ -604,13 +666,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - mir::Rvalue::NullaryOp(null_op, ty) => { + mir::Rvalue::NullaryOp(ref null_op, ty) => { let ty = self.monomorphize(ty); assert!(bx.cx().type_is_sized(ty)); let layout = bx.cx().layout_of(ty); let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), + mir::NullOp::OffsetOf(fields) => { + layout.offset_of_subfield(bx.cx(), fields.iter().map(|f| f.index())).bytes() + } }; let val = bx.cx().const_usize(val); let tcx = self.cx.tcx(); diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 98ac36c1ced..74030a43c50 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -14,6 +14,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 4bd6fe19931..99f180f475d 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -296,12 +296,12 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } let cid = key.value; - let def = cid.instance.def.with_opt_param(); - let is_static = tcx.is_static(def.did); + let def = cid.instance.def.def_id(); + let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( tcx, - tcx.def_span(def.did), + tcx.def_span(def), key.param_env, // Statics (and promoteds inside statics) may access other statics, because unlike consts // they do not have to behave "as if" they were evaluated at runtime. diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index a5dfd1072f0..814b67b46ec 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -375,9 +375,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { match instance { ty::InstanceDef::Item(def) => { - if ecx.tcx.is_ctfe_mir_available(def.did) { - Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def)) - } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst { + if ecx.tcx.is_ctfe_mir_available(def) { + Ok(ecx.tcx.mir_for_ctfe(def)) + } else if ecx.tcx.def_kind(def) == DefKind::AssocConst { let guar = ecx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", @@ -386,7 +386,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, // so this should be unreachable. - let path = ecx.tcx.def_path_str(def.did); + let path = ecx.tcx.def_path_str(def); bug!("trying to call extern function `{path}` at compile-time"); } } @@ -410,9 +410,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here. But we can at least rule out functions that are not const // at all. - if !ecx.tcx.is_const_fn_raw(def.did) { + if !ecx.tcx.is_const_fn_raw(def) { // allow calling functions inside a trait marked with #[const_trait]. - if !ecx.tcx.is_const_default_method(def.did) { + if !ecx.tcx.is_const_default_method(def) { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 557e721249d..015a9beab83 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -211,18 +211,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variant_index_relative = u32::try_from(variant_index_relative) .expect("we checked that this fits into a u32"); // Then computing the absolute variant idx should not overflow any more. - let variant_index = variants_start - .checked_add(variant_index_relative) - .expect("overflow computing absolute variant idx"); - let variants_len = op + let variant_index = VariantIdx::from_u32( + variants_start + .checked_add(variant_index_relative) + .expect("overflow computing absolute variant idx"), + ); + let variants = op .layout .ty .ty_adt_def() .expect("tagged layout for non adt") - .variants() - .len(); - assert!(usize::try_from(variant_index).unwrap() < variants_len); - VariantIdx::from_u32(variant_index) + .variants(); + assert!(variant_index < variants.next_index()); + variant_index } else { untagged_variant } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 3e58a58aef7..361ce123c78 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -5,7 +5,7 @@ use std::mem; use either::{Either, Left, Right}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir; use rustc_middle::mir::interpret::{ErrorHandled, InterpError}; use rustc_middle::ty::layout::{ @@ -132,11 +132,10 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> { } /// What we store about a frame in an interpreter backtrace. -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct FrameInfo<'tcx> { pub instance: ty::Instance<'tcx>, pub span: Span, - pub lint_root: Option<hir::HirId>, } #[derive(Clone, Copy, Eq, PartialEq, Debug)] // Miri debug-prints these @@ -462,10 +461,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { instance: ty::InstanceDef<'tcx>, promoted: Option<mir::Promoted>, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { - let def = instance.with_opt_param(); trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); let body = if let Some(promoted) = promoted { - &self.tcx.promoted_mir_opt_const_arg(def)[promoted] + let def = instance.def_id(); + &self.tcx.promoted_mir(def)[promoted] } else { M::load_mir(self, instance)? }; @@ -503,13 +502,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// The `substs` are assumed to already be in our interpreter "universe" (param_env). pub(super) fn resolve( &self, - def: ty::WithOptConstParam<DefId>, + def: DefId, substs: SubstsRef<'tcx>, ) -> InterpResult<'tcx, ty::Instance<'tcx>> { trace!("resolve: {:?}, {:#?}", def, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) { + match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), @@ -947,10 +946,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // This deliberately does *not* honor `requires_caller_location` since it is used for much // more than just panics. for frame in stack.iter().rev() { - let lint_root = frame.lint_root(); let span = frame.current_span(); - - frames.push(FrameInfo { span, instance: frame.instance, lint_root }); + frames.push(FrameInfo { span, instance: frame.instance }); } trace!("generate stacktrace: {:#?}", frames); frames diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 26fb041b455..eada75ae391 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -75,7 +75,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( } sym::type_id => { ensure_monomorphic_enough(tcx, tp_ty)?; - ConstValue::from_u64(tcx.type_id_hash(tp_ty)) + ConstValue::from_u64(tcx.type_id_hash(tp_ty).as_u64()) } sym::variant_count => match tp_ty.kind() { // Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough. diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 0291cca7378..b448e3a24c6 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -104,7 +104,7 @@ pub trait Machine<'mir, 'tcx>: Sized { type FrameExtra; /// Extra data stored in every allocation. - type AllocExtra: Debug + Clone + 'static; + type AllocExtra: Debug + Clone + 'tcx; /// Type for the bytes of the allocation. type Bytes: AllocBytes + 'static; diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index a3764a7d142..d5b6a581a79 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -215,7 +215,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.allocate_raw_ptr(alloc, kind) } - /// This can fail only of `alloc` contains provenance. + /// This can fail only if `alloc` contains provenance. pub fn allocate_raw_ptr( &mut self, alloc: Allocation, @@ -807,9 +807,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { DumpAllocs { ecx: self, allocs } } - /// Print leaked memory. Allocations reachable from `static_roots` or a `Global` allocation - /// are not considered leaked. Leaks whose kind `may_leak()` returns true are not reported. - pub fn leak_report(&self, static_roots: &[AllocId]) -> usize { + /// Find leaked allocations. Allocations reachable from `static_roots` or a `Global` allocation + /// are not considered leaked, as well as leaks whose kind's `may_leak()` returns true. + pub fn find_leaked_allocations( + &self, + static_roots: &[AllocId], + ) -> Vec<(AllocId, MemoryKind<M::MemoryKind>, Allocation<M::Provenance, M::AllocExtra, M::Bytes>)> + { // Collect the set of allocations that are *reachable* from `Global` allocations. let reachable = { let mut reachable = FxHashSet::default(); @@ -833,14 +837,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // All allocations that are *not* `reachable` and *not* `may_leak` are considered leaking. - let leaks: Vec<_> = self.memory.alloc_map.filter_map_collect(|&id, &(kind, _)| { - if kind.may_leak() || reachable.contains(&id) { None } else { Some(id) } - }); - let n = leaks.len(); - if n > 0 { - eprintln!("The following memory was leaked: {:?}", self.dump_allocs(leaks)); - } - n + self.memory.alloc_map.filter_map_collect(|id, (kind, alloc)| { + if kind.may_leak() || reachable.contains(id) { + None + } else { + Some((*id, *kind, alloc.clone())) + } + }) } } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 03b09cf830b..2a31a59ad6c 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -5,7 +5,7 @@ use either::{Either, Left, Right}; use rustc_ast::Mutability; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 9a366364e76..319b80d66e1 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -113,8 +113,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, - // Statements we do not track. - PlaceMention(..) | AscribeUserType(..) => {} + // Evaluate the place expression, without reading from it. + PlaceMention(box place) => { + let _ = self.eval_place(*place)?; + } + + // This exists purely to guide borrowck lifetime inference, and does not have + // an operational effect. + AscribeUserType(..) => {} // Currently, Miri discards Coverage statements. Coverage statements are only injected // via an optional compile time MIR pass and have no side effects. Since Coverage @@ -280,20 +286,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(*val, &dest)?; } - NullaryOp(null_op, ty) => { + NullaryOp(ref null_op, ty) => { let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; - if layout.is_unsized() { + if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() { // FIXME: This should be a span_bug (#80742) self.tcx.sess.delay_span_bug( self.frame().current_span(), - &format!("Nullary MIR operator called for unsized type {}", ty), + &format!("{null_op:?} MIR operator called for unsized type {ty}"), ); throw_inval!(SizeOfUnsizedType(ty)); } let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), + mir::NullOp::OffsetOf(fields) => { + layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes() + } }; self.write_scalar(Scalar::from_target_usize(val, self), &dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index a07702f7d9b..df387920010 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -83,8 +83,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) } ty::FnDef(def_id, substs) => { - let instance = - self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?; + let instance = self.resolve(def_id, substs)?; ( FnVal::Instance(instance), self.fn_abi_of_instance(instance, extra_args)?, diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index bf2b4ee69ab..7cb19744987 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -36,7 +36,7 @@ where ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) | ty::FnDef(def_id, substs) => { - let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)); + let instance = ty::InstanceDef::Item(def_id); let unused_params = self.tcx.unused_generic_params(instance); for (index, subst) in substs.into_iter().enumerate() { let index = index diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 93b5273e1b1..e06b634cdc3 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -784,7 +784,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> Abi::Scalar(scalar_layout) => { if !scalar_layout.is_uninit_valid() { // There is something to check here. - let scalar = self.read_scalar(op, "initiailized scalar value")?; + let scalar = self.read_scalar(op, "initialized scalar value")?; self.visit_scalar(scalar, scalar_layout)?; } } @@ -794,7 +794,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // the other must be init. if !a_layout.is_uninit_valid() && !b_layout.is_uninit_valid() { let (a, b) = - self.read_immediate(op, "initiailized scalar value")?.to_scalar_pair(); + self.read_immediate(op, "initialized scalar value")?.to_scalar_pair(); self.visit_scalar(a, a_layout)?; self.visit_scalar(b, b_layout)?; } diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 5ab389d04c7..1b66eca97a5 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -34,7 +34,7 @@ pub mod transform; pub mod util; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty; use rustc_middle::ty::query::Providers; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 9dad9479053..696c4517700 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -558,7 +558,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {} Rvalue::ShallowInitBox(_, _) => {} Rvalue::UnaryOp(_, operand) => { @@ -874,7 +874,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { debug!("Resolving ({:?}) -> {:?}", callee, instance); if let Ok(Some(func)) = instance { if let InstanceDef::Item(def) = func.def { - callee = def.did; + callee = def; } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index c0f5b3725b3..6c11edb742c 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -14,6 +14,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; use rustc_middle::ty::{Binder, TraitRef}; +use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{BytePos, Pos, Span, Symbol}; @@ -21,7 +22,6 @@ use rustc_trait_selection::traits::SelectionContext; use super::ConstCx; use crate::errors; -use crate::util::{call_kind, CallDesugaringKind, CallKind}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Status { @@ -610,10 +610,11 @@ pub struct RawPtrComparison; impl<'tcx> NonConstOp<'tcx> for RawPtrComparison { fn build_error( &self, - _: &ConstCx<'_, 'tcx>, + ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - span_bug!(span, "raw ptr comparison should already be caught in the trait system"); + // FIXME(const_trait_impl): revert to span_bug? + ccx.tcx.sess.create_err(errors::RawPtrComparisonErr { span }) } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 6758cba2eed..bf688f2b34e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -364,9 +364,8 @@ where assert!(promoted.is_none() || Q::ALLOW_PROMOTED); // Don't peek inside trait associated constants. - if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() { - assert_eq!(def.const_param_did, None, "expected associated const: {def:?}"); - let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did); + if promoted.is_none() && cx.tcx.trait_of_item(def).is_none() { + let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { return false; diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 7919aed097a..0e2d9ee8fb2 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt}; use rustc_span::Span; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use std::cell::Cell; use std::{cmp, iter, mem}; @@ -514,6 +514,7 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::NullaryOp(op, _) => match op { NullOp::SizeOf => {} NullOp::AlignOf => {} + NullOp::OffsetOf(_) => {} }, Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable), @@ -828,7 +829,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> { - let def = self.source.source.with_opt_param(); + let def = self.source.source.def_id(); let mut rvalue = { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); @@ -836,7 +837,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut promoted_operand = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); - let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did)); + let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def)); let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) }; Operand::Constant(Box::new(Constant { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index d4bed97380b..03ab2e568df 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -2,15 +2,16 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_infer::traits::Reveal; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{ traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location, - MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, - RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK, + MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef, + ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, + Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, + START_BLOCK, }; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; @@ -262,7 +263,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // We sometimes have to use `defining_opaque_types` for subtyping // to succeed here and figuring out how exactly that should work // is annoying. It is harmless enough to just not validate anything - // in that case. We still check this after analysis as all opque + // in that case. We still check this after analysis as all opaque // types have been revealed at this point. if (src, dest).has_opaque_types() { return true; @@ -711,10 +712,54 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => { + let fail_out_of_bounds = |this: &Self, location, field, ty| { + this.fail(location, format!("Out of bounds field {field:?} for {ty:?}")); + }; + + let mut current_ty = *container; + + for field in fields.iter() { + match current_ty.kind() { + ty::Tuple(fields) => { + let Some(&f_ty) = fields.get(field.as_usize()) else { + fail_out_of_bounds(self, location, field, current_ty); + return; + }; + + current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + } + ty::Adt(adt_def, substs) => { + if adt_def.is_enum() { + self.fail( + location, + format!("Cannot get field offset from enum {current_ty:?}"), + ); + return; + } + + let Some(field) = adt_def.non_enum_variant().fields.get(field) else { + fail_out_of_bounds(self, location, field, current_ty); + return; + }; + + let f_ty = field.ty(self.tcx, substs); + current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + } + _ => { + self.fail( + location, + format!("Cannot get field offset from non-adt type {current_ty:?}"), + ); + return; + } + } + } + } Rvalue::Repeat(_, _) | Rvalue::ThreadLocalRef(_) | Rvalue::AddressOf(_, _) - | Rvalue::NullaryOp(_, _) + | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::Discriminant(_) => {} } self.super_rvalue(rvalue, location); @@ -757,14 +802,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } - StatementKind::PlaceMention(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { - self.fail( - location, - "`PlaceMention` should have been removed after drop lowering phase", - ); - } - } StatementKind::AscribeUserType(..) => { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( @@ -874,6 +911,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { StatementKind::StorageDead(_) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(..) | StatementKind::Nop => {} } diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index c0aabd77cee..7641f560714 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -1,14 +1,9 @@ mod alignment; -mod call_kind; mod check_validity_requirement; -pub mod collect_writes; mod compare_types; -mod find_self_call; mod type_name; pub use self::alignment::is_disaligned; -pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind}; pub use self::check_validity_requirement::check_validity_requirement; pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype}; -pub use self::find_self_call::find_self_call; pub use self::type_name::type_name; diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 2102f09c56a..5e05fe463ed 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -21,13 +21,11 @@ rustc-hash = "1.1.0" rustc_index = { path = "../rustc_index", package = "rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } -serde_json = "1.0.59" smallvec = { version = "1.8.1", features = [ "const_generics", "union", "may_dangle", ] } -stable_deref_trait = "1.0.0" stacker = "0.1.15" tempfile = "3.2" thin-vec = "0.2.12" diff --git a/compiler/rustc_data_structures/src/aligned.rs b/compiler/rustc_data_structures/src/aligned.rs new file mode 100644 index 00000000000..0e5ecfd9bff --- /dev/null +++ b/compiler/rustc_data_structures/src/aligned.rs @@ -0,0 +1,33 @@ +use std::ptr::Alignment; + +/// Returns the ABI-required minimum alignment of a type in bytes. +/// +/// This is equivalent to [`mem::align_of`], but also works for some unsized +/// types (e.g. slices or rustc's `List`s). +/// +/// [`mem::align_of`]: std::mem::align_of +pub const fn align_of<T: ?Sized + Aligned>() -> Alignment { + T::ALIGN +} + +/// A type with a statically known alignment. +/// +/// # Safety +/// +/// `Self::ALIGN` must be equal to the alignment of `Self`. For sized types it +/// is [`mem::align_of<Self>()`], for unsized types it depends on the type, for +/// example `[T]` has alignment of `T`. +/// +/// [`mem::align_of<Self>()`]: std::mem::align_of +pub unsafe trait Aligned { + /// Alignment of `Self`. + const ALIGN: Alignment; +} + +unsafe impl<T> Aligned for T { + const ALIGN: Alignment = Alignment::of::<Self>(); +} + +unsafe impl<T> Aligned for [T] { + const ALIGN: Alignment = Alignment::of::<T>(); +} diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index b6e866f15ef..6fa76981408 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,4 +1,4 @@ -use crate::stable_hasher; +use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::hash::{Hash, Hasher}; @@ -9,32 +9,49 @@ mod tests; #[repr(C)] pub struct Fingerprint(u64, u64); -impl Fingerprint { - pub const ZERO: Fingerprint = Fingerprint(0, 0); +pub trait FingerprintComponent { + fn as_u64(&self) -> u64; +} +impl FingerprintComponent for Hash64 { #[inline] - pub fn new(_0: u64, _1: u64) -> Fingerprint { - Fingerprint(_0, _1) + fn as_u64(&self) -> u64 { + Hash64::as_u64(*self) + } +} + +impl FingerprintComponent for u64 { + #[inline] + fn as_u64(&self) -> u64 { + *self } +} + +impl Fingerprint { + pub const ZERO: Fingerprint = Fingerprint(0, 0); #[inline] - pub fn from_smaller_hash(hash: u64) -> Fingerprint { - Fingerprint(hash, hash) + pub fn new<A, B>(_0: A, _1: B) -> Fingerprint + where + A: FingerprintComponent, + B: FingerprintComponent, + { + Fingerprint(_0.as_u64(), _1.as_u64()) } #[inline] - pub fn to_smaller_hash(&self) -> u64 { + pub fn to_smaller_hash(&self) -> Hash64 { // Even though both halves of the fingerprint are expected to be good // quality hash values, let's still combine the two values because the // Fingerprints in DefPathHash have the StableCrateId portion which is // the same for all DefPathHashes from the same crate. Combining the // two halves makes sure we get a good quality hash in such cases too. - self.0.wrapping_mul(3).wrapping_add(self.1) + Hash64::new(self.0.wrapping_mul(3).wrapping_add(self.1)) } #[inline] - pub fn as_value(&self) -> (u64, u64) { - (self.0, self.1) + pub fn split(&self) -> (Hash64, Hash64) { + (Hash64::new(self.0), Hash64::new(self.1)) } #[inline] @@ -131,9 +148,9 @@ impl FingerprintHasher for crate::unhash::Unhasher { } } -impl stable_hasher::StableHasherResult for Fingerprint { +impl StableHasherResult for Fingerprint { #[inline] - fn finish(hasher: stable_hasher::StableHasher) -> Self { + fn finish(hasher: StableHasher) -> Self { let (_0, _1) = hasher.finalize(); Fingerprint(_0, _1) } diff --git a/compiler/rustc_data_structures/src/fingerprint/tests.rs b/compiler/rustc_data_structures/src/fingerprint/tests.rs index 9b0783e33ab..09ec2622a65 100644 --- a/compiler/rustc_data_structures/src/fingerprint/tests.rs +++ b/compiler/rustc_data_structures/src/fingerprint/tests.rs @@ -1,11 +1,12 @@ use super::*; +use crate::stable_hasher::Hash64; // Check that `combine_commutative` is order independent. #[test] fn combine_commutative_is_order_independent() { - let a = Fingerprint::new(0xf6622fb349898b06, 0x70be9377b2f9c610); - let b = Fingerprint::new(0xa9562bf5a2a5303c, 0x67d9b6c82034f13d); - let c = Fingerprint::new(0x0d013a27811dbbc3, 0x9a3f7b3d9142ec43); + let a = Fingerprint::new(Hash64::new(0xf6622fb349898b06), Hash64::new(0x70be9377b2f9c610)); + let b = Fingerprint::new(Hash64::new(0xa9562bf5a2a5303c), Hash64::new(0x67d9b6c82034f13d)); + let c = Fingerprint::new(Hash64::new(0x0d013a27811dbbc3), Hash64::new(0x9a3f7b3d9142ec43)); let permutations = [(a, b, c), (a, c, b), (b, a, c), (b, c, a), (c, a, b), (c, b, a)]; let f = a.combine_commutative(b).combine_commutative(c); for p in &permutations { diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs index 28fcf80b31b..e3fcaccb1bd 100644 --- a/compiler/rustc_data_structures/src/functor.rs +++ b/compiler/rustc_data_structures/src/functor.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use std::{mem, rc::Rc, sync::Arc}; pub trait IdFunctor: Sized { diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 0df9dc112ee..e76bdac2864 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -10,7 +10,8 @@ //! <https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf> use super::ControlFlowGraph; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; + use std::cmp::Ordering; #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 01a83b40a75..9eb4b5278c0 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -1,6 +1,6 @@ use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors}; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use std::ops::ControlFlow; #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 3560df6e5e2..e06ab2fe36b 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::Idx; +use rustc_index::Idx; pub mod dominators; pub mod implementation; diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 28c357e54dd..cf9312ea8fb 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -8,7 +8,7 @@ use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use std::ops::Range; #[cfg(test)] diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs index 94232bb7626..00f6266ce1d 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs @@ -1,5 +1,5 @@ use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/hashes.rs b/compiler/rustc_data_structures/src/hashes.rs new file mode 100644 index 00000000000..ad068cdbc98 --- /dev/null +++ b/compiler/rustc_data_structures/src/hashes.rs @@ -0,0 +1,132 @@ +//! rustc encodes a lot of hashes. If hashes are stored as `u64` or `u128`, a `derive(Encodable)` +//! will apply varint encoding to the hashes, which is less efficient than directly encoding the 8 +//! or 16 bytes of the hash. +//! +//! The types in this module represent 64-bit or 128-bit hashes produced by a `StableHasher`. +//! `Hash64` and `Hash128` expose some utilty functions to encourage users to not extract the inner +//! hash value as an integer type and accidentally apply varint encoding to it. +//! +//! In contrast with `Fingerprint`, users of these types cannot and should not attempt to construct +//! and decompose these types into constitutent pieces. The point of these types is only to +//! connect the fact that they can only be produced by a `StableHasher` to their +//! `Encode`/`Decode` impls. + +use crate::stable_hasher::{StableHasher, StableHasherResult}; +use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use std::fmt; +use std::ops::BitXorAssign; + +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +pub struct Hash64 { + inner: u64, +} + +impl Hash64 { + pub const ZERO: Hash64 = Hash64 { inner: 0 }; + + #[inline] + pub(crate) fn new(n: u64) -> Self { + Self { inner: n } + } + + #[inline] + pub fn as_u64(self) -> u64 { + self.inner + } +} + +impl BitXorAssign<u64> for Hash64 { + #[inline] + fn bitxor_assign(&mut self, rhs: u64) { + self.inner ^= rhs; + } +} + +impl<S: Encoder> Encodable<S> for Hash64 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.inner.to_le_bytes()); + } +} + +impl<D: Decoder> Decodable<D> for Hash64 { + #[inline] + fn decode(d: &mut D) -> Self { + Self { inner: u64::from_le_bytes(d.read_raw_bytes(8).try_into().unwrap()) } + } +} + +impl StableHasherResult for Hash64 { + #[inline] + fn finish(hasher: StableHasher) -> Self { + Self { inner: hasher.finalize().0 } + } +} + +impl fmt::Debug for Hash64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.inner.fmt(f) + } +} + +impl fmt::LowerHex for Hash64 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.inner, f) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Default)] +pub struct Hash128 { + inner: u128, +} + +impl Hash128 { + #[inline] + pub fn truncate(self) -> Hash64 { + Hash64 { inner: self.inner as u64 } + } + + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self { inner: self.inner.wrapping_add(other.inner) } + } + + #[inline] + pub fn as_u128(self) -> u128 { + self.inner + } +} + +impl<S: Encoder> Encodable<S> for Hash128 { + #[inline] + fn encode(&self, s: &mut S) { + s.emit_raw_bytes(&self.inner.to_le_bytes()); + } +} + +impl<D: Decoder> Decodable<D> for Hash128 { + #[inline] + fn decode(d: &mut D) -> Self { + Self { inner: u128::from_le_bytes(d.read_raw_bytes(16).try_into().unwrap()) } + } +} + +impl StableHasherResult for Hash128 { + #[inline] + fn finish(hasher: StableHasher) -> Self { + let (_0, _1) = hasher.finalize(); + Self { inner: u128::from(_0) | (u128::from(_1) << 64) } + } +} + +impl fmt::Debug for Hash128 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.inner.fmt(f) + } +} + +impl fmt::LowerHex for Hash128 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.inner, f) + } +} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index e373bd18402..004017ec5f3 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -29,10 +29,14 @@ #![feature(get_mut_unchecked)] #![feature(lint_reasons)] #![feature(unwrap_infallible)] +#![feature(strict_provenance)] +#![feature(ptr_alignment_type)] +#![feature(macro_metavar_expr)] #![allow(rustc::default_hash_types)] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +#![deny(unsafe_op_in_unsafe_fn)] #[macro_use] extern crate tracing; @@ -82,7 +86,9 @@ pub mod transitive_relation; pub mod vec_linked_list; pub mod work_queue; pub use atomic_ref::AtomicRef; +pub mod aligned; pub mod frozen; +mod hashes; pub mod owned_slice; pub mod sso; pub mod steal; diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs index ef37a606f31..ca908671ae5 100644 --- a/compiler/rustc_data_structures/src/memmap.rs +++ b/compiler/rustc_data_structures/src/memmap.rs @@ -13,7 +13,8 @@ pub struct Mmap(Vec<u8>); impl Mmap { #[inline] pub unsafe fn map(file: File) -> io::Result<Self> { - memmap2::Mmap::map(&file).map(Mmap) + // Safety: this is in fact not safe. + unsafe { memmap2::Mmap::map(&file).map(Mmap) } } } diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 1ed584eafad..572bd4ac21c 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -87,6 +87,7 @@ use crate::fx::FxHashMap; use std::borrow::Borrow; use std::collections::hash_map::Entry; use std::error::Error; +use std::fmt::Display; use std::fs; use std::intrinsics::unlikely; use std::path::Path; @@ -97,7 +98,6 @@ use std::time::{Duration, Instant}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; use parking_lot::RwLock; -use serde_json::json; use smallvec::SmallVec; bitflags::bitflags! { @@ -557,7 +557,7 @@ impl SelfProfiler { let crate_name = crate_name.unwrap_or("unknown-crate"); // HACK(eddyb) we need to pad the PID, strange as it may seem, as its // length can behave as a source of entropy for heap addresses, when - // ASLR is disabled and the heap is otherwise determinic. + // ASLR is disabled and the heap is otherwise deterministic. let pid: u32 = process::id(); let filename = format!("{crate_name}-{pid:07}.rustc_profile"); let path = output_directory.join(&filename); @@ -763,6 +763,31 @@ impl Drop for VerboseTimingGuard<'_> { } } +struct JsonTimePassesEntry<'a> { + pass: &'a str, + time: f64, + start_rss: Option<usize>, + end_rss: Option<usize>, +} + +impl Display for JsonTimePassesEntry<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { pass: what, time, start_rss, end_rss } = self; + write!(f, r#"{{"pass":"{what}","time":{time},"rss_start":"#).unwrap(); + match start_rss { + Some(rss) => write!(f, "{rss}")?, + None => write!(f, "null")?, + } + write!(f, r#","rss_end":"#)?; + match end_rss { + Some(rss) => write!(f, "{rss}")?, + None => write!(f, "null")?, + } + write!(f, "}}")?; + Ok(()) + } +} + pub fn print_time_passes_entry( what: &str, dur: Duration, @@ -772,13 +797,10 @@ pub fn print_time_passes_entry( ) { match format { TimePassesFormat::Json => { - let json = json!({ - "pass": what, - "time": dur.as_secs_f64(), - "rss_start": start_rss, - "rss_end": end_rss, - }); - eprintln!("time: {json}"); + let entry = + JsonTimePassesEntry { pass: what, time: dur.as_secs_f64(), start_rss, end_rss }; + + eprintln!(r#"time: {entry}"#); return; } TimePassesFormat::Text => (), @@ -894,3 +916,6 @@ cfg_if! { } } } + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/profiling/tests.rs b/compiler/rustc_data_structures/src/profiling/tests.rs new file mode 100644 index 00000000000..2b09de085da --- /dev/null +++ b/compiler/rustc_data_structures/src/profiling/tests.rs @@ -0,0 +1,19 @@ +use super::JsonTimePassesEntry; + +#[test] +fn with_rss() { + let entry = + JsonTimePassesEntry { pass: "typeck", time: 56.1, start_rss: Some(10), end_rss: Some(20) }; + + assert_eq!(entry.to_string(), r#"{"pass":"typeck","time":56.1,"rss_start":10,"rss_end":20}"#) +} + +#[test] +fn no_rss() { + let entry = JsonTimePassesEntry { pass: "typeck", time: 56.1, start_rss: None, end_rss: None }; + + assert_eq!( + entry.to_string(), + r#"{"pass":"typeck","time":56.1,"rss_start":null,"rss_end":null}"# + ) +} diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index d849fe0373f..4a0ed87f77c 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -96,28 +96,30 @@ macro_rules! compress { unsafe fn copy_nonoverlapping_small(src: *const u8, dst: *mut u8, count: usize) { debug_assert!(count <= 8); - if count == 8 { - ptr::copy_nonoverlapping(src, dst, 8); - return; - } + unsafe { + if count == 8 { + ptr::copy_nonoverlapping(src, dst, 8); + return; + } - let mut i = 0; - if i + 3 < count { - ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4); - i += 4; - } + let mut i = 0; + if i + 3 < count { + ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4); + i += 4; + } - if i + 1 < count { - ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2); - i += 2 - } + if i + 1 < count { + ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2); + i += 2 + } - if i < count { - *dst.add(i) = *src.add(i); - i += 1; - } + if i < count { + *dst.add(i) = *src.add(i); + i += 1; + } - debug_assert_eq!(i, count); + debug_assert_eq!(i, count); + } } // # Implementation @@ -232,38 +234,40 @@ impl SipHasher128 { // overflow) if it wasn't already. #[inline(never)] unsafe fn short_write_process_buffer<const LEN: usize>(&mut self, bytes: [u8; LEN]) { - let nbuf = self.nbuf; - debug_assert!(LEN <= 8); - debug_assert!(nbuf < BUFFER_SIZE); - debug_assert!(nbuf + LEN >= BUFFER_SIZE); - debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE); + unsafe { + let nbuf = self.nbuf; + debug_assert!(LEN <= 8); + debug_assert!(nbuf < BUFFER_SIZE); + debug_assert!(nbuf + LEN >= BUFFER_SIZE); + debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE); + + // Copy first part of input into end of buffer, possibly into spill + // element. The memcpy call is optimized away because the size is known. + let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); + ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN); + + // Process buffer. + for i in 0..BUFFER_CAPACITY { + let elem = self.buf.get_unchecked(i).assume_init().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + } - // Copy first part of input into end of buffer, possibly into spill - // element. The memcpy call is optimized away because the size is known. - let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); - ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN); - - // Process buffer. - for i in 0..BUFFER_CAPACITY { - let elem = self.buf.get_unchecked(i).assume_init().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; + // Copy remaining input into start of buffer by copying LEN - 1 + // elements from spill (at most LEN - 1 bytes could have overflowed + // into the spill). The memcpy call is optimized away because the size + // is known. And the whole copy is optimized away for LEN == 1. + let dst = self.buf.as_mut_ptr() as *mut u8; + let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; + ptr::copy_nonoverlapping(src, dst, LEN - 1); + + // This function should only be called when the write fills the buffer. + // Therefore, when LEN == 1, the new `self.nbuf` must be zero. + // LEN is statically known, so the branch is optimized away. + self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE }; + self.processed += BUFFER_SIZE; } - - // Copy remaining input into start of buffer by copying LEN - 1 - // elements from spill (at most LEN - 1 bytes could have overflowed - // into the spill). The memcpy call is optimized away because the size - // is known. And the whole copy is optimized away for LEN == 1. - let dst = self.buf.as_mut_ptr() as *mut u8; - let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; - ptr::copy_nonoverlapping(src, dst, LEN - 1); - - // This function should only be called when the write fills the buffer. - // Therefore, when LEN == 1, the new `self.nbuf` must be zero. - // LEN is statically known, so the branch is optimized away. - self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE }; - self.processed += BUFFER_SIZE; } // A write function for byte slices. @@ -301,57 +305,59 @@ impl SipHasher128 { // containing the byte offset `self.nbuf`. #[inline(never)] unsafe fn slice_write_process_buffer(&mut self, msg: &[u8]) { - let length = msg.len(); - let nbuf = self.nbuf; - debug_assert!(nbuf < BUFFER_SIZE); - debug_assert!(nbuf + length >= BUFFER_SIZE); - - // Always copy first part of input into current element of buffer. - // This function should only be called when the write fills the buffer, - // so we know that there is enough input to fill the current element. - let valid_in_elem = nbuf % ELEM_SIZE; - let needed_in_elem = ELEM_SIZE - valid_in_elem; - - let src = msg.as_ptr(); - let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); - copy_nonoverlapping_small(src, dst, needed_in_elem); - - // Process buffer. + unsafe { + let length = msg.len(); + let nbuf = self.nbuf; + debug_assert!(nbuf < BUFFER_SIZE); + debug_assert!(nbuf + length >= BUFFER_SIZE); + + // Always copy first part of input into current element of buffer. + // This function should only be called when the write fills the buffer, + // so we know that there is enough input to fill the current element. + let valid_in_elem = nbuf % ELEM_SIZE; + let needed_in_elem = ELEM_SIZE - valid_in_elem; + + let src = msg.as_ptr(); + let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); + copy_nonoverlapping_small(src, dst, needed_in_elem); + + // Process buffer. + + // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) / + // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0. + // We know that is true, because last step ensured we have a full + // element in the buffer. + let last = nbuf / ELEM_SIZE + 1; + + for i in 0..last { + let elem = self.buf.get_unchecked(i).assume_init().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + } - // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) / - // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0. - // We know that is true, because last step ensured we have a full - // element in the buffer. - let last = nbuf / ELEM_SIZE + 1; + // Process the remaining element-sized chunks of input. + let mut processed = needed_in_elem; + let input_left = length - processed; + let elems_left = input_left / ELEM_SIZE; + let extra_bytes_left = input_left % ELEM_SIZE; + + for _ in 0..elems_left { + let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + processed += ELEM_SIZE; + } - for i in 0..last { - let elem = self.buf.get_unchecked(i).assume_init().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; - } + // Copy remaining input into start of buffer. + let src = msg.as_ptr().add(processed); + let dst = self.buf.as_mut_ptr() as *mut u8; + copy_nonoverlapping_small(src, dst, extra_bytes_left); - // Process the remaining element-sized chunks of input. - let mut processed = needed_in_elem; - let input_left = length - processed; - let elems_left = input_left / ELEM_SIZE; - let extra_bytes_left = input_left % ELEM_SIZE; - - for _ in 0..elems_left { - let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; - processed += ELEM_SIZE; + self.nbuf = extra_bytes_left; + self.processed += nbuf + processed; } - - // Copy remaining input into start of buffer. - let src = msg.as_ptr().add(processed); - let dst = self.buf.as_mut_ptr() as *mut u8; - copy_nonoverlapping_small(src, dst, extra_bytes_left); - - self.nbuf = extra_bytes_left; - self.processed += nbuf + processed; } #[inline] diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index 7d23ff51948..c172ee1c970 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -3,7 +3,7 @@ use std::hash::{Hash, Hasher}; use crate::stable_hasher::{HashStable, StableHasher}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; /// An indexed multi-map that preserves insertion order while permitting both *O*(log *n*) lookup of /// an item by key and *O*(1) lookup by index. diff --git a/compiler/rustc_data_structures/src/sso/map.rs b/compiler/rustc_data_structures/src/sso/map.rs index 89b8c852649..99581ed2375 100644 --- a/compiler/rustc_data_structures/src/sso/map.rs +++ b/compiler/rustc_data_structures/src/sso/map.rs @@ -256,12 +256,9 @@ impl<K: Eq + Hash, V> SsoHashMap<K, V> { pub fn remove(&mut self, key: &K) -> Option<V> { match self { SsoHashMap::Array(array) => { - if let Some(index) = array.iter().position(|(k, _v)| k == key) { - Some(array.swap_remove(index).1) - } else { - None - } + array.iter().position(|(k, _v)| k == key).map(|index| array.swap_remove(index).1) } + SsoHashMap::Map(map) => map.remove(key), } } diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 3ed1de1bc3c..6d57d81c56a 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -1,7 +1,8 @@ use crate::sip128::SipHasher128; -use rustc_index::bit_set; -use rustc_index::vec; +use rustc_index::bit_set::{self, BitSet}; +use rustc_index::{Idx, IndexVec}; use smallvec::SmallVec; +use std::fmt; use std::hash::{BuildHasher, Hash, Hasher}; use std::marker::PhantomData; use std::mem; @@ -9,6 +10,8 @@ use std::mem; #[cfg(test)] mod tests; +pub use crate::hashes::{Hash128, Hash64}; + /// When hashing something that ends up affecting properties like symbol names, /// we want these symbol names to be calculated independently of other factors /// like what architecture you're compiling *from*. @@ -20,8 +23,8 @@ pub struct StableHasher { state: SipHasher128, } -impl ::std::fmt::Debug for StableHasher { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for StableHasher { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.state) } } @@ -42,21 +45,6 @@ impl StableHasher { } } -impl StableHasherResult for u128 { - #[inline] - fn finish(hasher: StableHasher) -> Self { - let (_0, _1) = hasher.finalize(); - u128::from(_0) | (u128::from(_1) << 64) - } -} - -impl StableHasherResult for u64 { - #[inline] - fn finish(hasher: StableHasher) -> Self { - hasher.finalize().0 - } -} - impl StableHasher { #[inline] pub fn finalize(self) -> (u64, u64) { @@ -107,7 +95,8 @@ impl Hasher for StableHasher { #[inline] fn write_u128(&mut self, i: u128) { - self.state.write(&i.to_le_bytes()); + self.write_u64(i as u64); + self.write_u64((i >> 64) as u64); } #[inline] @@ -286,6 +275,9 @@ impl_stable_traits_for_trivial_type!(i128); impl_stable_traits_for_trivial_type!(char); impl_stable_traits_for_trivial_type!(()); +impl_stable_traits_for_trivial_type!(Hash64); +impl_stable_traits_for_trivial_type!(Hash128); + impl<CTX> HashStable<CTX> for ! { fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) { unreachable!() @@ -565,7 +557,7 @@ where } } -impl<I: vec::Idx, T, CTX> HashStable<CTX> for vec::IndexVec<I, T> +impl<I: Idx, T, CTX> HashStable<CTX> for IndexVec<I, T> where T: HashStable<CTX>, { @@ -577,13 +569,13 @@ where } } -impl<I: vec::Idx, CTX> HashStable<CTX> for bit_set::BitSet<I> { +impl<I: Idx, CTX> HashStable<CTX> for BitSet<I> { fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } } -impl<R: vec::Idx, C: vec::Idx, CTX> HashStable<CTX> for bit_set::BitMatrix<R, C> { +impl<R: Idx, C: Idx, CTX> HashStable<CTX> for bit_set::BitMatrix<R, C> { fn hash_stable(&self, _ctx: &mut CTX, hasher: &mut StableHasher) { ::std::hash::Hash::hash(self, hasher); } @@ -668,7 +660,7 @@ fn stable_hash_reduce<HCX, I, C, F>( .map(|value| { let mut hasher = StableHasher::new(); hash_function(&mut hasher, hcx, value); - hasher.finish::<u128>() + hasher.finish::<Hash128>() }) .reduce(|accum, value| accum.wrapping_add(value)); hash.hash_stable(hcx, hasher); diff --git a/compiler/rustc_data_structures/src/stable_hasher/tests.rs b/compiler/rustc_data_structures/src/stable_hasher/tests.rs index a98b1bc3626..c8921f6a778 100644 --- a/compiler/rustc_data_structures/src/stable_hasher/tests.rs +++ b/compiler/rustc_data_structures/src/stable_hasher/tests.rs @@ -72,7 +72,7 @@ fn test_hash_isize() { assert_eq!(h.finalize(), expected); } -fn hash<T: HashStable<()>>(t: &T) -> u128 { +fn hash<T: HashStable<()>>(t: &T) -> Hash128 { let mut h = StableHasher::new(); let ctx = &mut (); t.hash_stable(ctx, &mut h); diff --git a/compiler/rustc_data_structures/src/svh.rs b/compiler/rustc_data_structures/src/svh.rs index 61654b9e8f5..a3d2724fcdb 100644 --- a/compiler/rustc_data_structures/src/svh.rs +++ b/compiler/rustc_data_structures/src/svh.rs @@ -5,40 +5,30 @@ //! mismatches where we have two versions of the same crate that were //! compiled from distinct sources. -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use crate::fingerprint::Fingerprint; use std::fmt; -use std::hash::{Hash, Hasher}; use crate::stable_hasher; -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Encodable, Decodable, Hash)] pub struct Svh { - hash: u64, + hash: Fingerprint, } impl Svh { /// Creates a new `Svh` given the hash. If you actually want to /// compute the SVH from some HIR, you want the `calculate_svh` /// function found in `rustc_incremental`. - pub fn new(hash: u64) -> Svh { + pub fn new(hash: Fingerprint) -> Svh { Svh { hash } } pub fn as_u64(&self) -> u64 { - self.hash + self.hash.to_smaller_hash().as_u64() } pub fn to_string(&self) -> String { - format!("{:016x}", self.hash) - } -} - -impl Hash for Svh { - fn hash<H>(&self, state: &mut H) - where - H: Hasher, - { - self.hash.to_le().hash(state); + format!("{:016x}", self.hash.to_smaller_hash()) } } @@ -48,18 +38,6 @@ impl fmt::Display for Svh { } } -impl<S: Encoder> Encodable<S> for Svh { - fn encode(&self, s: &mut S) { - s.emit_u64(self.as_u64().to_le()); - } -} - -impl<D: Decoder> Decodable<D> for Svh { - fn decode(d: &mut D) -> Svh { - Svh::new(u64::from_le(d.read_u64())) - } -} - impl<T> stable_hasher::HashStable<T> for Svh { #[inline] fn hash_stable(&self, ctx: &mut T, hasher: &mut stable_hasher::StableHasher) { diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs index 1783b4b3572..e36dded9e5e 100644 --- a/compiler/rustc_data_structures/src/sync/vec.rs +++ b/compiler/rustc_data_structures/src/sync/vec.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use rustc_index::vec::Idx; +use rustc_index::Idx; #[derive(Default)] pub struct AppendOnlyIndexVec<I: Idx, T: Copy> { diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index 651bc556c98..2914eece679 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs @@ -3,166 +3,281 @@ //! In order to utilize the pointer packing, you must have two types: a pointer, //! and a tag. //! -//! The pointer must implement the `Pointer` trait, with the primary requirement -//! being conversion to and from a usize. Note that the pointer must be -//! dereferenceable, so raw pointers generally cannot implement the `Pointer` -//! trait. This implies that the pointer must also be nonzero. +//! The pointer must implement the [`Pointer`] trait, with the primary +//! requirement being convertible to and from a raw pointer. Note that the +//! pointer must be dereferenceable, so raw pointers generally cannot implement +//! the [`Pointer`] trait. This implies that the pointer must also be non-null. //! -//! Many common pointer types already implement the `Pointer` trait. +//! Many common pointer types already implement the [`Pointer`] trait. //! -//! The tag must implement the `Tag` trait. We assert that the tag and `Pointer` -//! are compatible at compile time. +//! The tag must implement the [`Tag`] trait. +//! +//! We assert that the tag and the [`Pointer`] types are compatible at compile +//! time. -use std::mem::ManuallyDrop; use std::ops::Deref; +use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; +use crate::aligned::Aligned; + mod copy; mod drop; +mod impl_tag; pub use copy::CopyTaggedPtr; pub use drop::TaggedPtr; -/// This describes the pointer type encapsulated by TaggedPtr. +/// This describes the pointer type encapsulated by [`TaggedPtr`] and +/// [`CopyTaggedPtr`]. /// /// # Safety /// -/// The usize returned from `into_usize` must be a valid, dereferenceable, -/// pointer to `<Self as Deref>::Target`. Note that pointers to `Pointee` must -/// be thin, even though `Pointee` may not be sized. +/// The pointer returned from [`into_ptr`] must be a [valid], pointer to +/// [`<Self as Deref>::Target`]. /// -/// Note that the returned pointer from `into_usize` should be castable to `&mut -/// <Self as Deref>::Target` if `Pointer: DerefMut`. +/// Note that if `Self` implements [`DerefMut`] the pointer returned from +/// [`into_ptr`] must be valid for writes (and thus calling [`NonNull::as_mut`] +/// on it must be safe). /// -/// The BITS constant must be correct. At least `BITS` bits, least-significant, -/// must be zero on all returned pointers from `into_usize`. +/// The [`BITS`] constant must be correct. [`BITS`] least-significant bits, +/// must be zero on all pointers returned from [`into_ptr`]. /// -/// For example, if the alignment of `Pointee` is 2, then `BITS` should be 1. +/// For example, if the alignment of [`Self::Target`] is 2, then `BITS` should be 1. +/// +/// [`BITS`]: Pointer::BITS +/// [`into_ptr`]: Pointer::into_ptr +/// [valid]: std::ptr#safety +/// [`<Self as Deref>::Target`]: Deref::Target +/// [`Self::Target`]: Deref::Target +/// [`DerefMut`]: std::ops::DerefMut pub unsafe trait Pointer: Deref { + /// Number of unused (always zero) **least-significant bits** in this + /// pointer, usually related to the pointees alignment. + /// + /// For example if [`BITS`] = `2`, then given `ptr = Self::into_ptr(..)`, + /// `ptr.addr() & 0b11 == 0` must be true. + /// /// Most likely the value you want to use here is the following, unless - /// your Pointee type is unsized (e.g., `ty::List<T>` in rustc) in which - /// case you'll need to manually figure out what the right type to pass to - /// align_of is. + /// your [`Self::Target`] type is unsized (e.g., `ty::List<T>` in rustc) + /// or your pointer is over/under aligned, in which case you'll need to + /// manually figure out what the right type to pass to [`bits_for`] is, or + /// what the value to set here. /// - /// ```ignore UNSOLVED (what to do about the Self) + /// ```rust /// # use std::ops::Deref; - /// std::mem::align_of::<<Self as Deref>::Target>().trailing_zeros() as usize; + /// # use rustc_data_structures::tagged_ptr::bits_for; + /// # struct T; + /// # impl Deref for T { type Target = u8; fn deref(&self) -> &u8 { &0 } } + /// # impl T { + /// const BITS: u32 = bits_for::<<Self as Deref>::Target>(); + /// # } /// ``` - const BITS: usize; - fn into_usize(self) -> usize; + /// + /// [`BITS`]: Pointer::BITS + /// [`Self::Target`]: Deref::Target + const BITS: u32; - /// # Safety + /// Turns this pointer into a raw, non-null pointer. + /// + /// The inverse of this function is [`from_ptr`]. /// - /// The passed `ptr` must be returned from `into_usize`. + /// This function guarantees that the least-significant [`Self::BITS`] bits + /// are zero. /// - /// This acts as `ptr::read` semantically, it should not be called more than - /// once on non-`Copy` `Pointer`s. - unsafe fn from_usize(ptr: usize) -> Self; + /// [`from_ptr`]: Pointer::from_ptr + /// [`Self::BITS`]: Pointer::BITS + fn into_ptr(self) -> NonNull<Self::Target>; - /// This provides a reference to the `Pointer` itself, rather than the - /// `Deref::Target`. It is used for cases where we want to call methods that - /// may be implement differently for the Pointer than the Pointee (e.g., - /// `Rc::clone` vs cloning the inner value). + /// Re-creates the original pointer, from a raw pointer returned by [`into_ptr`]. /// /// # Safety /// - /// The passed `ptr` must be returned from `into_usize`. - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R; + /// The passed `ptr` must be returned from [`into_ptr`]. + /// + /// This acts as [`ptr::read::<Self>()`] semantically, it should not be called more than + /// once on non-[`Copy`] `Pointer`s. + /// + /// [`into_ptr`]: Pointer::into_ptr + /// [`ptr::read::<Self>()`]: std::ptr::read + unsafe fn from_ptr(ptr: NonNull<Self::Target>) -> Self; } -/// This describes tags that the `TaggedPtr` struct can hold. +/// This describes tags that the [`TaggedPtr`] struct can hold. /// /// # Safety /// -/// The BITS constant must be correct. +/// The [`BITS`] constant must be correct. /// -/// No more than `BITS` least significant bits may be set in the returned usize. +/// No more than [`BITS`] least-significant bits may be set in the returned usize. +/// +/// [`BITS`]: Tag::BITS pub unsafe trait Tag: Copy { - const BITS: usize; + /// Number of least-significant bits in the return value of [`into_usize`] + /// which may be non-zero. In other words this is the bit width of the + /// value. + /// + /// [`into_usize`]: Tag::into_usize + const BITS: u32; + /// Turns this tag into an integer. + /// + /// The inverse of this function is [`from_usize`]. + /// + /// This function guarantees that only the least-significant [`Self::BITS`] + /// bits can be non-zero. + /// + /// [`from_usize`]: Tag::from_usize + /// [`Self::BITS`]: Tag::BITS fn into_usize(self) -> usize; + /// Re-creates the tag from the integer returned by [`into_usize`]. + /// /// # Safety /// - /// The passed `tag` must be returned from `into_usize`. + /// The passed `tag` must be returned from [`into_usize`]. + /// + /// [`into_usize`]: Tag::into_usize unsafe fn from_usize(tag: usize) -> Self; } -unsafe impl<T> Pointer for Box<T> { - const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize; - #[inline] - fn into_usize(self) -> usize { - Box::into_raw(self) as usize +/// Returns the number of bits available for use for tags in a pointer to `T` +/// (this is based on `T`'s alignment). +pub const fn bits_for<T: ?Sized + Aligned>() -> u32 { + crate::aligned::align_of::<T>().as_nonzero().trailing_zeros() +} + +/// Returns the correct [`Tag::BITS`] constant for a set of tag values. +pub const fn bits_for_tags(mut tags: &[usize]) -> u32 { + let mut bits = 0; + + while let &[tag, ref rest @ ..] = tags { + tags = rest; + + // bits required to represent `tag`, + // position of the most significant 1 + let b = usize::BITS - tag.leading_zeros(); + if b > bits { + bits = b; + } } + + bits +} + +unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> { + const BITS: u32 = bits_for::<Self::Target>(); + #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - Box::from_raw(ptr as *mut T) + fn into_ptr(self) -> NonNull<T> { + // Safety: pointers from `Box::into_raw` are valid & non-null + unsafe { NonNull::new_unchecked(Box::into_raw(self)) } } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - let raw = ManuallyDrop::new(Self::from_usize(ptr)); - f(&raw) + + #[inline] + unsafe fn from_ptr(ptr: NonNull<T>) -> Self { + // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw` + unsafe { Box::from_raw(ptr.as_ptr()) } } } -unsafe impl<T> Pointer for Rc<T> { - const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize; +unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> { + const BITS: u32 = bits_for::<Self::Target>(); + #[inline] - fn into_usize(self) -> usize { - Rc::into_raw(self) as usize + fn into_ptr(self) -> NonNull<T> { + // Safety: pointers from `Rc::into_raw` are valid & non-null + unsafe { NonNull::new_unchecked(Rc::into_raw(self).cast_mut()) } } + #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - Rc::from_raw(ptr as *const T) - } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - let raw = ManuallyDrop::new(Self::from_usize(ptr)); - f(&raw) + unsafe fn from_ptr(ptr: NonNull<T>) -> Self { + // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw` + unsafe { Rc::from_raw(ptr.as_ptr()) } } } -unsafe impl<T> Pointer for Arc<T> { - const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize; +unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> { + const BITS: u32 = bits_for::<Self::Target>(); + #[inline] - fn into_usize(self) -> usize { - Arc::into_raw(self) as usize + fn into_ptr(self) -> NonNull<T> { + // Safety: pointers from `Arc::into_raw` are valid & non-null + unsafe { NonNull::new_unchecked(Arc::into_raw(self).cast_mut()) } } + #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - Arc::from_raw(ptr as *const T) - } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - let raw = ManuallyDrop::new(Self::from_usize(ptr)); - f(&raw) + unsafe fn from_ptr(ptr: NonNull<T>) -> Self { + // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw` + unsafe { Arc::from_raw(ptr.as_ptr()) } } } -unsafe impl<'a, T: 'a> Pointer for &'a T { - const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize; +unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T { + const BITS: u32 = bits_for::<Self::Target>(); + #[inline] - fn into_usize(self) -> usize { - self as *const T as usize + fn into_ptr(self) -> NonNull<T> { + NonNull::from(self) } + #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - &*(ptr as *const T) - } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - f(&*(&ptr as *const usize as *const Self)) + unsafe fn from_ptr(ptr: NonNull<T>) -> Self { + // Safety: + // `ptr` comes from `into_ptr` which gets the pointer from a reference + unsafe { ptr.as_ref() } } } -unsafe impl<'a, T: 'a> Pointer for &'a mut T { - const BITS: usize = std::mem::align_of::<T>().trailing_zeros() as usize; +unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T { + const BITS: u32 = bits_for::<Self::Target>(); + #[inline] - fn into_usize(self) -> usize { - self as *mut T as usize + fn into_ptr(self) -> NonNull<T> { + NonNull::from(self) } + #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - &mut *(ptr as *mut T) + unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self { + // Safety: + // `ptr` comes from `into_ptr` which gets the pointer from a reference + unsafe { ptr.as_mut() } + } +} + +/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[cfg(test)] +enum Tag2 { + B00 = 0b00, + B01 = 0b01, + B10 = 0b10, + B11 = 0b11, +} + +#[cfg(test)] +unsafe impl Tag for Tag2 { + const BITS: u32 = 2; + + fn into_usize(self) -> usize { + self as _ } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - f(&*(&ptr as *const usize as *const Self)) + + unsafe fn from_usize(tag: usize) -> Self { + match tag { + 0b00 => Tag2::B00, + 0b01 => Tag2::B01, + 0b10 => Tag2::B10, + 0b11 => Tag2::B11, + _ => unreachable!(), + } + } +} + +#[cfg(test)] +impl<HCX> crate::stable_hasher::HashStable<HCX> for Tag2 { + fn hash_stable(&self, hcx: &mut HCX, hasher: &mut crate::stable_hasher::StableHasher) { + (*self as u8).hash_stable(hcx, hasher); } } diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs index e1d3e0bd35a..691e92f196a 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/copy.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/copy.rs @@ -1,78 +1,92 @@ use super::{Pointer, Tag}; use crate::stable_hasher::{HashStable, StableHasher}; use std::fmt; +use std::hash::{Hash, Hasher}; use std::marker::PhantomData; +use std::mem::ManuallyDrop; use std::num::NonZeroUsize; +use std::ops::{Deref, DerefMut}; +use std::ptr::NonNull; -/// A `Copy` TaggedPtr. +/// A [`Copy`] tagged pointer. /// -/// You should use this instead of the `TaggedPtr` type in all cases where -/// `P: Copy`. +/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer. +/// +/// You should use this instead of the [`TaggedPtr`] type in all cases where +/// `P` implements [`Copy`]. /// /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without -/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that, -/// wrap the TaggedPtr. +/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`]; +/// if you want that, wrap the [`CopyTaggedPtr`]. +/// +/// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr pub struct CopyTaggedPtr<P, T, const COMPARE_PACKED: bool> where P: Pointer, T: Tag, { - packed: NonZeroUsize, - data: PhantomData<(P, T)>, -} - -impl<P, T, const COMPARE_PACKED: bool> Copy for CopyTaggedPtr<P, T, COMPARE_PACKED> -where - P: Pointer, - T: Tag, - P: Copy, -{ -} - -impl<P, T, const COMPARE_PACKED: bool> Clone for CopyTaggedPtr<P, T, COMPARE_PACKED> -where - P: Pointer, - T: Tag, - P: Copy, -{ - fn clone(&self) -> Self { - *self - } + /// This is semantically a pair of `pointer: P` and `tag: T` fields, + /// however we pack them in a single pointer, to save space. + /// + /// We pack the tag into the **most**-significant bits of the pointer to + /// ease retrieval of the value. A left shift is a multiplication and + /// those are embeddable in instruction encoding, for example: + /// + /// ```asm + /// // (<https://godbolt.org/z/jqcYPWEr3>) + /// example::shift_read3: + /// mov eax, dword ptr [8*rdi] + /// ret + /// + /// example::mask_read3: + /// and rdi, -8 + /// mov eax, dword ptr [rdi] + /// ret + /// ``` + /// + /// This is ASM outputted by rustc for reads of values behind tagged + /// pointers for different approaches of tagging: + /// - `shift_read3` uses `<< 3` (the tag is in the most-significant bits) + /// - `mask_read3` uses `& !0b111` (the tag is in the least-significant bits) + /// + /// The shift approach thus produces less instructions and is likely faster + /// (see <https://godbolt.org/z/Y913sMdWb>). + /// + /// Encoding diagram: + /// ```text + /// [ packed.addr ] + /// [ tag ] [ pointer.addr >> T::BITS ] <-- usize::BITS - T::BITS bits + /// ^ + /// | + /// T::BITS bits + /// ``` + /// + /// The tag can be retrieved by `packed.addr() >> T::BITS` and the pointer + /// can be retrieved by `packed.map_addr(|addr| addr << T::BITS)`. + packed: NonNull<P::Target>, + tag_ghost: PhantomData<T>, } -// We pack the tag into the *upper* bits of the pointer to ease retrieval of the -// value; a left shift is a multiplication and those are embeddable in -// instruction encoding. -impl<P, T, const COMPARE_PACKED: bool> CopyTaggedPtr<P, T, COMPARE_PACKED> +// Note that even though `CopyTaggedPtr` is only really expected to work with +// `P: Copy`, can't add `P: Copy` bound, because `CopyTaggedPtr` is used in the +// `TaggedPtr`'s implementation. +impl<P, T, const CP: bool> CopyTaggedPtr<P, T, CP> where P: Pointer, T: Tag, { - const TAG_BIT_SHIFT: usize = usize::BITS as usize - T::BITS; - const ASSERTION: () = { - assert!(T::BITS <= P::BITS); - // Used for the transmute_copy's below - assert!(std::mem::size_of::<&P::Target>() == std::mem::size_of::<usize>()); - }; - + /// Tags `pointer` with `tag`. + /// + /// Note that this leaks `pointer`: it won't be dropped when + /// `CopyTaggedPtr` is dropped. If you have a pointer with a significant + /// drop, use [`TaggedPtr`] instead. + /// + /// [`TaggedPtr`]: crate::tagged_ptr::TaggedPtr pub fn new(pointer: P, tag: T) -> Self { - // Trigger assert! - let () = Self::ASSERTION; - let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT; - - Self { - // SAFETY: We know that the pointer is non-null, as it must be - // dereferenceable per `Pointer` safety contract. - packed: unsafe { - NonZeroUsize::new_unchecked((P::into_usize(pointer) >> T::BITS) | packed_tag) - }, - data: PhantomData, - } + Self { packed: Self::pack(P::into_ptr(pointer), tag), tag_ghost: PhantomData } } - pub(super) fn pointer_raw(&self) -> usize { - self.packed.get() << T::BITS - } + /// Retrieves the pointer. pub fn pointer(self) -> P where P: Copy, @@ -81,66 +95,138 @@ where // // Note that this isn't going to double-drop or anything because we have // P: Copy - unsafe { P::from_usize(self.pointer_raw()) } - } - pub fn pointer_ref(&self) -> &P::Target { - // SAFETY: pointer_raw returns the original pointer - unsafe { std::mem::transmute_copy(&self.pointer_raw()) } - } - pub fn pointer_mut(&mut self) -> &mut P::Target - where - P: std::ops::DerefMut, - { - // SAFETY: pointer_raw returns the original pointer - unsafe { std::mem::transmute_copy(&self.pointer_raw()) } + unsafe { P::from_ptr(self.pointer_raw()) } } + + /// Retrieves the tag. #[inline] pub fn tag(&self) -> T { - unsafe { T::from_usize(self.packed.get() >> Self::TAG_BIT_SHIFT) } + // Unpack the tag, according to the `self.packed` encoding scheme + let tag = self.packed.addr().get() >> Self::TAG_BIT_SHIFT; + + // Safety: + // The shift retrieves the original value from `T::into_usize`, + // satisfying `T::from_usize`'s preconditions. + unsafe { T::from_usize(tag) } } + + /// Sets the tag to a new value. #[inline] pub fn set_tag(&mut self, tag: T) { - let mut packed = self.packed.get(); - let new_tag = T::into_usize(tag) << Self::TAG_BIT_SHIFT; - let tag_mask = (1 << T::BITS) - 1; - packed &= !(tag_mask << Self::TAG_BIT_SHIFT); - packed |= new_tag; - self.packed = unsafe { NonZeroUsize::new_unchecked(packed) }; + self.packed = Self::pack(self.pointer_raw(), tag); + } + + const TAG_BIT_SHIFT: u32 = usize::BITS - T::BITS; + const ASSERTION: () = { assert!(T::BITS <= P::BITS) }; + + /// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`, + /// according to `self.packed` encoding scheme. + /// + /// [`P::into_ptr`]: Pointer::into_ptr + fn pack(ptr: NonNull<P::Target>, tag: T) -> NonNull<P::Target> { + // Trigger assert! + let () = Self::ASSERTION; + + let packed_tag = tag.into_usize() << Self::TAG_BIT_SHIFT; + + ptr.map_addr(|addr| { + // Safety: + // - The pointer is `NonNull` => it's address is `NonZeroUsize` + // - `P::BITS` least significant bits are always zero (`Pointer` contract) + // - `T::BITS <= P::BITS` (from `Self::ASSERTION`) + // + // Thus `addr >> T::BITS` is guaranteed to be non-zero. + // + // `{non_zero} | packed_tag` can't make the value zero. + + let packed = (addr.get() >> T::BITS) | packed_tag; + unsafe { NonZeroUsize::new_unchecked(packed) } + }) + } + + /// Retrieves the original raw pointer from `self.packed`. + pub(super) fn pointer_raw(&self) -> NonNull<P::Target> { + self.packed.map_addr(|addr| unsafe { NonZeroUsize::new_unchecked(addr.get() << T::BITS) }) + } + + /// This provides a reference to the `P` pointer itself, rather than the + /// `Deref::Target`. It is used for cases where we want to call methods + /// that may be implement differently for the Pointer than the Pointee + /// (e.g., `Rc::clone` vs cloning the inner value). + pub(super) fn with_pointer_ref<R>(&self, f: impl FnOnce(&P) -> R) -> R { + // Safety: + // - `self.raw.pointer_raw()` is originally returned from `P::into_ptr` + // and as such is valid for `P::from_ptr`. + // - This also allows us to not care whatever `f` panics or not. + // - Even though we create a copy of the pointer, we store it inside + // `ManuallyDrop` and only access it by-ref, so we don't double-drop. + // + // Semantically this is just `f(&self.pointer)` (where `self.pointer` + // is non-packed original pointer). + // + // Note that even though `CopyTaggedPtr` is only really expected to + // work with `P: Copy`, we have to assume `P: ?Copy`, because + // `CopyTaggedPtr` is used in the `TaggedPtr`'s implementation. + let ptr = unsafe { ManuallyDrop::new(P::from_ptr(self.pointer_raw())) }; + f(&ptr) } } -impl<P, T, const COMPARE_PACKED: bool> std::ops::Deref for CopyTaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> Copy for CopyTaggedPtr<P, T, CP> +where + P: Pointer + Copy, + T: Tag, +{ +} + +impl<P, T, const CP: bool> Clone for CopyTaggedPtr<P, T, CP> +where + P: Pointer + Copy, + T: Tag, +{ + fn clone(&self) -> Self { + *self + } +} + +impl<P, T, const CP: bool> Deref for CopyTaggedPtr<P, T, CP> where P: Pointer, T: Tag, { type Target = P::Target; + fn deref(&self) -> &Self::Target { - self.pointer_ref() + // Safety: + // `pointer_raw` returns the original pointer from `P::into_ptr` which, + // by the `Pointer`'s contract, must be valid. + unsafe { self.pointer_raw().as_ref() } } } -impl<P, T, const COMPARE_PACKED: bool> std::ops::DerefMut for CopyTaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> DerefMut for CopyTaggedPtr<P, T, CP> where - P: Pointer + std::ops::DerefMut, + P: Pointer + DerefMut, T: Tag, { fn deref_mut(&mut self) -> &mut Self::Target { - self.pointer_mut() + // Safety: + // `pointer_raw` returns the original pointer from `P::into_ptr` which, + // by the `Pointer`'s contract, must be valid for writes if + // `P: DerefMut`. + unsafe { self.pointer_raw().as_mut() } } } -impl<P, T, const COMPARE_PACKED: bool> fmt::Debug for CopyTaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> fmt::Debug for CopyTaggedPtr<P, T, CP> where - P: Pointer, - P::Target: fmt::Debug, + P: Pointer + fmt::Debug, T: Tag + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("CopyTaggedPtr") - .field("pointer", &self.pointer_ref()) - .field("tag", &self.tag()) - .finish() + self.with_pointer_ref(|ptr| { + f.debug_struct("CopyTaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish() + }) } } @@ -161,25 +247,73 @@ where { } -impl<P, T> std::hash::Hash for CopyTaggedPtr<P, T, true> +impl<P, T> Hash for CopyTaggedPtr<P, T, true> where P: Pointer, T: Tag, { - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { self.packed.hash(state); } } -impl<P, T, HCX, const COMPARE_PACKED: bool> HashStable<HCX> for CopyTaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, HCX, const CP: bool> HashStable<HCX> for CopyTaggedPtr<P, T, CP> where P: Pointer + HashStable<HCX>, T: Tag + HashStable<HCX>, { fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { - unsafe { - Pointer::with_ref(self.pointer_raw(), |p: &P| p.hash_stable(hcx, hasher)); - } + self.with_pointer_ref(|ptr| ptr.hash_stable(hcx, hasher)); self.tag().hash_stable(hcx, hasher); } } + +// Safety: +// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such +// it's ok to implement `Sync` as long as `P: Sync, T: Sync` +unsafe impl<P, T, const CP: bool> Sync for CopyTaggedPtr<P, T, CP> +where + P: Sync + Pointer, + T: Sync + Tag, +{ +} + +// Safety: +// `CopyTaggedPtr<P, T, ..>` is semantically just `{ ptr: P, tag: T }`, as such +// it's ok to implement `Send` as long as `P: Send, T: Send` +unsafe impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP> +where + P: Send + Pointer, + T: Send + Tag, +{ +} + +/// Test that `new` does not compile if there is not enough alignment for the +/// tag in the pointer. +/// +/// ```compile_fail,E0080 +/// use rustc_data_structures::tagged_ptr::{CopyTaggedPtr, Tag}; +/// +/// #[derive(Copy, Clone, Debug, PartialEq, Eq)] +/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 }; +/// +/// unsafe impl Tag for Tag2 { +/// const BITS: u32 = 2; +/// +/// fn into_usize(self) -> usize { todo!() } +/// unsafe fn from_usize(tag: usize) -> Self { todo!() } +/// } +/// +/// let value = 12u16; +/// let reference = &value; +/// let tag = Tag2::B01; +/// +/// let _ptr = CopyTaggedPtr::<_, _, true>::new(reference, tag); +/// ``` +// For some reason miri does not get the compile error +// probably it `check`s instead of `build`ing? +#[cfg(not(miri))] +const _: () = (); + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs new file mode 100644 index 00000000000..bfcc2e603de --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/copy/tests.rs @@ -0,0 +1,50 @@ +use std::ptr; + +use crate::stable_hasher::{HashStable, StableHasher}; +use crate::tagged_ptr::{CopyTaggedPtr, Pointer, Tag, Tag2}; + +#[test] +fn smoke() { + let value = 12u32; + let reference = &value; + let tag = Tag2::B01; + + let ptr = tag_ptr(reference, tag); + + assert_eq!(ptr.tag(), tag); + assert_eq!(*ptr, 12); + assert!(ptr::eq(ptr.pointer(), reference)); + + let copy = ptr; + + let mut ptr = ptr; + ptr.set_tag(Tag2::B00); + assert_eq!(ptr.tag(), Tag2::B00); + + assert_eq!(copy.tag(), tag); + assert_eq!(*copy, 12); + assert!(ptr::eq(copy.pointer(), reference)); +} + +#[test] +fn stable_hash_hashes_as_tuple() { + let hash_packed = { + let mut hasher = StableHasher::new(); + tag_ptr(&12, Tag2::B11).hash_stable(&mut (), &mut hasher); + + hasher.finalize() + }; + + let hash_tupled = { + let mut hasher = StableHasher::new(); + (&12, Tag2::B11).hash_stable(&mut (), &mut hasher); + hasher.finalize() + }; + + assert_eq!(hash_packed, hash_tupled); +} + +/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter. +fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> CopyTaggedPtr<P, T, true> { + CopyTaggedPtr::new(ptr, tag) +} diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs index b0315c93d93..d418c06b7eb 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr/drop.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop.rs @@ -1,14 +1,21 @@ -use super::{Pointer, Tag}; -use crate::stable_hasher::{HashStable, StableHasher}; use std::fmt; +use std::hash::{Hash, Hasher}; +use std::ops::{Deref, DerefMut}; use super::CopyTaggedPtr; +use super::{Pointer, Tag}; +use crate::stable_hasher::{HashStable, StableHasher}; -/// A TaggedPtr implementing `Drop`. +/// A tagged pointer that supports pointers that implement [`Drop`]. +/// +/// This is essentially `{ pointer: P, tag: T }` packed in a single pointer. +/// +/// You should use [`CopyTaggedPtr`] instead of the this type in all cases +/// where `P` implements [`Copy`]. /// /// If `COMPARE_PACKED` is true, then the pointers will be compared and hashed without -/// unpacking. Otherwise we don't implement PartialEq/Eq/Hash; if you want that, -/// wrap the TaggedPtr. +/// unpacking. Otherwise we don't implement [`PartialEq`], [`Eq`] and [`Hash`]; +/// if you want that, wrap the [`TaggedPtr`]. pub struct TaggedPtr<P, T, const COMPARE_PACKED: bool> where P: Pointer, @@ -17,58 +24,61 @@ where raw: CopyTaggedPtr<P, T, COMPARE_PACKED>, } -impl<P, T, const COMPARE_PACKED: bool> Clone for TaggedPtr<P, T, COMPARE_PACKED> -where - P: Pointer + Clone, - T: Tag, -{ - fn clone(&self) -> Self { - unsafe { Self::new(P::with_ref(self.raw.pointer_raw(), |p| p.clone()), self.raw.tag()) } - } -} - -// We pack the tag into the *upper* bits of the pointer to ease retrieval of the -// value; a right shift is a multiplication and those are embeddable in -// instruction encoding. -impl<P, T, const COMPARE_PACKED: bool> TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> TaggedPtr<P, T, CP> where P: Pointer, T: Tag, { + /// Tags `pointer` with `tag`. pub fn new(pointer: P, tag: T) -> Self { TaggedPtr { raw: CopyTaggedPtr::new(pointer, tag) } } - pub fn pointer_ref(&self) -> &P::Target { - self.raw.pointer_ref() - } + /// Retrieves the tag. pub fn tag(&self) -> T { self.raw.tag() } + + /// Sets the tag to a new value. + pub fn set_tag(&mut self, tag: T) { + self.raw.set_tag(tag) + } } -impl<P, T, const COMPARE_PACKED: bool> std::ops::Deref for TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> Clone for TaggedPtr<P, T, CP> +where + P: Pointer + Clone, + T: Tag, +{ + fn clone(&self) -> Self { + let ptr = self.raw.with_pointer_ref(P::clone); + + Self::new(ptr, self.tag()) + } +} + +impl<P, T, const CP: bool> Deref for TaggedPtr<P, T, CP> where P: Pointer, T: Tag, { type Target = P::Target; fn deref(&self) -> &Self::Target { - self.raw.pointer_ref() + self.raw.deref() } } -impl<P, T, const COMPARE_PACKED: bool> std::ops::DerefMut for TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> DerefMut for TaggedPtr<P, T, CP> where - P: Pointer + std::ops::DerefMut, + P: Pointer + DerefMut, T: Tag, { fn deref_mut(&mut self) -> &mut Self::Target { - self.raw.pointer_mut() + self.raw.deref_mut() } } -impl<P, T, const COMPARE_PACKED: bool> Drop for TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> Drop for TaggedPtr<P, T, CP> where P: Pointer, T: Tag, @@ -76,22 +86,20 @@ where fn drop(&mut self) { // No need to drop the tag, as it's Copy unsafe { - drop(P::from_usize(self.raw.pointer_raw())); + drop(P::from_ptr(self.raw.pointer_raw())); } } } -impl<P, T, const COMPARE_PACKED: bool> fmt::Debug for TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, const CP: bool> fmt::Debug for TaggedPtr<P, T, CP> where - P: Pointer, - P::Target: fmt::Debug, + P: Pointer + fmt::Debug, T: Tag + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("TaggedPtr") - .field("pointer", &self.pointer_ref()) - .field("tag", &self.tag()) - .finish() + self.raw.with_pointer_ref(|ptr| { + f.debug_struct("TaggedPtr").field("pointer", ptr).field("tag", &self.tag()).finish() + }) } } @@ -112,17 +120,17 @@ where { } -impl<P, T> std::hash::Hash for TaggedPtr<P, T, true> +impl<P, T> Hash for TaggedPtr<P, T, true> where P: Pointer, T: Tag, { - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { self.raw.hash(state); } } -impl<P, T, HCX, const COMPARE_PACKED: bool> HashStable<HCX> for TaggedPtr<P, T, COMPARE_PACKED> +impl<P, T, HCX, const CP: bool> HashStable<HCX> for TaggedPtr<P, T, CP> where P: Pointer + HashStable<HCX>, T: Tag + HashStable<HCX>, @@ -131,3 +139,33 @@ where self.raw.hash_stable(hcx, hasher); } } + +/// Test that `new` does not compile if there is not enough alignment for the +/// tag in the pointer. +/// +/// ```compile_fail,E0080 +/// use rustc_data_structures::tagged_ptr::{TaggedPtr, Tag}; +/// +/// #[derive(Copy, Clone, Debug, PartialEq, Eq)] +/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 }; +/// +/// unsafe impl Tag for Tag2 { +/// const BITS: u32 = 2; +/// +/// fn into_usize(self) -> usize { todo!() } +/// unsafe fn from_usize(tag: usize) -> Self { todo!() } +/// } +/// +/// let value = 12u16; +/// let reference = &value; +/// let tag = Tag2::B01; +/// +/// let _ptr = TaggedPtr::<_, _, true>::new(reference, tag); +/// ``` +// For some reason miri does not get the compile error +// probably it `check`s instead of `build`ing? +#[cfg(not(miri))] +const _: () = (); + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs new file mode 100644 index 00000000000..2c17d678d3a --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/drop/tests.rs @@ -0,0 +1,71 @@ +use std::{ptr, sync::Arc}; + +use crate::tagged_ptr::{Pointer, Tag, Tag2, TaggedPtr}; + +#[test] +fn smoke() { + let value = 12u32; + let reference = &value; + let tag = Tag2::B01; + + let ptr = tag_ptr(reference, tag); + + assert_eq!(ptr.tag(), tag); + assert_eq!(*ptr, 12); + + let clone = ptr.clone(); + assert_eq!(clone.tag(), tag); + assert_eq!(*clone, 12); + + let mut ptr = ptr; + ptr.set_tag(Tag2::B00); + assert_eq!(ptr.tag(), Tag2::B00); + + assert_eq!(clone.tag(), tag); + assert_eq!(*clone, 12); + assert!(ptr::eq(&*ptr, &*clone)) +} + +#[test] +fn boxed() { + let value = 12u32; + let boxed = Box::new(value); + let tag = Tag2::B01; + + let ptr = tag_ptr(boxed, tag); + + assert_eq!(ptr.tag(), tag); + assert_eq!(*ptr, 12); + + let clone = ptr.clone(); + assert_eq!(clone.tag(), tag); + assert_eq!(*clone, 12); + + let mut ptr = ptr; + ptr.set_tag(Tag2::B00); + assert_eq!(ptr.tag(), Tag2::B00); + + assert_eq!(clone.tag(), tag); + assert_eq!(*clone, 12); + assert!(!ptr::eq(&*ptr, &*clone)) +} + +#[test] +fn arclones() { + let value = 12u32; + let arc = Arc::new(value); + let tag = Tag2::B01; + + let ptr = tag_ptr(arc, tag); + + assert_eq!(ptr.tag(), tag); + assert_eq!(*ptr, 12); + + let clone = ptr.clone(); + assert!(ptr::eq(&*ptr, &*clone)) +} + +/// Helper to create tagged pointers without specifying `COMPARE_PACKED` if it does not matter. +fn tag_ptr<P: Pointer, T: Tag>(ptr: P, tag: T) -> TaggedPtr<P, T, true> { + TaggedPtr::new(ptr, tag) +} diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs new file mode 100644 index 00000000000..cb7f7d318dc --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag.rs @@ -0,0 +1,144 @@ +/// Implements [`Tag`] for a given type. +/// +/// You can use `impl_tag` on structs and enums. +/// You need to specify the type and all its possible values, +/// which can only be paths with optional fields. +/// +/// [`Tag`]: crate::tagged_ptr::Tag +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// #![feature(macro_metavar_expr)] +/// use rustc_data_structures::{impl_tag, tagged_ptr::Tag}; +/// +/// #[derive(Copy, Clone, PartialEq, Debug)] +/// enum SomeTag { +/// A, +/// B, +/// X { v: bool }, +/// Y(bool, bool), +/// } +/// +/// impl_tag! { +/// // The type for which the `Tag` will be implemented +/// impl Tag for SomeTag; +/// // You need to specify all possible tag values: +/// SomeTag::A, // 0 +/// SomeTag::B, // 1 +/// // For variants with fields, you need to specify the fields: +/// SomeTag::X { v: true }, // 2 +/// SomeTag::X { v: false }, // 3 +/// // For tuple variants use named syntax: +/// SomeTag::Y { 0: true, 1: true }, // 4 +/// SomeTag::Y { 0: false, 1: true }, // 5 +/// SomeTag::Y { 0: true, 1: false }, // 6 +/// SomeTag::Y { 0: false, 1: false }, // 7 +/// } +/// +/// // Tag values are assigned in order: +/// assert_eq!(SomeTag::A.into_usize(), 0); +/// assert_eq!(SomeTag::X { v: false }.into_usize(), 3); +/// assert_eq!(SomeTag::Y(false, true).into_usize(), 5); +/// +/// assert_eq!(unsafe { SomeTag::from_usize(1) }, SomeTag::B); +/// assert_eq!(unsafe { SomeTag::from_usize(2) }, SomeTag::X { v: true }); +/// assert_eq!(unsafe { SomeTag::from_usize(7) }, SomeTag::Y(false, false)); +/// ``` +/// +/// Structs are supported: +/// +/// ``` +/// #![feature(macro_metavar_expr)] +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// struct Flags { a: bool, b: bool } +/// +/// impl_tag! { +/// impl Tag for Flags; +/// Flags { a: true, b: true }, +/// Flags { a: false, b: true }, +/// Flags { a: true, b: false }, +/// Flags { a: false, b: false }, +/// } +/// ``` +/// +/// Not specifying all values results in a compile error: +/// +/// ```compile_fail,E0004 +/// #![feature(macro_metavar_expr)] +/// # use rustc_data_structures::impl_tag; +/// #[derive(Copy, Clone)] +/// enum E { +/// A, +/// B, +/// } +/// +/// impl_tag! { +/// impl Tag for E; +/// E::A, +/// } +/// ``` +#[macro_export] +macro_rules! impl_tag { + ( + impl Tag for $Self:ty; + $( + $($path:ident)::* $( { $( $fields:tt )* })?, + )* + ) => { + // Safety: + // `bits_for_tags` is called on the same `${index()}`-es as + // `into_usize` returns, thus `BITS` constant is correct. + unsafe impl $crate::tagged_ptr::Tag for $Self { + const BITS: u32 = $crate::tagged_ptr::bits_for_tags(&[ + $( + ${index()}, + $( ${ignore(path)} )* + )* + ]); + + #[inline] + fn into_usize(self) -> usize { + // This forbids use of repeating patterns (`Enum::V`&`Enum::V`, etc) + // (or at least it should, see <https://github.com/rust-lang/rust/issues/110613>) + #[forbid(unreachable_patterns)] + match self { + // `match` is doing heavy lifting here, by requiring exhaustiveness + $( + $($path)::* $( { $( $fields )* } )? => ${index()}, + )* + } + } + + #[inline] + unsafe fn from_usize(tag: usize) -> Self { + match tag { + $( + ${index()} => $($path)::* $( { $( $fields )* } )?, + )* + + // Safety: + // `into_usize` only returns `${index()}` of the same + // repetition as we are filtering above, thus if this is + // reached, the safety contract of this function was + // already breached. + _ => unsafe { + debug_assert!( + false, + "invalid tag: {tag}\ + (this is a bug in the caller of `from_usize`)" + ); + std::hint::unreachable_unchecked() + }, + } + } + + } + }; +} + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs new file mode 100644 index 00000000000..62c926153e1 --- /dev/null +++ b/compiler/rustc_data_structures/src/tagged_ptr/impl_tag/tests.rs @@ -0,0 +1,34 @@ +#[test] +fn bits_constant() { + use crate::tagged_ptr::Tag; + + #[derive(Copy, Clone)] + struct Unit; + impl_tag! { impl Tag for Unit; Unit, } + assert_eq!(Unit::BITS, 0); + + #[derive(Copy, Clone)] + enum Enum3 { + A, + B, + C, + } + impl_tag! { impl Tag for Enum3; Enum3::A, Enum3::B, Enum3::C, } + assert_eq!(Enum3::BITS, 2); + + #[derive(Copy, Clone)] + struct Eight(bool, bool, bool); + impl_tag! { + impl Tag for Eight; + Eight { 0: true, 1: true, 2: true }, + Eight { 0: true, 1: true, 2: false }, + Eight { 0: true, 1: false, 2: true }, + Eight { 0: true, 1: false, 2: false }, + Eight { 0: false, 1: true, 2: true }, + Eight { 0: false, 1: true, 2: false }, + Eight { 0: false, 1: false, 2: true }, + Eight { 0: false, 1: false, 2: false }, + } + + assert_eq!(Eight::BITS, 3); +} diff --git a/compiler/rustc_data_structures/src/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs index ce60d40b24b..fda72c9a3b2 100644 --- a/compiler/rustc_data_structures/src/vec_linked_list.rs +++ b/compiler/rustc_data_structures/src/vec_linked_list.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; pub fn iter<Ls>( first: Option<Ls::LinkIndex>, diff --git a/compiler/rustc_data_structures/src/work_queue.rs b/compiler/rustc_data_structures/src/work_queue.rs index 10317f1afff..9db6b6f20be 100644 --- a/compiler/rustc_data_structures/src/work_queue.rs +++ b/compiler/rustc_data_structures/src/work_queue.rs @@ -1,5 +1,5 @@ use rustc_index::bit_set::BitSet; -use rustc_index::vec::Idx; +use rustc_index::Idx; use std::collections::VecDeque; /// A work queue is a handy data structure for tracking work left to diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 73a1f79a020..cc4c5a0cacd 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -18,6 +18,7 @@ rustc_const_eval = { path = "../rustc_const_eval" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_expand = { path = "../rustc_expand" } rustc_hir_typeck = { path = "../rustc_hir_typeck" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_incremental = { path = "../rustc_incremental" } rustc_infer = { path = "../rustc_infer" } rustc_mir_build = { path = "../rustc_mir_build" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b9f0e756e65..5fac485de64 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -28,10 +28,10 @@ use rustc_errors::{ DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl, }; use rustc_feature::find_gated_cfg; +use rustc_fluent_macro::fluent_messages; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; -use rustc_macros::fluent_messages; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; @@ -58,8 +58,16 @@ use std::str; use std::sync::LazyLock; use std::time::Instant; +// This import blocks the use of panicking `print` and `println` in all the code +// below. Please use `safe_print` and `safe_println` to avoid ICE when +// encountering an I/O error during print. +#[allow(unused_imports)] +use std::{compile_error as print, compile_error as println}; + pub mod args; pub mod pretty; +#[macro_use] +mod print; mod session_diagnostics; use crate::session_diagnostics::{ @@ -511,7 +519,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { if io::stdout().is_terminal() { show_content_with_pager(&text); } else { - print!("{text}"); + safe_print!("{text}"); } } Err(InvalidErrorCode) => { @@ -547,7 +555,7 @@ fn show_content_with_pager(content: &str) { // If pager fails for whatever reason, we should still print the content // to standard output if fallback_to_println { - print!("{content}"); + safe_print!("{content}"); } } @@ -601,7 +609,7 @@ pub fn list_metadata(sess: &Session, metadata_loader: &dyn MetadataLoader) -> Co let path = &(*ifile); let mut v = Vec::new(); locator::list_file_metadata(&sess.target, path, metadata_loader, &mut v).unwrap(); - println!("{}", String::from_utf8(v).unwrap()); + safe_println!("{}", String::from_utf8(v).unwrap()); } Input::Str { .. } => { early_error(ErrorOutputType::default(), "cannot list metadata for stdin"); @@ -642,12 +650,12 @@ fn print_crate_info( TargetList => { let mut targets = rustc_target::spec::TARGETS.to_vec(); targets.sort_unstable(); - println!("{}", targets.join("\n")); + safe_println!("{}", targets.join("\n")); } - Sysroot => println!("{}", sess.sysroot.display()), - TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()), + Sysroot => safe_println!("{}", sess.sysroot.display()), + TargetLibdir => safe_println!("{}", sess.target_tlib_path.dir.display()), TargetSpec => { - println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); + safe_println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap()); } AllTargetSpecs => { let mut targets = BTreeMap::new(); @@ -656,7 +664,7 @@ fn print_crate_info( let target = Target::expect_builtin(&triple); targets.insert(name, target.to_json()); } - println!("{}", serde_json::to_string_pretty(&targets).unwrap()); + safe_println!("{}", serde_json::to_string_pretty(&targets).unwrap()); } FileNames | CrateName => { let Some(attrs) = attrs.as_ref() else { @@ -666,14 +674,14 @@ fn print_crate_info( let t_outputs = rustc_interface::util::build_output_filenames(attrs, sess); let id = rustc_session::output::find_crate_name(sess, attrs); if *req == PrintRequest::CrateName { - println!("{id}"); + safe_println!("{id}"); continue; } let crate_types = collect_crate_types(sess, attrs); for &style in &crate_types { let fname = rustc_session::output::filename_for_input(sess, style, id, &t_outputs); - println!("{}", fname.file_name().unwrap().to_string_lossy()); + safe_println!("{}", fname.file_name().unwrap().to_string_lossy()); } } Cfg => { @@ -707,13 +715,13 @@ fn print_crate_info( cfgs.sort(); for cfg in cfgs { - println!("{cfg}"); + safe_println!("{cfg}"); } } CallingConventions => { let mut calling_conventions = rustc_target::spec::abi::all_names(); calling_conventions.sort_unstable(); - println!("{}", calling_conventions.join("\n")); + safe_println!("{}", calling_conventions.join("\n")); } RelocationModels | CodeModels @@ -733,7 +741,7 @@ fn print_crate_info( let stable = sess.target.options.supported_split_debuginfo.contains(split); let unstable_ok = sess.unstable_options(); if stable || unstable_ok { - println!("{split}"); + safe_println!("{split}"); } } } @@ -770,14 +778,14 @@ pub fn version_at_macro_invocation( ) { let verbose = matches.opt_present("verbose"); - println!("{binary} {version}"); + safe_println!("{binary} {version}"); if verbose { - println!("binary: {binary}"); - println!("commit-hash: {commit_hash}"); - println!("commit-date: {commit_date}"); - println!("host: {}", config::host_triple()); - println!("release: {release}"); + safe_println!("binary: {binary}"); + safe_println!("commit-hash: {commit_hash}"); + safe_println!("commit-date: {commit_date}"); + safe_println!("host: {}", config::host_triple()); + safe_println!("release: {release}"); let debug_flags = matches.opt_strs("Z"); let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend=")); @@ -807,7 +815,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) { } else { "" }; - println!( + safe_println!( "{options}{at_path}\nAdditional help: -C help Print codegen options -W help \ @@ -820,7 +828,7 @@ fn usage(verbose: bool, include_unstable_options: bool, nightly_build: bool) { } fn print_wall_help() { - println!( + safe_println!( " The flag `-Wall` does not exist in `rustc`. Most useful lints are enabled by default. Use `rustc -W help` to see all available lints. It's more common to put @@ -832,7 +840,7 @@ the command line flag directly. /// Write to stdout lint command options, together with a list of all available lints pub fn describe_lints(sess: &Session, lint_store: &LintStore, loaded_plugins: bool) { - println!( + safe_println!( " Available lint options: -W <foo> Warn about <foo> @@ -877,21 +885,21 @@ Available lint options: s }; - println!("Lint checks provided by rustc:\n"); + safe_println!("Lint checks provided by rustc:\n"); let print_lints = |lints: Vec<&Lint>| { - println!(" {} {:7.7} {}", padded("name"), "default", "meaning"); - println!(" {} {:7.7} {}", padded("----"), "-------", "-------"); + safe_println!(" {} {:7.7} {}", padded("name"), "default", "meaning"); + safe_println!(" {} {:7.7} {}", padded("----"), "-------", "-------"); for lint in lints { let name = lint.name_lower().replace('_', "-"); - println!( + safe_println!( " {} {:7.7} {}", padded(&name), lint.default_level(sess.edition()).as_str(), lint.desc ); } - println!("\n"); + safe_println!("\n"); }; print_lints(builtin); @@ -912,14 +920,14 @@ Available lint options: s }; - println!("Lint groups provided by rustc:\n"); + safe_println!("Lint groups provided by rustc:\n"); let print_lint_groups = |lints: Vec<(&'static str, Vec<LintId>)>, all_warnings| { - println!(" {} sub-lints", padded("name")); - println!(" {} ---------", padded("----")); + safe_println!(" {} sub-lints", padded("name")); + safe_println!(" {} ---------", padded("----")); if all_warnings { - println!(" {} all lints that are set to issue warnings", padded("warnings")); + safe_println!(" {} all lints that are set to issue warnings", padded("warnings")); } for (name, to) in lints { @@ -929,26 +937,26 @@ Available lint options: .map(|x| x.to_string().replace('_', "-")) .collect::<Vec<String>>() .join(", "); - println!(" {} {}", padded(&name), desc); + safe_println!(" {} {}", padded(&name), desc); } - println!("\n"); + safe_println!("\n"); }; print_lint_groups(builtin_groups, true); match (loaded_plugins, plugin.len(), plugin_groups.len()) { (false, 0, _) | (false, _, 0) => { - println!("Lint tools like Clippy can provide additional lints and lint groups."); + safe_println!("Lint tools like Clippy can provide additional lints and lint groups."); } (false, ..) => panic!("didn't load lint plugins but got them anyway!"), - (true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."), + (true, 0, 0) => safe_println!("This crate does not load any lint plugins or lint groups."), (true, l, g) => { if l > 0 { - println!("Lint checks provided by plugins loaded by this crate:\n"); + safe_println!("Lint checks provided by plugins loaded by this crate:\n"); print_lints(plugin); } if g > 0 { - println!("Lint groups provided by plugins loaded by this crate:\n"); + safe_println!("Lint groups provided by plugins loaded by this crate:\n"); print_lint_groups(plugin_groups, false); } } @@ -996,12 +1004,12 @@ pub fn describe_flag_categories(matches: &Matches) -> bool { } fn describe_debug_flags() { - println!("\nAvailable options:\n"); + safe_println!("\nAvailable options:\n"); print_flag_list("-Z", config::Z_OPTIONS); } fn describe_codegen_flags() { - println!("\nAvailable codegen options:\n"); + safe_println!("\nAvailable codegen options:\n"); print_flag_list("-C", config::CG_OPTIONS); } @@ -1012,7 +1020,7 @@ fn print_flag_list<T>( let max_len = flag_list.iter().map(|&(name, _, _, _)| name.chars().count()).max().unwrap_or(0); for &(name, _, _, desc) in flag_list { - println!( + safe_println!( " {} {:>width$}=val -- {}", cmdline_opt, name.replace('_', "-"), diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 446c6832cb7..ee64b18d3f6 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -488,12 +488,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR tree"); for did in tcx.hir().body_owners() { - let _ = writeln!( - out, - "{:?}:\n{}\n", - did, - tcx.thir_tree(ty::WithOptConstParam::unknown(did)) - ); + let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did)); } out } @@ -503,12 +498,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR flat"); for did in tcx.hir().body_owners() { - let _ = writeln!( - out, - "{:?}:\n{}\n", - did, - tcx.thir_flat(ty::WithOptConstParam::unknown(did)) - ); + let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did)); } out } diff --git a/compiler/rustc_driver_impl/src/print.rs b/compiler/rustc_driver_impl/src/print.rs new file mode 100644 index 00000000000..70de55320f7 --- /dev/null +++ b/compiler/rustc_driver_impl/src/print.rs @@ -0,0 +1,20 @@ +use std::fmt; +use std::io::{self, Write as _}; + +macro_rules! safe_print { + ($($arg:tt)*) => {{ + $crate::print::print(std::format_args!($($arg)*)); + }}; +} + +macro_rules! safe_println { + ($($arg:tt)*) => { + safe_print!("{}\n", std::format_args!($($arg)*)) + }; +} + +pub(crate) fn print(args: fmt::Arguments<'_>) { + if let Err(_) = io::stdout().write_fmt(args) { + rustc_errors::FatalError.raise(); + } +} diff --git a/compiler/rustc_error_codes/src/error_codes/E0026.md b/compiler/rustc_error_codes/src/error_codes/E0026.md index 72c575aabb6..f485112cca2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0026.md +++ b/compiler/rustc_error_codes/src/error_codes/E0026.md @@ -1,4 +1,4 @@ -A struct pattern attempted to extract a non-existent field from a struct. +A struct pattern attempted to extract a nonexistent field from a struct. Erroneous code example: diff --git a/compiler/rustc_error_codes/src/error_codes/E0208.md b/compiler/rustc_error_codes/src/error_codes/E0208.md index 1ae01106f20..c6db9b5d61b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0208.md +++ b/compiler/rustc_error_codes/src/error_codes/E0208.md @@ -32,7 +32,7 @@ error: [-, o] This error is deliberately triggered with the `#[rustc_variance]` attribute (`#![feature(rustc_attrs)]` must be enabled) and helps to show you the variance of the type's generic parameters. You can read more about variance and -subtyping in [this section of the Rustnomicon]. For a more in depth look at +subtyping in [this section of the Rustonomicon]. For a more in depth look at variance (including a more complete list of common variances) see [this section of the Reference]. For information on how variance is implemented in the compiler, see [this section of `rustc-dev-guide`]. @@ -41,6 +41,6 @@ This error can be easily fixed by removing the `#[rustc_variance]` attribute, the compiler's suggestion to comment it out can be applied automatically with `rustfix`. -[this section of the Rustnomicon]: https://doc.rust-lang.org/nomicon/subtyping.html +[this section of the Rustonomicon]: https://doc.rust-lang.org/nomicon/subtyping.html [this section of the Reference]: https://doc.rust-lang.org/reference/subtyping.html#variance [this section of `rustc-dev-guide`]: https://rustc-dev-guide.rust-lang.org/variance.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0311.md b/compiler/rustc_error_codes/src/error_codes/E0311.md index 08159d3f469..c1104a88a76 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0311.md +++ b/compiler/rustc_error_codes/src/error_codes/E0311.md @@ -29,7 +29,7 @@ If `no_restriction()` were to use `&T` instead of `&()` as an argument, the compiler would have added an implied bound, causing this to compile. This error can be resolved by explicitly naming the elided lifetime for `x` and -then explicily requiring that the generic parameter `T` outlives that lifetime: +then explicitly requiring that the generic parameter `T` outlives that lifetime: ``` fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { diff --git a/compiler/rustc_error_codes/src/error_codes/E0457.md b/compiler/rustc_error_codes/src/error_codes/E0457.md index 53d384d36c4..2c33d1e6a24 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0457.md +++ b/compiler/rustc_error_codes/src/error_codes/E0457.md @@ -1,6 +1,6 @@ Plugin `..` only found in rlib format, but must be available in dylib format. -Erroronous code example: +Erroneous code example: `rlib-plugin.rs` ```ignore (needs-linkage-with-other-tests) diff --git a/compiler/rustc_error_codes/src/error_codes/E0576.md b/compiler/rustc_error_codes/src/error_codes/E0576.md index 8eead4e7e3b..300a57a1985 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0576.md +++ b/compiler/rustc_error_codes/src/error_codes/E0576.md @@ -10,7 +10,7 @@ trait Hello { } ``` -In this example, we tried to use the non-existent associated type `You` of the +In this example, we tried to use the nonexistent associated type `You` of the `Hello` trait. To fix this error, use an existing associated type: ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0609.md b/compiler/rustc_error_codes/src/error_codes/E0609.md index a9db34f474e..0f5ac94e6d5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0609.md +++ b/compiler/rustc_error_codes/src/error_codes/E0609.md @@ -1,4 +1,4 @@ -Attempted to access a non-existent field in a struct. +Attempted to access a nonexistent field in a struct. Erroneous code example: diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 27783d60be4..481c94266f2 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -11,6 +11,7 @@ fluent-syntax = "0.11" intl-memoizer = "0.5.1" rustc_baked_icu_data = { path = "../rustc_baked_icu_data" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6f319b96f2f..88d94c93bf5 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -12,7 +12,8 @@ use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker}; use rustc_data_structures::sync::Lrc; -use rustc_macros::{fluent_messages, Decodable, Encodable}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; use std::borrow::Cow; use std::error::Error; diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index e1ead08ea66..46ace8eb2dd 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -10,6 +10,7 @@ tracing = "0.1" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_error_messages = { path = "../rustc_error_messages" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index fe44799efdb..2498ae2b7bc 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1336,6 +1336,7 @@ impl EmitterWriter { // see? for (text, style) in msg.iter() { let text = self.translate_message(text, args).map_err(Report::new).unwrap(); + let text = &normalize_whitespace(&text); let lines = text.split('\n').collect::<Vec<_>>(); if lines.len() > 1 { for (i, line) in lines.iter().enumerate() { @@ -1980,7 +1981,7 @@ impl EmitterWriter { } if let DisplaySuggestion::Add = show_code_change && is_item_attribute { // The suggestion adds an entire line of code, ending on a newline, so we'll also - // print the *following* line, to provide context of what we're advicing people to + // print the *following* line, to provide context of what we're advising people to // do. Otherwise you would only see contextless code that can be confused for // already existing code, despite the colors and UI elements. // We special case `#[derive(_)]\n` and other attribute suggestions, because those diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index d20b168904d..b65a636d770 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -31,15 +31,15 @@ use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; use registry::Registry; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; -use rustc_data_structures::stable_hasher::StableHasher; +use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; pub use rustc_lint_defs::{pluralize, Applicability}; -use rustc_macros::fluent_messages; use rustc_span::source_map::SourceMap; pub use rustc_span::ErrorGuaranteed; use rustc_span::{Loc, Span}; @@ -427,7 +427,7 @@ struct HandlerInner { /// This set contains a hash of every diagnostic that has been emitted by /// this handler. These hashes is used to avoid emitting the same error /// twice. - emitted_diagnostics: FxHashSet<u128>, + emitted_diagnostics: FxHashSet<Hash128>, /// Stashed diagnostics emitted in one stage of the compiler that may be /// stolen by other stages (e.g. to improve them and add more information). diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index c971714e05b..2dae0e3f53c 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -16,6 +16,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index ced7531c3fe..83a5043b0aa 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -21,7 +21,7 @@ extern crate tracing; extern crate proc_macro as pm; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod placeholders; mod proc_macro_server; diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 5679cdcbbd0..3aeb2edb54c 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -341,7 +341,7 @@ pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( Success(named_matches) => { debug!("Parsed arm successfully"); // The matcher was `Success(..)`ful. - // Merge the gated spans from parsing the matcher with the pre-existing ones. + // Merge the gated spans from parsing the matcher with the preexisting ones. sess.gated_spans.merge(gated_spans_snapshot); return Ok((i, named_matches)); @@ -873,7 +873,7 @@ impl<'tt> FirstSets<'tt> { } } -// Most `mbe::TokenTree`s are pre-existing in the matcher, but some are defined +// Most `mbe::TokenTree`s are preexisting in the matcher, but some are defined // implicitly, such as opening/closing delimiters and sequence repetition ops. // This type encapsulates both kinds. It implements `Clone` while avoiding the // need for `mbe::TokenTree` to implement `Clone`. diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 341ae18541b..1e7d07bc22d 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -18,7 +18,7 @@ use rustc_span::def_id::CrateNum; use rustc_span::symbol::{self, sym, Symbol}; use rustc_span::{BytePos, FileName, Pos, SourceFile, Span}; use smallvec::{smallvec, SmallVec}; -use std::ops::Bound; +use std::ops::{Bound, Range}; trait FromInternal<T> { fn from_internal(x: T) -> Self; @@ -634,6 +634,15 @@ impl server::Span for Rustc<'_, '_> { span.source_callsite() } + fn byte_range(&mut self, span: Self::Span) -> Range<usize> { + let source_map = self.sess().source_map(); + + let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos; + let relative_end_pos = source_map.lookup_byte_offset(span.hi()).pos; + + Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize } + } + fn start(&mut self, span: Self::Span) -> LineColumn { let loc = self.sess().source_map().lookup_char_pos(span.lo()); LineColumn { line: loc.line, column: loc.col.to_usize() } diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 480d95b77e9..8a5e09475ff 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -513,7 +513,7 @@ error: foo } #[test] -fn non_overlaping() { +fn non_overlapping() { test_harness( r#" fn foo() { @@ -552,7 +552,7 @@ error: foo } #[test] -fn overlaping_start_and_end() { +fn overlapping_start_and_end() { test_harness( r#" fn foo() { diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 48d9fbfa6d2..876a31abdf8 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -139,7 +139,7 @@ declare_features! ( /// Allows using `#[on_unimplemented(..)]` on traits. /// (Moved to `rustc_attrs`.) (removed, on_unimplemented, "1.40.0", None, None, None), - /// A way to temporarily opt out of opt in copy. This will *never* be accepted. + /// A way to temporarily opt out of opt-in copy. This will *never* be accepted. (removed, opt_out_copy, "1.0.0", None, None, None), /// Allows features specific to OIBIT (now called auto traits). /// Renamed to `auto_traits`. diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml new file mode 100644 index 00000000000..f5a6585b5c6 --- /dev/null +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rustc_fluent_macro" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +annotate-snippets = "0.9" +fluent-bundle = "0.15.2" +fluent-syntax = "0.11" +syn = { version = "2", features = ["full"] } +proc-macro2 = "1" +quote = "1" +unic-langid = { version = "0.9.0", features = ["macros"] } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 607d51f5608..9dffc9a7645 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -68,7 +68,7 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream { .into() } -/// See [rustc_macros::fluent_messages]. +/// See [rustc_fluent_macro::fluent_messages]. pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let crate_name = std::env::var("CARGO_PKG_NAME") // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs new file mode 100644 index 00000000000..a01643cd67d --- /dev/null +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -0,0 +1,64 @@ +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(proc_macro_diagnostic)] +#![feature(proc_macro_span)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] +#![allow(rustc::default_hash_types)] + +use proc_macro::TokenStream; + +mod fluent; + +/// Implements the `fluent_messages` macro, which performs compile-time validation of the +/// compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same +/// messages) and generates constants that make using those messages in diagnostics more ergonomic. +/// +/// For example, given the following invocation of the macro.. +/// +/// ```ignore (rust) +/// fluent_messages! { "./typeck.ftl" } +/// ``` +/// ..where `typeck.ftl` has the following contents.. +/// +/// ```fluent +/// typeck_field_multiply_specified_in_initializer = +/// field `{$ident}` specified more than once +/// .label = used more than once +/// .label_previous_use = first use of `{$ident}` +/// ``` +/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and +/// will generate the following code: +/// +/// ```ignore (rust) +/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); +/// +/// mod fluent_generated { +/// mod typeck { +/// pub const field_multiply_specified_in_initializer: DiagnosticMessage = +/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer"); +/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage = +/// DiagnosticMessage::fluent_attr( +/// "typeck_field_multiply_specified_in_initializer", +/// "previous_use_label" +/// ); +/// } +/// } +/// ``` +/// When emitting a diagnostic, the generated constants can be used as follows: +/// +/// ```ignore (rust) +/// let mut err = sess.struct_span_err( +/// span, +/// fluent::typeck::field_multiply_specified_in_initializer +/// ); +/// err.span_default_label(span); +/// err.span_label( +/// previous_use_span, +/// fluent::typeck::field_multiply_specified_in_initializer_label_previous_use +/// ); +/// err.emit(); +/// ``` +#[proc_macro] +pub fn fluent_messages(input: TokenStream) -> TokenStream { + fluent::fluent_messages(input) +} diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index c89e7eb75f8..e213623e06d 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,56 +1,17 @@ /// This higher-order macro declares a list of types which can be allocated by `Arena`. -/// -/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`, -/// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. +/// Note that all `Copy` types can be allocated by default and need not be specified here. #[macro_export] macro_rules! arena_types { ($macro:path) => ( $macro!([ // HIR types [] hir_krate: rustc_hir::Crate<'tcx>, - [] arm: rustc_hir::Arm<'tcx>, - [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, - [] closure: rustc_hir::Closure<'tcx>, - [] block: rustc_hir::Block<'tcx>, - [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, - [] body: rustc_hir::Body<'tcx>, - [] generics: rustc_hir::Generics<'tcx>, - [] generic_arg: rustc_hir::GenericArg<'tcx>, - [] generic_args: rustc_hir::GenericArgs<'tcx>, - [] generic_bound: rustc_hir::GenericBound<'tcx>, - [] generic_param: rustc_hir::GenericParam<'tcx>, - [] expr: rustc_hir::Expr<'tcx>, - [] impl_: rustc_hir::Impl<'tcx>, - [] let_expr: rustc_hir::Let<'tcx>, - [] expr_field: rustc_hir::ExprField<'tcx>, - [] pat_field: rustc_hir::PatField<'tcx>, - [] fn_decl: rustc_hir::FnDecl<'tcx>, - [] foreign_item: rustc_hir::ForeignItem<'tcx>, - [] foreign_item_ref: rustc_hir::ForeignItemRef, - [] impl_item: rustc_hir::ImplItem<'tcx>, - [] impl_item_ref: rustc_hir::ImplItemRef, - [] item: rustc_hir::Item<'tcx>, - [] inline_asm: rustc_hir::InlineAsm<'tcx>, - [] local: rustc_hir::Local<'tcx>, - [] mod_: rustc_hir::Mod<'tcx>, [] owner_info: rustc_hir::OwnerInfo<'tcx>, - [] param: rustc_hir::Param<'tcx>, - [] pat: rustc_hir::Pat<'tcx>, - [] path: rustc_hir::Path<'tcx>, [] use_path: rustc_hir::UsePath<'tcx>, - [] path_segment: rustc_hir::PathSegment<'tcx>, - [] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>, - [] qpath: rustc_hir::QPath<'tcx>, - [] stmt: rustc_hir::Stmt<'tcx>, - [] field_def: rustc_hir::FieldDef<'tcx>, - [] trait_item: rustc_hir::TraitItem<'tcx>, - [] trait_item_ref: rustc_hir::TraitItemRef, - [] ty: rustc_hir::Ty<'tcx>, - [] type_binding: rustc_hir::TypeBinding<'tcx>, - [] variant: rustc_hir::Variant<'tcx>, - [] where_predicate: rustc_hir::WherePredicate<'tcx>, + [] lit: rustc_hir::Lit, + [] macro_def: rustc_ast::MacroDef, ]); ) } diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 8c58129c800..30bf8c2ad10 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -234,10 +234,7 @@ impl DefKind { #[inline] pub fn is_fn_like(self) -> bool { - match self { - DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator => true, - _ => false, - } + matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator) } /// Whether `query get_codegen_attrs` should be used with this definition. diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 8ceb176491b..66b153d8931 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -9,8 +9,8 @@ use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_IND use crate::def_path_hash_map::DefPathHashMap; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::StableHasher; -use rustc_index::vec::IndexVec; +use rustc_data_structures::stable_hasher::{Hash64, StableHasher}; +use rustc_index::IndexVec; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::{self, Write}; @@ -130,7 +130,7 @@ impl DefKey { disambiguator.hash(&mut hasher); - let local_hash: u64 = hasher.finish(); + let local_hash = hasher.finish(); // Construct the new DefPathHash, making sure that the `crate_id` // portion of the hash is properly copied from the parent. This way the @@ -325,7 +325,7 @@ impl Definitions { }, }; - let parent_hash = DefPathHash::new(stable_crate_id, 0); + let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO); let def_path_hash = key.compute_stable_hash(parent_hash); // Create the root definition. diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 35a72f868fb..21b4a3370d3 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -14,7 +14,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_error_messages::MultiSpan; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_macros::HashStable_Generic; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::Spanned; @@ -182,7 +182,7 @@ impl Lifetime { /// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Path<'hir, R = Res> { pub span: Span, /// The resolution for the path. @@ -202,7 +202,7 @@ impl Path<'_> { /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, @@ -243,13 +243,13 @@ impl<'hir> PathSegment<'hir> { } } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct ConstArg { pub value: AnonConst, pub span: Span, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { pub hir_id: HirId, pub span: Span, @@ -261,7 +261,7 @@ impl InferArg { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericArg<'hir> { Lifetime(&'hir Lifetime), Type(&'hir Ty<'hir>), @@ -318,7 +318,7 @@ impl GenericArg<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericArgs<'hir> { /// The generic arguments for this path segment. pub args: &'hir [GenericArg<'hir>], @@ -447,7 +447,7 @@ pub enum TraitBoundModifier { /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` @@ -488,7 +488,7 @@ pub enum LifetimeParamKind { Error, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericParamKind<'hir> { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime { @@ -505,7 +505,7 @@ pub enum GenericParamKind<'hir> { }, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericParam<'hir> { pub hir_id: HirId, pub def_id: LocalDefId, @@ -557,7 +557,7 @@ pub struct GenericParamCount { /// Represents lifetimes and type parameters attached to a declaration /// of a function, enum, trait, etc. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Generics<'hir> { pub params: &'hir [GenericParam<'hir>], pub predicates: &'hir [WherePredicate<'hir>], @@ -729,7 +729,7 @@ impl<'hir> Generics<'hir> { } /// A single predicate in a where-clause. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum WherePredicate<'hir> { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), @@ -773,7 +773,7 @@ pub enum PredicateOrigin { } /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereBoundPredicate<'hir> { pub hir_id: HirId, pub span: Span, @@ -795,7 +795,7 @@ impl<'hir> WhereBoundPredicate<'hir> { } /// A lifetime predicate (e.g., `'a: 'b + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereRegionPredicate<'hir> { pub span: Span, pub in_where_clause: bool, @@ -811,7 +811,7 @@ impl<'hir> WhereRegionPredicate<'hir> { } /// An equality predicate (e.g., `T = int`); currently unsupported. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { pub span: Span, pub lhs_ty: &'hir Ty<'hir>, @@ -821,7 +821,7 @@ pub struct WhereEqPredicate<'hir> { /// HIR node coupled with its parent's id in the same HIR owner. /// /// The parent is trash when the node is a HIR owner. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ParentedNode<'tcx> { pub parent: ItemLocalId, pub node: Node<'tcx>, @@ -863,7 +863,7 @@ pub struct OwnerNodes<'tcx> { impl<'tcx> OwnerNodes<'tcx> { pub fn node(&self) -> OwnerNode<'tcx> { - use rustc_index::vec::Idx; + use rustc_index::Idx; let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node; let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode. node @@ -959,7 +959,7 @@ pub struct Crate<'hir> { pub opt_hir_hash: Option<Fingerprint>, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Closure<'hir> { pub def_id: LocalDefId, pub binder: ClosureBinder, @@ -978,7 +978,7 @@ pub struct Closure<'hir> { /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Block<'hir> { /// Statements in a block. pub stmts: &'hir [Stmt<'hir>], @@ -1006,7 +1006,7 @@ impl<'hir> Block<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Pat<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1085,7 +1085,7 @@ impl<'hir> Pat<'hir> { /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` /// are treated the same as` x: x, y: ref y, z: ref mut z`, /// except `is_shorthand` is true. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PatField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1141,7 +1141,7 @@ impl fmt::Debug for DotDotPos { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum PatKind<'hir> { /// Represents a wildcard pattern (i.e., `_`). Wild, @@ -1351,7 +1351,7 @@ impl UnOp { } /// A statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Stmt<'hir> { pub hir_id: HirId, pub kind: StmtKind<'hir>, @@ -1359,7 +1359,7 @@ pub struct Stmt<'hir> { } /// The contents of a statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum StmtKind<'hir> { /// A local (`let`) binding. Local(&'hir Local<'hir>), @@ -1375,7 +1375,7 @@ pub enum StmtKind<'hir> { } /// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Local<'hir> { pub pat: &'hir Pat<'hir>, /// Type annotation, if any (otherwise the type will be inferred). @@ -1393,7 +1393,7 @@ pub struct Local<'hir> { /// Represents a single arm of a `match` expression, e.g. /// `<pat> (if <guard>) => <body>`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Arm<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1411,7 +1411,7 @@ pub struct Arm<'hir> { /// /// In an if-let, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of the /// desugaring to if-let. Only let-else supports the type annotation at present. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Let<'hir> { pub hir_id: HirId, pub span: Span, @@ -1420,7 +1420,7 @@ pub struct Let<'hir> { pub init: &'hir Expr<'hir>, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), IfLet(&'hir Let<'hir>), @@ -1440,7 +1440,7 @@ impl<'hir> Guard<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ExprField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1488,7 +1488,7 @@ pub struct BodyId { /// /// All bodies have an **owner**, which can be accessed via the HIR /// map using `body_owner_def_id()`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Body<'hir> { pub params: &'hir [Param<'hir>], pub value: &'hir Expr<'hir>, @@ -1679,7 +1679,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1715,6 +1715,7 @@ impl Expr<'_> { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, ExprKind::Yield(..) => ExprPrecedence::Yield, @@ -1774,6 +1775,7 @@ impl Expr<'_> { | ExprKind::Loop(..) | ExprKind::Assign(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::AssignOp(..) | ExprKind::Lit(_) | ExprKind::ConstBlock(..) @@ -1818,7 +1820,7 @@ impl Expr<'_> { pub fn can_have_side_effects(&self) -> bool { match self.peel_drop_temps().kind { - ExprKind::Path(_) | ExprKind::Lit(_) => false, + ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) => false, ExprKind::Type(base, _) | ExprKind::Unary(_, base) | ExprKind::Field(base, _) @@ -1920,7 +1922,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ExprKind<'hir> { /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), @@ -1957,10 +1959,10 @@ pub enum ExprKind<'hir> { /// A unary operation (e.g., `!x`, `*x`). Unary(UnOp, &'hir Expr<'hir>), /// A literal (e.g., `1`, `"foo"`). - Lit(Lit), + Lit(&'hir Lit), /// A cast (e.g., `foo as f64`). Cast(&'hir Expr<'hir>, &'hir Ty<'hir>), - /// A type reference (e.g., `Foo`). + /// A type ascription (e.g., `x: Foo`). See RFC 3307. Type(&'hir Expr<'hir>, &'hir Ty<'hir>), /// Wraps the expression in a terminating scope. /// This makes it semantically equivalent to `{ let _t = expr; _t }`. @@ -2022,6 +2024,9 @@ pub enum ExprKind<'hir> { /// Inline assembly (from `asm!`), with its outputs and inputs. InlineAsm(&'hir InlineAsm<'hir>), + /// Field offset (`offset_of!`) + OffsetOf(&'hir Ty<'hir>, &'hir [Ident]), + /// A struct or struct-like variant literal expression. /// /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`, @@ -2046,7 +2051,7 @@ pub enum ExprKind<'hir> { /// To resolve the path to a `DefId`, call [`qpath_res`]. /// /// [`qpath_res`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum QPath<'hir> { /// Path to a definition, optionally "fully-qualified" with a `Self` /// type, if the path points to an associated item in a trait. @@ -2238,7 +2243,7 @@ impl From<GeneratorKind> for YieldSource { // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct MutTy<'hir> { pub ty: &'hir Ty<'hir>, pub mutbl: Mutability, @@ -2246,7 +2251,7 @@ pub struct MutTy<'hir> { /// Represents a function's signature in a trait declaration, /// trait implementation, or a free function. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnSig<'hir> { pub header: FnHeader, pub decl: &'hir FnDecl<'hir>, @@ -2273,7 +2278,7 @@ impl TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2322,7 +2327,7 @@ impl<'hir> TraitItem<'hir> { } /// Represents a trait method's body (or just argument names). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub enum TraitFn<'hir> { /// No default body in the trait, just a signature. Required(&'hir [Ident]), @@ -2332,7 +2337,7 @@ pub enum TraitFn<'hir> { } /// Represents a trait method or associated constant or type -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(&'hir Ty<'hir>, Option<BodyId>), @@ -2360,7 +2365,7 @@ impl ImplItemId { } /// Represents anything within an `impl` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2410,7 +2415,7 @@ impl<'hir> ImplItem<'hir> { } /// Represents various kinds of content within an `impl`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. @@ -2439,7 +2444,7 @@ pub const FN_OUTPUT_NAME: Symbol = sym::Output; /// Binding(...), /// } /// ``` -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TypeBinding<'hir> { pub hir_id: HirId, pub ident: Ident, @@ -2448,7 +2453,7 @@ pub struct TypeBinding<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Term<'hir> { Ty(&'hir Ty<'hir>), Const(AnonConst), @@ -2467,7 +2472,7 @@ impl<'hir> From<AnonConst> for Term<'hir> { } // Represents the two kinds of type bindings. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TypeBindingKind<'hir> { /// E.g., `Foo<Bar: Send>`. Constraint { bounds: &'hir [GenericBound<'hir>] }, @@ -2490,7 +2495,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2635,7 +2640,7 @@ impl PrimTy { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct BareFnTy<'hir> { pub unsafety: Unsafety, pub abi: Abi, @@ -2644,7 +2649,7 @@ pub struct BareFnTy<'hir> { pub param_names: &'hir [Ident], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, @@ -2664,7 +2669,7 @@ pub enum OpaqueTyOrigin { } /// The various kinds of types recognized by the compiler. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyKind<'hir> { /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), @@ -2704,7 +2709,7 @@ pub enum TyKind<'hir> { Err(rustc_span::ErrorGuaranteed), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, @@ -2757,7 +2762,7 @@ impl<'hir> InlineAsmOperand<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct InlineAsm<'hir> { pub template: &'hir [InlineAsmTemplatePiece], pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)], @@ -2767,7 +2772,7 @@ pub struct InlineAsm<'hir> { } /// Represents a parameter in a function header. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Param<'hir> { pub hir_id: HirId, pub pat: &'hir Pat<'hir>, @@ -2776,7 +2781,7 @@ pub struct Param<'hir> { } /// Represents the header (not the body) of a function declaration. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnDecl<'hir> { /// The types of the function's parameters. /// @@ -2849,7 +2854,7 @@ impl Defaultness { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum FnRetTy<'hir> { /// Return type is not specified. /// @@ -2882,7 +2887,7 @@ pub enum ClosureBinder { For { span: Span }, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct Mod<'hir> { pub spans: ModSpans, pub item_ids: &'hir [ItemId], @@ -2897,12 +2902,12 @@ pub struct ModSpans { pub inject_use_span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct EnumDef<'hir> { pub variants: &'hir [Variant<'hir>], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Variant<'hir> { /// Name of the variant. pub ident: Ident, @@ -2939,7 +2944,7 @@ pub enum UseKind { /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct TraitRef<'hir> { pub path: &'hir Path<'hir>, // Don't hash the `ref_id`. It is tracked via the thing it is used to access. @@ -2958,7 +2963,7 @@ impl TraitRef<'_> { } } -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], @@ -2969,7 +2974,7 @@ pub struct PolyTraitRef<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FieldDef<'hir> { pub span: Span, pub vis_span: Span, @@ -2988,7 +2993,7 @@ impl FieldDef<'_> { } /// Fields and constructor IDs of enum variants and structs. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum VariantData<'hir> { /// A struct variant. /// @@ -3058,7 +3063,7 @@ impl ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Item<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -3146,7 +3151,6 @@ impl<'hir> Item<'hir> { (ty, gen) } - /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`. /// Expect an [`ItemKind::OpaqueTy`] or panic. #[track_caller] pub fn expect_opaque_ty(&self) -> &OpaqueTy<'hir> { @@ -3168,7 +3172,6 @@ impl<'hir> Item<'hir> { (data, gen) } - /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`. /// Expect an [`ItemKind::Union`] or panic. #[track_caller] pub fn expect_union(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { @@ -3268,7 +3271,7 @@ impl FnHeader { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// @@ -3289,7 +3292,7 @@ pub enum ItemKind<'hir> { /// A function declaration. Fn(FnSig<'hir>, &'hir Generics<'hir>, BodyId), /// A MBE macro definition (`macro_rules!` or `macro`). - Macro(ast::MacroDef, MacroKind), + Macro(&'hir ast::MacroDef, MacroKind), /// A module. Mod(&'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. @@ -3315,7 +3318,7 @@ pub enum ItemKind<'hir> { Impl(&'hir Impl<'hir>), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { pub unsafety: Unsafety, pub polarity: ImplPolarity, @@ -3378,7 +3381,7 @@ impl ItemKind<'_> { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItemRef { pub id: TraitItemId, pub ident: Ident, @@ -3392,7 +3395,7 @@ pub struct TraitItemRef { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItemRef { pub id: ImplItemId, pub ident: Ident, @@ -3431,14 +3434,14 @@ impl ForeignItemId { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItemRef { pub id: ForeignItemId, pub ident: Ident, pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItem<'hir> { pub ident: Ident, pub kind: ForeignItemKind<'hir>, @@ -3460,7 +3463,7 @@ impl ForeignItem<'_> { } /// An item within an `extern` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ForeignItemKind<'hir> { /// A foreign function. Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>), @@ -3480,7 +3483,7 @@ pub struct Upvar { // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and // has length > 0 if the trait is found through an chain of imports, starting with the // import/use statement in the scope where the trait is used. -#[derive(Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Encodable, Decodable, Debug, Clone, HashStable_Generic)] pub struct TraitCandidate { pub def_id: DefId, pub import_ids: SmallVec<[LocalDefId; 1]>, @@ -3531,12 +3534,20 @@ impl<'hir> OwnerNode<'hir> { pub fn body_id(&self) -> Option<BodyId> { match self { - OwnerNode::TraitItem(TraitItem { - kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)), + OwnerNode::Item(Item { + kind: + ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body), .. }) - | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. }) - | OwnerNode::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id), + | OwnerNode::TraitItem(TraitItem { + kind: + TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + .. + }) + | OwnerNode::ImplItem(ImplItem { + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), + .. + }) => Some(*body), _ => None, } } @@ -3731,12 +3742,27 @@ impl<'hir> Node<'hir> { pub fn body_id(&self) -> Option<BodyId> { match self { - Node::TraitItem(TraitItem { - kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)), + Node::Item(Item { + kind: + ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body), + .. + }) + | Node::TraitItem(TraitItem { + kind: + TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), .. }) - | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. }) - | Node::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id), + | Node::Expr(Expr { + kind: + ExprKind::ConstBlock(AnonConst { body, .. }) + | ExprKind::Closure(Closure { body, .. }) + | ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })), + .. + }) => Some(*body), _ => None, } } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 37ac3723161..d549f52f873 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -35,7 +35,7 @@ impl OwnerId { } } -impl rustc_index::vec::Idx for OwnerId { +impl rustc_index::Idx for OwnerId { #[inline] fn new(idx: usize) -> Self { OwnerId { def_id: LocalDefId { local_def_index: DefIndex::from_usize(idx) } } @@ -116,10 +116,7 @@ impl HirId { } pub fn index(self) -> (usize, usize) { - ( - rustc_index::vec::Idx::index(self.owner.def_id), - rustc_index::vec::Idx::index(self.local_id), - ) + (rustc_index::Idx::index(self.owner.def_id), rustc_index::Idx::index(self.local_id)) } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 234256ab553..df0047d82e1 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -786,6 +786,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::InlineAsm(ref asm) => { visitor.visit_inline_asm(asm, expression.hir_id); } + ExprKind::OffsetOf(ref container, ref fields) => { + visitor.visit_ty(container); + walk_list!(visitor, visit_ident, fields.iter().copied()); + } ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); } diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index d4791150947..c7ac01b3334 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -1,4 +1,5 @@ use crate::definitions::{DefKey, DefPathData, DisambiguatedDefPathData}; +use rustc_data_structures::stable_hasher::Hash64; use rustc_span::def_id::{DefPathHash, StableCrateId}; use rustc_span::edition::Edition; use rustc_span::{create_session_if_not_set_then, Symbol}; @@ -24,7 +25,7 @@ fn def_path_hash_depends_on_crate_id() { assert_ne!(h0.local_hash(), h1.local_hash()); fn mk_test_hash(stable_crate_id: StableCrateId) -> DefPathHash { - let parent_hash = DefPathHash::new(stable_crate_id, 0); + let parent_hash = DefPathHash::new(stable_crate_id, Hash64::ZERO); let key = DefKey { parent: None, diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index fab16b80fb5..4eb94d5bc63 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -15,6 +15,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } @@ -23,8 +24,7 @@ rustc_span = { path = "../rustc_span" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } -rustc_lint = { path = "../rustc_lint" } +rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_type_ir = { path = "../rustc_type_ir" } rustc_feature = { path = "../rustc_feature" } -thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 1d7965ff5f6..f32ae509e33 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -225,3 +225,40 @@ hir_analysis_functions_names_duplicated = functions names are duplicated hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code .help = add `#![feature(simd_ffi)]` to the crate attributes to enable + +hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` + .label = cannot specialize default item `{$ident}` + .ok_label = parent `impl` is here + .note = to specialize, `{$ident}` in the parent `impl` must be marked `default` + +hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default` + .note = parent implementation is in crate `{$cname}` + +hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}` + .label = missing `{$missing_items_msg}` in implementation + +hir_analysis_missing_trait_item_suggestion = implement the missing item: `{$snippet}` + +hir_analysis_missing_trait_item_label = `{$item}` from trait + +hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}` + .label = missing one of `{$missing_items_msg}` in implementation + .note = required because of this annotation + +hir_analysis_missing_trait_item_unstable = not all trait items implemented, missing: `{$missing_item_name}` + .note = default implementation of `{$missing_item_name}` is unstable + .some_note = use of unstable library feature '{$feature}': {$r} + .none_note = use of unstable library feature '{$feature}' + +hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number} + .label = needs exactly one variant, but has {$number} + .many_label = too many variants in `{$path}` + .multi_label = variant here + +hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$desc} needs at most one non-zero-sized field, but has {$field_count} + .label = needs at most one non-zero-sized field, but has {$field_count} + .labels = this field is non-zero-sized + +hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one non-zero-sized field, but has {$field_count} + .label = needs at most one non-zero-sized field, but has {$field_count} + .labels = this field is non-zero-sized diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 8d1156c1771..992316edb63 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -447,14 +447,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { handle_ty_args(has_default, &inf.to_ty()) } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - ty::Const::from_opt_const_arg_anon_const( - tcx, - ty::WithOptConstParam { - did: ct.value.def_id, - const_param_did: Some(param.def_id), - }, - ) - .into() + let did = ct.value.def_id; + tcx.feed_anon_const_type(did, tcx.type_of(param.def_id)); + ty::Const::from_anon_const(tcx, did).into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { let ty = tcx @@ -2061,7 +2056,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.note("enum variants can't have type parameters"); let type_name = tcx.item_name(adt_def.did()); let msg = format!( - "you might have meant to specity type parameters on enum \ + "you might have meant to specify type parameters on enum \ `{type_name}`" ); let Some(args) = assoc_segment.args else { return; }; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0bb98fdf2a2..65c2f5955cd 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -15,7 +15,7 @@ use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; -use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; +use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::hir::nested_filter; use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; @@ -320,7 +320,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( }; let prohibit_opaque = tcx .explicit_item_bounds(def_id) - .iter() + .subst_identity_iter_copied() .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); if let Some(ty) = prohibit_opaque.break_value() { @@ -494,7 +494,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { debug!( "check_item_type(it.def_id={:?}, it.name={})", id.owner_id, - tcx.def_path_str(id.owner_id.to_def_id()) + tcx.def_path_str(id.owner_id) ); let _indenter = indenter(); match tcx.def_kind(id.owner_id) { @@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>( if !missing_items.is_empty() { let full_impl_span = tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); - missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span); + missing_items_err(tcx, impl_id, &missing_items, full_impl_span); } if let Some(missing_items) = must_implement_one_of { diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 5d119a7737a..48214b899a4 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -579,7 +579,7 @@ fn compare_asyncness<'tcx>( pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( tcx: TyCtxt<'tcx>, impl_m_def_id: LocalDefId, -) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> { +) -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> { let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap(); let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap(); let impl_trait_ref = @@ -782,14 +782,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( }) }); debug!(%ty); - collected_tys.insert(def_id, ty); + collected_tys.insert(def_id, ty::EarlyBinder(ty)); } Err(err) => { let reported = tcx.sess.delay_span_bug( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, tcx.ty_error(reported)); + collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported))); } } } @@ -839,7 +839,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> { }); self.types.insert(proj.def_id, (infer_ty, proj.substs)); // Recurse into bounds - for (pred, pred_span) in self.interner().bound_explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { + for (pred, pred_span) in self.interner().explicit_item_bounds(proj.def_id).subst_iter_copied(self.interner(), proj.substs) { let pred = pred.fold_with(self); let pred = self.ocx.normalize( &ObligationCause::misc(self.span, self.body_id), @@ -1317,7 +1317,7 @@ fn compare_number_of_generics<'tcx>( impl_count, kind, pluralize!(impl_count), - suffix.unwrap_or_else(String::new), + suffix.unwrap_or_default(), ), ); } @@ -2023,7 +2023,7 @@ pub(super) fn check_type_bounds<'tcx>( }; let obligations: Vec<_> = tcx - .bound_explicit_item_bounds(trait_ty.def_id) + .explicit_item_bounds(trait_ty.def_id) .subst_iter_copied(tcx, rebased_substs) .map(|(concrete_ty_bound, span)| { debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 854974d1605..0fcbaa2efab 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -198,7 +198,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()), sym::forget => (1, vec![param(0)], tcx.mk_unit()), - sym::transmute => (2, vec![param(0)], param(1)), + sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)), sym::prefetch_read_data | sym::prefetch_write_data | sym::prefetch_read_instruction diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 0d482b53afe..a28814681db 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -84,33 +84,45 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Adt(adt, substs) if adt.repr().simd() => { let fields = &adt.non_enum_variant().fields; let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs); - match elem_ty.kind() { - ty::Never | ty::Error(_) => return None, - ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => { - Some(InlineAsmType::VecI8(fields.len() as u64)) + + let (size, ty) = match elem_ty.kind() { + ty::Array(ty, len) => { + if let Some(len) = + len.try_eval_target_usize(self.tcx, self.tcx.param_env(adt.did())) + { + (len, *ty) + } else { + return None; + } } + _ => (fields.len() as u64, elem_ty), + }; + + match ty.kind() { + ty::Never | ty::Error(_) => return None, + ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)), ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => { - Some(InlineAsmType::VecI16(fields.len() as u64)) + Some(InlineAsmType::VecI16(size)) } ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => { - Some(InlineAsmType::VecI32(fields.len() as u64)) + Some(InlineAsmType::VecI32(size)) } ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => { - Some(InlineAsmType::VecI64(fields.len() as u64)) + Some(InlineAsmType::VecI64(size)) } ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => { - Some(InlineAsmType::VecI128(fields.len() as u64)) + Some(InlineAsmType::VecI128(size)) } ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => { Some(match self.tcx.sess.target.pointer_width { - 16 => InlineAsmType::VecI16(fields.len() as u64), - 32 => InlineAsmType::VecI32(fields.len() as u64), - 64 => InlineAsmType::VecI64(fields.len() as u64), + 16 => InlineAsmType::VecI16(size), + 32 => InlineAsmType::VecI32(size), + 64 => InlineAsmType::VecI64(size), _ => unreachable!(), }) } - ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(fields.len() as u64)), - ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(fields.len() as u64)), + ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)), + ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)), _ => None, } } diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8fe4c44fca4..08154cdae47 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -74,7 +74,7 @@ pub use check::check_abi; use check::check_mod_item_types; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{pluralize, struct_span_err, Diagnostic, DiagnosticBuilder}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_index::bit_set::BitSet; @@ -90,6 +90,7 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor; use std::num::NonZeroU32; +use crate::errors; use crate::require_c_abi_if_c_variadic; use crate::util::common::indenter; @@ -171,34 +172,18 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) { fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_impl: DefId) { let span = tcx.def_span(impl_item); let ident = tcx.item_name(impl_item); - let mut err = struct_span_err!( - tcx.sess, - span, - E0520, - "`{}` specializes an item from a parent `impl`, but that item is not marked `default`", - ident, - ); - err.span_label(span, format!("cannot specialize default item `{}`", ident)); - - match tcx.span_of_impl(parent_impl) { - Ok(span) => { - err.span_label(span, "parent `impl` is here"); - err.note(&format!( - "to specialize, `{}` in the parent `impl` must be marked `default`", - ident - )); - } - Err(cname) => { - err.note(&format!("parent implementation is in crate `{cname}`")); - } - } - err.emit(); + let err = match tcx.span_of_impl(parent_impl) { + Ok(sp) => errors::ImplNotMarkedDefault::Ok { span, ident, ok_label: sp }, + Err(cname) => errors::ImplNotMarkedDefault::Err { span, ident, cname }, + }; + + tcx.sess.emit_err(err); } fn missing_items_err( tcx: TyCtxt<'_>, - impl_span: Span, + impl_def_id: LocalDefId, missing_items: &[ty::AssocItem], full_impl_span: Span, ) { @@ -211,14 +196,6 @@ fn missing_items_err( .collect::<Vec<_>>() .join("`, `"); - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing: `{missing_items_msg}`", - ); - err.span_label(impl_span, format!("missing `{missing_items_msg}` in implementation")); - // `Span` before impl block closing brace. let hi = full_impl_span.hi() - BytePos(1); // Point at the place right before the closing brace of the relevant `impl` to suggest @@ -227,20 +204,40 @@ fn missing_items_err( // Obtain the level of indentation ending in `sugg_sp`. let padding = tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new()); + let (mut missing_trait_item, mut missing_trait_item_none, mut missing_trait_item_label) = + (Vec::new(), Vec::new(), Vec::new()); for &trait_item in missing_items { - let snippet = suggestion_signature(trait_item, tcx); + let snippet = suggestion_signature( + tcx, + trait_item, + tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(), + ); let code = format!("{}{}\n{}", padding, snippet, padding); - let msg = format!("implement the missing item: `{snippet}`"); - let appl = Applicability::HasPlaceholders; if let Some(span) = tcx.hir().span_if_local(trait_item.def_id) { - err.span_label(span, format!("`{}` from trait", trait_item.name)); - err.tool_only_span_suggestion(sugg_sp, &msg, code, appl); + missing_trait_item_label + .push(errors::MissingTraitItemLabel { span, item: trait_item.name }); + missing_trait_item.push(errors::MissingTraitItemSuggestion { + span: sugg_sp, + code, + snippet, + }); } else { - err.span_suggestion_hidden(sugg_sp, &msg, code, appl); + missing_trait_item_none.push(errors::MissingTraitItemSuggestionNone { + span: sugg_sp, + code, + snippet, + }) } } - err.emit(); + + tcx.sess.emit_err(errors::MissingTraitItem { + span: tcx.span_of_impl(impl_def_id.to_def_id()).unwrap(), + missing_items_msg, + missing_trait_item_label, + missing_trait_item, + missing_trait_item_none, + }); } fn missing_items_must_implement_one_of_err( @@ -252,19 +249,11 @@ fn missing_items_must_implement_one_of_err( let missing_items_msg = missing_items.iter().map(Ident::to_string).collect::<Vec<_>>().join("`, `"); - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing one of: `{missing_items_msg}`", - ); - err.span_label(impl_span, format!("missing one of `{missing_items_msg}` in implementation")); - - if let Some(annotation_span) = annotation_span { - err.span_note(annotation_span, "required because of this annotation"); - } - - err.emit(); + tcx.sess.emit_err(errors::MissingOneOfTraitItem { + span: impl_span, + note: annotation_span, + missing_items_msg, + }); } fn default_body_is_unstable( @@ -276,36 +265,42 @@ fn default_body_is_unstable( issue: Option<NonZeroU32>, ) { let missing_item_name = tcx.associated_item(item_did).name; - let use_of_unstable_library_feature_note = match reason { - Some(r) => format!("use of unstable library feature '{feature}': {r}"), - None => format!("use of unstable library feature '{feature}'"), + let (mut some_note, mut none_note, mut reason_str) = (false, false, String::new()); + match reason { + Some(r) => { + some_note = true; + reason_str = r.to_string(); + } + None => none_note = true, }; - let mut err = struct_span_err!( - tcx.sess, - impl_span, - E0046, - "not all trait items implemented, missing: `{missing_item_name}`", - ); - err.note(format!("default implementation of `{missing_item_name}` is unstable")); - err.note(use_of_unstable_library_feature_note); + let mut err = tcx.sess.create_err(errors::MissingTraitItemUnstable { + span: impl_span, + some_note, + none_note, + missing_item_name, + feature, + reason: reason_str, + }); + rustc_session::parse::add_feature_diagnostics_for_issue( &mut err, &tcx.sess.parse_sess, feature, rustc_feature::GateIssue::Library(issue), ); + err.emit(); } /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions. fn bounds_from_generic_predicates<'tcx>( tcx: TyCtxt<'tcx>, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>, ) -> (String, String) { let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default(); let mut projections = vec![]; - for (predicate, _) in predicates.predicates { + for (predicate, _) in predicates { debug!("predicate {:?}", predicate); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { @@ -367,7 +362,7 @@ fn fn_sig_suggestion<'tcx>( tcx: TyCtxt<'tcx>, sig: ty::FnSig<'tcx>, ident: Ident, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>, assoc: ty::AssocItem, ) -> String { let args = sig @@ -436,7 +431,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { /// Return placeholder code for the given associated item. /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a /// structured suggestion. -fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { +fn suggestion_signature<'tcx>( + tcx: TyCtxt<'tcx>, + assoc: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, +) -> String { + let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto( + tcx, + assoc.container_id(tcx), + impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs, + ); + match assoc.kind { ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all @@ -445,16 +450,22 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { // regions just fine, showing `fn(&MyType)`. fn_sig_suggestion( tcx, - tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(), + tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(), assoc.ident(tcx), - tcx.predicates_of(assoc.def_id), + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), assoc, ) } - ty::AssocKind::Type => format!("type {} = Type;", assoc.name), + ty::AssocKind::Type => { + let (generics, where_clauses) = bounds_from_generic_predicates( + tcx, + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), + ); + format!("type {}{generics} = /* Type */{where_clauses};", assoc.name) + } ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).subst_identity(); - let val = ty_kind_suggestion(ty).unwrap_or("value"); + let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); format!("const {}: {} = {};", assoc.name, ty, val) } } @@ -467,16 +478,18 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>, sp: Span, d .iter() .map(|variant| tcx.hir().span_if_local(variant.def_id).unwrap()) .collect(); - let msg = format!("needs exactly one variant, but has {}", adt.variants().len(),); - let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {msg}"); - err.span_label(sp, &msg); + let (mut spans, mut many) = (Vec::new(), None); if let [start @ .., end] = &*variant_spans { - for variant_span in start { - err.span_label(*variant_span, ""); - } - err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did))); + spans = start.to_vec(); + many = Some(*end); } - err.emit(); + tcx.sess.emit_err(errors::TransparentEnumVariant { + span: sp, + spans, + many, + number: adt.variants().len(), + path: tcx.def_path_str(did), + }); } /// Emit an error when encountering two or more non-zero-sized fields in a transparent @@ -488,21 +501,21 @@ fn bad_non_zero_sized_fields<'tcx>( field_spans: impl Iterator<Item = Span>, sp: Span, ) { - let msg = format!("needs at most one non-zero-sized field, but has {field_count}"); - let mut err = struct_span_err!( - tcx.sess, - sp, - E0690, - "{}transparent {} {}", - if adt.is_enum() { "the variant of a " } else { "" }, - adt.descr(), - msg, - ); - err.span_label(sp, &msg); - for sp in field_spans { - err.span_label(sp, "this field is non-zero-sized"); + if adt.is_enum() { + tcx.sess.emit_err(errors::TransparentNonZeroSizedEnum { + span: sp, + spans: field_spans.collect(), + field_count, + desc: adt.descr(), + }); + } else { + tcx.sess.emit_err(errors::TransparentNonZeroSized { + span: sp, + spans: field_spans.collect(), + field_count, + desc: adt.descr(), + }); } - err.emit(); } // FIXME: Consider moving this method to a more fitting place. diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index b28bfb1d54b..421b3df2d53 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, Local, Pat, PatKind, Stmt}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::middle::region::*; use rustc_middle::ty::TyCtxt; use rustc_span::source_map; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 53197bc8491..0eafab017c7 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -155,7 +155,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { @@ -251,7 +251,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { @@ -360,7 +360,9 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, associated_items: &[hir::TraitItemRe tcx, param_env, item_def_id, - tcx.explicit_item_bounds(item_def_id).to_vec(), + tcx.explicit_item_bounds(item_def_id) + .subst_identity_iter_copied() + .collect::<Vec<_>>(), &FxIndexSet::default(), gat_def_id.def_id, gat_generics, @@ -1125,7 +1127,7 @@ fn check_associated_type_bounds(wfcx: &WfCheckingCtxt<'_, '_>, item: ty::AssocIt let bounds = wfcx.tcx().explicit_item_bounds(item.def_id); debug!("check_associated_type_bounds: bounds={:?}", bounds); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let wf_obligations = bounds.subst_identity_iter_copied().flat_map(|(bound, bound_span)| { let normalized_bound = wfcx.normalize(span, None, bound); traits::wf::predicate_obligations( wfcx.infcx, @@ -1588,7 +1590,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> { } }); for (bound, bound_span) in tcx - .bound_explicit_item_bounds(opaque_ty.def_id) + .explicit_item_bounds(opaque_ty.def_id) .subst_iter_copied(tcx, opaque_ty.substs) { let bound = self.wfcx.normalize(bound_span, None, bound); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 0f40cca9427..611ce13b739 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -74,16 +74,15 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type); - let span = match tcx.hir().expect_item(impl_did).kind { - ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return, - ItemKind::Impl(impl_) => impl_.self_ty.span, - _ => bug!("expected Copy impl item"), + let span = match tcx.hir().expect_item(impl_did).expect_impl() { + hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return, + hir::Impl { self_ty, .. } => self_ty.span, }; let cause = traits::ObligationCause::misc(span, impl_did); match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) { Ok(()) => {} - Err(CopyImplementationError::InfrigingFields(fields)) => { + Err(CopyImplementationError::InfringingFields(fields)) => { let mut err = struct_span_err!( tcx.sess, span, diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index ad76e2bed20..bd6252344b2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -3,7 +3,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Symbol; diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 465e787c92a..ac393ee15a6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -22,7 +22,7 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef< debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, - tcx.def_path_str(impl_def_id.to_def_id()) + tcx.def_path_str(impl_def_id) ); // Skip impls where one of the self type is an error type. diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index cbbaf8f857d..9fe0c07814e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -55,7 +55,6 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { pub fn provide(providers: &mut Providers) { resolve_bound_vars::provide(providers); *providers = Providers { - opt_const_param_of: type_of::opt_const_param_of, type_of: type_of::type_of, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, @@ -1147,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(ty); + let mut diag = bad_placeholder(tcx, visitor.0, "return type"); let ret_ty = fn_sig.output(); + // Don't leak types into signatures unless they're nameable! + // For example, if a function returns itself, we don't want that + // recursive function definition to leak out into the fn sig. + let mut should_recover = false; + if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) { diag.span_suggestion( ty.span, @@ -1156,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( ret_ty, Applicability::MachineApplicable, ); - } else if matches!(ret_ty.kind(), ty::FnDef(..)) - && let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false) - { - diag.span_suggestion( - ty.span, - "replace with the correct return type", - fn_sig, - Applicability::MachineApplicable, - ); + should_recover = true; } else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) { diag.span_suggestion( ty.span, @@ -1182,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>( https://doc.rust-lang.org/book/ch13-01-closures.html", ); } - diag.emit(); - ty::Binder::dummy(fn_sig) + let guar = diag.emit(); + + if should_recover { + ty::Binder::dummy(fn_sig) + } else { + ty::Binder::dummy(tcx.mk_fn_sig( + fn_sig.inputs().iter().copied(), + tcx.ty_error(guar), + fn_sig.c_variadic, + fn_sig.unsafety, + fn_sig.abi, + )) + } } None => icx.astconv().ty_of_fn( hir_id, @@ -1457,10 +1465,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( } fn is_foreign_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - match tcx.hir().get_by_def_id(def_id) { - Node::ForeignItem(..) => true, - _ => false, - } + matches!(tcx.hir().get_by_def_id(def_id), Node::ForeignItem(..)) } fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorKind> { diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 2e56d24638c..80d6bc7db9e 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -79,14 +79,14 @@ fn opaque_type_bounds<'tcx>( pub(super) fn explicit_item_bounds( tcx: TyCtxt<'_>, def_id: LocalDefId, -) -> &'_ [(ty::Predicate<'_>, Span)] { +) -> ty::EarlyBinder<&'_ [(ty::Predicate<'_>, Span)]> { match tcx.opt_rpitit_info(def_id.to_def_id()) { // RPITIT's bounds are the same as opaque type bounds, but with // a projection self type. Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => { let item = tcx.hir().get_by_def_id(opaque_def_id.expect_local()).expect_item(); let opaque_ty = item.expect_opaque_ty(); - return opaque_type_bounds( + return ty::EarlyBinder(opaque_type_bounds( tcx, opaque_def_id.expect_local(), opaque_ty.bounds, @@ -95,7 +95,7 @@ pub(super) fn explicit_item_bounds( ty::InternalSubsts::identity_for_item(tcx, def_id), ), item.span, - ); + )); } // These should have been fed! Some(ty::ImplTraitInTraitData::Impl { .. }) => unreachable!(), @@ -103,7 +103,7 @@ pub(super) fn explicit_item_bounds( } let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { + let bounds = match tcx.hir().get(hir_id) { hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(bounds, _), span, @@ -123,16 +123,18 @@ pub(super) fn explicit_item_bounds( opaque_type_bounds(tcx, def_id, bounds, item_ty, *span) } _ => bug!("item_bounds called on {:?}", def_id), - } + }; + ty::EarlyBinder(bounds) } pub(super) fn item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> { - let bounds = tcx.mk_predicates_from_iter(util::elaborate( - tcx, - tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), - )); - ty::EarlyBinder(bounds) + tcx.explicit_item_bounds(def_id).map_bound(|bounds| { + tcx.mk_predicates_from_iter(util::elaborate( + tcx, + bounds.iter().map(|&(bound, _span)| bound), + )) + }) } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index e758fe95d9c..3cb217335bd 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1333,7 +1333,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT. // AST-based resolution does not care for impl-trait desugaring, which are the - // responibility of lowering. This may create a mismatch between the resolution + // responsibility of lowering. This may create a mismatch between the resolution // AST found (`region_def_id`) which points to HRTB, and what HIR allows. // ``` // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {} diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index c173bd913a8..d7d509e5394 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -1,6 +1,6 @@ use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; @@ -16,22 +16,81 @@ use super::ItemCtxt; use super::{bad_placeholder, is_suggestable_infer_ty}; use crate::errors::UnconstrainedOpaqueType; -/// Computes the relevant generic parameter for a potential generic const argument. -/// -/// This should be called using the query `tcx.opt_const_param_of`. -pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> { +fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use hir::*; let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { - Node::AnonConst(_) => (), - _ => return None, - }; + let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() }; let parent_node_id = tcx.hir().parent_id(hir_id); let parent_node = tcx.hir().get(parent_node_id); let (generics, arg_idx) = match parent_node { + // Easy case: arrays repeat expressions. + Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) + | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id() == hir_id => + { + return tcx.types.usize + } + Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => { + return tcx.typeck(def_id).node_type(e.hir_id) + } + Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. }) + if anon_const.hir_id == hir_id => + { + let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); + return substs.as_inline_const().ty() + } + Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + if asm.operands.iter().any(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, + _ => false, + }) => + { + return tcx.typeck(def_id).node_type(hir_id) + } + Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { + return tcx + .adt_def(tcx.hir().get_parent_item(hir_id)) + .repr() + .discr_type() + .to_ty(tcx) + } + Node::GenericParam(&GenericParam { + def_id: param_def_id, + kind: GenericParamKind::Const { default: Some(ct), .. }, + .. + }) if ct.hir_id == hir_id => { + return tcx.type_of(param_def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } + + Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) + if let Node::TraitRef(trait_ref) = tcx.hir().get( + tcx.hir().parent_id(binding_id) + ) => + { + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), + ); + return if let Some(assoc_item) = assoc_item { + tcx.type_of(assoc_item.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait") + } + } + // This match arm is for when the def_id appears in a GAT whose // path can't be resolved without typechecking e.g. // @@ -86,11 +145,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< (generics, arg_index) } else { // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "unexpected non-GAT usage of an anon const", ); - return None; } } Node::Expr(&Expr { @@ -103,7 +161,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // This may fail in case the method/path does not actually exist. // As there is no relevant param for `def_id`, we simply return // `None` here. - let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?; + let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("unable to find type-dependent def for {:?}", parent_node_id), + ); + }; let idx = segment .args .and_then(|args| { @@ -140,19 +203,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) { path } else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unable to find const parent for {} in pat {:?}", hir_id, pat), ); - return None; } } _ => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unexpected const parent path {:?}", parent_node), ); - return None; } }; @@ -171,32 +232,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< .position(|ct| ct.hir_id == hir_id) .map(|idx| (idx, seg))) }) else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "no arg matching AnonConst in path", ); - return None; }; let generics = match tcx.res_generics_def_id(segment.res) { Some(def_id) => tcx.generics_of(def_id), None => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), ); - return None; } }; (generics, arg_index) } - _ => return None, + + _ => return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("unexpected const parent in type_of(): {parent_node:?}"), + ), }; debug!(?parent_node); debug!(?generics, ?arg_idx); - generics + if let Some(param_def_id) = generics .params .iter() .filter(|param| param.kind.is_ty_or_const()) @@ -211,6 +274,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< } _ => None, }) + { + tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic") + } else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"), + ); + } } fn get_path_containing_arg_in_pat<'hir>( @@ -251,7 +322,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) { Ok(map) => { let assoc_item = tcx.associated_item(def_id); - return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]); + return map[&assoc_item.trait_item_def_id.unwrap()]; } Err(_) => { return ty::EarlyBinder(tcx.ty_error_with_message( @@ -415,143 +486,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty tcx.typeck(def_id).node_type(hir_id) } - Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => { - // We defer to `type_of` of the corresponding parameter - // for generic arguments. - tcx.type_of(param).subst_identity() - } - - Node::AnonConst(_) => { - let parent_node = tcx.hir().get_parent(hir_id); - match parent_node { - Node::Ty(Ty { kind: TyKind::Array(_, constant), .. }) - | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. }) - if constant.hir_id() == hir_id => - { - tcx.types.usize - } - Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => { - tcx.typeck(def_id).node_type(e.hir_id) - } - - Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. }) - if anon_const.hir_id == hir_id => - { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - substs.as_inline_const().ty() - } - - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { - anon_const.hir_id == hir_id - } - _ => false, - }) => - { - tcx.typeck(def_id).node_type(hir_id) - } - - Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - kind: TypeBindingKind::Equality { term: Term::Const(e) }, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && e.hir_id == hir_id => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - ty::AssocKind::Const, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find associated const on trait", - ) - } - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - gen_args, - kind, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && let Some((idx, _)) = - gen_args.args.iter().enumerate().find(|(_, arg)| { - if let GenericArg::Const(ct) = arg { - ct.value.hir_id == hir_id - } else { - false - } - }) => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - match kind { - // I think `<A: T>` type bindings requires that `A` is a type - TypeBindingKind::Constraint { .. } - | TypeBindingKind::Equality { term: Term::Ty(..) } => { - ty::AssocKind::Type - } - TypeBindingKind::Equality { term: Term::Const(..) } => { - ty::AssocKind::Const - } - }, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item - && let param = &tcx.generics_of(assoc_item.def_id).params[idx] - && matches!(param.kind, ty::GenericParamDefKind::Const { .. }) - { - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find const param on associated item", - ) - } - } - - Node::GenericParam(&GenericParam { - def_id: param_def_id, - kind: GenericParamKind::Const { default: Some(ct), .. }, - .. - }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(), - - x => tcx.ty_error_with_message( - DUMMY_SP, - &format!("unexpected const parent in type_of(): {x:?}"), - ), - } - } + Node::AnonConst(_) => anon_const_type_of(tcx, def_id), Node::GenericParam(param) => match ¶m.kind { GenericParamKind::Type { default: Some(ty), .. } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 2a3a683489d..cfce2463b18 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -631,3 +631,141 @@ pub(crate) struct SIMDFFIHighlyExperimental { pub span: Span, pub snip: String, } + +#[derive(Diagnostic)] +pub enum ImplNotMarkedDefault { + #[diag(hir_analysis_impl_not_marked_default, code = "E0520")] + #[note] + Ok { + #[primary_span] + #[label] + span: Span, + #[label(hir_analysis_ok_label)] + ok_label: Span, + ident: Symbol, + }, + #[diag(hir_analysis_impl_not_marked_default_err, code = "E0520")] + #[note] + Err { + #[primary_span] + #[label] + span: Span, + cname: Symbol, + ident: Symbol, + }, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_trait_item, code = "E0046")] +pub(crate) struct MissingTraitItem { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub missing_trait_item_label: Vec<MissingTraitItemLabel>, + #[subdiagnostic] + pub missing_trait_item: Vec<MissingTraitItemSuggestion>, + #[subdiagnostic] + pub missing_trait_item_none: Vec<MissingTraitItemSuggestionNone>, + pub missing_items_msg: String, +} + +#[derive(Subdiagnostic)] +#[label(hir_analysis_missing_trait_item_label)] +pub(crate) struct MissingTraitItemLabel { + #[primary_span] + pub span: Span, + pub item: Symbol, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_analysis_missing_trait_item_suggestion, + style = "tool-only", + applicability = "has-placeholders", + code = "{code}" +)] +pub(crate) struct MissingTraitItemSuggestion { + #[primary_span] + pub span: Span, + pub code: String, + pub snippet: String, +} + +#[derive(Subdiagnostic)] +#[suggestion( + hir_analysis_missing_trait_item_suggestion, + style = "hidden", + applicability = "has-placeholders", + code = "{code}" +)] +pub(crate) struct MissingTraitItemSuggestionNone { + #[primary_span] + pub span: Span, + pub code: String, + pub snippet: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_one_of_trait_item, code = "E0046")] +pub(crate) struct MissingOneOfTraitItem { + #[primary_span] + #[label] + pub span: Span, + #[note] + pub note: Option<Span>, + pub missing_items_msg: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_missing_trait_item_unstable, code = "E0046")] +#[note] +pub(crate) struct MissingTraitItemUnstable { + #[primary_span] + pub span: Span, + #[note(hir_analysis_some_note)] + pub some_note: bool, + #[note(hir_analysis_none_note)] + pub none_note: bool, + pub missing_item_name: Symbol, + pub feature: Symbol, + pub reason: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_enum_variant, code = "E0731")] +pub(crate) struct TransparentEnumVariant { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_multi_label)] + pub spans: Vec<Span>, + #[label(hir_analysis_many_label)] + pub many: Option<Span>, + pub number: usize, + pub path: String, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_non_zero_sized_enum, code = "E0690")] +pub(crate) struct TransparentNonZeroSizedEnum<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_labels)] + pub spans: Vec<Span>, + pub field_count: usize, + pub desc: &'a str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_transparent_non_zero_sized, code = "E0690")] +pub(crate) struct TransparentNonZeroSized<'a> { + #[primary_span] + #[label] + pub span: Span, + #[label(hir_analysis_labels)] + pub spans: Vec<Span>, + pub field_count: usize, + pub desc: &'a str, +} diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 27e56180349..a4b797f77f7 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -99,10 +99,10 @@ mod variance; use rustc_errors::ErrorGuaranteed; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; -use rustc_macros::fluent_messages; use rustc_middle::middle; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -496,8 +496,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module)) }); - tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(())); - check_unused::check_crate(tcx); check_for_entry_fn(tcx); diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 408bec71ee0..6f0afae1b4c 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn build_constraints_for_item(&mut self, def_id: LocalDefId) { let tcx = self.tcx(); - debug!("build_constraints_for_item({})", tcx.def_path_str(def_id.to_def_id())); + debug!("build_constraints_for_item({})", tcx.def_path_str(def_id)); // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(def_id).count() == 0 { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 0a45119ff05..e735b048d73 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -105,7 +105,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { self.variances[ebr.index as usize] = ty::Invariant; } - r.super_visit_with(self) + ControlFlow::Continue(()) } #[instrument(level = "trace", skip(self), ret)] @@ -153,8 +153,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc let mut collector = OpaqueTypeLifetimeCollector { tcx, root_def_id: item_def_id.to_def_id(), variances }; let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id); - for pred in tcx.bound_explicit_item_bounds(item_def_id.to_def_id()).transpose_iter() { - let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); + for (pred, _) in tcx.explicit_item_bounds(item_def_id).subst_iter_copied(tcx, id_substs) { debug!(?pred); // We only ignore opaque type substs if the opaque type is the outermost type. diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 74f5b359021..2db4f1e50d4 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1551,6 +1551,23 @@ impl<'a> State<'a> { self.word("asm!"); self.print_inline_asm(asm); } + hir::ExprKind::OffsetOf(container, ref fields) => { + self.word("offset_of!("); + self.print_type(container); + self.word(","); + self.space(); + + if let Some((&first, rest)) = fields.split_first() { + self.print_ident(first); + + for &field in rest { + self.word("."); + self.print_ident(field); + } + } + + self.word(")"); + } hir::ExprKind::Yield(expr, _) => { self.word_space("yield"); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 093f9bb8448..13e1ea31c4d 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 2c537bf4064..6d40df7d0cc 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -3,21 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer = .label = used more than once .previous_use_label = first use of `{$ident}` -hir_typeck_copy_impl_on_type_with_dtor = - the trait `Copy` cannot be implemented for this type; the type has a destructor - .label = `Copy` not allowed on types with destructors - -hir_typeck_multiple_relaxed_default_bounds = - type parameter has more than one relaxed default bound, only one is supported - -hir_typeck_copy_impl_on_non_adt = - the trait `Copy` cannot be implemented for this type - .label = type is not a structure or enumeration - -hir_typeck_trait_object_declared_with_no_traits = - at least one trait is required for an object type - .alias_span = this alias does not contain a trait - hir_typeck_functional_record_update_on_non_struct = functional record update syntax requires a struct diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 6c2ce62722a..aefde8109a0 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -530,7 +530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for ty in [first_ty, second_ty] { for (pred, _) in self .tcx - .bound_explicit_item_bounds(rpit_def_id) + .explicit_item_bounds(rpit_def_id) .subst_iter_copied(self.tcx, substs) { let pred = pred.kind().rebind(match pred.kind().skip_binder() { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index 8c2495e1dd8..7046269c2de 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -172,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self .deduce_closure_signature_from_predicates( expected_ty, - self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), + self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs), ), ty::Dynamic(ref object_type, ..) => { let sig = object_type.projection_bounds().find_map(|pb| { @@ -713,13 +713,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => self .tcx - .bound_explicit_item_bounds(def_id) + .explicit_item_bounds(def_id) .subst_iter_copied(self.tcx, substs) .find_map(|(p, s)| get_future_output(p, s))?, ty::Error(_) => return None, ty::Alias(ty::Projection, proj) if self.tcx.is_impl_trait_in_trait(proj.def_id) => self .tcx - .bound_explicit_item_bounds(proj.def_id) + .explicit_item_bounds(proj.def_id) .subst_iter_copied(self.tcx, proj.substs) .find_map(|(p, s)| get_future_output(p, s))?, _ => span_bug!( diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 8fa3bcd68c3..507c24d540c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -976,7 +976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Attempt to coerce an expression to a type, and return the /// adjusted type of the expression, if successful. /// Adjustments are only recorded if the coercion succeeded. - /// The expressions *must not* have any pre-existing adjustments. + /// The expressions *must not* have any preexisting adjustments. pub fn try_coerce( &self, expr: &hir::Expr<'_>, @@ -1340,7 +1340,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } /// As an optimization, you can create a `CoerceMany` with a - /// pre-existing slice of expressions. In this case, you are + /// preexisting slice of expressions. In this case, you are /// expected to pass each element in the slice to `coerce(...)` in /// order. This is used with arrays in particular to avoid /// needlessly cloning the slice. diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 13442c31649..525acfdaa81 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -17,7 +17,6 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span, DUMMY_SP}; -use rustc_target::abi::FieldIdx; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::ObligationCause; @@ -875,7 +874,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant.fields.len() == 1 }) .filter_map(|variant| { - let sole_field = &variant.fields[FieldIdx::from_u32(0)]; + let sole_field = &variant.single_field(); let field_is_local = sole_field.did.is_local(); let field_is_accessible = diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 3eee2278dca..5be78416e61 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -108,7 +108,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { #[derive(Diagnostic)] #[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")] -pub struct MissingParentheseInRange { +pub struct MissingParenthesesInRange { #[primary_span] #[label(hir_typeck_missing_parentheses_in_range)] pub span: Span, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 6ffa0134f3d..3ffc583d43f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -38,6 +38,7 @@ use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::InferOk; +use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; @@ -53,6 +54,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; +use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; +use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCauseCode}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -306,6 +309,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id)); self.check_expr_asm(asm) } + ExprKind::OffsetOf(container, ref fields) => { + self.check_offset_of(container, fields, expr) + } ExprKind::Break(destination, ref expr_opt) => { self.check_expr_break(destination, expr_opt.as_deref(), expr) } @@ -1735,10 +1741,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { self.check_expr_has_type_or_error(base_expr, adt_ty, |_| { let base_ty = self.typeck_results.borrow().expr_ty(*base_expr); - let same_adt = match (adt_ty.kind(), base_ty.kind()) { - (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt => true, - _ => false, - }; + let same_adt = matches!((adt_ty.kind(), base_ty.kind()), + (ty::Adt(adt, _), ty::Adt(base_adt, _)) if adt == base_adt); if self.tcx.sess.is_nightly_build() && same_adt { feature_err( &self.tcx.sess.parse_sess, @@ -2449,15 +2453,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_did: DefId, return_ty: Option<Ty<'tcx>>, ) -> ErrorGuaranteed { - let struct_path = self.tcx().def_path_str(base_did); - let kind_name = self.tcx().def_descr(base_did); - let mut err = struct_span_err!( - self.tcx().sess, - field.span, - E0616, - "field `{field}` of {kind_name} `{struct_path}` is private", - ); - err.span_label(field.span, "private field"); + let mut err = self.private_field_err(field, base_did); + // Also check if an accessible method exists, which is often what is meant. if self.method_exists(field, expr_t, expr.hir_id, false, return_ty) && !self.expr_in_place(expr.hir_id) @@ -2697,6 +2694,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err } + fn private_field_err( + &self, + field: Ident, + base_did: DefId, + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let struct_path = self.tcx().def_path_str(base_did); + let kind_name = self.tcx().def_descr(base_did); + let mut err = struct_span_err!( + self.tcx().sess, + field.span, + E0616, + "field `{field}` of {kind_name} `{struct_path}` is private", + ); + err.span_label(field.span, "private field"); + + err + } + pub(crate) fn get_field_candidates_considering_privacy( &self, span: Span, @@ -2802,6 +2817,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { element_ty } None => { + // Attempt to *shallowly* search for an impl which matches, + // but has nested obligations which are unsatisfied. + for (base_t, _) in self.autoderef(base.span, base_t).silence_errors() { + if let Some((_, index_ty, element_ty)) = + self.find_and_report_unsatisfied_index_impl(expr.hir_id, base, base_t) + { + self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No); + return element_ty; + } + } + let mut err = type_error_struct!( self.tcx.sess, expr.span, @@ -2845,6 +2871,82 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Try to match an implementation of `Index` against a self type, and report + /// the unsatisfied predicates that result from confirming this impl. + /// + /// Given an index expression, sometimes the `Self` type shallowly but does not + /// deeply satisfy an impl predicate. Instead of simply saying that the type + /// does not support being indexed, we want to point out exactly what nested + /// predicates cause this to be, so that the user can add them to fix their code. + fn find_and_report_unsatisfied_index_impl( + &self, + index_expr_hir_id: HirId, + base_expr: &hir::Expr<'_>, + base_ty: Ty<'tcx>, + ) -> Option<(ErrorGuaranteed, Ty<'tcx>, Ty<'tcx>)> { + let index_trait_def_id = self.tcx.lang_items().index_trait()?; + let index_trait_output_def_id = self.tcx.get_diagnostic_item(sym::IndexOutput)?; + + let mut relevant_impls = vec![]; + self.tcx.for_each_relevant_impl(index_trait_def_id, base_ty, |impl_def_id| { + relevant_impls.push(impl_def_id); + }); + let [impl_def_id] = relevant_impls[..] else { + // Only report unsatisfied impl predicates if there's one impl + return None; + }; + + self.commit_if_ok(|_| { + let ocx = ObligationCtxt::new_in_snapshot(self); + let impl_substs = self.fresh_substs_for_item(base_expr.span, impl_def_id); + let impl_trait_ref = + self.tcx.impl_trait_ref(impl_def_id).unwrap().subst(self.tcx, impl_substs); + let cause = self.misc(base_expr.span); + + // Match the impl self type against the base ty. If this fails, + // we just skip this impl, since it's not particularly useful. + let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref); + ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?; + + // Register the impl's predicates. One of these predicates + // must be unsatisfied, or else we wouldn't have gotten here + // in the first place. + ocx.register_obligations(traits::predicates_for_generics( + |idx, span| { + traits::ObligationCause::new( + base_expr.span, + self.body_id, + if span.is_dummy() { + traits::ExprItemObligation(impl_def_id, index_expr_hir_id, idx) + } else { + traits::ExprBindingObligation(impl_def_id, span, index_expr_hir_id, idx) + }, + ) + }, + self.param_env, + self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_substs), + )); + + // Normalize the output type, which we can use later on as the + // return type of the index expression... + let element_ty = ocx.normalize( + &cause, + self.param_env, + self.tcx.mk_projection(index_trait_output_def_id, impl_trait_ref.substs), + ); + + let errors = ocx.select_where_possible(); + // There should be at least one error reported. If not, we + // will still delay a span bug in `report_fulfillment_errors`. + Ok::<_, NoSolution>(( + self.err_ctxt().report_fulfillment_errors(&errors), + impl_trait_ref.substs.type_at(1), + element_ty, + )) + }) + .ok() + } + fn point_at_index_if_possible( &self, errors: &mut Vec<traits::FulfillmentError<'tcx>>, @@ -2954,4 +3056,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.mk_unit() } } + + fn check_offset_of( + &self, + container: &'tcx hir::Ty<'tcx>, + fields: &[Ident], + expr: &'tcx hir::Expr<'tcx>, + ) -> Ty<'tcx> { + let container = self.to_ty(container).normalized; + + let mut field_indices = Vec::with_capacity(fields.len()); + let mut current_container = container; + + for &field in fields { + let container = self.structurally_resolved_type(expr.span, current_container); + + match container.kind() { + ty::Adt(container_def, substs) if !container_def.is_enum() => { + let block = self.tcx.hir().local_def_id_to_hir_id(self.body_id); + let (ident, def_scope) = + self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block); + + let fields = &container_def.non_enum_variant().fields; + if let Some((index, field)) = fields + .iter_enumerated() + .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident) + { + let field_ty = self.field_ty(expr.span, field, substs); + + // FIXME: DSTs with static alignment should be allowed + self.require_type_is_sized(field_ty, expr.span, traits::MiscObligation); + + if field.vis.is_accessible_from(def_scope, self.tcx) { + self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); + } else { + self.private_field_err(ident, container_def.did()).emit(); + } + + // Save the index of all fields regardless of their visibility in case + // of error recovery. + field_indices.push(index); + current_container = field_ty; + + continue; + } + } + ty::Tuple(tys) => { + let fstr = field.as_str(); + + if let Ok(index) = fstr.parse::<usize>() { + if fstr == index.to_string() { + if let Some(&field_ty) = tys.get(index) { + field_indices.push(index.into()); + current_container = field_ty; + + continue; + } + } + } + } + _ => (), + }; + + self.no_such_field_err(field, container, expr.hir_id).emit(); + + break; + } + + self.typeck_results + .borrow_mut() + .offset_of_data_mut() + .insert(expr.hir_id, (container, field_indices)); + + self.tcx.types.usize + } } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index ee1c6fbfd65..94b6a0f8f47 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -300,6 +300,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::Continue(..) | hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Err(_) => {} hir::ExprKind::Loop(blk, ..) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index f736f7a9620..2b5af4bc81b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -420,9 +420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast_c: &hir::AnonConst, param_def_id: DefId, ) -> ty::Const<'tcx> { - let const_def = - ty::WithOptConstParam { did: ast_c.def_id, const_param_did: Some(param_def_id) }; - let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def); + let did = ast_c.def_id; + self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id)); + let c = ty::Const::from_anon_const(self.tcx, did); self.register_wf_obligation( c.into(), self.tcx.hir().span(ast_c.hir_id), @@ -827,7 +827,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } QPath::TypeRelative(ref qself, ref segment) => { // Don't use `self.to_ty`, since this will register a WF obligation. - // If we're trying to call a non-existent method on a trait + // If we're trying to call a nonexistent method on a trait // (e.g. `MyTrait::missing_method`), then resolution will // give us a `QPath::TypeRelative` with a trait object as // `qself`. In that case, we want to avoid registering a WF obligation diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index c3e5f9cb745..56c94505727 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -330,7 +330,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// expression mentioned. /// /// `blame_specific_arg_if_possible` will find the most-specific expression anywhere inside - /// the provided function call expression, and mark it as responsible for the fullfillment + /// the provided function call expression, and mark it as responsible for the fulfillment /// error. fn blame_specific_arg_if_possible( &self, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index 6f26afcaf16..d45e3d395e4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -1,6 +1,6 @@ use std::cmp; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::error::TypeError; rustc_index::newtype_index! { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index ea1b52daaa5..955463c1434 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -21,7 +21,7 @@ use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::structured_errors::StructuredDiagnostic; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::TypeTrace; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c6fd0b61035..3ba679df3ed 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,6 @@ use rustc_infer::infer; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; use rustc_span::symbol::Ident; @@ -250,16 +249,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { - if let Some(param) = param { - if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() { - return ty; - } - unreachable!() - } else { - self.next_ty_var(TypeVariableOrigin { + match param { + Some(param) => self.var_for_def(span, param).as_type().unwrap(), + None => self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span, - }) + }), } } @@ -269,16 +264,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { param: Option<&ty::GenericParamDef>, span: Span, ) -> Const<'tcx> { - if let Some(param) = param { - if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() { - return ct; - } - unreachable!() - } else { - self.next_const_var( + match param { + Some(param) => self.var_for_def(span, param).as_const().unwrap(), + None => self.next_const_var( ty, ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span }, - ) + ), } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 5fda4e191c2..eef2b5009c8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -794,7 +794,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; }; - // get all where BoundPredicates here, because they are used in to cases below + // get all where BoundPredicates here, because they are used in two cases below let where_predicates = predicates .iter() .filter_map(|p| match p { @@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node: rustc_ast::LitKind::Int(lit, rustc_ast::LitIntType::Unsuffixed), span, }) => { - let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) else { return false; }; + let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(*span) else { return false; }; if !(snippet.starts_with("0x") || snippet.starts_with("0X")) { return false; } @@ -1311,7 +1311,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We have satisfied all requirements to provide a suggestion. Emit it. err.span_suggestion( - span, + *span, format!("if you meant to create a null pointer, use `{null_path_str}()`"), null_path_str + "()", Applicability::MachineApplicable, diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index 3e9a9ce1b31..e4a62ec05ae 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -8,7 +8,7 @@ use hir::{ }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_infer::infer::InferCtxt; use rustc_middle::{ hir::map::Map, @@ -215,6 +215,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) @@ -485,6 +486,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { | ExprKind::Field(..) | ExprKind::Index(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::Let(..) | ExprKind::Lit(..) | ExprKind::Path(..) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs index 139d17d2e1c..633b478895b 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs @@ -1,5 +1,5 @@ use super::{DropRangesBuilder, PostOrderId}; -use rustc_index::{bit_set::BitSet, vec::IndexVec}; +use rustc_index::{bit_set::BitSet, IndexVec}; use std::collections::BTreeMap; impl DropRangesBuilder { diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs index f7b493bc224..cd3966a1214 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs @@ -20,7 +20,7 @@ use hir::{Body, HirId, HirIdMap, Node}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::hir::map::Map; use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId}; use rustc_middle::ty; @@ -268,8 +268,7 @@ impl DropRangesBuilder { fn node_mut(&mut self, id: PostOrderId) -> &mut NodeInfo { let size = self.num_values(); - self.nodes.ensure_contains_elem(id, || NodeInfo::new(size)); - &mut self.nodes[id] + self.nodes.ensure_contains_elem(id, || NodeInfo::new(size)) } fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) { diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index f3971080443..5b432475fc3 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -571,7 +571,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in fcx.tcx.explicit_item_bounds(def) { + for &(predicate, _) in fcx.tcx.explicit_item_bounds(def).skip_binder() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() @@ -650,7 +650,7 @@ fn check_must_not_suspend_ty<'tcx>( }, ) } - // If drop tracking is enabled, we want to look through references, since the referrent + // If drop tracking is enabled, we want to look through references, since the referent // may not be considered live across the await point. ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => { let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix); diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 106f5bcd755..2ad79cd85b1 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -1,10 +1,10 @@ use hir::HirId; use rustc_errors::struct_span_err; use rustc_hir as hir; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_target::abi::{FieldIdx, Pointer, VariantIdx}; +use rustc_target::abi::{Pointer, VariantIdx}; use super::FnCtxt; @@ -28,7 +28,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } if def.variant(data_idx).fields.len() == 1 { - return def.variant(data_idx).fields[FieldIdx::from_u32(0)].ty(tcx, substs); + return def.variant(data_idx).single_field().ty(tcx, substs); } } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 45890abad92..5ccac9a6925 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -59,6 +59,7 @@ use rustc_errors::{ struct_span_err, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; @@ -66,7 +67,6 @@ use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::check_abi; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -152,25 +152,9 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef &*tcx.typeck(def_id).used_trait_imports } -fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) { - tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id)); -} - -fn typeck_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, - (did, param_did): (LocalDefId, DefId), -) -> &ty::TypeckResults<'tcx> { - let fallback = move || tcx.type_of(param_did).subst_identity(); - typeck_with_fallback(tcx, did, fallback) -} - fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> { - if let Some(param_did) = tcx.opt_const_param_of(def_id) { - tcx.typeck_const_arg((def_id, param_did)) - } else { - let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); - typeck_with_fallback(tcx, def_id, fallback) - } + let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); + typeck_with_fallback(tcx, def_id, fallback) } /// Used only to get `TypeckResults` for type inference during error recovery. @@ -491,8 +475,6 @@ fn has_expected_num_generic_args( pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { - typeck_item_bodies, - typeck_const_arg, typeck, diagnostic_only_typeck, has_typeck_results, diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 6c861b5930a..f5fca14eca8 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -381,6 +381,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), } } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 0456dd56c34..fab9a8a5f4f 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -300,8 +300,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { trait_def_id: DefId, self_ty: Ty<'tcx>, opt_input_types: Option<&[Ty<'tcx>]>, - ) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>) - { + ) -> (traits::PredicateObligation<'tcx>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>) { // Construct a trait-reference `self_ty : Trait<input_tys>` let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| { match param.kind { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 900a6fa0d8d..db1f10f645f 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1530,7 +1530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); if pick.is_ok() { let range_span = parent_expr.span.with_hi(expr.span.hi()); - tcx.sess.emit_err(errors::MissingParentheseInRange { + tcx.sess.emit_err(errors::MissingParenthesesInRange { span, ty_str: ty_str.to_string(), method_name: item_name.as_str().to_string(), diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index af0bd26dec5..7160d1c67b2 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1659,7 +1659,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if tcx.sess.teach(&err.get_code().unwrap()) { err.note( "This error indicates that a struct pattern attempted to \ - extract a non-existent field from a struct. Struct fields \ + extract a nonexistent field from a struct. Struct fields \ are identified by the name used before the colon : so struct \ patterns should resemble the declaration of the struct type \ being matched.\n\n\ diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 41a6ad80b65..147b3e74d0f 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -223,7 +223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let closure_hir_id = self.tcx.hir().local_def_id_to_hir_id(closure_def_id); if should_do_rust_2021_incompatible_closure_captures_analysis(self.tcx, closure_hir_id) { - self.perform_2229_migration_anaysis(closure_def_id, body_id, capture_clause, span); + self.perform_2229_migration_analysis(closure_def_id, body_id, capture_clause, span); } let after_feature_tys = self.final_upvar_tys(closure_def_id); @@ -731,7 +731,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Perform the migration analysis for RFC 2229, and emit lint /// `disjoint_capture_drop_reorder` if needed. - fn perform_2229_migration_anaysis( + fn perform_2229_migration_analysis( &self, closure_def_id: LocalDefId, body_id: hir::BodyId, diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index e876fa27593..9432a5840b2 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -70,6 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.visit_user_provided_tys(); wbcx.visit_user_provided_sigs(); wbcx.visit_generator_interior_types(); + wbcx.visit_offset_of_container_types(); wbcx.typeck_results.rvalue_scopes = mem::take(&mut self.typeck_results.borrow_mut().rvalue_scopes); @@ -295,7 +296,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { self.visit_field_id(field.hir_id); } } - hir::ExprKind::Field(..) => { + hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => { self.visit_field_id(e.hir_id); } hir::ExprKind::ConstBlock(anon_const) => { @@ -682,6 +683,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } + fn visit_offset_of_container_types(&mut self) { + let fcx_typeck_results = self.fcx.typeck_results.borrow(); + assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); + let common_hir_owner = fcx_typeck_results.hir_owner; + + for (local_id, &(container, ref indices)) in + fcx_typeck_results.offset_of_data().items_in_stable_order() + { + let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + + if cfg!(debug_assertions) && container.needs_infer() { + span_bug!( + hir_id.to_span(self.fcx.tcx), + "writeback: `{:?}` has inference variables", + container + ); + }; + + self.typeck_results.offset_of_data_mut().insert(hir_id, (container, indices.clone())); + } + } + fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T where T: TypeFoldable<TyCtxt<'tcx>>, diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index ad89393956e..59a0623c1e1 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index df958e4a61f..11710c368ce 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -33,6 +33,6 @@ pub use persist::LoadResult; pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 1d88dfd20c8..43274091cb8 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -139,7 +139,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { return; } - // can't add `#[rustc_clean]` etc without opting in to this feature + // can't add `#[rustc_clean]` etc without opting into this feature if !tcx.features().rustc_attrs { return; } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index d6f83838a04..ec6d61f9e5f 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -601,7 +601,7 @@ fn string_to_timestamp(s: &str) -> Result<SystemTime, ()> { fn crate_path(sess: &Session, crate_name: Symbol, stable_crate_id: StableCrateId) -> PathBuf { let incr_dir = sess.opts.incremental.as_ref().unwrap().clone(); - let stable_crate_id = base_n::encode(stable_crate_id.to_u64() as u128, INT_ENCODE_BASE); + let stable_crate_id = base_n::encode(stable_crate_id.as_u64() as u128, INT_ENCODE_BASE); let crate_name = format!("{}-{}", crate_name, stable_crate_id); incr_dir.join(crate_name) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 271ab830694..a1ab9c8c5ec 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1,6 +1,3 @@ -use crate::vec::{Idx, IndexVec}; -use arrayvec::ArrayVec; -use smallvec::{smallvec, SmallVec}; use std::fmt; use std::iter; use std::marker::PhantomData; @@ -9,8 +6,13 @@ use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds use std::rc::Rc; use std::slice; +use arrayvec::ArrayVec; +use smallvec::{smallvec, SmallVec}; + use rustc_macros::{Decodable, Encodable}; +use crate::{Idx, IndexVec}; + use Chunk::*; #[cfg(test)] diff --git a/compiler/rustc_index/src/idx.rs b/compiler/rustc_index/src/idx.rs new file mode 100644 index 00000000000..b85160540d8 --- /dev/null +++ b/compiler/rustc_index/src/idx.rs @@ -0,0 +1,45 @@ +use std::fmt::Debug; +use std::hash::Hash; + +/// Represents some newtyped `usize` wrapper. +/// +/// Purpose: avoid mixing indexes for different bitvector domains. +pub trait Idx: Copy + 'static + Eq + PartialEq + Debug + Hash { + fn new(idx: usize) -> Self; + + fn index(self) -> usize; + + #[inline] + fn increment_by(&mut self, amount: usize) { + *self = self.plus(amount); + } + + #[inline] + #[must_use = "Use `increment_by` if you wanted to update the index in-place"] + fn plus(self, amount: usize) -> Self { + Self::new(self.index() + amount) + } +} + +impl Idx for usize { + #[inline] + fn new(idx: usize) -> Self { + idx + } + #[inline] + fn index(self) -> usize { + self + } +} + +impl Idx for u32 { + #[inline] + fn new(idx: usize) -> Self { + assert!(idx <= u32::MAX as usize); + idx as u32 + } + #[inline] + fn index(self) -> usize { + self as usize + } +} diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs index d809740c6ab..7ed4860c274 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -3,10 +3,11 @@ use std::marker::PhantomData; use std::ops::RangeBounds; use std::ops::{Bound, Range}; -use crate::vec::Idx; -use crate::vec::IndexVec; use smallvec::SmallVec; +use crate::idx::Idx; +use crate::vec::IndexVec; + #[cfg(test)] mod tests; @@ -261,8 +262,7 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> { } fn ensure_row(&mut self, row: R) -> &mut IntervalSet<C> { - self.rows.ensure_contains_elem(row, || IntervalSet::new(self.column_size)); - &mut self.rows[row] + self.rows.ensure_contains_elem(row, || IntervalSet::new(self.column_size)) } pub fn union_row(&mut self, row: R, from: &IntervalSet<C>) -> bool diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index db2c7915256..6fd9f34b29e 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -17,7 +17,12 @@ pub mod bit_set; #[cfg(feature = "nightly")] pub mod interval; -pub mod vec; + +mod idx; +mod slice; +mod vec; + +pub use {idx::Idx, slice::IndexSlice, vec::IndexVec}; #[cfg(feature = "rustc_macros")] pub use rustc_macros::newtype_index; diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs new file mode 100644 index 00000000000..0663c7247de --- /dev/null +++ b/compiler/rustc_index/src/slice.rs @@ -0,0 +1,256 @@ +use std::{ + fmt, + marker::PhantomData, + ops::{Index, IndexMut}, + slice, +}; + +use crate::{Idx, IndexVec}; + +/// A view into contiguous `T`s, indexed by `I` rather than by `usize`. +/// +/// One common pattern you'll see is code that uses [`IndexVec::from_elem`] +/// to create the storage needed for a particular "universe" (aka the set of all +/// the possible keys that need an associated value) then passes that working +/// area as `&mut IndexSlice<I, T>` to clarify that nothing will be added nor +/// removed during processing (and, as a bonus, to chase fewer pointers). +#[derive(PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct IndexSlice<I: Idx, T> { + _marker: PhantomData<fn(&I)>, + pub raw: [T], +} + +impl<I: Idx, T> IndexSlice<I, T> { + #[inline] + pub const fn empty() -> &'static Self { + Self::from_raw(&[]) + } + + #[inline] + pub const fn from_raw(raw: &[T]) -> &Self { + let ptr: *const [T] = raw; + // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice + unsafe { &*(ptr as *const Self) } + } + + #[inline] + pub fn from_raw_mut(raw: &mut [T]) -> &mut Self { + let ptr: *mut [T] = raw; + // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice + unsafe { &mut *(ptr as *mut Self) } + } + + #[inline] + pub const fn len(&self) -> usize { + self.raw.len() + } + + #[inline] + pub const fn is_empty(&self) -> bool { + self.raw.is_empty() + } + + /// Gives the next index that will be assigned when `push` is called. + /// + /// Manual bounds checks can be done using `idx < slice.next_index()` + /// (as opposed to `idx.index() < slice.len()`). + #[inline] + pub fn next_index(&self) -> I { + I::new(self.len()) + } + + #[inline] + pub fn iter(&self) -> slice::Iter<'_, T> { + self.raw.iter() + } + + #[inline] + pub fn iter_enumerated( + &self, + ) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator + '_ { + self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) + } + + #[inline] + pub fn indices( + &self, + ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static { + (0..self.len()).map(|n| I::new(n)) + } + + #[inline] + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { + self.raw.iter_mut() + } + + #[inline] + pub fn iter_enumerated_mut( + &mut self, + ) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator + '_ { + self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) + } + + #[inline] + pub fn last_index(&self) -> Option<I> { + self.len().checked_sub(1).map(I::new) + } + + #[inline] + pub fn swap(&mut self, a: I, b: I) { + self.raw.swap(a.index(), b.index()) + } + + #[inline] + pub fn get(&self, index: I) -> Option<&T> { + self.raw.get(index.index()) + } + + #[inline] + pub fn get_mut(&mut self, index: I) -> Option<&mut T> { + self.raw.get_mut(index.index()) + } + + /// Returns mutable references to two distinct elements, `a` and `b`. + /// + /// Panics if `a == b`. + #[inline] + pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { + let (ai, bi) = (a.index(), b.index()); + assert!(ai != bi); + + if ai < bi { + let (c1, c2) = self.raw.split_at_mut(bi); + (&mut c1[ai], &mut c2[0]) + } else { + let (c2, c1) = self.pick2_mut(b, a); + (c1, c2) + } + } + + /// Returns mutable references to three distinct elements. + /// + /// Panics if the elements are not distinct. + #[inline] + pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) { + let (ai, bi, ci) = (a.index(), b.index(), c.index()); + assert!(ai != bi && bi != ci && ci != ai); + let len = self.raw.len(); + assert!(ai < len && bi < len && ci < len); + let ptr = self.raw.as_mut_ptr(); + unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } + } + + #[inline] + pub fn binary_search(&self, value: &T) -> Result<I, I> + where + T: Ord, + { + match self.raw.binary_search(value) { + Ok(i) => Ok(Idx::new(i)), + Err(i) => Err(Idx::new(i)), + } + } +} + +impl<I: Idx, J: Idx> IndexSlice<I, J> { + /// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`, + /// assuming the values in `self` are a permutation of `0..self.len()`. + /// + /// This is used to go between `memory_index` (source field order to memory order) + /// and `inverse_memory_index` (memory order to source field order). + /// See also `FieldsShape::Arbitrary::memory_index` for more details. + // FIXME(eddyb) build a better abstraction for permutations, if possible. + pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> { + debug_assert_eq!( + self.iter().map(|x| x.index() as u128).sum::<u128>(), + (0..self.len() as u128).sum::<u128>(), + "The values aren't 0..N in input {self:?}", + ); + + let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len()); + for (i1, &i2) in self.iter_enumerated() { + inverse[i2] = i1; + } + + debug_assert_eq!( + inverse.iter().map(|x| x.index() as u128).sum::<u128>(), + (0..inverse.len() as u128).sum::<u128>(), + "The values aren't 0..N in result {self:?}", + ); + + inverse + } +} + +impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) + } +} + +impl<I: Idx, T> Index<I> for IndexSlice<I, T> { + type Output = T; + + #[inline] + fn index(&self, index: I) -> &T { + &self.raw[index.index()] + } +} + +impl<I: Idx, T> IndexMut<I> for IndexSlice<I, T> { + #[inline] + fn index_mut(&mut self, index: I) -> &mut T { + &mut self.raw[index.index()] + } +} + +impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + + #[inline] + fn into_iter(self) -> slice::Iter<'a, T> { + self.raw.iter() + } +} + +impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + + #[inline] + fn into_iter(self) -> slice::IterMut<'a, T> { + self.raw.iter_mut() + } +} + +impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> { + type Owned = IndexVec<I, T>; + + fn to_owned(&self) -> IndexVec<I, T> { + IndexVec::from_raw(self.raw.to_owned()) + } + + fn clone_into(&self, target: &mut IndexVec<I, T>) { + self.raw.clone_into(&mut target.raw) + } +} + +impl<I: Idx, T> Default for &IndexSlice<I, T> { + #[inline] + fn default() -> Self { + IndexSlice::from_raw(Default::default()) + } +} + +impl<I: Idx, T> Default for &mut IndexSlice<I, T> { + #[inline] + fn default() -> Self { + IndexSlice::from_raw_mut(Default::default()) + } +} + +// Whether `IndexSlice` is `Send` depends only on the data, +// not the phantom data. +unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {} diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index ae2f52c513e..99e72e49f8e 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -3,55 +3,13 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::borrow::{Borrow, BorrowMut}; use std::fmt; -use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; -use std::ops::{Deref, DerefMut, Index, IndexMut, RangeBounds}; +use std::ops::{Deref, DerefMut, RangeBounds}; use std::slice; use std::vec; -/// Represents some newtyped `usize` wrapper. -/// -/// Purpose: avoid mixing indexes for different bitvector domains. -pub trait Idx: Copy + 'static + Eq + PartialEq + Debug + Hash { - fn new(idx: usize) -> Self; - - fn index(self) -> usize; - - #[inline] - fn increment_by(&mut self, amount: usize) { - *self = self.plus(amount); - } - - #[inline] - #[must_use = "Use `increment_by` if you wanted to update the index in-place"] - fn plus(self, amount: usize) -> Self { - Self::new(self.index() + amount) - } -} - -impl Idx for usize { - #[inline] - fn new(idx: usize) -> Self { - idx - } - #[inline] - fn index(self) -> usize { - self - } -} - -impl Idx for u32 { - #[inline] - fn new(idx: usize) -> Self { - assert!(idx <= u32::MAX as usize); - idx as u32 - } - #[inline] - fn index(self) -> usize { - self as usize - } -} +use crate::{Idx, IndexSlice}; /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. /// @@ -66,68 +24,20 @@ pub struct IndexVec<I: Idx, T> { _marker: PhantomData<fn(&I)>, } -/// A view into contiguous `T`s, indexed by `I` rather than by `usize`. -/// -/// One common pattern you'll see is code that uses [`IndexVec::from_elem`] -/// to create the storage needed for a particular "universe" (aka the set of all -/// the possible keys that need an associated value) then passes that working -/// area as `&mut IndexSlice<I, T>` to clarify that nothing will be added nor -/// removed during processing (and, as a bonus, to chase fewer pointers). -#[derive(PartialEq, Eq, Hash)] -#[repr(transparent)] -pub struct IndexSlice<I: Idx, T> { - _marker: PhantomData<fn(&I)>, - pub raw: [T], -} - -// Whether `IndexVec` is `Send` depends only on the data, -// not the phantom data. -unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {} - -// Whether `IndexSlice` is `Send` depends only on the data, -// not the phantom data. -unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {} - -#[cfg(feature = "rustc_serialize")] -impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> { - fn encode(&self, s: &mut S) { - Encodable::encode(&self.raw, s); - } -} - -#[cfg(feature = "rustc_serialize")] -impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> { - fn decode(d: &mut D) -> Self { - IndexVec { raw: Decodable::decode(d), _marker: PhantomData } - } -} - -impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.raw, fmt) - } -} - -impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.raw, fmt) - } -} - impl<I: Idx, T> IndexVec<I, T> { #[inline] - pub fn new() -> Self { - IndexVec { raw: Vec::new(), _marker: PhantomData } + pub const fn new() -> Self { + IndexVec::from_raw(Vec::new()) } #[inline] - pub fn from_raw(raw: Vec<T>) -> Self { + pub const fn from_raw(raw: Vec<T>) -> Self { IndexVec { raw, _marker: PhantomData } } #[inline] pub fn with_capacity(capacity: usize) -> Self { - IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } + IndexVec::from_raw(Vec::with_capacity(capacity)) } /// Creates a new vector with a copy of `elem` for each index in `universe`. @@ -146,7 +56,7 @@ impl<I: Idx, T> IndexVec<I, T> { where T: Clone, { - IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } + IndexVec::from_raw(vec![elem; universe.len()]) } #[inline] @@ -154,7 +64,7 @@ impl<I: Idx, T> IndexVec<I, T> { where T: Clone, { - IndexVec { raw: vec![elem; n], _marker: PhantomData } + IndexVec::from_raw(vec![elem; n]) } /// Create an `IndexVec` with `n` elements, where the value of each @@ -162,8 +72,7 @@ impl<I: Idx, T> IndexVec<I, T> { /// be allocated only once, with a capacity of at least `n`.) #[inline] pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self { - let indices = (0..n).map(I::new); - Self::from_raw(indices.map(func).collect()) + IndexVec::from_raw((0..n).map(I::new).map(func).collect()) } #[inline] @@ -178,7 +87,7 @@ impl<I: Idx, T> IndexVec<I, T> { #[inline] pub fn push(&mut self, d: T) -> I { - let idx = I::new(self.len()); + let idx = self.next_index(); self.raw.push(d); idx } @@ -229,216 +138,37 @@ impl<I: Idx, T> IndexVec<I, T> { } pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> { - IndexVec { raw: self.raw, _marker: PhantomData } + IndexVec::from_raw(self.raw) } /// Grows the index vector so that it contains an entry for /// `elem`; if that is already true, then has no /// effect. Otherwise, inserts new values as needed by invoking /// `fill_value`. + /// + /// Returns a reference to the `elem` entry. #[inline] - pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -> &mut T { let min_new_len = elem.index() + 1; if self.len() < min_new_len { self.raw.resize_with(min_new_len, fill_value); } - } - - #[inline] - pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - self.raw.resize_with(min_new_len, fill_value); - } -} - -impl<I: Idx, T> Deref for IndexVec<I, T> { - type Target = IndexSlice<I, T>; - - #[inline] - fn deref(&self) -> &Self::Target { - self.as_slice() - } -} - -impl<I: Idx, T> DerefMut for IndexVec<I, T> { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut_slice() - } -} - -impl<I: Idx, T> Borrow<IndexSlice<I, T>> for IndexVec<I, T> { - fn borrow(&self) -> &IndexSlice<I, T> { - self - } -} - -impl<I: Idx, T> BorrowMut<IndexSlice<I, T>> for IndexVec<I, T> { - fn borrow_mut(&mut self) -> &mut IndexSlice<I, T> { - self - } -} - -impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> { - type Owned = IndexVec<I, T>; - - fn to_owned(&self) -> IndexVec<I, T> { - IndexVec::from_raw(self.raw.to_owned()) - } - - fn clone_into(&self, target: &mut IndexVec<I, T>) { - self.raw.clone_into(&mut target.raw) - } -} - -impl<I: Idx, T> IndexSlice<I, T> { - #[inline] - pub fn empty() -> &'static Self { - Default::default() - } - - #[inline] - pub fn from_raw(raw: &[T]) -> &Self { - let ptr: *const [T] = raw; - // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice - unsafe { &*(ptr as *const Self) } - } - - #[inline] - pub fn from_raw_mut(raw: &mut [T]) -> &mut Self { - let ptr: *mut [T] = raw; - // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice - unsafe { &mut *(ptr as *mut Self) } - } - - #[inline] - pub fn len(&self) -> usize { - self.raw.len() - } - - /// Gives the next index that will be assigned when `push` is called. - /// - /// Manual bounds checks can be done using `idx < slice.next_index()` - /// (as opposed to `idx.index() < slice.len()`). - #[inline] - pub fn next_index(&self) -> I { - I::new(self.len()) - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.raw.is_empty() - } - - #[inline] - pub fn iter(&self) -> slice::Iter<'_, T> { - self.raw.iter() - } - #[inline] - pub fn iter_enumerated( - &self, - ) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator + '_ { - self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) - } - - #[inline] - pub fn indices( - &self, - ) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static { - (0..self.len()).map(|n| I::new(n)) - } - - #[inline] - pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { - self.raw.iter_mut() + &mut self[elem] } #[inline] - pub fn iter_enumerated_mut( - &mut self, - ) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator + '_ { - self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) - } - - #[inline] - pub fn last_index(&self) -> Option<I> { - self.len().checked_sub(1).map(I::new) - } - - #[inline] - pub fn swap(&mut self, a: I, b: I) { - self.raw.swap(a.index(), b.index()) - } - - #[inline] - pub fn get(&self, index: I) -> Option<&T> { - self.raw.get(index.index()) - } - - #[inline] - pub fn get_mut(&mut self, index: I) -> Option<&mut T> { - self.raw.get_mut(index.index()) - } - - /// Returns mutable references to two distinct elements, `a` and `b`. - /// - /// Panics if `a == b`. - #[inline] - pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { - let (ai, bi) = (a.index(), b.index()); - assert!(ai != bi); - - if ai < bi { - let (c1, c2) = self.raw.split_at_mut(bi); - (&mut c1[ai], &mut c2[0]) - } else { - let (c2, c1) = self.pick2_mut(b, a); - (c1, c2) - } + pub fn resize(&mut self, new_len: usize, value: T) + where + T: Clone, + { + self.raw.resize(new_len, value) } - /// Returns mutable references to three distinct elements. - /// - /// Panics if the elements are not distinct. #[inline] - pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) { - let (ai, bi, ci) = (a.index(), b.index(), c.index()); - assert!(ai != bi && bi != ci && ci != ai); - let len = self.raw.len(); - assert!(ai < len && bi < len && ci < len); - let ptr = self.raw.as_mut_ptr(); - unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } - } -} - -impl<I: Idx, J: Idx> IndexSlice<I, J> { - /// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`, - /// assuming the values in `self` are a permutation of `0..self.len()`. - /// - /// This is used to go between `memory_index` (source field order to memory order) - /// and `inverse_memory_index` (memory order to source field order). - /// See also `FieldsShape::Arbitrary::memory_index` for more details. - // FIXME(eddyb) build a better abstraction for permutations, if possible. - pub fn invert_bijective_mapping(&self) -> IndexVec<J, I> { - debug_assert_eq!( - self.iter().map(|x| x.index() as u128).sum::<u128>(), - (0..self.len() as u128).sum::<u128>(), - "The values aren't 0..N in input {self:?}", - ); - - let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len()); - for (i1, &i2) in self.iter_enumerated() { - inverse[i2] = i1; - } - - debug_assert_eq!( - inverse.iter().map(|x| x.index() as u128).sum::<u128>(), - (0..inverse.len() as u128).sum::<u128>(), - "The values aren't 0..N in result {self:?}", - ); - - inverse + pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + self.raw.resize_with(min_new_len, fill_value); } } @@ -446,74 +176,51 @@ impl<I: Idx, J: Idx> IndexSlice<I, J> { impl<I: Idx, T> IndexVec<I, Option<T>> { #[inline] pub fn insert(&mut self, index: I, value: T) -> Option<T> { - self.ensure_contains_elem(index, || None); - self[index].replace(value) + self.ensure_contains_elem(index, || None).replace(value) } #[inline] pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T { - self.ensure_contains_elem(index, || None); - self[index].get_or_insert_with(value) + self.ensure_contains_elem(index, || None).get_or_insert_with(value) } #[inline] pub fn remove(&mut self, index: I) -> Option<T> { - self.ensure_contains_elem(index, || None); - self[index].take() - } -} - -impl<I: Idx, T: Clone> IndexVec<I, T> { - #[inline] - pub fn resize(&mut self, new_len: usize, value: T) { - self.raw.resize(new_len, value) + self.get_mut(index)?.take() } } -impl<I: Idx, T: Ord> IndexSlice<I, T> { - #[inline] - pub fn binary_search(&self, value: &T) -> Result<I, I> { - match self.raw.binary_search(value) { - Ok(i) => Ok(Idx::new(i)), - Err(i) => Err(Idx::new(i)), - } +impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) } } -impl<I: Idx, T> Index<I> for IndexSlice<I, T> { - type Output = T; - - #[inline] - fn index(&self, index: I) -> &T { - &self.raw[index.index()] - } -} +impl<I: Idx, T> Deref for IndexVec<I, T> { + type Target = IndexSlice<I, T>; -impl<I: Idx, T> IndexMut<I> for IndexSlice<I, T> { #[inline] - fn index_mut(&mut self, index: I) -> &mut T { - &mut self.raw[index.index()] + fn deref(&self) -> &Self::Target { + self.as_slice() } } -impl<I: Idx, T> Default for IndexVec<I, T> { +impl<I: Idx, T> DerefMut for IndexVec<I, T> { #[inline] - fn default() -> Self { - Self::new() + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() } } -impl<I: Idx, T> Default for &IndexSlice<I, T> { - #[inline] - fn default() -> Self { - IndexSlice::from_raw(Default::default()) +impl<I: Idx, T> Borrow<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow(&self) -> &IndexSlice<I, T> { + self } } -impl<I: Idx, T> Default for &mut IndexSlice<I, T> { - #[inline] - fn default() -> Self { - IndexSlice::from_raw_mut(Default::default()) +impl<I: Idx, T> BorrowMut<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow_mut(&mut self) -> &mut IndexSlice<I, T> { + self } } @@ -542,14 +249,7 @@ impl<I: Idx, T> FromIterator<T> for IndexVec<I, T> { where J: IntoIterator<Item = T>, { - IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } - } -} - -impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> { - #[inline] - fn from(array: [T; N]) -> Self { - IndexVec::from_raw(array.into()) + IndexVec::from_raw(Vec::from_iter(iter)) } } @@ -569,7 +269,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a IndexVec<I, T> { #[inline] fn into_iter(self) -> slice::Iter<'a, T> { - self.raw.iter() + self.iter() } } @@ -579,29 +279,41 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> { #[inline] fn into_iter(self) -> slice::IterMut<'a, T> { - self.raw.iter_mut() + self.iter_mut() } } -impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> { - type Item = &'a T; - type IntoIter = slice::Iter<'a, T>; +impl<I: Idx, T> Default for IndexVec<I, T> { + #[inline] + fn default() -> Self { + IndexVec::new() + } +} +impl<I: Idx, T, const N: usize> From<[T; N]> for IndexVec<I, T> { #[inline] - fn into_iter(self) -> slice::Iter<'a, T> { - self.raw.iter() + fn from(array: [T; N]) -> Self { + IndexVec::from_raw(array.into()) } } -impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> { - type Item = &'a mut T; - type IntoIter = slice::IterMut<'a, T>; +#[cfg(feature = "rustc_serialize")] +impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> { + fn encode(&self, s: &mut S) { + Encodable::encode(&self.raw, s); + } +} - #[inline] - fn into_iter(self) -> slice::IterMut<'a, T> { - self.raw.iter_mut() +#[cfg(feature = "rustc_serialize")] +impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> { + fn decode(d: &mut D) -> Self { + IndexVec::from_raw(Vec::<T>::decode(d)) } } +// Whether `IndexVec` is `Send` depends only on the data, +// not the phantom data. +unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {} + #[cfg(test)] mod tests; diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 02ac83a5e8b..9dd5868adc7 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -12,6 +12,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index c8998ea91bf..fdc4ff0896f 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -80,7 +80,7 @@ infer_subtype = ...so that the {$requirement -> [no_else] `if` missing an `else` returns `()` [fn_main_correct_type] `main` function has the correct type [fn_start_correct_type] `#[start]` function has the correct type - [intristic_correct_type] intrinsic has the correct type + [intrinsic_correct_type] intrinsic has the correct type [method_correct_type] method receiver has the correct type *[other] types are compatible } @@ -93,7 +93,7 @@ infer_subtype_2 = ...so that {$requirement -> [no_else] `if` missing an `else` returns `()` [fn_main_correct_type] `main` function has the correct type [fn_start_correct_type] `#[start]` function has the correct type - [intristic_correct_type] intrinsic has the correct type + [intrinsic_correct_type] intrinsic has the correct type [method_correct_type] method receiver has the correct type *[other] types are compatible } @@ -341,8 +341,8 @@ infer_await_note = calling an async function returns a future infer_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here... infer_prlf_defined_without_sub = the lifetime defined here... -infer_prlf_must_oultive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here -infer_prlf_must_oultive_without_sup = ...must outlive the lifetime defined here +infer_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here +infer_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here infer_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information) infer_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds @@ -380,7 +380,7 @@ infer_oc_no_else = `if` may be missing an `else` clause infer_oc_no_diverge = `else` clause of `let...else` does not diverge infer_oc_fn_main_correct_type = `main` function has wrong type infer_oc_fn_start_correct_type = `#[start]` function has wrong type -infer_oc_intristic_correct_type = intrinsic has wrong type +infer_oc_intrinsic_correct_type = intrinsic has wrong type infer_oc_method_correct_type = mismatched `self` parameter type infer_oc_closure_selfref = closure/generator type that references itself infer_oc_cant_coerce = cannot coerce intrinsics to function pointers diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 65b3dd1a892..b1e819e83f1 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -71,7 +71,7 @@ pub struct AmbiguousImpl<'a> { // Copy of `AnnotationRequired` for E0284 #[derive(Diagnostic)] #[diag(infer_type_annotations_needed, code = "E0284")] -pub struct AmbigousReturn<'a> { +pub struct AmbiguousReturn<'a> { #[primary_span] pub span: Span, pub source_kind: &'static str, @@ -1085,7 +1085,7 @@ pub enum PlaceholderRelationLfNotSatisfied { span: Span, #[note(infer_prlf_defined_with_sub)] sub_span: Span, - #[note(infer_prlf_must_oultive_with_sup)] + #[note(infer_prlf_must_outlive_with_sup)] sup_span: Span, sub_symbol: Symbol, sup_symbol: Symbol, @@ -1098,7 +1098,7 @@ pub enum PlaceholderRelationLfNotSatisfied { span: Span, #[note(infer_prlf_defined_with_sub)] sub_span: Span, - #[note(infer_prlf_must_oultive_without_sup)] + #[note(infer_prlf_must_outlive_without_sup)] sup_span: Span, sub_symbol: Symbol, #[note(infer_prlf_known_limitation)] @@ -1110,7 +1110,7 @@ pub enum PlaceholderRelationLfNotSatisfied { span: Span, #[note(infer_prlf_defined_without_sub)] sub_span: Span, - #[note(infer_prlf_must_oultive_with_sup)] + #[note(infer_prlf_must_outlive_with_sup)] sup_span: Span, sup_symbol: Symbol, #[note(infer_prlf_known_limitation)] @@ -1122,7 +1122,7 @@ pub enum PlaceholderRelationLfNotSatisfied { span: Span, #[note(infer_prlf_defined_without_sub)] sub_span: Span, - #[note(infer_prlf_must_oultive_without_sup)] + #[note(infer_prlf_must_outlive_without_sup)] sup_span: Span, #[note(infer_prlf_known_limitation)] note: (), @@ -1488,8 +1488,8 @@ pub enum ObligationCauseFailureCode { #[subdiagnostic] subdiags: Vec<TypeErrorAdditionalDiags>, }, - #[diag(infer_oc_intristic_correct_type, code = "E0308")] - IntristicCorrectType { + #[diag(infer_oc_intrinsic_correct_type, code = "E0308")] + IntrinsicCorrectType { #[primary_span] span: Span, #[subdiagnostic] diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index e808911a38b..e6e1bc0393f 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, use std::sync::atomic::Ordering; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::Idx; +use rustc_index::Idx; use smallvec::SmallVec; impl<'tcx> InferCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index fbb2257bf67..2abdd5b0aec 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -23,7 +23,7 @@ use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::{self, List, TyCtxt}; diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index e98f68ae5a8..3605e10fecd 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -19,8 +19,8 @@ use crate::traits::query::{Fallible, NoSolution}; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt}; use rustc_data_structures::captures::Captures; -use rustc_index::vec::Idx; -use rustc_index::vec::IndexVec; +use rustc_index::Idx; +use rustc_index::IndexVec; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::fold::TypeFoldable; @@ -467,11 +467,11 @@ impl<'tcx> InferCtxt<'tcx> { } } GenericArgKind::Const(result_value) => { - if let ty::ConstKind::Bound(debrujin, b) = result_value.kind() { + if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() { // ...in which case we would set `canonical_vars[0]` to `Some(const X)`. // We only allow a `ty::INNERMOST` index in substitutions. - assert_eq!(debrujin, ty::INNERMOST); + assert_eq!(debruijn, ty::INNERMOST); opt_values[b] = Some(*original_value); } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index fe45b5ebe61..9b670c76a18 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -832,7 +832,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should - /// be used if control over the obligaton causes is required. + /// be used if control over the obligation causes is required. fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>); /// Register an obligation that both constants must be equal to each other. diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index fe4a2dd3800..f90f7674b55 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -178,7 +178,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { where T: Relate<'tcx>, { - // A binder is equal to itself if it's structually equal to itself + // A binder is equal to itself if it's structurally equal to itself if a == b { return Ok(a); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 9e5f6d107d1..547f851526f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -74,7 +74,6 @@ use rustc_middle::ty::{ self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; -use rustc_span::DUMMY_SP; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; use std::ops::{ControlFlow, Deref}; @@ -138,7 +137,7 @@ impl Drop for TypeErrCtxt<'_, '_> { self.infcx .tcx .sess - .delay_span_bug(DUMMY_SP, "used a `TypeErrCtxt` without failing compilation"); + .delay_good_path_bug("used a `TypeErrCtxt` without raising an error or lint"); } } } @@ -403,7 +402,7 @@ impl<'tcx> InferCtxt<'tcx> { let future_trait = self.tcx.require_lang_item(LangItem::Future, None); let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0]; - self.tcx.bound_explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( + self.tcx.explicit_item_bounds(def_id).subst_iter_copied(self.tcx, substs).find_map( |(predicate, _)| { predicate .kind() @@ -1927,6 +1926,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { { let span = self.tcx.def_span(def_id); diag.span_note(span, "this closure does not fulfill the lifetime requirements"); + self.suggest_for_all_lifetime_closure(span, self.tcx.hir().get_by_def_id(def_id), &exp_found, diag); } // It reads better to have the error origin as the final @@ -2885,7 +2885,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> { LetElse => ObligationCauseFailureCode::NoDiverge { span, subdiags }, MainFunctionType => ObligationCauseFailureCode::FnMainCorrectType { span }, StartFunctionType => ObligationCauseFailureCode::FnStartCorrectType { span, subdiags }, - IntrinsicType => ObligationCauseFailureCode::IntristicCorrectType { span, subdiags }, + IntrinsicType => ObligationCauseFailureCode::IntrinsicCorrectType { span, subdiags }, MethodReceiver => ObligationCauseFailureCode::MethodCorrectType { span, subdiags }, // In the case where we have no more specific thing to @@ -2942,7 +2942,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> { IfExpressionWithNoElse => "no_else", MainFunctionType => "fn_main_correct_type", StartFunctionType => "fn_start_correct_type", - IntrinsicType => "intristic_correct_type", + IntrinsicType => "intrinsic_correct_type", MethodReceiver => "method_correct_type", _ => "other", } diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 75cc4e257bd..58e3159a4e2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -1,5 +1,5 @@ use crate::errors::{ - AmbigousReturn, AmbiguousImpl, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator, + AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator, SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::error_reporting::TypeErrCtxt; @@ -368,7 +368,7 @@ impl<'tcx> InferCtxt<'tcx> { bad_label, } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), - TypeAnnotationNeeded::E0284 => AmbigousReturn { + TypeAnnotationNeeded::E0284 => AmbiguousReturn { span, source_kind, source_name, @@ -573,7 +573,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { bad_label: None, } .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic), - TypeAnnotationNeeded::E0284 => AmbigousReturn { + TypeAnnotationNeeded::E0284 => AmbiguousReturn { span, source_kind, source_name: &name, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 22c1e387117..27c3b796d14 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -312,13 +312,10 @@ pub fn suggest_new_region_bound( Applicability::MaybeIncorrect, ); } - } else if opaque.bounds.iter().any(|arg| match arg { - GenericBound::Outlives(Lifetime { ident, .. }) - if ident.name.to_string() == lifetime_name => - { - true - } - _ => false, + } else if opaque.bounds.iter().any(|arg| { + matches!(arg, + GenericBound::Outlives(Lifetime { ident, .. }) + if ident.name.to_string() == lifetime_name ) }) { } else { // get a lifetime name of existing named lifetimes if any diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 2875448ee15..ce70bcc5c85 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor; use rustc_middle::hir::nested_filter; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::RegionHighlightMode; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; use rustc_span::Span; use std::ops::ControlFlow; @@ -81,7 +81,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { self.highlight.highlighting_region(r, self.counter); self.counter += 1; } - r.super_visit_with(self) + ControlFlow::Continue(()) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b38bbdfe7bb..e410172c8c8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -462,10 +462,7 @@ fn foo(&self) -> Self::T { String::new() } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() { let opaque_local_def_id = def_id.as_local(); let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { - match &tcx.hir().expect_item(opaque_local_def_id).kind { - hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty, - _ => bug!("The HirId comes from a `ty::Opaque`"), - } + tcx.hir().expect_item(opaque_local_def_id).expect_opaque_ty() } else { return false; }; diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index b5aeca12a1f..d885d040707 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -1,16 +1,15 @@ use hir::def::CtorKind; use hir::intravisit::{walk_expr, walk_stmt, Visitor}; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::Diagnostic; +use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_middle::traits::{ IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, StatementAsExpression, }; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self as ty, GenericArgKind, IsSuggestable, Ty, TypeVisitableExt}; use rustc_span::{sym, BytePos, Span}; -use rustc_target::abi::FieldIdx; use crate::errors::{ ConsiderAddingAwait, FnConsiderCasting, FnItemsAreDistinct, FnUniqTypes, @@ -114,7 +113,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) }) .filter_map(|variant| { - let sole_field = &variant.fields[FieldIdx::from_u32(0)]; + let sole_field = &variant.single_field(); let sole_field_ty = sole_field.ty(self.tcx, substs); if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { let variant_path = @@ -536,6 +535,82 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } None } + + /// For "one type is more general than the other" errors on closures, suggest changing the lifetime + /// of the parameters to accept all lifetimes. + pub(super) fn suggest_for_all_lifetime_closure( + &self, + span: Span, + hir: hir::Node<'_>, + exp_found: &ty::error::ExpectedFound<ty::PolyTraitRef<'tcx>>, + diag: &mut Diagnostic, + ) { + // 0. Extract fn_decl from hir + let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(hir::Closure { body, fn_decl, .. }), .. }) = hir else { return; }; + let hir::Body { params, .. } = self.tcx.hir().body(*body); + + // 1. Get the substs of the closure. + // 2. Assume exp_found is FnOnce / FnMut / Fn, we can extract function parameters from [1]. + let Some(expected) = exp_found.expected.skip_binder().substs.get(1) else { return; }; + let Some(found) = exp_found.found.skip_binder().substs.get(1) else { return; }; + let expected = expected.unpack(); + let found = found.unpack(); + // 3. Extract the tuple type from Fn trait and suggest the change. + if let GenericArgKind::Type(expected) = expected && + let GenericArgKind::Type(found) = found && + let ty::Tuple(expected) = expected.kind() && + let ty::Tuple(found)= found.kind() && + expected.len() == found.len() { + let mut suggestion = "|".to_string(); + let mut is_first = true; + let mut has_suggestion = false; + + for (((expected, found), param_hir), arg_hir) in expected.iter() + .zip(found.iter()) + .zip(params.iter()) + .zip(fn_decl.inputs.iter()) { + if is_first { + is_first = false; + } else { + suggestion += ", "; + } + + if let ty::Ref(expected_region, _, _) = expected.kind() && + let ty::Ref(found_region, _, _) = found.kind() && + expected_region.is_late_bound() && + !found_region.is_late_bound() && + let hir::TyKind::Infer = arg_hir.kind { + // If the expected region is late bound, the found region is not, and users are asking compiler + // to infer the type, we can suggest adding `: &_`. + if param_hir.pat.span == param_hir.ty_span { + // for `|x|`, `|_|`, `|x: impl Foo|` + let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; + suggestion += &format!("{}: &_", pat); + } else { + // for `|x: ty|`, `|_: ty|` + let Ok(pat) = self.tcx.sess.source_map().span_to_snippet(param_hir.pat.span) else { return; }; + let Ok(ty) = self.tcx.sess.source_map().span_to_snippet(param_hir.ty_span) else { return; }; + suggestion += &format!("{}: &{}", pat, ty); + } + has_suggestion = true; + } else { + let Ok(arg) = self.tcx.sess.source_map().span_to_snippet(param_hir.span) else { return; }; + // Otherwise, keep it as-is. + suggestion += &arg; + } + } + suggestion += "|"; + + if has_suggestion { + diag.span_suggestion_verbose( + span, + "consider specifying the type of the closure parameters", + suggestion, + Applicability::MaybeIncorrect, + ); + } + } + } } impl<'tcx> TypeErrCtxt<'_, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index a63cfbc919c..c304cd25c9c 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -42,7 +42,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> { // Next, we instantiate each bound region in the subtype // with a fresh region variable. These region variables -- - // but no other pre-existing region variables -- can name + // but no other preexisting region variables -- can name // the placeholders. let sub_prime = self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index f298b95ca35..bd1bfed3a0c 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::intern::Interned; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -131,10 +131,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.dump_constraints(); } - let graph = self.construct_graph(); self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); - self.collect_var_errors(&var_data, &graph, errors); + self.collect_var_errors(&var_data, errors); var_data } @@ -622,7 +621,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn collect_var_errors( &self, var_data: &LexicalRegionResolutions<'tcx>, - graph: &RegionGraph<'tcx>, errors: &mut Vec<RegionResolutionError<'tcx>>, ) { debug!("collect_var_errors, var_data = {:#?}", var_data.values); @@ -640,6 +638,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // overlapping locations. let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars()); + // Only construct the graph when necessary, because it's moderately + // expensive. + let mut graph = None; + for (node_vid, value) in var_data.values.iter_enumerated() { match *value { VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ } @@ -672,7 +674,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // influence the constraints on this value for // richer diagnostics in `static_impl_trait`. - self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors); + let g = graph.get_or_insert_with(|| self.construct_graph()); + self.collect_error_for_expanding_node(g, &mut dup_vec, node_vid, errors); } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 66f51328bbe..1cd09cde0fc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1228,11 +1228,11 @@ impl<'tcx> InferCtxt<'tcx> { /// hence that `resolve_regions_and_report_errors` can never be /// called. This is used only during NLL processing to "hand off" ownership /// of the set of region variables into the NLL region context. - pub fn take_region_var_origins(&self) -> VarInfos { + pub fn get_region_var_origins(&self) -> VarInfos { let mut inner = self.inner.borrow_mut(); let (var_infos, data) = inner .region_constraint_storage - .take() + .clone() .expect("regions already resolved") .with_log(&mut inner.undo_log) .into_infos_and_data(); @@ -1500,7 +1500,7 @@ impl<'tcx> InferCtxt<'tcx> { Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)), Ok(None) => { let tcx = self.tcx; - let def_id = unevaluated.def.did; + let def_id = unevaluated.def; span_bug!( tcx.def_span(def_id), "unable to construct a constant value for the unevaluated constant {:?}", @@ -1547,8 +1547,8 @@ impl<'tcx> InferCtxt<'tcx> { substs = replace_param_and_infer_substs_with_placeholder(tcx, substs); } } else { - substs = InternalSubsts::identity_for_item(tcx, unevaluated.def.did); - param_env = tcx.param_env(unevaluated.def.did); + substs = InternalSubsts::identity_for_item(tcx, unevaluated.def); + param_env = tcx.param_env(unevaluated.def); } } @@ -1577,10 +1577,10 @@ impl<'tcx> InferCtxt<'tcx> { (TyOrConstInferVar::Ty(ty_var), Ok(inner)) => { use self::type_variable::TypeVariableValue; - match inner.try_type_variables_probe_ref(ty_var) { - Some(TypeVariableValue::Unknown { .. }) => true, - _ => false, - } + matches!( + inner.try_type_variables_probe_ref(ty_var), + Some(TypeVariableValue::Unknown { .. }) + ) } _ => false, }; diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 3a0a0494a7e..334395945ea 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -392,12 +392,7 @@ impl<'tcx> InferCtxt<'tcx> { /// defining scope. #[instrument(skip(self), level = "trace", ret)] fn opaque_type_origin_unchecked(&self, def_id: LocalDefId) -> OpaqueTyOrigin { - match self.tcx.hir().expect_item(def_id).kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin, - ref itemkind => { - bug!("weird opaque type: {:?}, {:#?}", def_id, itemkind) - } - } + self.tcx.hir().expect_item(def_id).expect_opaque_ty().origin } } @@ -545,7 +540,7 @@ impl<'tcx> InferCtxt<'tcx> { .obligations; } - let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id()); + let item_bounds = tcx.explicit_item_bounds(def_id); for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) { let predicate = predicate.fold_with(&mut BottomUpFolder { diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index ff23087fe8d..cb63d2f18b6 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -143,7 +143,7 @@ fn compute_components<'tcx>( // through and constrain Pi. let mut subcomponents = smallvec![]; let mut subvisited = SsoHashSet::new(); - compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited); + compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } } @@ -193,7 +193,43 @@ fn compute_components<'tcx>( /// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. -pub(super) fn compute_components_recursive<'tcx>( +pub(super) fn compute_alias_components_recursive<'tcx>( + tcx: TyCtxt<'tcx>, + alias_ty: Ty<'tcx>, + out: &mut SmallVec<[Component<'tcx>; 4]>, + visited: &mut SsoHashSet<GenericArg<'tcx>>, +) { + let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; + let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; + for (index, child) in alias_ty.substs.iter().enumerate() { + if opt_variances.get(index) == Some(&ty::Bivariant) { + continue; + } + if !visited.insert(child) { + continue; + } + match child.unpack() { + GenericArgKind::Type(ty) => { + compute_components(tcx, ty, out, visited); + } + GenericArgKind::Lifetime(lt) => { + // Ignore late-bound regions. + if !lt.is_late_bound() { + out.push(Component::Region(lt)); + } + } + GenericArgKind::Const(_) => { + compute_components_recursive(tcx, child, out, visited); + } + } + } +} + +/// Collect [Component]s for *all* the substs of `parent`. +/// +/// This should not be used to get the components of `parent` itself. +/// Use [push_outlives_components] instead. +fn compute_components_recursive<'tcx>( tcx: TyCtxt<'tcx>, parent: GenericArg<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>, diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 9a9a1696b00..8a44d503159 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -61,7 +61,7 @@ impl<'tcx> InferCtxt<'tcx> { }; let lexical_region_resolutions = LexicalRegionResolutions { - values: rustc_index::vec::IndexVec::from_elem_n( + values: rustc_index::IndexVec::from_elem_n( crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased), var_infos.len(), ), diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index ccf11c61b57..2f5e2e417a6 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -344,12 +344,14 @@ where // the problem is to add `T: 'r`, which isn't true. So, if there are no // inference variables, we use a verify constraint instead of adding // edges, which winds up enforcing the same condition. + let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque; if approx_env_bounds.is_empty() && trait_bounds.is_empty() - && (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque) + && (alias_ty.needs_infer() || is_opaque) { debug!("no declared bounds"); - self.substs_must_outlive(alias_ty.substs, origin, region); + let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id)); + self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances); return; } @@ -395,22 +397,31 @@ where self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound); } + #[instrument(level = "debug", skip(self))] fn substs_must_outlive( &mut self, substs: SubstsRef<'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, + opt_variances: Option<&[ty::Variance]>, ) { let constraint = origin.to_constraint_category(); - for k in substs { + for (index, k) in substs.iter().enumerate() { match k.unpack() { GenericArgKind::Lifetime(lt) => { - self.delegate.push_sub_region_constraint( - origin.clone(), - region, - lt, - constraint, - ); + let variance = if let Some(variances) = opt_variances { + variances[index] + } else { + ty::Invariant + }; + if variance == ty::Invariant { + self.delegate.push_sub_region_constraint( + origin.clone(), + region, + lt, + constraint, + ); + } } GenericArgKind::Type(ty) => { self.type_must_outlive(origin.clone(), ty, region, constraint); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index bae246418b0..e1cb53bc71d 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,4 +1,4 @@ -use crate::infer::outlives::components::{compute_components_recursive, Component}; +use crate::infer::outlives::components::{compute_alias_components_recursive, Component}; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::VerifyBound; @@ -130,7 +130,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; - compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited); + compute_alias_components_recursive( + self.tcx, + alias_ty_as_ty.into(), + &mut components, + visited, + ); self.bound_from_components(&components, visited) }; diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index b8ba98fc0a9..89cfc9ea3d1 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -5,7 +5,7 @@ use rustc_data_structures::{ graph::{scc::Sccs, vec_graph::VecGraph}, undo_log::UndoLogs, }; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::RelateResult; diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 7b272dfd2a4..6692cd1d389 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -12,7 +12,7 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; use rustc_data_structures::unify as ut; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::infer::unify_key::{RegionVidKey, UnifiedRegion}; use rustc_middle::ty::ReStatic; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 0dd73a6e999..3766c250a9c 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -210,7 +210,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { where T: Relate<'tcx>, { - // A binder is always a subtype of itself if it's structually equal to itself + // A binder is always a subtype of itself if it's structurally equal to itself if a == b { return Ok(a); } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 738a1237651..e92ba05aa67 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -35,7 +35,7 @@ extern crate tracing; extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod errors; pub mod infer; diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index e01b6caf430..8ce8b4e2024 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -89,10 +89,10 @@ impl<'tcx> PredicateObligation<'tcx> { impl<'tcx> TraitObligation<'tcx> { /// Returns `true` if the trait predicate is considered `const` in its ParamEnv. pub fn is_const(&self) -> bool { - match (self.predicate.skip_binder().constness, self.param_env.constness()) { - (ty::BoundConstness::ConstIfConst, hir::Constness::Const) => true, - _ => false, - } + matches!( + (self.predicate.skip_binder().constness, self.param_env.constness()), + (ty::BoundConstness::ConstIfConst, hir::Constness::Const) + ) } pub fn derived_cause( @@ -123,7 +123,7 @@ pub struct FulfillmentError<'tcx> { #[derive(Clone)] pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only if it is already implemented. - CodeCycle(Vec<Obligation<'tcx, ty::Predicate<'tcx>>>), + CodeCycle(Vec<PredicateObligation<'tcx>>), CodeSelectionError(SelectionError<'tcx>), CodeProjectionError(MismatchedProjectionTypes<'tcx>), CodeSubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index ac455055b43..8d0af738dd1 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -103,7 +103,7 @@ pub enum ProjectionCacheEntry<'tcx> { /// if this field is set. Evaluation only /// cares about the final result, so we don't /// care about any region constraint side-effects - /// produced by evaluating the sub-boligations. + /// produced by evaluating the sub-obligations. /// /// Additionally, we will clear out the sub-obligations /// entirely if we ever evaluate the cache entry (along diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 98d3ab87f9c..41a0254df18 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -10,12 +10,12 @@ libloading = "0.7.1" tracing = "0.1" rustc-rayon-core = { version = "0.5.0", optional = true } rustc-rayon = { version = "0.5.0", optional = true } -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_expand = { path = "../rustc_expand" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_macros = { path = "../rustc_macros" } rustc_parse = { path = "../rustc_parse" } diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 9664ba8bd8a..51bd8381e93 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -13,7 +13,7 @@ extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod callbacks; mod errors; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 0e4e20c7cd1..61923db9623 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -761,27 +761,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // passes are timed inside typeck rustc_hir_analysis::check_crate(tcx)?; - sess.time("misc_checking_2", || { - parallel!( - { - sess.time("match_checking", || { - tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id)) - }); - }, - { - sess.time("liveness_checking", || { - tcx.hir().par_body_owners(|def_id| { - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? - tcx.ensure().check_liveness(def_id.to_def_id()); - }); - }); - } - ); - }); - sess.time("MIR_borrow_checking", || { tcx.hir().par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); }); @@ -794,9 +773,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { } tcx.ensure().has_ffi_unwind_calls(def_id); - if tcx.hir().body_const_context(def_id).is_some() { - tcx.ensure() - .mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id)); + // If we need to codegen, ensure that we emit all errors from + // `mir_drops_elaborated_and_const_checked` now, to avoid discovering + // them later during codegen. + if tcx.sess.opts.output_types.should_codegen() + || tcx.hir().body_const_context(def_id).is_some() + { + tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); + tcx.ensure().unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id())); } } }); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 10dfd32d418..7b0b5102c2d 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -747,7 +747,7 @@ fn test_unstable_options_tracking_hash() { tracked!(emit_thin_lto, false); tracked!(export_executable_symbols, true); tracked!(fewer_names, Some(true)); - tracked!(flatten_format_args, true); + tracked!(flatten_format_args, false); tracked!(force_unstable_if_unmarked, true); tracked!(fuel, Some(("abc".to_string(), 99))); tracked!(function_sections, Some(false)); @@ -768,6 +768,7 @@ fn test_unstable_options_tracking_hash() { tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); + tracked!(mir_keep_place_mention, true); tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index abe61406c21..539eea3d816 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index db15b176df0..3d1b8f8ed95 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -445,7 +445,7 @@ lint_builtin_incomplete_features = the feature `{$name}` is incomplete and may n .help = consider using `min_{$name}` instead, which is more stable and complete lint_builtin_unpermitted_type_init_zeroed = the type `{$ty}` does not permit zero-initialization -lint_builtin_unpermitted_type_init_unint = the type `{$ty}` does not permit being left uninitialized +lint_builtin_unpermitted_type_init_uninit = the type `{$ty}` does not permit being left uninitialized lint_builtin_unpermitted_type_init_label = this code causes undefined behavior when executed lint_builtin_unpermitted_type_init_label_suggestion = help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6b387df785e..aeb791901bd 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -22,7 +22,7 @@ use crate::fluent_generated as fluent; use crate::{ - errors::BuiltinEllpisisInclusiveRangePatterns, + errors::BuiltinEllipsisInclusiveRangePatterns, lints::{ BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinClashingExtern, BuiltinClashingExternSub, BuiltinConstNoMangle, BuiltinDeprecatedAttrLink, @@ -166,10 +166,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]); impl BoxPointers { fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { - if leaf_ty.is_box() { - cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); - } + if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() { + cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); } } } @@ -1711,13 +1709,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } } - let (parenthesise, endpoints) = match &pat.kind { + let (parentheses, endpoints) = match &pat.kind { PatKind::Ref(subpat, _) => (true, matches_ellipsis_pat(&subpat)), _ => (false, matches_ellipsis_pat(pat)), }; if let Some((start, end, join)) = endpoints { - if parenthesise { + if parentheses { self.node_id = Some(pat.id); let end = expr_to_string(&end); let replace = match start { @@ -1725,7 +1723,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { None => format!("&(..={})", end), }; if join.edition() >= Edition::Edition2021 { - cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + cx.sess().emit_err(BuiltinEllipsisInclusiveRangePatterns { span: pat.span, suggestion: pat.span, replace, @@ -1743,7 +1741,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { } else { let replace = "..="; if join.edition() >= Edition::Edition2021 { - cx.sess().emit_err(BuiltinEllpisisInclusiveRangePatterns { + cx.sess().emit_err(BuiltinEllipsisInclusiveRangePatterns { span: pat.span, suggestion: join, replace: replace.to_string(), @@ -2560,7 +2558,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { .subst(cx.tcx, substs) .apply_any_module(cx.tcx, cx.param_env) { - // Entirely skip uninhbaited variants. + // Entirely skip uninhabited variants. Some(false) => return None, // Forward the others, but remember which ones are definitely inhabited. Some(true) => true, @@ -2628,7 +2626,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { if let Some(err) = with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { let msg = match init { InitKind::Zeroed => fluent::lint_builtin_unpermitted_type_init_zeroed, - InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_unint, + InitKind::Uninit => fluent::lint_builtin_unpermitted_type_init_uninit, }; let sub = BuiltinUnpermittedTypeInitSub { err }; cx.emit_spanned_lint( diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index 9af5284df1e..bbae3d368f4 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -81,7 +81,7 @@ pub struct UnknownToolInScopedLint { #[derive(Diagnostic)] #[diag(lint_builtin_ellipsis_inclusive_range_patterns, code = "E0783")] -pub struct BuiltinEllpisisInclusiveRangePatterns { +pub struct BuiltinEllipsisInclusiveRangePatterns { #[primary_span] pub span: Span, #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")] diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index bb863f09516..a43c09a7939 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -14,7 +14,7 @@ use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b3578540516..76f07257907 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -82,9 +82,9 @@ pub use array_into_iter::ARRAY_INTO_ITER; use rustc_ast as ast; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_macros::fluent_messages; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 9efc14849c7..79253cbc8b4 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -33,6 +33,11 @@ pub fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext } } +fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool { + let item = cx.tcx.associated_item(ii.owner_id); + item.trait_item_def_id.is_some() +} + declare_lint! { /// The `non_camel_case_types` lint detects types, variants, traits and /// type parameters that don't have camel case names. @@ -177,6 +182,7 @@ impl EarlyLintPass for NonCamelCaseTypes { // trait impls where we should have warned for the trait definition already. ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => { for it in items { + // FIXME: this doesn't respect `#[allow(..)]` on the item itself. if let ast::AssocItemKind::Type(..) = it.kind { self.check_case(cx, "associated type", &it.ident); } @@ -505,7 +511,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { } fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) { - if let hir::ImplItemKind::Const(..) = ii.kind { + if let hir::ImplItemKind::Const(..) = ii.kind && !assoc_item_in_trait_impl(cx, ii) { NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident); } } diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index f9d43fe2200..15715c8fca0 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // For every projection predicate in the opaque type's explicit bounds, // check that the type that we're assigning actually satisfies the bounds // of the associated type. - for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) { + for (pred, pred_span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { // Liberate bound regions in the predicate since we // don't actually care about lifetimes in this check. let predicate = cx.tcx.liberate_late_bound_regions(def_id, pred.kind()); @@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // with `impl Send: OtherTrait`. for (assoc_pred, assoc_pred_span) in cx .tcx - .bound_explicit_item_bounds(proj.projection_ty.def_id) + .explicit_item_bounds(proj.projection_ty.def_id) .subst_iter_copied(cx.tcx, &proj.projection_ty.substs) { let assoc_pred = assoc_pred.fold_with(proj_replacer); diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 1159d11e5c0..eb175e96997 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -254,7 +254,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { - elaborate(cx.tcx, cx.tcx.explicit_item_bounds(def).iter().cloned()) + elaborate(cx.tcx, cx.tcx.explicit_item_bounds(def).subst_identity_iter_copied()) // We only care about self bounds for the impl-trait .filter_only_self() .find_map(|(pred, _span)| { @@ -569,36 +569,50 @@ trait UnusedDelimLint { } } - // Prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }` - let lhs_needs_parens = { + // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`. + { let mut innermost = inner; loop { innermost = match &innermost.kind { - ExprKind::Binary(_, lhs, _rhs) => lhs, + ExprKind::Binary(_op, lhs, _rhs) => lhs, ExprKind::Call(fn_, _params) => fn_, ExprKind::Cast(expr, _ty) => expr, ExprKind::Type(expr, _ty) => expr, ExprKind::Index(base, _subscript) => base, - _ => break false, + _ => break, }; if !classify::expr_requires_semi_to_be_stmt(innermost) { - break true; + return true; } } - }; + } - lhs_needs_parens - || (followed_by_block - && match &inner.kind { - ExprKind::Ret(_) - | ExprKind::Break(..) - | ExprKind::Yield(..) - | ExprKind::Yeet(..) => true, - ExprKind::Range(_lhs, Some(rhs), _limits) => { - matches!(rhs.kind, ExprKind::Block(..)) - } - _ => parser::contains_exterior_struct_lit(&inner), - }) + // Check if RHS needs parens to prevent false-positives in cases like `if (() == return) {}`. + if !followed_by_block { + return false; + } + let mut innermost = inner; + loop { + innermost = match &innermost.kind { + ExprKind::Unary(_op, expr) => expr, + ExprKind::Binary(_op, _lhs, rhs) => rhs, + ExprKind::AssignOp(_op, _lhs, rhs) => rhs, + ExprKind::Assign(_lhs, rhs, _span) => rhs, + + ExprKind::Ret(_) | ExprKind::Yield(..) | ExprKind::Yeet(..) => return true, + + ExprKind::Break(_label, None) => return false, + ExprKind::Break(_label, Some(break_expr)) => { + return matches!(break_expr.kind, ExprKind::Block(..)); + } + + ExprKind::Range(_lhs, Some(rhs), _limits) => { + return matches!(rhs.kind, ExprKind::Block(..)); + } + + _ => return parser::contains_exterior_struct_lit(&inner), + } + } } fn emit_unused_delims_expr( @@ -636,20 +650,14 @@ trait UnusedDelimLint { return; } let spans = match value.kind { - ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => { - if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) { - Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))) - } else { - None - } - } + ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => block.stmts[0] + .span + .find_ancestor_inside(value.span) + .map(|span| (value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))), ast::ExprKind::Paren(ref expr) => { - let expr_span = expr.span.find_ancestor_inside(value.span); - if let Some(expr_span) = expr_span { - Some((value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi()))) - } else { - None - } + expr.span.find_ancestor_inside(value.span).map(|expr_span| { + (value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi())) + }) } _ => return, }; @@ -928,11 +936,10 @@ impl UnusedParens { // Otherwise proceed with linting. _ => {} } - let spans = if let Some(inner) = inner.span.find_ancestor_inside(value.span) { - Some((value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi()))) - } else { - None - }; + let spans = inner + .span + .find_ancestor_inside(value.span) + .map(|inner| (value.span.with_hi(inner.lo()), value.span.with_lo(inner.hi()))); self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space); } } @@ -1043,11 +1050,11 @@ impl EarlyLintPass for UnusedParens { if self.with_self_ty_parens && b.generic_params.len() > 0 => {} ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} _ => { - let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) { - Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))) - } else { - None - }; + let spans = r + .span + .find_ancestor_inside(ty.span) + .map(|r| (ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi()))); + self.emit_unused_delims(cx, ty.span, spans, "type", (false, false)); } } diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9d6ab0b75df..b223b8c137a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1021,7 +1021,7 @@ declare_lint! { declare_lint! { /// The `invalid_alignment` lint detects dereferences of misaligned pointers during - /// constant evluation. + /// constant evaluation. /// /// ### Example /// @@ -1854,7 +1854,7 @@ declare_lint! { /// When new methods are added to traits in the standard library, they are /// usually added in an "unstable" form which is only available on the /// [nightly channel] with a [`feature` attribute]. If there is any - /// pre-existing code which extends a trait to have a method with the same + /// preexisting code which extends a trait to have a method with the same /// name, then the names will collide. In the future, when the method is /// stabilized, this will cause an error due to the ambiguity. This lint /// is an early-warning to let you know that there may be a collision in diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp index 448a1f62f69..35d6b9ed7a4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp @@ -39,6 +39,7 @@ enum class LLVMRustArchiveKind { BSD, DARWIN, COFF, + AIX_BIG, }; static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { @@ -51,6 +52,8 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { return Archive::K_DARWIN; case LLVMRustArchiveKind::COFF: return Archive::K_COFF; + case LLVMRustArchiveKind::AIX_BIG: + return Archive::K_AIXBIG; default: report_fatal_error("Bad ArchiveKind."); } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 08e38b0c9d5..1acdc95ca8d 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -310,12 +310,14 @@ static size_t getLongestEntryLength(ArrayRef<KV> Table) { extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) { const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch(); + const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable(); unsigned MaxCPULen = getLongestEntryLength(CPUTable); printf("Available CPUs for this target:\n"); + // Don't print the "native" entry when the user specifies --target with a + // different arch since that could be wrong or misleading. if (HostArch == TargetArch) { const StringRef HostCPU = sys::getHostCPUName(); printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", @@ -408,10 +410,15 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( } Options.RelaxELFRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; + +#if LLVM_VERSION_LT(17, 0) if (ForceEmulatedTls) { Options.ExplicitEmulatedTLS = true; Options.EmulatedTLS = true; } +#else + Options.EmulatedTLS = ForceEmulatedTls || Trip.hasDefaultEmulatedTLS(); +#endif if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction. @@ -523,14 +530,14 @@ extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmS extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) { - if (any_isa<const Module *>(WrappedIr)) - return any_cast<const Module *>(WrappedIr)->getName().str(); - if (any_isa<const Function *>(WrappedIr)) - return any_cast<const Function *>(WrappedIr)->getName().str(); - if (any_isa<const Loop *>(WrappedIr)) - return any_cast<const Loop *>(WrappedIr)->getName().str(); - if (any_isa<const LazyCallGraph::SCC *>(WrappedIr)) - return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName(); + if (const auto *Cast = any_cast<const Module *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Function *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Loop *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const LazyCallGraph::SCC *>(&WrappedIr)) + return (*Cast)->getName(); return "<UNKNOWN>"; } @@ -811,7 +818,7 @@ LLVMRustOptimize( ModulePassManager MPM; bool NeedThinLTOBufferPasses = UseThinLTOBuffers; if (!NoPrepopulatePasses) { - // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead. + // The pre-link pipelines don't support O0 and require using buildO0DefaultPipeline() instead. // At the same time, the LTO pipelines do support O0 and using them is required. bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO; if (OptLevel == OptimizationLevel::O0 && !IsLTO) { diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index 745983e7e86..1f1201b0035 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -7,11 +7,7 @@ edition = "2021" proc-macro = true [dependencies] -annotate-snippets = "0.9" -fluent-bundle = "0.15.2" -fluent-syntax = "0.11" synstructure = "0.13.0" syn = { version = "2", features = ["full"] } proc-macro2 = "1" quote = "1" -unic-langid = { version = "0.9.0", features = ["macros"] } diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 78df0cd1d34..bd84681cbb4 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -1,12 +1,10 @@ mod diagnostic; mod diagnostic_builder; mod error; -mod fluent; mod subdiagnostic; mod utils; use diagnostic::{DiagnosticDerive, LintDiagnosticDerive}; -pub(crate) use fluent::fluent_messages; use proc_macro2::TokenStream; use quote::format_ident; use subdiagnostic::SubdiagnosticDeriveBuilder; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 737500cc257..904f8eb5731 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -54,60 +54,6 @@ pub fn newtype_index(input: TokenStream) -> TokenStream { newtype::newtype(input) } -/// Implements the `fluent_messages` macro, which performs compile-time validation of the -/// compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same -/// messages) and generates constants that make using those messages in diagnostics more ergonomic. -/// -/// For example, given the following invocation of the macro.. -/// -/// ```ignore (rust) -/// fluent_messages! { "./typeck.ftl" } -/// ``` -/// ..where `typeck.ftl` has the following contents.. -/// -/// ```fluent -/// typeck_field_multiply_specified_in_initializer = -/// field `{$ident}` specified more than once -/// .label = used more than once -/// .label_previous_use = first use of `{$ident}` -/// ``` -/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and -/// will generate the following code: -/// -/// ```ignore (rust) -/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); -/// -/// mod fluent_generated { -/// mod typeck { -/// pub const field_multiply_specified_in_initializer: DiagnosticMessage = -/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer"); -/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage = -/// DiagnosticMessage::fluent_attr( -/// "typeck_field_multiply_specified_in_initializer", -/// "previous_use_label" -/// ); -/// } -/// } -/// ``` -/// When emitting a diagnostic, the generated constants can be used as follows: -/// -/// ```ignore (rust) -/// let mut err = sess.struct_span_err( -/// span, -/// fluent::typeck::field_multiply_specified_in_initializer -/// ); -/// err.span_default_label(span); -/// err.span_label( -/// previous_use_span, -/// fluent::typeck::field_multiply_specified_in_initializer_label_previous_use -/// ); -/// err.emit(); -/// ``` -#[proc_macro] -pub fn fluent_messages(input: TokenStream) -> TokenStream { - diagnostics::fluent_messages(input) -} - decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index 78a6f74887d..415a89b0f92 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -254,7 +254,7 @@ impl Parse for Newtype { } } - impl rustc_index::vec::Idx for #name { + impl rustc_index::Idx for #name { #[inline] fn new(value: usize) -> Self { Self::from_usize(value) diff --git a/compiler/rustc_macros/src/query.rs b/compiler/rustc_macros/src/query.rs index f85ba38003c..a8b25ff66d7 100644 --- a/compiler/rustc_macros/src/query.rs +++ b/compiler/rustc_macros/src/query.rs @@ -112,9 +112,6 @@ struct QueryModifiers { /// Use a separate query provider for local and extern crates separate_provide_extern: Option<Ident>, - /// Always remap the ParamEnv's constness before hashing. - remap_env_constness: Option<Ident>, - /// Generate a `feed` method to set the query's value from another query. feedable: Option<Ident>, } @@ -130,7 +127,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { let mut eval_always = None; let mut depth_limit = None; let mut separate_provide_extern = None; - let mut remap_env_constness = None; let mut feedable = None; while !input.is_empty() { @@ -189,8 +185,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { try_insert!(depth_limit = modifier); } else if modifier == "separate_provide_extern" { try_insert!(separate_provide_extern = modifier); - } else if modifier == "remap_env_constness" { - try_insert!(remap_env_constness = modifier); } else if modifier == "feedable" { try_insert!(feedable = modifier); } else { @@ -211,7 +205,6 @@ fn parse_query_modifiers(input: ParseStream<'_>) -> Result<QueryModifiers> { eval_always, depth_limit, separate_provide_extern, - remap_env_constness, feedable, }) } @@ -332,7 +325,6 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { eval_always, depth_limit, separate_provide_extern, - remap_env_constness, ); if modifiers.cache.is_some() { diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 4d7c133e09b..840111c31b4 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -11,13 +11,13 @@ libloading = "0.7.1" odht = { version = "0.3.1", features = ["nightly"] } snap = "1" tracing = "0.1" -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tempfile = "3.2" rustc_middle = { path = "../rustc_middle" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 23aceca0622..179453238f2 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -12,7 +12,7 @@ use rustc_data_structures::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, use rustc_expand::base::SyntaxExtension; use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, ExternLocation}; use rustc_session::cstore::ExternCrateSource; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 81e62eccb8a..9f664d0f0c8 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -28,7 +28,7 @@ extern crate tracing; pub use rmeta::{provide, provide_extern}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod dependency_format; mod foreign_modules; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2930ce75028..a310cbb8029 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -16,14 +16,14 @@ use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::diagnostic_items::DiagnosticItems; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::GeneratorDiagnosticData; -use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility}; +use rustc_middle::ty::{self, ParameterizedOverTcx, Predicate, Ty, TyCtxt, Visibility}; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; use rustc_session::cstore::{ @@ -117,7 +117,7 @@ pub(crate) struct CrateMetadata { /// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext` /// and `ExpnId`). - /// Note that we store a `HygieneDecodeContext` for each `CrateMetadat`. This is + /// Note that we store a `HygieneDecodeContext` for each `CrateMetadata`. This is /// because `SyntaxContext` ids are not globally unique, so we need /// to track which ids we've decoded on a per-crate basis. hygiene_context: HygieneDecodeContext, @@ -373,16 +373,6 @@ impl<'a, 'tcx> TyDecoder for DecodeContext<'a, 'tcx> { self.tcx() } - #[inline] - fn peek_byte(&self) -> u8 { - self.opaque.data[self.opaque.position()] - } - - #[inline] - fn position(&self) -> usize { - self.opaque.position() - } - fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx> where F: FnOnce(&mut Self) -> Ty<'tcx>, @@ -404,7 +394,7 @@ impl<'a, 'tcx> TyDecoder for DecodeContext<'a, 'tcx> { where F: FnOnce(&mut Self) -> R, { - let new_opaque = MemDecoder::new(self.opaque.data, pos); + let new_opaque = MemDecoder::new(self.opaque.data(), pos); let old_opaque = mem::replace(&mut self.opaque, new_opaque); let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode); let r = f(self); @@ -625,17 +615,12 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol { SYMBOL_OFFSET => { // read str offset let pos = d.read_usize(); - let old_pos = d.opaque.position(); - // move to str ofset and read - d.opaque.set_position(pos); - let s = d.read_str(); - let sym = Symbol::intern(s); - - // restore position - d.opaque.set_position(old_pos); - - sym + // move to str offset and read + d.opaque.with_position(pos, |d| { + let s = d.read_str(); + Symbol::intern(s) + }) } SYMBOL_PREINTERNED => { let symbol_index = d.read_u32(); @@ -857,6 +842,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) } + fn get_explicit_item_bounds( + self, + index: DefIndex, + tcx: TyCtxt<'tcx>, + ) -> ty::EarlyBinder<&'tcx [(Predicate<'tcx>, Span)]> { + let lazy = self.root.tables.explicit_item_bounds.get(self, index); + let output = if lazy.is_default() { + &mut [] + } else { + tcx.arena.alloc_from_iter(lazy.decode((self, tcx))) + }; + ty::EarlyBinder(&*output) + } + fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef { let adt_kind = match kind { DefKind::Variant => ty::AdtKind::Enum, @@ -876,16 +875,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { variant_did, ctor, data.discr, - self.root - .tables - .children - .get(self, index) - .expect("fields are not encoded for a variant") - .decode(self) - .map(|index| ty::FieldDef { - did: self.local_def_id(index), - name: self.item_name(index), - vis: self.get_visibility(index), + self.get_associated_item_or_field_def_ids(index) + .map(|did| ty::FieldDef { + did, + name: self.item_name(did.index), + vis: self.get_visibility(did.index), }) .collect(), adt_kind, @@ -910,7 +904,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let variants = if let ty::AdtKind::Enum = adt_kind { self.root .tables - .children + .module_children_non_reexports .get(self, item_id) .expect("variants are not encoded for an enum") .decode(self) @@ -998,9 +992,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let ident = self.item_ident(id, sess); let res = Res::Def(self.def_kind(id), self.local_def_id(id)); let vis = self.get_visibility(id); - let span = self.get_span(id, sess); - ModChild { ident, res, vis, span, reexport_chain: Default::default() } + ModChild { ident, res, vis, reexport_chain: Default::default() } } /// Iterates over all named children of the given module, @@ -1023,11 +1016,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } else { // Iterate over all children. - for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) { - // FIXME: Do not encode RPITITs as a part of this list. - if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() { - yield self.get_mod_child(child_index, sess); - } + let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); + for child_index in non_reexports.unwrap().decode(self) { + yield self.get_mod_child(child_index, sess); } let reexports = self.root.tables.module_children_reexports.get(self, id); @@ -1059,17 +1050,16 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .map_or(false, |ident| ident.name == kw::SelfLower) } - fn get_associated_item_def_ids( + fn get_associated_item_or_field_def_ids( self, id: DefIndex, - sess: &'a Session, ) -> impl Iterator<Item = DefId> + 'a { self.root .tables - .children + .associated_item_or_field_def_ids .get(self, id) - .expect("associated items not encoded for an item") - .decode((self, sess)) + .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id)) + .decode(self) .map(move |child_index| self.local_def_id(child_index)) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 31798afb852..4a3b783c636 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -203,7 +203,7 @@ impl IntoArgs for (CrateNum, SimplifiedType) { } provide! { tcx, def_id, other, cdata, - explicit_item_bounds => { table_defaulted_array } + explicit_item_bounds => { cdata.get_explicit_item_bounds(def_id.index, tcx) } explicit_predicates_of => { table } generics_of => { table } inferred_outlives_of => { table_defaulted_array } @@ -276,7 +276,7 @@ provide! { tcx, def_id, other, cdata, tcx.calculate_dtor(def_id, |_,_| Ok(())) } associated_item_def_ids => { - tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess)) + tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) } associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } @@ -516,14 +516,6 @@ impl CStore { self.get_crate_data(def.krate).get_ctor(def.index) } - pub fn module_children_untracked<'a>( - &'a self, - def_id: DefId, - sess: &'a Session, - ) -> impl Iterator<Item = ModChild> + 'a { - self.get_crate_data(def_id.krate).get_module_children(def_id.index, sess) - } - pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { let _prof_timer = sess.prof.generic_activity("metadata_load_macro"); diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 02cab561b8f..05402a58701 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -45,9 +45,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefPathHashMapRef<'tcx> { impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> { fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> { - // Import TyDecoder so we can access the DecodeContext::position() method - use crate::rustc_middle::ty::codec::TyDecoder; - let len = d.read_usize(); let pos = d.position(); let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 657b903e0a8..f5ffdd27cae 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -7,7 +7,7 @@ use rustc_ast::Attribute; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::{Mmap, MmapMut}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator}; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_hir as hir; @@ -531,7 +531,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { adapted.name_hash = { let mut hasher: StableHasher = StableHasher::new(); adapted.name.hash(&mut hasher); - hasher.finish::<u128>() + hasher.finish::<Hash128>() }; Lrc::new(adapted) } else { @@ -823,6 +823,8 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::TraitAlias | DefKind::AssocTy | DefKind::TyParam + | DefKind::ConstParam + | DefKind::LifetimeParam | DefKind::Fn | DefKind::Const | DefKind::Static(_) @@ -830,6 +832,8 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::AssocFn | DefKind::AssocConst | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use | DefKind::AnonConst | DefKind::InlineConst | DefKind::OpaqueTy @@ -837,13 +841,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => true, - DefKind::ConstParam - | DefKind::ExternCrate - | DefKind::Use - | DefKind::ForeignMod - | DefKind::ImplTraitPlaceholder - | DefKind::LifetimeParam - | DefKind::GlobalAsm => false, + DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false, } } @@ -1367,7 +1365,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if adt_def.is_enum() { let module_children = tcx.module_children_non_reexports(local_def_id); - record_array!(self.tables.children[def_id] <- + record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|def_id| def_id.local_def_index)); } else { // For non-enum, there is only one variant, and its def_id is the adt's. @@ -1385,7 +1383,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.variant_data[variant.def_id] <- data); self.tables.constness.set_some(variant.def_id.index, hir::Constness::Const); - record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| { + record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index })); @@ -1415,7 +1413,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { let non_reexports = tcx.module_children_non_reexports(local_def_id); - record_array!(self.tables.children[def_id] <- + record_array!(self.tables.module_children_non_reexports[def_id] <- non_reexports.iter().map(|def_id| def_id.local_def_index)); record_defaulted_array!(self.tables.module_children_reexports[def_id] <- @@ -1425,7 +1423,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_explicit_item_bounds(&mut self, def_id: DefId) { debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id); - let bounds = self.tcx.explicit_item_bounds(def_id); + let bounds = self.tcx.explicit_item_bounds(def_id).skip_binder(); record_defaulted_array!(self.tables.explicit_item_bounds[def_id] <- bounds); } @@ -1469,8 +1467,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match impl_item.kind { ty::AssocKind::Fn => { - let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local()); - let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() }; + let (sig, body) = + self.tcx.hir().expect_impl_item(def_id.expect_local()).expect_fn(); self.tables.asyncness.set_some(def_id.index, sig.header.asyncness); record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); // Can be inside `impl const Trait`, so using sig.header.constness is not reliable @@ -1539,8 +1537,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); - let instance = - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id())); + let instance = ty::InstanceDef::Item(def_id.to_def_id()); let unused = tcx.unused_generic_params(instance); self.tables.unused_generic_params.set(def_id.local_def_index, unused); } @@ -1618,7 +1615,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_info_for_item({:?})", def_id); let record_associated_item_def_ids = |this: &mut Self, def_ids: &[DefId]| { - record_array!(this.tables.children[def_id] <- def_ids.iter().map(|&def_id| { + record_array!(this.tables.associated_item_or_field_def_ids[def_id] <- def_ids.iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index })) @@ -1679,6 +1676,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Trait(..) => { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + let module_children = tcx.module_children_non_reexports(item.owner_id.def_id); + record_array!(self.tables.module_children_non_reexports[def_id] <- + module_children.iter().map(|def_id| def_id.local_def_index)); + let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record_associated_item_def_ids(self, associated_item_def_ids); for &item_def_id in associated_item_def_ids { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index dc77a079b07..dd02463e16a 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -14,7 +14,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}; use rustc_hir::definitions::DefKey; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; @@ -361,7 +361,8 @@ define_tables! { - optional: attributes: Table<DefIndex, LazyArray<ast::Attribute>>, - children: Table<DefIndex, LazyArray<DefIndex>>, + module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>, + associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>, opt_def_kind: Table<DefIndex, DefKind>, visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>, def_span: Table<DefIndex, LazyValue<Span>>, @@ -416,7 +417,7 @@ define_tables! { macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>, proc_macro: Table<DefIndex, MacroKind>, deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>, - trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>, + trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, ty::EarlyBinder<Ty<'static>>>>>, doc_link_resolutions: Table<DefIndex, LazyValue<DocLinkResMap>>, doc_link_traits_in_scope: Table<DefIndex, LazyArray<DefId>>, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 364fa74ab7b..dda30bce2c0 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -2,7 +2,7 @@ use crate::rmeta::*; use rustc_data_structures::fingerprint::Fingerprint; use rustc_hir::def::{CtorKind, CtorOf}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::ty::{ParameterizedOverTcx, UnusedGenericParams}; use rustc_serialize::opaque::FileEncoder; use rustc_serialize::Encoder as _; @@ -413,8 +413,8 @@ impl<I: Idx, const N: usize, T: FixedSizeEncoding<ByteArray = [u8; N]>> TableBui // > Space requirements could perhaps be optimized by using the HAMT `popcnt` // > trick (i.e. divide things into buckets of 32 or 64 items and then // > store bit-masks of which item in each bucket is actually serialized). - self.blocks.ensure_contains_elem(i, || [0; N]); - value.write_to_bytes(&mut self.blocks[i]); + let block = self.blocks.ensure_contains_elem(i, || [0; N]); + value.write_to_bytes(block); } } diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 5b2ec9029b1..dfbe8ac0ba3 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -21,6 +21,7 @@ rustc_errors = { path = "../rustc_errors" } # Used for intra-doc links rustc_error_messages = { path = "../rustc_error_messages" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index dd1e254f405..6a1a2a061dd 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -17,13 +17,13 @@ macro_rules! arena_types { [decode] mir: rustc_middle::mir::Body<'tcx>, [] steal_promoted: rustc_data_structures::steal::Steal< - rustc_index::vec::IndexVec< + rustc_index::IndexVec< rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> > >, [decode] promoted: - rustc_index::vec::IndexVec< + rustc_index::IndexVec< rustc_middle::mir::Promoted, rustc_middle::mir::Body<'tcx> >, @@ -114,7 +114,11 @@ macro_rules! arena_types { [] dep_kind: rustc_middle::dep_graph::DepKindStruct<'tcx>, - [decode] trait_impl_trait_tys: rustc_data_structures::fx::FxHashMap<rustc_hir::def_id::DefId, rustc_middle::ty::Ty<'tcx>>, + [decode] trait_impl_trait_tys: + rustc_data_structures::fx::FxHashMap< + rustc_hir::def_id::DefId, + rustc_middle::ty::EarlyBinder<rustc_middle::ty::Ty<'tcx>> + >, [] bit_set_u32: rustc_index::bit_set::BitSet<u32>, [] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>, [decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap, diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 865bb70afb5..2dc5b896993 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -357,20 +357,20 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { Fingerprint::new( // `owner` is local, so is completely defined by the local hash def_path_hash.local_hash(), - local_id.as_u32().into(), + local_id.as_u32() as u64, ) } #[inline(always)] fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { let HirId { owner, local_id } = *self; - format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32()) + format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32()) } #[inline(always)] fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { - let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value(); + let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split(); let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash); let def_id = tcx .def_path_hash_to_def_id(def_path_hash, &mut || { @@ -378,6 +378,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { }) .expect_local(); let local_id = local_id + .as_u64() .try_into() .unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id)); Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) }) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e551c76f8db..15d672c1408 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -11,7 +11,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::*; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1199,7 +1199,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { stable_hasher.finish() }); - Svh::new(crate_hash.to_smaller_hash()) + Svh::new(crate_hash) } fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { @@ -1217,7 +1217,7 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { } fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id.to_def_id()); + let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index b5b712c367d..c4e41e00520 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -348,14 +348,6 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> { } } -impl<'tcx, R> Canonical<'tcx, ty::ParamEnvAnd<'tcx, R>> { - #[inline] - pub fn without_const(mut self) -> Self { - self.value = self.value.without_const(); - self - } -} - impl<'tcx, V> Canonical<'tcx, V> { /// Allows you to map the `value` of a canonical while keeping the /// same set of bound variables. @@ -400,10 +392,8 @@ pub type QueryOutlivesConstraint<'tcx> = (ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>); TrivialTypeTraversalAndLiftImpls! { - for <'tcx> { - crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalTyVarKind, - } + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalTyVarKind, } impl<'tcx> CanonicalVarValues<'tcx> { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index b4edb02f6c4..e9172e767e0 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -59,6 +59,8 @@ #![feature(result_option_inspect)] #![feature(const_option)] #![feature(trait_alias)] +#![feature(ptr_alignment_type)] +#![feature(macro_metavar_expr)] #![recursion_limit = "512"] #![allow(rustc::potential_query_instability)] @@ -74,7 +76,7 @@ extern crate tracing; extern crate smallvec; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; #[cfg(test)] mod tests; @@ -99,13 +101,9 @@ pub mod mir; pub mod thir; pub mod traits; pub mod ty; +pub mod util; mod values; -pub mod util { - pub mod bug; - pub mod common; -} - // Allows macros to refer to this crate as `::rustc_middle` extern crate self as rustc_middle; diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 89014f62d4d..cd1c6c330bc 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -43,34 +43,26 @@ macro_rules! span_bug { #[macro_export] macro_rules! CloneLiftImpls { - (for <$tcx:lifetime> { $($ty:ty,)+ }) => { + ($($ty:ty,)+) => { $( - impl<$tcx> $crate::ty::Lift<$tcx> for $ty { + impl<'tcx> $crate::ty::Lift<'tcx> for $ty { type Lifted = Self; - fn lift_to_tcx(self, _: $crate::ty::TyCtxt<$tcx>) -> Option<Self> { + fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> { Some(self) } } )+ }; - - ($($ty:ty,)+) => { - CloneLiftImpls! { - for <'tcx> { - $($ty,)+ - } - } - }; } /// Used for types that are `Copy` and which **do not care arena /// allocated data** (i.e., don't need to be folded). #[macro_export] macro_rules! TrivialTypeTraversalImpls { - (for <$tcx:lifetime> { $($ty:ty,)+ }) => { + ($($ty:ty,)+) => { $( - impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { - fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<$tcx>>>( + impl<'tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<'tcx>> for $ty { + fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<'tcx>>>( self, _: &mut F, ) -> ::std::result::Result<Self, F::Error> { @@ -78,7 +70,7 @@ macro_rules! TrivialTypeTraversalImpls { } #[inline] - fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<$tcx>>>( + fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<'tcx>>>( self, _: &mut F, ) -> Self { @@ -86,9 +78,9 @@ macro_rules! TrivialTypeTraversalImpls { } } - impl<$tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty { + impl<'tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<'tcx>> for $ty { #[inline] - fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<$tcx>>>( + fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<'tcx>>>( &self, _: &mut F) -> ::std::ops::ControlFlow<F::BreakTy> @@ -98,14 +90,6 @@ macro_rules! TrivialTypeTraversalImpls { } )+ }; - - ($($ty:ty,)+) => { - TrivialTypeTraversalImpls! { - for<'tcx> { - $($ty,)+ - } - } - }; } #[macro_export] diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index f3170e0ec0e..674402cb4bf 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -4,7 +4,6 @@ use rustc_hir::def::Res; use rustc_macros::HashStable; use rustc_span::def_id::DefId; use rustc_span::symbol::Ident; -use rustc_span::Span; use smallvec::SmallVec; /// A simplified version of `ImportKind` from resolve. @@ -41,8 +40,6 @@ pub struct ModChild { pub res: Res<!>, /// Visibility of the item. pub vis: ty::Visibility<DefId>, - /// Span of the item. - pub span: Span, /// Reexport chain linking this module child to its original reexported item. /// Empty if the module child is a proper item. pub reexport_chain: SmallVec<[Reexport; 2]>, diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index c0c0fd07b6e..9041da9a060 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -72,6 +72,6 @@ pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String { format!( "rust_metadata_{}_{:08x}", tcx.crate_name(LOCAL_CRATE), - tcx.sess.local_stable_crate_id().to_u64(), + tcx.sess.local_stable_crate_id(), ) } diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index 3fb46837935..1319ddbb877 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -6,7 +6,7 @@ use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::OnceCell; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs index cf6d46e1e2c..2de73db3a3c 100644 --- a/compiler/rustc_middle/src/mir/graphviz.rs +++ b/compiler/rustc_middle/src/mir/graphviz.rs @@ -16,19 +16,16 @@ where { let def_ids = dump_mir_def_ids(tcx, single); - let mirs = - def_ids - .iter() - .flat_map(|def_id| { - if tcx.is_const_fn_raw(*def_id) { - vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)] - } else { - vec![tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - *def_id, - )))] - } - }) - .collect::<Vec<_>>(); + let mirs = def_ids + .iter() + .flat_map(|def_id| { + if tcx.is_const_fn_raw(*def_id) { + vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)] + } else { + vec![tcx.instance_mir(ty::InstanceDef::Item(*def_id))] + } + }) + .collect::<Vec<_>>(); let use_subgraphs = mirs.len() > 1; if use_subgraphs { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index dcb56a1755e..d4dd56a42c1 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -5,7 +5,9 @@ use std::hash; use std::iter; use std::ops::Range; +use rustc_serialize::{Decodable, Encodable}; use rustc_target::abi::Size; +use rustc_type_ir::{TyDecoder, TyEncoder}; use super::AllocRange; @@ -182,11 +184,39 @@ impl InitMask { /// The actual materialized blocks of the bitmask, when we can't keep the `InitMask` lazy. // Note: for performance reasons when interning, some of the fields can be partially // hashed. (see the `Hash` impl below for more details), so the impl is not derived. -#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, HashStable)] +#[derive(Clone, Debug, Eq, PartialEq, HashStable)] struct InitMaskMaterialized { blocks: Vec<Block>, } +// `Block` is a `u64`, but it is a bitmask not a numeric value. If we were to just derive +// Encodable and Decodable we would apply varint encoding to the bitmasks, which is slower +// and also produces more output when the high bits of each `u64` are occupied. +// Note: There is probably a remaining optimization for masks that do not use an entire +// `Block`. +impl<E: TyEncoder> Encodable<E> for InitMaskMaterialized { + fn encode(&self, encoder: &mut E) { + encoder.emit_usize(self.blocks.len()); + for block in &self.blocks { + encoder.emit_raw_bytes(&block.to_le_bytes()); + } + } +} + +// This implementation is deliberately not derived, see the matching `Encodable` impl. +impl<D: TyDecoder> Decodable<D> for InitMaskMaterialized { + fn decode(decoder: &mut D) -> Self { + let num_blocks = decoder.read_usize(); + let mut blocks = Vec::with_capacity(num_blocks); + for _ in 0..num_blocks { + let bytes = decoder.read_raw_bytes(8); + let block = u64::from_le_bytes(bytes.try_into().unwrap()); + blocks.push(block); + } + InitMaskMaterialized { blocks } + } +} + // Const allocations are only hashed for interning. However, they can be large, making the hashing // expensive especially since it uses `FxHash`: it's better suited to short keys, not potentially // big buffers like the allocation's init mask. We can partially hash some fields when they're diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index 60927eed85d..65d04919357 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -102,7 +102,7 @@ impl<T: HasDataLayout> PointerArithmetic for T {} /// This trait abstracts over the kind of provenance that is associated with a `Pointer`. It is /// mostly opaque; the `Machine` trait extends it with some more operations that also have access to /// some global state. -/// The `Debug` rendering is used to distplay bare provenance, and for the default impl of `fmt`. +/// The `Debug` rendering is used to display bare provenance, and for the default impl of `fmt`. pub trait Provenance: Copy + fmt::Debug { /// Says whether the `offset` field of `Pointer`s with this provenance is the actual physical address. /// - If `false`, the offset *must* be relative. This means the bytes representing a pointer are diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 856d821a5cf..ed4ee93e97d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> { span: Option<Span>, ) -> EvalToConstValueResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference - // variables. We reject those here since `resolve_opt_const_arg` + // variables. We reject those here since `resolve` // would fail otherwise. // // When trying to evaluate constants containing inference variables, @@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve_opt_const_arg( + match ty::Instance::resolve( self, param_env, // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? ct.def, ct.substs, @@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> { span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference - // variables. We reject those here since `resolve_opt_const_arg` + // variables. We reject those here since `resolve` // would fail otherwise. // // When trying to evaluate constants containing inference variables, @@ -82,7 +82,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { + match ty::Instance::resolve(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| { @@ -94,14 +94,14 @@ impl<'tcx> TyCtxt<'tcx> { // used generic parameters is a bug of evaluation, so checking for it // here does feel somewhat sensible. if !self.features().generic_const_exprs && ct.substs.has_non_region_param() { - assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst)); - let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def); + assert!(matches!(self.def_kind(ct.def), DefKind::AnonConst)); + let mir_body = self.mir_for_ctfe(ct.def); if mir_body.is_polymorphic { - let Some(local_def_id) = ct.def.did.as_local() else { return }; + let Some(local_def_id) = ct.def.as_local() else { return }; self.struct_span_lint_hir( lint::builtin::CONST_EVALUATABLE_UNCHECKED, self.hir().local_def_id_to_hir_id(local_def_id), - self.def_span(ct.def.did), + self.def_span(ct.def), "cannot use constants which depend on generic parameters in types", |err| err, ) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 2ea8602af12..039194284b8 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -27,7 +27,7 @@ use polonius_engine::Atom; pub use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -191,20 +191,13 @@ pub struct MirSource<'tcx> { impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { - MirSource { - instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - promoted: None, - } + MirSource { instance: InstanceDef::Item(def_id), promoted: None } } pub fn from_instance(instance: InstanceDef<'tcx>) -> Self { MirSource { instance, promoted: None } } - pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> { - self.instance.with_opt_param() - } - #[inline] pub fn def_id(&self) -> DefId { self.instance.def_id() @@ -714,9 +707,7 @@ pub enum BindingForm<'tcx> { } TrivialTypeTraversalAndLiftImpls! { - for<'tcx> { - BindingForm<'tcx>, - } + BindingForm<'tcx>, } mod binding_form_impl { @@ -2050,7 +2041,11 @@ impl<'tcx> Debug for Rvalue<'tcx> { } UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Discriminant(ref place) => write!(fmt, "discriminant({:?})", place), - NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t), + NullaryOp(ref op, ref t) => match op { + NullOp::SizeOf => write!(fmt, "SizeOf({:?})", t), + NullOp::AlignOf => write!(fmt, "AlignOf({:?})", t), + NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({:?}, {:?})", t, fields), + }, ThreadLocalRef(did) => ty::tls::with(|tcx| { let muta = tcx.static_mutability(did).unwrap().prefix_str(); write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did)) @@ -2438,16 +2433,6 @@ impl<'tcx> ConstantKind<'tcx> { Self::Val(val, ty) } - /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly - /// converted to a constant, everything else becomes `Unevaluated`. - pub fn from_anon_const( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { - Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env) - } - #[instrument(skip(tcx), level = "debug", ret)] pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); @@ -2487,28 +2472,25 @@ impl<'tcx> ConstantKind<'tcx> { ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty }) .substs; - let uneval = UnevaluatedConst { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: None, - }; + let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None }; debug_assert!(!uneval.has_free_regions()); Self::Unevaluated(uneval, ty) } + /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly + /// converted to a constant, everything else becomes `Unevaluated`. #[instrument(skip(tcx), level = "debug", ret)] - fn from_opt_const_arg_anon_const( + pub fn from_anon_const( tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, param_env: ty::ParamEnv<'tcx>, ) -> Self { - let body_id = match tcx.hir().get_by_def_id(def.did) { + let body_id = match tcx.hir().get_by_def_id(def) { hir::Node::AnonConst(ac) => ac.body, - _ => span_bug!( - tcx.def_span(def.did.to_def_id()), - "from_anon_const can only process anonymous constants" - ), + _ => { + span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants") + } }; let expr = &tcx.hir().body(body_id).value; @@ -2524,7 +2506,7 @@ impl<'tcx> ConstantKind<'tcx> { }; debug!("expr.kind: {:?}", expr.kind); - let ty = tcx.type_of(def.def_id_for_type_of()).subst_identity(); + let ty = tcx.type_of(def).subst_identity(); debug!(?ty); // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` @@ -2551,7 +2533,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => {} } - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) && let Some(parent_did) = parent_hir_id.as_owner() { @@ -2561,15 +2543,14 @@ impl<'tcx> ConstantKind<'tcx> { }; debug!(?parent_substs); - let did = def.did.to_def_id(); + let did = def.to_def_id(); let child_substs = InternalSubsts::identity_for_item(tcx, did); let substs = tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter())); debug!(?substs); - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let span = tcx.hir().span(hir_id); - let uneval = UnevaluatedConst::new(def.to_global(), substs); + let span = tcx.def_span(def); + let uneval = UnevaluatedConst::new(did, substs); debug!(?span, ?param_env); match tcx.const_eval_resolve(param_env, uneval, Some(span)) { @@ -2583,8 +2564,8 @@ impl<'tcx> ConstantKind<'tcx> { // new unevaluated const and error hard later in codegen Self::Unevaluated( UnevaluatedConst { - def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did), + def: did, + substs: InternalSubsts::identity_for_item(tcx, did), promoted: None, }, ty, @@ -2609,7 +2590,7 @@ impl<'tcx> ConstantKind<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { - pub def: ty::WithOptConstParam<DefId>, + pub def: DefId, pub substs: SubstsRef<'tcx>, pub promoted: Option<Promoted>, } @@ -2625,10 +2606,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { impl<'tcx> UnevaluatedConst<'tcx> { #[inline] - pub fn new( - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> UnevaluatedConst<'tcx> { + pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> { UnevaluatedConst { def, substs, promoted: Default::default() } } } @@ -3118,9 +3096,11 @@ mod size_asserts { // tidy-alphabetical-start static_assert_size!(BasicBlockData<'_>, 144); static_assert_size!(LocalDecl<'_>, 40); + static_assert_size!(SourceScopeData<'_>, 72); static_assert_size!(Statement<'_>, 32); static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 112); static_assert_size!(TerminatorKind<'_>, 96); + static_assert_size!(VarDebugInfo<'_>, 80); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index f592f1515c1..ff54ec56a29 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -4,10 +4,10 @@ use rustc_attr::InlineAttr; use rustc_data_structures::base_n; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher}; use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::ItemId; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_query_system::ich::StableHashingContext; use rustc_session::config::OptLevel; use rustc_span::source_map::Span; @@ -313,8 +313,8 @@ impl<'tcx> CodegenUnit<'tcx> { // avoid collisions and is still reasonably short for filenames. let mut hasher = StableHasher::new(); human_readable_name.hash(&mut hasher); - let hash: u128 = hasher.finish(); - let hash = hash & ((1u128 << 80) - 1); + let hash: Hash128 = hasher.finish(); + let hash = hash.as_u128() & ((1u128 << 80) - 1); base_n::encode(hash, base_n::CASE_INSENSITIVE) } @@ -373,7 +373,7 @@ impl<'tcx> CodegenUnit<'tcx> { // instances into account. The others don't matter for // the codegen tests and can even make item order // unstable. - InstanceDef::Item(def) => def.did.as_local().map(Idx::index), + InstanceDef::Item(def) => def.as_local().map(Idx::index), InstanceDef::VTableShim(..) | InstanceDef::ReifyShim(..) | InstanceDef::Intrinsic(..) @@ -505,22 +505,13 @@ impl<'tcx> CodegenUnitNameBuilder<'tcx> { // instantiating stuff for upstream crates. let local_crate_id = if cnum != LOCAL_CRATE { let local_stable_crate_id = tcx.sess.local_stable_crate_id(); - format!( - "-in-{}.{:08x}", - tcx.crate_name(LOCAL_CRATE), - local_stable_crate_id.to_u64() as u32, - ) + format!("-in-{}.{:08x}", tcx.crate_name(LOCAL_CRATE), local_stable_crate_id) } else { String::new() }; let stable_crate_id = tcx.sess.local_stable_crate_id(); - format!( - "{}.{:08x}{}", - tcx.crate_name(cnum), - stable_crate_id.to_u64() as u32, - local_crate_id, - ) + format!("{}.{:08x}{}", tcx.crate_name(cnum), stable_crate_id, local_crate_id) }); write!(cgu_name, "{}", crate_prefix).unwrap(); diff --git a/compiler/rustc_middle/src/mir/patch.rs b/compiler/rustc_middle/src/mir/patch.rs index f62853c3e74..c4c3341f873 100644 --- a/compiler/rustc_middle/src/mir/patch.rs +++ b/compiler/rustc_middle/src/mir/patch.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::*; use rustc_middle::ty::Ty; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7e51953599d..fa8a339631e 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -10,7 +10,7 @@ use super::spanview::write_mir_fn_spanview; use either::Either; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::interpret::{ alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, ConstAllocation, ConstValue, GlobalAlloc, Pointer, Provenance, @@ -298,8 +298,7 @@ pub fn write_mir_pretty<'tcx>( // are shared between mir_for_ctfe and optimized_mir write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?; } else { - let instance_mir = - tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id))); + let instance_mir = tcx.instance_mir(ty::InstanceDef::Item(def_id)); render_body(w, instance_mir)?; } } @@ -464,11 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Param(p) => format!("Param({})", p), ty::ConstKind::Unevaluated(uv) => { - format!( - "Unevaluated({}, {:?})", - self.tcx.def_path_str(uv.def.did), - uv.substs, - ) + format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.substs,) } ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)), ty::ConstKind::Error(_) => "Error".to_string(), @@ -481,7 +476,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ConstantKind::Unevaluated(uv, _) => { format!( "Unevaluated({}, {:?}, {:?})", - self.tcx.def_path_str(uv.def.did), + self.tcx.def_path_str(uv.def), uv.substs, uv.promoted, ) diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index cfdf1dcf5c0..53fd2dd23a7 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,14 +1,14 @@ //! Values computed by queries that use MIR. -use crate::mir::{Body, ConstantKind, Promoted}; +use crate::mir::ConstantKind; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitMatrix; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx}; use smallvec::SmallVec; @@ -454,42 +454,3 @@ pub struct CoverageInfo { /// The total number of coverage region counter expressions added to the MIR `Body`. pub num_expressions: u32, } - -/// Shims which make dealing with `WithOptConstParam` easier. -/// -/// For more information on why this is needed, consider looking -/// at the docs for `WithOptConstParam` itself. -impl<'tcx> TyCtxt<'tcx> { - #[inline] - pub fn mir_const_qualif_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> ConstQualifs { - if let Some(param_did) = def.const_param_did { - self.mir_const_qualif_const_arg((def.did, param_did)) - } else { - self.mir_const_qualif(def.did) - } - } - - #[inline] - pub fn promoted_mir_opt_const_arg( - self, - def: ty::WithOptConstParam<DefId>, - ) -> &'tcx IndexVec<Promoted, Body<'tcx>> { - if let Some((did, param_did)) = def.as_const_arg() { - self.promoted_mir_of_const_arg((did, param_did)) - } else { - self.promoted_mir(def.did) - } - } - - #[inline] - pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> { - if let Some((did, param_did)) = def.as_const_arg() { - self.mir_for_ctfe_of_const_arg((did, param_did)) - } else { - self.mir_for_ctfe(def.did) - } - } -} diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 135889d0da8..a8293ba1819 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -16,7 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir}; use rustc_hir::{self, GeneratorKind}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; @@ -251,7 +251,7 @@ pub enum StatementKind<'tcx> { /// **Needs clarification**: The implication of the above idea would be that assignment implies /// that the resulting value is initialized. I believe we could commit to this separately from /// committing to whatever part of the memory model we would need to decide on to make the above - /// paragragh precise. Do we want to? + /// paragraph precise. Do we want to? /// /// Assignments in which the types of the place and rvalue differ are not well-formed. /// @@ -331,9 +331,8 @@ pub enum StatementKind<'tcx> { /// This is especially useful for `let _ = PLACE;` bindings that desugar to a single /// `PlaceMention(PLACE)`. /// - /// When executed at runtime this is a nop. - /// - /// Disallowed after drop elaboration. + /// When executed at runtime, this computes the given place, but then discards + /// it without doing a load. It is UB if the place is not pointing to live memory. PlaceMention(Box<Place<'tcx>>), /// Encodes a user's type ascription. These need to be preserved @@ -997,7 +996,7 @@ pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>; /// This is what is implemented in miri today. Are these the semantics we want for MIR? Is this /// something we can even decide without knowing more about Rust's memory model? /// -/// **Needs clarifiation:** Is loading a place that has its variant index set well-formed? Miri +/// **Needs clarification:** Is loading a place that has its variant index set well-formed? Miri /// currently implements it, but it seems like this may be something to check against in the /// validator. #[derive(Clone, PartialEq, TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] @@ -1115,7 +1114,7 @@ pub enum Rvalue<'tcx> { CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>), /// Computes a value as described by the operation. - NullaryOp(NullOp, Ty<'tcx>), + NullaryOp(NullOp<'tcx>, Ty<'tcx>), /// Exactly like `BinaryOp`, but less operands. /// @@ -1211,12 +1210,14 @@ pub enum AggregateKind<'tcx> { Generator(DefId, SubstsRef<'tcx>, hir::Movability), } -#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] -pub enum NullOp { +#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +pub enum NullOp<'tcx> { /// Returns the size of a value of that type SizeOf, /// Returns the minimum alignment of a type AlignOf, + /// Returns the offset of a field + OffsetOf(&'tcx List<FieldIdx>), } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 4f00abf7fab..5ca82413448 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -188,7 +188,9 @@ impl<'tcx> Rvalue<'tcx> { } Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx), Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize, + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { + tcx.types.usize + } Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), AggregateKind::Tuple => { diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 9881583214e..06874741bb0 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -16,7 +16,6 @@ TrivialTypeTraversalAndLiftImpls! { UserTypeAnnotationIndex, BorrowKind, CastKind, - NullOp, hir::Movability, BasicBlock, SwitchTargets, @@ -25,9 +24,8 @@ TrivialTypeTraversalAndLiftImpls! { } TrivialTypeTraversalImpls! { - for <'tcx> { - ConstValue<'tcx>, - } + ConstValue<'tcx>, + NullOp<'tcx>, } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] { diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 23b28ac5ca9..fa62b7f32b1 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -174,14 +174,6 @@ impl AsLocalKey for DefId { } } -impl Key for ty::WithOptConstParam<LocalDefId> { - type CacheSelector = DefaultCacheSelector<Self>; - - fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - self.did.default_span(tcx) - } -} - impl Key for SimplifiedType { type CacheSelector = DefaultCacheSelector<Self>; @@ -313,7 +305,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { type CacheSelector = DefaultCacheSelector<Self>; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - (self.0).def.did.default_span(tcx) + (self.0).def.default_span(tcx) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7a5a1603585..84b5d6b0d0f 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -83,7 +83,7 @@ rustc_queries! { /// Avoid calling this query directly. query hir_module_items(key: LocalDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache - desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -92,14 +92,14 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner(key: hir::OwnerId) -> Option<crate::hir::Owner<'tcx>> { - desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// /// Definitions that were generated with no HIR, would be fed to return `None`. query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{ - desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } feedable } @@ -108,7 +108,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_parent(key: hir::OwnerId) -> hir::HirId { - desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR nodes and bodies inside the HIR owner `key`. @@ -116,7 +116,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_nodes(key: hir::OwnerId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> { - desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR attributes inside the HIR owner `key`. @@ -124,30 +124,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { - desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) } - } - - /// Computes the `DefId` of the corresponding const parameter in case the `key` is a - /// const argument and returns `None` otherwise. - /// - /// ```ignore (incomplete) - /// let a = foo::<7>(); - /// // ^ Calling `opt_const_param_of` for this argument, - /// - /// fn foo<const N: usize>() - /// // ^ returns this `DefId`. - /// - /// fn bar() { - /// // ^ While calling `opt_const_param_of` for other bodies returns `None`. - /// } - /// ``` - // It looks like caching this query on disk actually slightly - // worsened performance in #74376. - // - // Once const generics are more prevalently used, we might want to - // consider only caching calls returning `Some`. - query opt_const_param_of(key: LocalDefId) -> Option<DefId> { - desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } } /// Given the def_id of a const-generic parameter, computes the associated default const @@ -181,7 +158,7 @@ rustc_queries! { } query collect_return_position_impl_trait_in_trait_tys(key: DefId) - -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> + -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> { desc { "comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process" } cache_on_disk_if { key.is_local() } @@ -274,7 +251,7 @@ rustc_queries! { /// `key` is the `DefId` of the associated type or opaque type. /// /// Bounds from the parent (e.g. with nested impl trait) are not included. - query explicit_item_bounds(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query explicit_item_bounds(key: DefId) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, Span)]> { desc { |tcx| "finding item bounds for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern @@ -318,7 +295,7 @@ rustc_queries! { query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { eval_always // fetches `resolutions` arena_cache - desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } } query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { @@ -328,7 +305,7 @@ rustc_queries! { query parent_module_from_def_id(key: LocalDefId) -> LocalDefId { eval_always - desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key) } } query expn_that_defined(key: DefId) -> rustc_span::ExpnId { @@ -344,7 +321,7 @@ rustc_queries! { /// Checks whether a type is representable or infinitely sized query representability(_: LocalDefId) -> rustc_middle::ty::Representability { - desc { "checking if `{}` is representable", tcx.def_path_str(key.to_def_id()) } + desc { "checking if `{}` is representable", tcx.def_path_str(key) } // infinitely sized types will cause a cycle cycle_delay_bug // we don't want recursive representability calls to be forced with @@ -369,26 +346,24 @@ rustc_queries! { } /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. - query thir_body(key: ty::WithOptConstParam<LocalDefId>) - -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> - { + query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash - desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } } /// Create a THIR tree for debugging. - query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String { + query thir_tree(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) } } /// Create a list-like THIR representation for debugging. - query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String { + query thir_flat(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) } } /// Set of all the `DefId`s in this crate that have MIR associated with @@ -407,31 +382,19 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - query mir_const_qualif_const_arg( - key: (LocalDefId, DefId) - ) -> mir::ConstQualifs { - desc { - |tcx| "const checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. - query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } + query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } } /// Fetch the MIR for a given `DefId` up till the point where it is /// ready for const qualification. /// /// See the README for the `mir` module for details. - query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { - desc { - |tcx| "preparing {}`{}` for borrow checking", - if key.const_param_did.is_some() { "the const argument " } else { "" }, - tcx.def_path_str(key.did.to_def_id()), - } + query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) } no_hash } @@ -444,22 +407,10 @@ rustc_queries! { } separate_provide_extern } - /// Try to build an abstract representation of the given constant. - query thir_abstract_const_of_const_arg( - key: (LocalDefId, DefId) - ) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> { - desc { - |tcx| - "building an abstract representation for the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } - query mir_drops_elaborated_and_const_checked( - key: ty::WithOptConstParam<LocalDefId> - ) -> &'tcx Steal<mir::Body<'tcx>> { + query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } } query mir_for_ctfe( @@ -470,30 +421,18 @@ rustc_queries! { separate_provide_extern } - query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> { - desc { - |tcx| "caching MIR for CTFE of the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } - - query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) -> - ( - &'tcx Steal<mir::Body<'tcx>>, - &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> - ) { + query mir_promoted(key: LocalDefId) -> ( + &'tcx Steal<mir::Body<'tcx>>, + &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> + ) { no_hash - desc { - |tcx| "processing MIR for {}`{}`", - if key.const_param_did.is_some() { "the const argument " } else { "" }, - tcx.def_path_str(key.did.to_def_id()), - } + desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } } query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { desc { |tcx| "finding symbols for captures of closure `{}`", - tcx.def_path_str(key.to_def_id()) + tcx.def_path_str(key) } } @@ -505,7 +444,7 @@ rustc_queries! { } query check_generator_obligations(key: LocalDefId) { - desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key) } } /// MIR after our optimization passes have run. This is MIR that is ready @@ -544,14 +483,6 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - query promoted_mir_of_const_arg( - key: (LocalDefId, DefId) - ) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { - desc { - |tcx| "optimizing promoted MIR for the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } /// Erases regions from `ty` to yield a new type. /// Normally you would just use `tcx.erase_regions(value)`, @@ -595,7 +526,7 @@ rustc_queries! { /// `explicit_predicates_of` and `explicit_item_bounds` will then take /// the appropriate subsets of the predicates here. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } /// Returns the predicates written explicitly by the user. @@ -739,9 +670,10 @@ rustc_queries! { desc { "computing the inferred outlives predicates for items in this crate" } } - /// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items. + /// Maps from an impl/trait or struct/variant `DefId` + /// to a list of the `DefId`s of its associated items or fields. query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } + desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -837,28 +769,16 @@ rustc_queries! { /// The result of unsafety-checking this `LocalDefId`. query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query unsafety_check_result_for_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::UnsafetyCheckResult { - desc { - |tcx| "unsafety-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be /// used with `-Zthir-unsafeck`. query thir_check_unsafety(key: LocalDefId) { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query thir_check_unsafety_for_const_arg(key: (LocalDefId, DefId)) { - desc { - |tcx| "unsafety-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Returns the types assumed to be well formed while "inside" of the given item. /// @@ -913,7 +833,7 @@ rustc_queries! { desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } } - query check_liveness(key: DefId) { + query check_liveness(key: LocalDefId) { desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) } } @@ -952,29 +872,17 @@ rustc_queries! { separate_provide_extern } - query typeck_item_bodies(_: ()) -> () { - desc { "type-checking all item bodies" } - } - query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query typeck_const_arg( - key: (LocalDefId, DefId) - ) -> &'tcx ty::TypeckResults<'tcx> { - desc { - |tcx| "type-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { - desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -989,15 +897,9 @@ rustc_queries! { /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> { - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } } - query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> { - desc { - |tcx| "borrow-checking the const argument`{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Gets a complete map from all types to their inherent impls. /// Not meant to be used directly outside of coherence. @@ -1017,7 +919,7 @@ rustc_queries! { query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking whether impl `{}` follows the orphan rules", - tcx.def_path_str(key.to_def_id()), + tcx.def_path_str(key), } } @@ -1029,7 +931,7 @@ rustc_queries! { desc { |tcx| "computing if `{}` (transitively) calls `{}`", key.0, - tcx.def_path_str(key.1.to_def_id()), + tcx.def_path_str(key.1), } } @@ -1094,7 +996,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> ) -> Option<mir::DestructuredConstant<'tcx>> { desc { "destructuring MIR constant"} - remap_env_constness } /// Dereference a constant reference or raw pointer and turn the result into a constant @@ -1103,7 +1004,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, mir::ConstantKind<'tcx>> ) -> mir::ConstantKind<'tcx> { desc { "dereferencing MIR constant" } - remap_env_constness } query const_caller_location(key: (rustc_span::Symbol, u32, u32)) -> ConstValue<'tcx> { @@ -1122,7 +1022,7 @@ rustc_queries! { } query check_match(key: LocalDefId) { - desc { |tcx| "match-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -1346,32 +1246,26 @@ rustc_queries! { /// `ty.is_copy()`, etc, since that will prune the environment where possible. query is_copy_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Copy`", env.value } - remap_env_constness } /// Query backing `Ty::is_sized`. query is_sized_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Sized`", env.value } - remap_env_constness } /// Query backing `Ty::is_freeze`. query is_freeze_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is freeze", env.value } - remap_env_constness } /// Query backing `Ty::is_unpin`. query is_unpin_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` is `Unpin`", env.value } - remap_env_constness } /// Query backing `Ty::needs_drop`. query needs_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` needs drop", env.value } - remap_env_constness } /// Query backing `Ty::has_significant_drop_raw`. query has_significant_drop_raw(env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { desc { "computing whether `{}` has a significant drop", env.value } - remap_env_constness } /// Query backing `Ty::is_structural_eq_shallow`. @@ -1411,7 +1305,6 @@ rustc_queries! { ) -> Result<ty::layout::TyAndLayout<'tcx>, ty::layout::LayoutError<'tcx>> { depth_limit desc { "computing layout of `{}`", key.value } - remap_env_constness } /// Compute a `FnAbi` suitable for indirect calls, i.e. to `fn` pointers. @@ -1422,7 +1315,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)> ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}` function pointers", key.value.0 } - remap_env_constness } /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for @@ -1434,7 +1326,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)> ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}`", key.value.0 } - remap_env_constness } query dylib_dependency_formats(_: CrateNum) @@ -1478,7 +1369,7 @@ rustc_queries! { separate_provide_extern } query has_ffi_unwind_calls(key: LocalDefId) -> bool { - desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } cache_on_disk_if { true } } query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> { @@ -1524,7 +1415,7 @@ rustc_queries! { } query check_well_formed(key: hir::OwnerId) -> () { - desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } } // The `DefId`s of all non-generic functions and statics in the given crate @@ -1553,7 +1444,7 @@ rustc_queries! { query is_unreachable_local_definition(def_id: LocalDefId) -> bool { desc { |tcx| "checking whether `{}` is reachable from outside the crate", - tcx.def_path_str(def_id.to_def_id()), + tcx.def_path_str(def_id), } } @@ -1747,7 +1638,7 @@ rustc_queries! { separate_provide_extern } query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> { - desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) } } query lib_features(_: ()) -> &'tcx LibFeatures { @@ -1851,7 +1742,7 @@ rustc_queries! { desc { "fetching potentially unused trait imports" } } query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet<Symbol> { - desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) } } query stability_index(_: ()) -> &'tcx stability::Index { @@ -1937,7 +1828,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: invoke `try_normalize_erasing_regions` instead. @@ -1945,7 +1835,6 @@ rustc_queries! { goal: ParamEnvAnd<'tcx, GenericArg<'tcx>> ) -> Result<GenericArg<'tcx>, NoSolution> { desc { "normalizing `{}`", goal.value } - remap_env_constness } query implied_outlives_bounds( @@ -1955,7 +1844,6 @@ rustc_queries! { NoSolution, > { desc { "computing implied outlives bounds for `{}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: @@ -1967,7 +1855,6 @@ rustc_queries! { NoSolution, > { desc { "computing dropck types for `{}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: invoke `infcx.predicate_may_hold()` or @@ -1995,7 +1882,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_ascribe_user_type` `{:?}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: part of the `Eq` type-op @@ -2006,7 +1892,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_eq` `{:?}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: part of the `Subtype` type-op @@ -2017,7 +1902,6 @@ rustc_queries! { NoSolution, > { desc { "evaluating `type_op_subtype` `{:?}`", goal.value.value } - remap_env_constness } /// Do not call this query directly: part of the `ProvePredicate` type-op @@ -2038,7 +1922,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{}`", goal.value.value.value } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -2049,7 +1932,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal.value.value.value } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -2060,7 +1942,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal.value.value.value } - remap_env_constness } /// Do not call this query directly: part of the `Normalize` type-op @@ -2071,7 +1952,6 @@ rustc_queries! { NoSolution, > { desc { "normalizing `{:?}`", goal.value.value.value } - remap_env_constness } query subst_and_check_impossible_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { @@ -2093,7 +1973,6 @@ rustc_queries! { goal: CanonicalTyGoal<'tcx> ) -> MethodAutoderefStepsResult<'tcx> { desc { "computing autoderef types for `{}`", goal.value.value } - remap_env_constness } query supported_target_features(_: CrateNum) -> &'tcx FxHashMap<String, Option<Symbol>> { @@ -2138,17 +2017,6 @@ rustc_queries! { key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)> ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } - remap_env_constness - } - - query resolve_instance_of_const_arg( - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)> - ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { - desc { - "resolving instance of the const argument `{}`", - ty::Instance::new(key.value.0.to_def_id(), key.value.2), - } - remap_env_constness } query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> { @@ -2197,7 +2065,7 @@ rustc_queries! { query compare_impl_const( key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.to_def_id()) } + desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0) } } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 7d79a13d3fd..da86cfd4772 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -14,13 +14,13 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::RangeEnd; use rustc_index::newtype_index; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp}; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts}; +use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts}; use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -481,6 +481,11 @@ pub enum ExprKind<'tcx> { }, /// Inline assembly, i.e. `asm!()`. InlineAsm(Box<InlineAsmExpr<'tcx>>), + /// Field offset (`offset_of!`) + OffsetOf { + container: Ty<'tcx>, + fields: &'tcx List<FieldIdx>, + }, /// An expression taking a reference to a thread local. ThreadLocalRef(DefId), /// A `yield` expression. @@ -929,8 +934,8 @@ mod size_asserts { static_assert_size!(Block, 56); static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 40); - static_assert_size!(Pat<'_>, 72); - static_assert_size!(PatKind<'_>, 56); + static_assert_size!(Pat<'_>, 64); + static_assert_size!(PatKind<'_>, 48); static_assert_size!(Stmt<'_>, 56); static_assert_size!(StmtKind<'_>, 48); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 5614528c4cb..5c7ec31cf93 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -160,6 +160,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } } } + OffsetOf { container: _, fields: _ } => {} ThreadLocalRef(_) => {} Yield { value } => visitor.visit_expr(&visitor.thir()[value]), } diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index f889ce82706..029cf793ad8 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -1,4 +1,4 @@ -//! A subset of a mir body used for const evaluatability checking. +//! A subset of a mir body used for const evaluability checking. use crate::ty::{ self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, @@ -36,15 +36,8 @@ pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, impl<'tcx> TyCtxt<'tcx> { /// Returns a const without substs applied - pub fn bound_abstract_const( - self, - uv: ty::WithOptConstParam<DefId>, - ) -> BoundAbstractConst<'tcx> { - let ac = if let Some((did, param_did)) = uv.as_const_arg() { - self.thir_abstract_const_of_const_arg((did, param_did)) - } else { - self.thir_abstract_const(uv.did) - }; + pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> { + let ac = self.thir_abstract_const(uv); Ok(ac?.map(|ac| EarlyBinder(ac))) } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 3a03c0901d7..30e488a9e47 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 8ef4a46a733..3793d85c85a 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; use rustc_serialize::{Decodable, Encodable}; use rustc_span::Span; +use rustc_target::abi::FieldIdx; pub use rustc_type_ir::{TyDecoder, TyEncoder}; use std::hash::Hash; use std::intrinsics; @@ -401,6 +402,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty } } +impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<FieldIdx> { + fn decode(decoder: &mut D) -> &'tcx Self { + let len = decoder.read_usize(); + decoder + .interner() + .mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder))) + } +} + impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List<Ty<'tcx>>, @@ -412,6 +422,7 @@ impl_decodable_via_ref! { &'tcx mir::coverage::CodeRegion, &'tcx ty::List<ty::BoundVariableKind>, &'tcx ty::List<ty::Predicate<'tcx>>, + &'tcx ty::List<FieldIdx>, } #[macro_export] @@ -519,6 +530,16 @@ macro_rules! implement_ty_decoder { fn read_raw_bytes(&mut self, len: usize) -> &[u8] { self.opaque.read_raw_bytes(len) } + + #[inline] + fn position(&self) -> usize { + self.opaque.position() + } + + #[inline] + fn peek_byte(&self) -> u8 { + self.opaque.peek_byte() + } } } } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index bcedae233d9..0a191ff7626 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -53,19 +53,12 @@ impl<'tcx> Const<'tcx> { /// Literals and const generic parameters are eagerly converted to a constant, everything else /// becomes `Unevaluated`. - pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id)) - } - #[instrument(skip(tcx), level = "debug")] - pub fn from_opt_const_arg_anon_const( - tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, - ) -> Self { - let body_id = match tcx.hir().get_by_def_id(def.did) { + pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { + let body_id = match tcx.hir().get_by_def_id(def) { hir::Node::AnonConst(ac) => ac.body, _ => span_bug!( - tcx.def_span(def.did.to_def_id()), + tcx.def_span(def.to_def_id()), "from_anon_const can only process anonymous constants" ), }; @@ -73,17 +66,14 @@ impl<'tcx> Const<'tcx> { let expr = &tcx.hir().body(body_id).value; debug!(?expr); - let ty = tcx - .type_of(def.def_id_for_type_of()) - .no_bound_vars() - .expect("const parameter types cannot be generic"); + let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); match Self::try_eval_lit_or_param(tcx, ty, expr) { Some(v) => v, None => tcx.mk_const( ty::UnevaluatedConst { - def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did), + def: def.to_def_id(), + substs: InternalSubsts::identity_for_item(tcx, def.to_def_id()), }, ty, ), diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index c0e557d480d..d1dbc531edf 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -141,14 +141,18 @@ impl<CTX> crate::ty::HashStable<CTX> for ScalarInt { impl<S: Encoder> Encodable<S> for ScalarInt { fn encode(&self, s: &mut S) { - s.emit_u128(self.data); - s.emit_u8(self.size.get()); + let size = self.size.get(); + s.emit_u8(size); + s.emit_raw_bytes(&self.data.to_le_bytes()[..size as usize]); } } impl<D: Decoder> Decodable<D> for ScalarInt { fn decode(d: &mut D) -> ScalarInt { - ScalarInt { data: d.read_u128(), size: NonZeroU8::new(d.read_u8()).unwrap() } + let mut data = [0u8; 16]; + let size = d.read_u8(); + data[..size as usize].copy_from_slice(d.read_raw_bytes(size as usize)); + ScalarInt { data: u128::from_le_bytes(data), size: NonZeroU8::new(size).unwrap() } } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 560caa041a7..1ac2cd13982 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -17,7 +17,7 @@ use super::ScalarInt; #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { - pub def: ty::WithOptConstParam<DefId>, + pub def: DefId, pub substs: SubstsRef<'tcx>, } @@ -36,10 +36,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { impl<'tcx> UnevaluatedConst<'tcx> { #[inline] - pub fn new( - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> UnevaluatedConst<'tcx> { + pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> { UnevaluatedConst { def, substs } } } @@ -224,9 +221,9 @@ impl<'tcx> ConstKind<'tcx> { // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. let param_env_and = if (param_env, unevaluated).has_non_region_infer() { - tcx.param_env(unevaluated.def.did).and(ty::UnevaluatedConst { + tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst { def: unevaluated.def, - substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did), + substs: InternalSubsts::identity_for_item(tcx, unevaluated.def), }) } else { tcx.erase_regions(param_env) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 63f7cc2ee73..7df4be263d5 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -13,7 +13,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; -use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted}; +use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::query::LocalCrate; use crate::thir::Thir; use crate::traits; @@ -24,7 +24,7 @@ use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, - TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility, + TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility, }; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; use rustc_ast::{self as ast, attr}; @@ -50,7 +50,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::{ Constness, ExprKind, HirId, ImplItemKind, ItemKind, Node, TraitCandidate, TraitItemKind, }; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_macros::HashStable; use rustc_query_system::dep_graph::DepNodeIndex; use rustc_query_system::ich::StableHashingContext; @@ -80,6 +80,8 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; +use super::query::IntoQueryParam; + const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { @@ -141,6 +143,7 @@ pub struct CtxtInterners<'tcx> { type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>, const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, + type_lists: InternedSet<'tcx, List<Ty<'tcx>>>, canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>, region: InternedSet<'tcx, RegionKind<'tcx>>, poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>, @@ -154,6 +157,7 @@ pub struct CtxtInterners<'tcx> { layout: InternedSet<'tcx, LayoutS>, adt_def: InternedSet<'tcx, AdtDefData>, external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, + fields: InternedSet<'tcx, List<FieldIdx>>, } impl<'tcx> CtxtInterners<'tcx> { @@ -163,6 +167,7 @@ impl<'tcx> CtxtInterners<'tcx> { type_: Default::default(), const_lists: Default::default(), substs: Default::default(), + type_lists: Default::default(), region: Default::default(), poly_existential_predicates: Default::default(), canonical_var_infos: Default::default(), @@ -176,6 +181,7 @@ impl<'tcx> CtxtInterners<'tcx> { layout: Default::default(), adt_def: Default::default(), external_constraints: Default::default(), + fields: Default::default(), } } @@ -447,6 +453,14 @@ impl<'tcx> TyCtxt<'tcx> { pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> { TyCtxtFeed { tcx: self, key: LOCAL_CRATE } } + + /// In order to break cycles involving `AnonConst`, we need to set the expected type by side + /// effect. However, we do not want this as a general capability, so this interface restricts + /// to the only allowed case. + pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<Ty<'tcx>>) { + debug_assert_eq!(self.def_kind(key), DefKind::AnonConst); + TyCtxtFeed { tcx: self, key }.type_of(value) + } } impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> { @@ -581,28 +595,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn typeck_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> &'tcx TypeckResults<'tcx> { - if let Some(param_did) = def.const_param_did { - self.typeck_const_arg((def.did, param_did)) - } else { - self.typeck(def.did) - } - } - - pub fn mir_borrowck_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> &'tcx BorrowCheckResult<'tcx> { - if let Some(param_did) = def.const_param_did { - self.mir_borrowck_const_arg((def.did, param_did)) - } else { - self.mir_borrowck(def.did) - } - } - pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> { self.arena.alloc(Steal::new(thir)) } @@ -834,7 +826,8 @@ impl<'tcx> TyCtxt<'tcx> { self.features_query(()) } - pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { + pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey { + let id = id.into_query_param(); // Accessing the DefKey is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { self.definitions_untracked().def_key(id) @@ -925,7 +918,7 @@ impl<'tcx> TyCtxt<'tcx> { crate_name, // Don't print the whole stable crate id. That's just // annoying in debug output. - stable_crate_id.to_u64() >> (8 * 6), + stable_crate_id.as_u64() >> (8 * 6), self.def_path(def_id).to_string_no_crate_verbose() ) } @@ -1278,25 +1271,6 @@ macro_rules! nop_lift { }; } -// Can't use the macros as we have reuse the `substs` here. -// -// See `mk_type_list` for more info. -impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> { - type Lifted = &'tcx List<Ty<'tcx>>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - if self.is_empty() { - return Some(List::empty()); - } - - tcx.interners - .substs - .contains_pointer_to(&InternedInSet(self.as_substs())) - // SAFETY: `self` is interned and therefore valid - // for the entire lifetime of the `TyCtxt`. - .then(|| unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) }) - } -} - macro_rules! nop_list_lift { ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { @@ -1320,6 +1294,7 @@ nop_lift! {const_; Const<'a> => Const<'tcx>} nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>} nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>} +nop_list_lift! {type_lists; Ty<'a> => Ty<'tcx>} nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} @@ -1329,9 +1304,12 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable // This is the impl for `&'a InternalSubsts<'a>`. nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} -CloneLiftImpls! { for<'tcx> { - Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint, -} } +CloneLiftImpls! { + Constness, + traits::WellFormedLoc, + ImplPolarity, + crate::mir::ReturnConstraint, +} macro_rules! sty_debug_print { ($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{ @@ -1591,12 +1569,14 @@ macro_rules! slice_interners { slice_interners!( const_lists: pub mk_const_list(Const<'tcx>), substs: pub mk_substs(GenericArg<'tcx>), + type_lists: pub mk_type_list(Ty<'tcx>), canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>), poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>), predicates: intern_predicates(Predicate<'tcx>), projs: pub mk_projs(ProjectionKind), place_elems: pub mk_place_elems(PlaceElem<'tcx>), bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind), + fields: pub mk_fields(FieldIdx), ); impl<'tcx> TyCtxt<'tcx> { @@ -1623,7 +1603,7 @@ impl<'tcx> TyCtxt<'tcx> { let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = ty.kind() else { return false }; let future_trait = self.require_lang_item(LangItem::Future, None); - self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { + self.explicit_item_bounds(def_id).skip_binder().iter().any(|&(predicate, _)| { let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() else { return false; }; @@ -2190,18 +2170,6 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(iter, |xs| self.mk_const_list(xs)) } - pub fn mk_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> { - // Actually intern type lists as lists of `GenericArg`s. - // - // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound - // as explained in `ty_slice_as_generic_arg`. With this, - // we guarantee that even when transmuting between `List<Ty<'tcx>>` - // and `List<GenericArg<'tcx>>`, the uniqueness requirement for - // lists is upheld. - let substs = self.mk_substs(ty::subst::ty_slice_as_generic_args(ts)); - substs.try_as_type_list().unwrap() - } - // Unlike various other `mk_*_from_iter` functions, this one uses `I: // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice // variant, because of the need to combine `inputs` and `output`. This @@ -2277,6 +2245,14 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(iter, |xs| self.mk_place_elems(xs)) } + pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output + where + I: Iterator<Item = T>, + T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>, + { + T::collect_and_apply(iter, |xs| self.mk_fields(xs)) + } + pub fn mk_substs_trait( self, self_ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 31d00b65e98..76f61d9ac9c 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -68,7 +68,7 @@ pub enum TreatParams { } /// During fast-rejection, we have the choice of treating projection types -/// as either simplifyable or not, depending on whether we expect the projection +/// as either simplifiable or not, depending on whether we expect the projection /// to be normalized/rigid. #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub enum TreatProjections { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 5a6ee123811..68002bfcfbd 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -178,7 +178,7 @@ impl FlagComputation { &ty::Alias(ty::Projection, data) => { self.add_flags(TypeFlags::HAS_TY_PROJECTION); - self.add_projection_ty(data); + self.add_alias_ty(data); } &ty::Alias(ty::Opaque, ty::AliasTy { substs, .. }) => { @@ -267,7 +267,7 @@ impl FlagComputation { projection_ty, term, })) => { - self.add_projection_ty(projection_ty); + self.add_alias_ty(projection_ty); self.add_term(term); } ty::PredicateKind::WellFormed(arg) => { @@ -372,8 +372,8 @@ impl FlagComputation { } } - fn add_projection_ty(&mut self, projection_ty: ty::AliasTy<'_>) { - self.add_substs(projection_ty.substs); + fn add_alias_ty(&mut self, alias_ty: ty::AliasTy<'_>) { + self.add_substs(alias_ty.substs); } fn add_substs(&mut self, substs: &[GenericArg<'_>]) { diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 203e16bea27..25890eb15cd 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -37,7 +37,8 @@ where } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - let r = r.super_fold_with(self); + // This one is a little different, because `super_fold_with` is not + // implemented on non-recursive `Region`. (self.lt_op)(r) } diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 4c7822acdf7..02baa395c3c 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -73,34 +73,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'t } } -impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKind<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - match self { - // WARNING: We dedup cache the `HashStable` results for `List` - // while ignoring types and freely transmute - // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. - // See `fn mk_type_list` for more details. - // - // We therefore hash types without adding a hash for their discriminant. - // - // In order to make it very unlikely for the sequence of bytes being hashed for - // a `GenericArgKind::Type` to be the same as the sequence of bytes being - // hashed for one of the other variants, we hash some very high number instead - // of their actual discriminant since `TyKind` should never start with anything - // that high. - ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher), - ty::subst::GenericArgKind::Const(ct) => { - 0xF3u8.hash_stable(hcx, hasher); - ct.hash_stable(hcx, hasher); - } - ty::subst::GenericArgKind::Lifetime(lt) => { - 0xF5u8.hash_stable(hcx, hasher); - lt.hash_stable(hcx, hasher); - } - } - } -} - // AllocIds get resolved to whatever they point to (to be stable) impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e73225f70cc..cc86cba6fda 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -34,7 +34,7 @@ pub enum InstanceDef<'tcx> { /// - `fn` items /// - closures /// - generators - Item(ty::WithOptConstParam<DefId>), + Item(DefId), /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI). /// @@ -143,7 +143,7 @@ impl<'tcx> Instance<'tcx> { match self.def { InstanceDef::Item(def) => tcx - .upstream_monomorphizations_for(def.did) + .upstream_monomorphizations_for(def) .and_then(|monos| monos.get(&self.substs).cloned()), InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs), _ => None, @@ -155,8 +155,8 @@ impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(self) -> DefId { match self { - InstanceDef::Item(def) => def.did, - InstanceDef::VTableShim(def_id) + InstanceDef::Item(def_id) + | InstanceDef::VTableShim(def_id) | InstanceDef::ReifyShim(def_id) | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) @@ -172,7 +172,7 @@ impl<'tcx> InstanceDef<'tcx> { /// Returns the `DefId` of instances which might not require codegen locally. pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> { match self { - ty::InstanceDef::Item(def) => Some(def.did), + ty::InstanceDef::Item(def) => Some(def), ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => { Some(def_id) } @@ -189,23 +189,6 @@ impl<'tcx> InstanceDef<'tcx> { } #[inline] - pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> { - match self { - InstanceDef::Item(def) => def, - InstanceDef::VTableShim(def_id) - | InstanceDef::ReifyShim(def_id) - | InstanceDef::FnPtrShim(def_id, _) - | InstanceDef::Virtual(def_id, _) - | InstanceDef::Intrinsic(def_id) - | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } - | InstanceDef::DropGlue(def_id, _) - | InstanceDef::CloneShim(def_id, _) - | InstanceDef::ThreadLocalShim(def_id) - | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), - } - } - - #[inline] pub fn get_attrs( &self, tcx: TyCtxt<'tcx>, @@ -222,7 +205,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; let def_id = match *self { - ty::InstanceDef::Item(def) => def.did, + ty::InstanceDef::Item(def) => def, ty::InstanceDef::DropGlue(_, Some(_)) => return false, ty::InstanceDef::ThreadLocalShim(_) => return false, _ => return true, @@ -273,8 +256,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { - InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. }) - | InstanceDef::Virtual(def_id, _) => { + InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller, @@ -358,7 +340,7 @@ impl<'tcx> Instance<'tcx> { def_id, substs ); - Instance { def: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs } + Instance { def: InstanceDef::Item(def_id), substs } } pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { @@ -403,18 +385,21 @@ impl<'tcx> Instance<'tcx> { /// couldn't complete due to errors elsewhere - this is distinct /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause + #[instrument(level = "debug", skip(tcx))] pub fn resolve( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - Instance::resolve_opt_const_arg( - tcx, - param_env, - ty::WithOptConstParam::unknown(def_id), - substs, - ) + // All regions in the result of this query are erased, so it's + // fine to erase all of the input regions. + + // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)` + // below is more likely to ignore the bounds in scope (e.g. if the only + // generic parameters mentioned by `substs` were lifetime ones). + let substs = tcx.erase_regions(substs); + tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs)))) } pub fn expect_resolve( @@ -432,31 +417,6 @@ impl<'tcx> Instance<'tcx> { } } - // This should be kept up to date with `resolve`. - pub fn resolve_opt_const_arg( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - // All regions in the result of this query are erased, so it's - // fine to erase all of the input regions. - - // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)` - // below is more likely to ignore the bounds in scope (e.g. if the only - // generic parameters mentioned by `substs` were lifetime ones). - let substs = tcx.erase_regions(substs); - - // FIXME(eddyb) should this always use `param_env.with_reveal_all()`? - if let Some((did, param_did)) = def.as_const_arg() { - tcx.resolve_instance_of_const_arg( - tcx.erase_regions(param_env.and((did, param_did, substs))), - ) - } else { - tcx.resolve_instance(tcx.erase_regions(param_env.and((def.did, substs)))) - } - } - pub fn resolve_for_fn_ptr( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -470,7 +430,7 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceDef::ReifyShim(def.did); + resolved.def = InstanceDef::ReifyShim(def); } InstanceDef::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); @@ -513,23 +473,23 @@ impl<'tcx> Instance<'tcx> { if resolved.def.requires_caller_location(tcx) // 2) The caller location parameter comes from having `#[track_caller]` // on the implementation, and *not* on the trait method. - && !tcx.should_inherit_track_caller(def.did) + && !tcx.should_inherit_track_caller(def) // If the method implementation comes from the trait definition itself // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), // then we don't need to generate a shim. This check is needed because // `should_inherit_track_caller` returns `false` if our method // implementation comes from the trait block, and not an impl block && !matches!( - tcx.opt_associated_item(def.did), + tcx.opt_associated_item(def), Some(ty::AssocItem { container: ty::AssocItemContainer::TraitContainer, .. }) ) { - if tcx.is_closure(def.did) { + if tcx.is_closure(def) { debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", - def.did, def_id, substs); + def, def_id, substs); // Create a shim for the `FnOnce/FnMut/Fn` method we are calling // - unlike functions, invoking a closure always goes through a @@ -537,9 +497,9 @@ impl<'tcx> Instance<'tcx> { resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs }; } else { debug!( - " => vtable fn pointer created for function with #[track_caller]: {:?}", def.did + " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceDef::ReifyShim(def.did); + resolved.def = InstanceDef::ReifyShim(def); } } } @@ -714,11 +674,8 @@ fn polymorphize<'tcx>( debug!("fold_ty: ty={:?}", ty); match *ty.kind() { ty::Closure(def_id, substs) => { - let polymorphized_substs = polymorphize( - self.tcx, - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - substs, - ); + let polymorphized_substs = + polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs); if substs == polymorphized_substs { ty } else { @@ -726,11 +683,8 @@ fn polymorphize<'tcx>( } } ty::Generator(def_id, substs, movability) => { - let polymorphized_substs = polymorphize( - self.tcx, - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - substs, - ); + let polymorphized_substs = + polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs); if substs == polymorphized_substs { ty } else { diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 195d951f9f3..6e6b7c39ecb 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -5,7 +5,7 @@ use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_session::config::OptLevel; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -235,7 +235,7 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> { } } -// FIXME: Once the other errors that embed this error have been converted to translateable +// FIXME: Once the other errors that embed this error have been converted to translatable // diagnostics, this Display impl should be removed. impl<'tcx> fmt::Display for LayoutError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -458,10 +458,10 @@ impl<'tcx> SizeSkeleton<'tcx> { } } -/// When creating the layout for types with abstract conts in their size (i.e. [usize; 4 * N]), +/// When creating the layout for types with abstract consts in their size (i.e. [usize; 4 * N]), /// to ensure that they have a canonical order and can be compared directly we combine all /// constants, and sort the other terms. This allows comparison of expressions of sizes, -/// allowing for things like transmutating between types that depend on generic consts. +/// allowing for things like transmuting between types that depend on generic consts. /// This returns `None` if multiplication of constants overflows. fn mul_sorted_consts<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index 79365ef281b..30f036e471c 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -1,4 +1,5 @@ use crate::arena::Arena; +use rustc_data_structures::aligned::{align_of, Aligned}; use rustc_serialize::{Encodable, Encoder}; use std::alloc::Layout; use std::cmp::Ordering; @@ -198,22 +199,17 @@ impl<'a, T: Copy> IntoIterator for &'a List<T> { unsafe impl<T: Sync> Sync for List<T> {} -unsafe impl<'a, T: 'a> rustc_data_structures::tagged_ptr::Pointer for &'a List<T> { - const BITS: usize = std::mem::align_of::<usize>().trailing_zeros() as usize; - - #[inline] - fn into_usize(self) -> usize { - self as *const List<T> as usize - } - - #[inline] - unsafe fn from_usize(ptr: usize) -> &'a List<T> { - &*(ptr as *const List<T>) - } +// Safety: +// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail, +// thus aligns of `Equivalent<T>` and `List<T>` must be the same. +unsafe impl<T> Aligned for List<T> { + const ALIGN: ptr::Alignment = { + #[repr(C)] + struct Equivalent<T> { + _len: usize, + _data: [T; 0], + } - unsafe fn with_ref<R, F: FnOnce(&Self) -> R>(ptr: usize, f: F) -> R { - // `Self` is `&'a List<T>` which impls `Copy`, so this is fine. - let ptr = Self::from_usize(ptr); - f(&ptr) - } + align_of::<Equivalent<T>>() + }; } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2e516f291bc..8e4e708b73c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -41,7 +41,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; use rustc_hir::Node; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; use rustc_serialize::{Decodable, Encodable}; @@ -861,6 +861,11 @@ impl<'tcx> PolyTraitPredicate<'tcx> { pub fn is_const_if_const(self) -> bool { self.skip_binder().is_const_if_const() } + + #[inline] + pub fn polarity(self) -> ImplPolarity { + self.skip_binder().polarity + } } /// `A: B` @@ -1007,7 +1012,7 @@ impl<'tcx> Term<'tcx> { _ => None, }, TermKind::Const(ct) => match ct.kind() { - ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def.did, uv.substs)), + ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.substs)), _ => None, }, } @@ -1471,135 +1476,6 @@ pub struct BoundConst<'tcx> { pub type PlaceholderConst<'tcx> = Placeholder<BoundVar>; -/// A `DefId` which, in case it is a const argument, is potentially bundled with -/// the `DefId` of the generic parameter it instantiates. -/// -/// This is used to avoid calls to `type_of` for const arguments during typeck -/// which cause cycle errors. -/// -/// ```rust -/// struct A; -/// impl A { -/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] } -/// // ^ const parameter -/// } -/// struct B; -/// impl B { -/// fn foo<const M: u8>(&self) -> usize { 42 } -/// // ^ const parameter -/// } -/// -/// fn main() { -/// let a = A; -/// let _b = a.foo::<{ 3 + 7 }>(); -/// // ^^^^^^^^^ const argument -/// } -/// ``` -/// -/// Let's look at the call `a.foo::<{ 3 + 7 }>()` here. We do not know -/// which `foo` is used until we know the type of `a`. -/// -/// We only know the type of `a` once we are inside of `typeck(main)`. -/// We also end up normalizing the type of `_b` during `typeck(main)` which -/// requires us to evaluate the const argument. -/// -/// To evaluate that const argument we need to know its type, -/// which we would get using `type_of(const_arg)`. This requires us to -/// resolve `foo` as it can be either `usize` or `u8` in this example. -/// However, resolving `foo` once again requires `typeck(main)` to get the type of `a`, -/// which results in a cycle. -/// -/// In short we must not call `type_of(const_arg)` during `typeck(main)`. -/// -/// When first creating the `ty::Const` of the const argument inside of `typeck` we have -/// already resolved `foo` so we know which const parameter this argument instantiates. -/// This means that we also know the expected result of `type_of(const_arg)` even if we -/// aren't allowed to call that query: it is equal to `type_of(const_param)` which is -/// trivial to compute. -/// -/// If we now want to use that constant in a place which potentially needs its type -/// we also pass the type of its `const_param`. This is the point of `WithOptConstParam`, -/// except that instead of a `Ty` we bundle the `DefId` of the const parameter. -/// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some` -/// to get the type of `did`. -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -#[derive(Hash, HashStable)] -pub struct WithOptConstParam<T> { - pub did: T, - /// The `DefId` of the corresponding generic parameter in case `did` is - /// a const argument. - /// - /// Note that even if `did` is a const argument, this may still be `None`. - /// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)` - /// to potentially update `param_did` in the case it is `None`. - pub const_param_did: Option<DefId>, -} - -impl<T> WithOptConstParam<T> { - /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`. - #[inline(always)] - pub fn unknown(did: T) -> WithOptConstParam<T> { - WithOptConstParam { did, const_param_did: None } - } -} - -impl WithOptConstParam<LocalDefId> { - /// Returns `Some((did, param_did))` if `def_id` is a const argument, - /// `None` otherwise. - #[inline(always)] - pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> { - tcx.opt_const_param_of(did).map(|param_did| (did, param_did)) - } - - /// In case `self` is unknown but `self.did` is a const argument, this returns - /// a `WithOptConstParam` with the correct `const_param_did`. - #[inline(always)] - pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> { - if self.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) { - return Some(WithOptConstParam { did: self.did, const_param_did }); - } - } - - None - } - - pub fn to_global(self) -> WithOptConstParam<DefId> { - WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did } - } - - pub fn def_id_for_type_of(self) -> DefId { - if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() } - } -} - -impl WithOptConstParam<DefId> { - pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> { - self.did - .as_local() - .map(|did| WithOptConstParam { did, const_param_did: self.const_param_did }) - } - - pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> { - if let Some(param_did) = self.const_param_did { - if let Some(did) = self.did.as_local() { - return Some((did, param_did)); - } - } - - None - } - - pub fn is_local(self) -> bool { - self.did.is_local() - } - - pub fn def_id_for_type_of(self) -> DefId { - self.const_param_did.unwrap_or(self.did) - } -} - /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. @@ -1626,27 +1502,12 @@ struct ParamTag { constness: hir::Constness, } -unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag { - const BITS: usize = 2; - #[inline] - fn into_usize(self) -> usize { - match self { - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst } => 0, - Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst } => 1, - Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const } => 2, - Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3, - } - } - #[inline] - unsafe fn from_usize(ptr: usize) -> Self { - match ptr { - 0 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, - 1 => Self { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, - 2 => Self { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, - 3 => Self { reveal: traits::Reveal::All, constness: hir::Constness::Const }, - _ => std::hint::unreachable_unchecked(), - } - } +impl_tag! { + impl Tag for ParamTag; + ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst }, + ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::NotConst }, + ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const }, + ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::Const }, } impl<'tcx> fmt::Debug for ParamEnv<'tcx> { @@ -1850,12 +1711,6 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> { pub fn into_parts(self) -> (ParamEnv<'tcx>, T) { (self.param_env, self.value) } - - #[inline] - pub fn without_const(mut self) -> Self { - self.param_env = self.param_env.without_const(); - self - } } #[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)] @@ -1969,6 +1824,16 @@ impl VariantDef { pub fn ctor_def_id(&self) -> Option<DefId> { self.ctor.map(|(_, def_id)| def_id) } + + /// Returns the one field in this variant. + /// + /// `panic!`s if there are no fields or multiple fields. + #[inline] + pub fn single_field(&self) -> &FieldDef { + assert!(self.fields.len() == 1); + + &self.fields[FieldIdx::from_u32(0)] + } } impl PartialEq for VariantDef { @@ -2361,7 +2226,7 @@ impl<'tcx> TyCtxt<'tcx> { match instance { ty::InstanceDef::Item(def) => { debug!("calling def_kind on def: {:?}", def); - let def_kind = self.def_kind(def.did); + let def_kind = self.def_kind(def); debug!("returned from def_kind: {:?}", def_kind); match def_kind { DefKind::Const @@ -2369,13 +2234,10 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::AssocConst | DefKind::Ctor(..) | DefKind::AnonConst - | DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def), + | DefKind::InlineConst => self.mir_for_ctfe(def), // If the caller wants `mir_for_ctfe` of a function they should not be using // `instance_mir`, so we'll assume const fn also wants the optimized version. - _ => { - assert_eq!(def.const_param_did, None); - self.optimized_mir(def.did) - } + _ => self.optimized_mir(def), } } ty::InstanceDef::VTableShim(..) diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 7534d06ae91..810c388ebbe 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefIndex; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use crate::ty; diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index d947d96041e..5ce32c7aaaa 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -327,6 +327,6 @@ pub fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { if def_id.is_top_level_module() { "top-level module".to_string() } else { - format!("module `{}`", tcx.def_path_str(def_id.to_def_id())) + format!("module `{}`", tcx.def_path_str(def_id)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 72caadaf661..1c1432ecd5a 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,4 +1,5 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -738,7 +739,9 @@ pub trait PrettyPrinter<'tcx>: } } ty::Placeholder(placeholder) => match placeholder.bound.kind { - ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)), + ty::BoundTyKind::Anon => { + self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { @@ -911,7 +914,7 @@ pub trait PrettyPrinter<'tcx>: // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = tcx.bound_explicit_item_bounds(def_id); + let bounds = tcx.explicit_item_bounds(def_id); let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); @@ -1172,6 +1175,18 @@ pub trait PrettyPrinter<'tcx>: } } + fn pretty_print_placeholder_var( + &mut self, + ui: ty::UniverseIndex, + var: ty::BoundVar, + ) -> Result<(), Self::Error> { + if ui == ty::UniverseIndex::ROOT { + write!(self, "!{}", var.index()) + } else { + write!(self, "!{}_{}", ui.index(), var.index()) + } + } + fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> { None } @@ -1328,13 +1343,13 @@ pub trait PrettyPrinter<'tcx>: match ct.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { - match self.tcx().def_kind(def.did) { + match self.tcx().def_kind(def) { DefKind::Const | DefKind::AssocConst => { - p!(print_value_path(def.did, substs)) + p!(print_value_path(def, substs)) } DefKind::AnonConst => { if def.is_local() - && let span = self.tcx().def_span(def.did) + && let span = self.tcx().def_span(def) && let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { p!(write("{}", snip)) @@ -1344,7 +1359,7 @@ pub trait PrettyPrinter<'tcx>: // cause printing to enter an infinite recursion if the anon const is in the self type i.e. // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {` // where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}` - p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose())) + p!(write("{}::{}", self.tcx().crate_name(def.krate), self.tcx().def_path(def).to_string_no_crate_verbose())) } } defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind), @@ -1787,17 +1802,27 @@ fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace { impl<'t> TyCtxt<'t> { /// Returns a string identifying this `DefId`. This string is /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { + pub fn def_path_str(self, def_id: impl IntoQueryParam<DefId>) -> String { self.def_path_str_with_substs(def_id, &[]) } - pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn def_path_str_with_substs( + self, + def_id: impl IntoQueryParam<DefId>, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer() } - pub fn value_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn value_path_str_with_substs( + self, + def_id: impl IntoQueryParam<DefId>, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer() @@ -2518,7 +2543,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { self.used_region_names.insert(name); } - r.super_visit_with(self) + ControlFlow::Continue(()) } // We collect types in order to prevent really large types from compiling for diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index fa9fea72344..f4456628457 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -57,7 +57,7 @@ use rustc_hir::def_id::{ use rustc_hir::hir_id::OwnerId; use rustc_hir::lang_items::{LangItem, LanguageItems}; use rustc_hir::{Crate, ItemLocalId, TraitCandidate}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; pub(crate) use rustc_query_system::query::QueryJobId; use rustc_query_system::query::*; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; @@ -76,6 +76,9 @@ use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_query_system::ich::StableHashingContext; + #[derive(Default)] pub struct QuerySystem<'tcx> { pub arenas: QueryArenas<'tcx>, @@ -202,16 +205,6 @@ macro_rules! separate_provide_extern_default { }; } -macro_rules! opt_remap_env_constness { - ([][$name:ident]) => {}; - ([(remap_env_constness) $($rest:tt)*][$name:ident]) => { - let $name = $name.without_const(); - }; - ([$other:tt $($modifiers:tt)*][$name:ident]) => { - opt_remap_env_constness!([$($modifiers)*][$name]) - }; -} - macro_rules! define_callbacks { ( $($(#[$attr:meta])* @@ -353,7 +346,6 @@ macro_rules! define_callbacks { #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { let key = key.into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) { Some(_) => return, @@ -372,7 +364,6 @@ macro_rules! define_callbacks { #[inline(always)] pub fn $name(self, key: query_helper_param_ty!($($K)*)) { let key = key.into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) { Some(_) => return, @@ -402,7 +393,6 @@ macro_rules! define_callbacks { pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> $V { let key = key.into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); restore::<$V>(match try_get_cached(self.tcx, &self.tcx.query_system.caches.$name, &key) { Some(value) => value, @@ -490,22 +480,33 @@ macro_rules! define_feedable { $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] - pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { + pub fn $name(self, value: query_provided::$name<'tcx>) { let key = self.key().into_query_param(); - opt_remap_env_constness!([$($modifiers)*][key]); let tcx = self.tcx; let erased = query_provided_to_value::$name(tcx, value); let value = restore::<$V>(erased); let cache = &tcx.query_system.caches.$name; + let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]); match try_get_cached(tcx, cache, &key) { Some(old) => { let old = restore::<$V>(old); - bug!( - "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", - stringify!($name), - ) + if let Some(hasher) = hasher { + let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx| + (hasher(&mut hcx, &value), hasher(&mut hcx, &old)) + ); + assert_eq!( + old_hash, value_hash, + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } else { + bug!( + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } } None => { let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key); @@ -517,7 +518,6 @@ macro_rules! define_feedable { hash_result!([$($modifiers)*]), ); cache.complete(key, erased, dep_node_index); - value } } } @@ -587,7 +587,7 @@ mod sealed { } } -use sealed::IntoQueryParam; +pub use sealed::IntoQueryParam; impl<'tcx> TyCtxt<'tcx> { pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 46c931d61dc..c6d10f4741a 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -7,7 +7,7 @@ use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable}; use crate::ty::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_hir as ast; +use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_target::spec::abi; use std::iter; @@ -123,8 +123,8 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>( } else { let mutbl = a.mutbl; let (variance, info) = match mutbl { - ast::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None), - ast::Mutability::Mut => { + hir::Mutability::Not => (ty::Covariant, ty::VarianceDiagInfo::None), + hir::Mutability::Mut => { (ty::Invariant, ty::VarianceDiagInfo::Invariant { ty: base_ty, param_index: 0 }) } }; @@ -239,12 +239,12 @@ impl<'tcx> Relate<'tcx> for ty::BoundConstness { } } -impl<'tcx> Relate<'tcx> for ast::Unsafety { +impl<'tcx> Relate<'tcx> for hir::Unsafety { fn relate<R: TypeRelation<'tcx>>( relation: &mut R, - a: ast::Unsafety, - b: ast::Unsafety, - ) -> RelateResult<'tcx, ast::Unsafety> { + a: hir::Unsafety, + b: hir::Unsafety, + ) -> RelateResult<'tcx, hir::Unsafety> { if a != b { Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b))) } else { diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 5c604bb6db2..b35b514d795 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -10,7 +10,7 @@ use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; use rustc_hir::def::Namespace; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_target::abi::TyAndLayout; use std::fmt; @@ -95,7 +95,7 @@ impl<'tcx> fmt::Debug for ty::FnSig<'tcx> { impl<'tcx> fmt::Debug for ty::ConstVid<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}c", self.index) + write!(f, "?{}c", self.index) } } @@ -197,7 +197,7 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { // Atomic structs // // For things that don't carry any arena-allocated data (and are -// copy...), just add them to one of these lists as appropriat. +// copy...), just add them to one of these lists as appropriate. // For things for which the type library provides traversal implementations // for all Interners, we only need to provide a Lift implementation: @@ -276,9 +276,7 @@ TrivialTypeTraversalAndLiftImpls! { } TrivialTypeTraversalAndLiftImpls! { - for<'tcx> { - ty::ValTree<'tcx>, - } + ty::ValTree<'tcx>, } /////////////////////////////////////////////////////////////////////////// @@ -583,24 +581,6 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { } } -impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( - self, - _folder: &mut F, - ) -> Result<Self, F::Error> { - Ok(self) - } -} - -impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( - &self, - _visitor: &mut V, - ) -> ControlFlow<V::BreakTy> { - ControlFlow::Continue(()) - } -} - impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 96c1577d52b..82dec7d98ad 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -19,7 +19,7 @@ use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; @@ -1436,7 +1436,7 @@ pub struct ConstVid<'tcx> { rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. #[derive(HashStable)] - #[debug_format = "'_#{}r"] + #[debug_format = "'?{}"] pub struct RegionVid {} } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index f05b873432d..63b2acdbe4e 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -21,7 +21,6 @@ use std::marker::PhantomData; use std::mem; use std::num::NonZeroUsize; use std::ops::{ControlFlow, Deref}; -use std::slice; /// An entity in the Rust type system, which can be one of /// several kinds (types, lifetimes, and consts). @@ -48,38 +47,13 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), Const(ty::Const<'tcx>), } -/// This function goes from `&'a [Ty<'tcx>]` to `&'a [GenericArg<'tcx>]` -/// -/// This is sound as, for types, `GenericArg` is just -/// `NonZeroUsize::new_unchecked(ty as *const _ as usize)` as -/// long as we use `0` for the `TYPE_TAG`. -pub fn ty_slice_as_generic_args<'a, 'tcx>(ts: &'a [Ty<'tcx>]) -> &'a [GenericArg<'tcx>] { - assert_eq!(TYPE_TAG, 0); - // SAFETY: the whole slice is valid and immutable. - // `Ty` and `GenericArg` is explained above. - unsafe { slice::from_raw_parts(ts.as_ptr().cast(), ts.len()) } -} - -impl<'tcx> List<Ty<'tcx>> { - /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. - /// - /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have - /// be interned together, see `mk_type_list` for more details. - #[inline] - pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> { - assert_eq!(TYPE_TAG, 0); - // SAFETY: `List<T>` is `#[repr(C)]`. `Ty` and `GenericArg` is explained above. - unsafe { &*(self as *const List<Ty<'tcx>> as *const List<GenericArg<'tcx>>) } - } -} - impl<'tcx> GenericArgKind<'tcx> { #[inline] fn pack(self) -> GenericArg<'tcx> { @@ -180,30 +154,45 @@ impl<'tcx> GenericArg<'tcx> { } } - /// Unpack the `GenericArg` as a region when it is known certainly to be a region. - pub fn expect_region(self) -> ty::Region<'tcx> { + #[inline] + pub fn as_type(self) -> Option<Ty<'tcx>> { match self.unpack() { - GenericArgKind::Lifetime(lt) => lt, - _ => bug!("expected a region, but found another kind"), + GenericArgKind::Type(ty) => Some(ty), + _ => None, } } + #[inline] + pub fn as_region(self) -> Option<ty::Region<'tcx>> { + match self.unpack() { + GenericArgKind::Lifetime(re) => Some(re), + _ => None, + } + } + + #[inline] + pub fn as_const(self) -> Option<ty::Const<'tcx>> { + match self.unpack() { + GenericArgKind::Const(ct) => Some(ct), + _ => None, + } + } + + /// Unpack the `GenericArg` as a region when it is known certainly to be a region. + pub fn expect_region(self) -> ty::Region<'tcx> { + self.as_region().unwrap_or_else(|| bug!("expected a region, but found another kind")) + } + /// Unpack the `GenericArg` as a type when it is known certainly to be a type. /// This is true in cases where `Substs` is used in places where the kinds are known /// to be limited (e.g. in tuples, where the only parameters are type parameters). pub fn expect_ty(self) -> Ty<'tcx> { - match self.unpack() { - GenericArgKind::Type(ty) => ty, - _ => bug!("expected a type, but found another kind"), - } + self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind")) } /// Unpack the `GenericArg` as a const when it is known certainly to be a const. pub fn expect_const(self) -> ty::Const<'tcx> { - match self.unpack() { - GenericArgKind::Const(c) => c, - _ => bug!("expected a const, but found another kind"), - } + self.as_const().unwrap_or_else(|| bug!("expected a const, but found another kind")) } pub fn is_non_region_infer(self) -> bool { @@ -268,13 +257,16 @@ pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>; pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>; impl<'tcx> InternalSubsts<'tcx> { - /// Checks whether all elements of this list are types, if so, transmute. - pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> { - self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))).then(|| { - assert_eq!(TYPE_TAG, 0); - // SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`. - unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) } - }) + /// Converts substs to a type list. + /// + /// # Panics + /// + /// If any of the generic arguments are not types. + pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List<Ty<'tcx>> { + tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.unpack() { + GenericArgKind::Type(ty) => ty, + _ => bug!("`into_type_list` called on substs with non-types"), + })) } /// Interpret these substitutions as the substitutions of a closure type. @@ -379,22 +371,17 @@ impl<'tcx> InternalSubsts<'tcx> { #[inline] pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx { - self.iter() - .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None }) + self.iter().filter_map(|k| k.as_type()) } #[inline] pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx { - self.iter().filter_map(|k| { - if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None } - }) + self.iter().filter_map(|k| k.as_region()) } #[inline] pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx { - self.iter().filter_map(|k| { - if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None } - }) + self.iter().filter_map(|k| k.as_const()) } #[inline] @@ -410,31 +397,21 @@ impl<'tcx> InternalSubsts<'tcx> { #[inline] #[track_caller] pub fn type_at(&self, i: usize) -> Ty<'tcx> { - if let GenericArgKind::Type(ty) = self[i].unpack() { - ty - } else { - bug!("expected type for param #{} in {:?}", i, self); - } + self[i].as_type().unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self)) } #[inline] #[track_caller] pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { - if let GenericArgKind::Lifetime(lt) = self[i].unpack() { - lt - } else { - bug!("expected region for param #{} in {:?}", i, self); - } + self[i] + .as_region() + .unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self)) } #[inline] #[track_caller] pub fn const_at(&self, i: usize) -> ty::Const<'tcx> { - if let GenericArgKind::Const(ct) = self[i].unpack() { - ct - } else { - bug!("expected const for param #{} in {:?}", i, self); - } + self[i].as_const().unwrap_or_else(|| bug!("expected const for param #{} in {:?}", i, self)) } #[inline] @@ -635,6 +612,12 @@ where ) -> SubstIter<'s, 'tcx, I> { SubstIter { it: self.0.into_iter(), tcx, substs } } + + /// Similar to [`subst_identity`](EarlyBinder::subst_identity), + /// but on an iterator of `TypeFoldable` values. + pub fn subst_identity_iter(self) -> I::IntoIter { + self.0.into_iter() + } } pub struct SubstIter<'s, 'tcx, I: IntoIterator> { @@ -687,6 +670,12 @@ where ) -> SubstIterCopied<'s, 'tcx, I> { SubstIterCopied { it: self.0.into_iter(), tcx, substs } } + + /// Similar to [`subst_identity`](EarlyBinder::subst_identity), + /// but on an iterator of values that deref to a `TypeFoldable`. + pub fn subst_identity_iter_copied(self) -> impl Iterator<Item = <I::Item as Deref>::Target> { + self.0.into_iter().map(|v| *v) + } } pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> { diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 6747da7abd3..e61037e5ea8 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -139,40 +139,6 @@ impl<'tcx> TyCtxt<'tcx> { treat_projections: TreatProjections, mut f: impl FnMut(DefId), ) { - let _: Option<()> = - self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| { - f(did); - None - }); - } - - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn non_blanket_impls_for_ty( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - ) -> impl Iterator<Item = DefId> + 'tcx { - let impls = self.trait_impls_of(trait_def_id); - if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { - if let Some(impls) = impls.non_blanket_impls.get(&simp) { - return impls.iter().copied(); - } - } - - [].iter().copied() - } - - /// Applies function to every impl that could possibly match the self type `self_ty` and returns - /// the first non-none value. - /// - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn find_map_relevant_impl<T>( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - treat_projections: TreatProjections, - mut f: impl FnMut(DefId) -> Option<T>, - ) -> Option<T> { // FIXME: This depends on the set of all impls for the trait. That is // unfortunate wrt. incremental compilation. // @@ -181,9 +147,7 @@ impl<'tcx> TyCtxt<'tcx> { let impls = self.trait_impls_of(trait_def_id); for &impl_def_id in impls.blanket_impls.iter() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } // Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using @@ -199,20 +163,30 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) { if let Some(impls) = impls.non_blanket_impls.get(&simp) { for &impl_def_id in impls { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } } else { for &impl_def_id in impls.non_blanket_impls.values().flatten() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } + } - None + /// `trait_def_id` MUST BE the `DefId` of a trait. + pub fn non_blanket_impls_for_ty( + self, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + ) -> impl Iterator<Item = DefId> + 'tcx { + let impls = self.trait_impls_of(trait_def_id); + if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { + if let Some(impls) = impls.non_blanket_impls.get(&simp) { + return impls.iter().copied(); + } + } + + [].iter().copied() } /// Returns an iterator containing all impls for `trait_def_id`. diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 47943b94c3b..5a0571f4bb7 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -20,7 +20,7 @@ use rustc_hir::{ hir_id::OwnerId, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, }; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_middle::mir::FakeReadCause; use rustc_session::Session; @@ -208,6 +208,9 @@ pub struct TypeckResults<'tcx> { /// Contains the data for evaluating the effect of feature `capture_disjoint_fields` /// on closure size. pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>, + + /// Container types and field indices of `offset_of!` expressions + offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>, } /// Whenever a value may be live across a generator yield, the type of that value winds up in the @@ -280,6 +283,7 @@ impl<'tcx> TypeckResults<'tcx> { generator_interior_predicates: Default::default(), treat_byte_string_as_slice: Default::default(), closure_size_eval: Default::default(), + offset_of_data: Default::default(), } } @@ -530,6 +534,14 @@ impl<'tcx> TypeckResults<'tcx> { pub fn coercion_casts(&self) -> &ItemLocalSet { &self.coercion_casts } + + pub fn offset_of_data(&self) -> LocalTableInContext<'_, (Ty<'tcx>, Vec<FieldIdx>)> { + LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data } + } + + pub fn offset_of_data_mut(&mut self) -> LocalTableInContextMut<'_, (Ty<'tcx>, Vec<FieldIdx>)> { + LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data } + } } /// Validate that the given HirId (respectively its `local_id` part) can be diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c8a78ec03d9..4c346b00256 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,7 +2,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; -use crate::ty::fast_reject::TreatProjections; use crate::ty::layout::IntegerExt; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -11,13 +10,13 @@ use crate::ty::{ use crate::ty::{GenericArgKind, SubstsRef}; use rustc_apfloat::Float as _; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_session::Limit; use rustc_span::sym; @@ -124,7 +123,7 @@ impl IntTypeExt for IntegerType { impl<'tcx> TyCtxt<'tcx> { /// Creates a hash of the type `Ty` which will be the same no matter what crate /// context it's calculated within. This is used by the `type_id` intrinsic. - pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 { + pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash64 { // We want the type_id be independent of the types free regions, so we // erase them. The erase_regions() call will also anonymize bound // regions, which is desirable too. @@ -359,21 +358,29 @@ impl<'tcx> TyCtxt<'tcx> { self.ensure().coherent_trait(drop_trait); let ty = self.type_of(adt_did).subst_identity(); - let (did, constness) = self.find_map_relevant_impl( - drop_trait, - ty, - // FIXME: This could also be some other mode, like "unexpected" - TreatProjections::ForLookup, - |impl_did| { - if let Some(item_id) = self.associated_item_def_ids(impl_did).first() { - if validate(self, impl_did).is_ok() { - return Some((*item_id, self.constness(impl_did))); - } - } - None - }, - )?; + let mut dtor_candidate = None; + self.for_each_relevant_impl(drop_trait, ty, |impl_did| { + let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + return; + }; + + if validate(self, impl_did).is_err() { + // Already `ErrorGuaranteed`, no need to delay a span bug here. + return; + } + + if let Some((old_item_id, _)) = dtor_candidate { + self.sess + .struct_span_err(self.def_span(item_id), "multiple drop impls found") + .span_note(self.def_span(old_item_id), "other impl here") + .delay_as_bug(); + } + + dtor_candidate = Some((*item_id, self.constness(impl_did))); + }); + let (did, constness) = dtor_candidate?; Some(ty::Destructor { did, constness }) } @@ -642,7 +649,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - /// Return the set of types that should be taken into accound when checking + /// Return the set of types that should be taken into account when checking /// trait bounds on a generator's internal state. pub fn generator_hidden_types( self, @@ -694,20 +701,6 @@ impl<'tcx> TyCtxt<'tcx> { if visitor.found_recursion { Err(expanded_type) } else { Ok(expanded_type) } } - pub fn bound_return_position_impl_trait_in_trait_tys( - self, - def_id: DefId, - ) -> ty::EarlyBinder<Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed>> { - ty::EarlyBinder(self.collect_return_position_impl_trait_in_trait_tys(def_id)) - } - - pub fn bound_explicit_item_bounds( - self, - def_id: DefId, - ) -> ty::EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> { - ty::EarlyBinder(self.explicit_item_bounds(def_id)) - } - /// Returns names of captured upvars for closures and generators. /// /// Here are some examples: @@ -1402,7 +1395,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool { } /// Does the equivalent of -/// ```ignore (ilustrative) +/// ```ignore (illustrative) /// let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>(); /// folder.tcx().intern_*(&v) /// ``` diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 08a62c900f9..1b07f52afca 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -33,6 +33,14 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> { } fn has_type_flags(&self, flags: TypeFlags) -> bool { + // N.B. Even though this uses a visitor, the visitor does not actually + // recurse through the whole `TypeVisitable` implementor type. + // + // Instead it stops on the first "level", visiting types, regions, + // consts and predicates just fetches their type flags. + // + // Thus this is a lot faster than it might seem and should be + // optimized to a simple field access. let res = self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); trace!(?self, ?flags, ?res, "has_type_flags"); @@ -364,7 +372,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { _ => (), }; - r.super_visit_with(self) + ControlFlow::Continue(()) } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 182945b9c3d..04a635a6803 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -194,7 +194,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::FnDef(_, substs) => { stack.extend(substs.iter().rev()); } - ty::Tuple(ts) => stack.extend(ts.as_substs().iter().rev()), + ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)), ty::GeneratorWitness(ts) => { stack.extend(ts.skip_binder().iter().rev().map(|ty| ty.into())); } diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs index 995363c0edd..627c84c388c 100644 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ b/compiler/rustc_middle/src/util/call_kind.rs @@ -2,10 +2,10 @@ //! as well as errors when attempting to call a non-const function in a const //! context. +use crate::ty::subst::SubstsRef; +use crate::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt}; use rustc_hir::def_id::DefId; use rustc_hir::{lang_items, LangItem}; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{AssocItemContainer, Instance, ParamEnv, Ty, TyCtxt}; use rustc_span::symbol::Ident; use rustc_span::{sym, DesugaringKind, Span}; diff --git a/compiler/rustc_const_eval/src/util/find_self_call.rs b/compiler/rustc_middle/src/util/find_self_call.rs index 33ad128eeeb..0eab0adf07e 100644 --- a/compiler/rustc_const_eval/src/util/find_self_call.rs +++ b/compiler/rustc_middle/src/util/find_self_call.rs @@ -1,6 +1,6 @@ -use rustc_middle::mir::*; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, TyCtxt}; +use crate::mir::*; +use crate::ty::subst::SubstsRef; +use crate::ty::{self, TyCtxt}; use rustc_span::def_id::DefId; /// Checks if the specified `local` is used as the `self` parameter of a method call diff --git a/compiler/rustc_middle/src/util/mod.rs b/compiler/rustc_middle/src/util/mod.rs new file mode 100644 index 00000000000..53b4257899b --- /dev/null +++ b/compiler/rustc_middle/src/util/mod.rs @@ -0,0 +1,7 @@ +pub mod bug; +pub mod call_kind; +pub mod common; +pub mod find_self_call; + +pub use call_kind::{call_kind, CallDesugaringKind, CallKind}; +pub use find_self_call::find_self_call; diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 55aa4fcff2c..5c38c0acc7f 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -158,8 +158,8 @@ pub fn recursive_type_error( } let items_list = { let mut s = String::new(); - for (i, (item_id, _)) in item_and_field_ids.iter().enumerate() { - let path = tcx.def_path_str(item_id.to_def_id()); + for (i, &(item_id, _)) in item_and_field_ids.iter().enumerate() { + let path = tcx.def_path_str(item_id); write!(&mut s, "`{path}`").unwrap(); if i == (ITEM_LIMIT - 1) && cycle_len > ITEM_LIMIT { write!(&mut s, " and {} more", cycle_len - 5).unwrap(); diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index f24b165d7c2..58449ee9eb4 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -14,6 +14,7 @@ rustc_apfloat = { path = "../rustc_apfloat" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index d385153ba94..32c618828c9 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -21,7 +21,7 @@ use rustc_ast::Attribute; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_hir::HirId; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::{ mir::*, thir::*, diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs index 12b2f5d8077..803207d9dc6 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::{mir::*, thir::*, ty::Ty}; use rustc_span::Span; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 99291740ac8..fbcfd433724 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -78,7 +78,7 @@ pub fn as_constant_inner<'tcx>( ExprKind::NamedConst { def_id, substs, ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); - let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = mir::UnevaluatedConst::new(def_id, substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty, span, literal } @@ -90,7 +90,7 @@ pub fn as_constant_inner<'tcx>( Constant { user_ty: None, span, literal } } ExprKind::ConstBlock { did: def_id, substs } => { - let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = mir::UnevaluatedConst::new(def_id, substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty: None, span, literal } diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index fb775766c65..7ec57add66b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -557,6 +557,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::ConstBlock { .. } | ExprKind::StaticRef { .. } | ExprKind::InlineAsm { .. } + | ExprKind::OffsetOf { .. } | ExprKind::Yield { .. } | ExprKind::ThreadLocalRef(_) | ExprKind::Call { .. } => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 8631749a524..c385b00692f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -1,6 +1,6 @@ //! See docs in `build/expr/mod.rs`. -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::ty::util::IntTypeExt; use rustc_target::abi::{Abi, FieldIdx, Primitive}; @@ -481,6 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { })))) } + ExprKind::OffsetOf { container, fields } => { + block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container)) + } + ExprKind::Literal { .. } | ExprKind::NamedConst { .. } | ExprKind::NonHirLiteral { .. } diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index d33401f0764..d9aa461c19d 100644 --- a/compiler/rustc_mir_build/src/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs @@ -67,7 +67,8 @@ impl Category { | ExprKind::Repeat { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } - | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)), + | ExprKind::ThreadLocalRef(_) + | ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), ExprKind::ConstBlock { .. } | ExprKind::Literal { .. } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 05a723a6b67..29ff916d2cc 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -163,13 +163,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // // [block: If(lhs)] -true-> [else_block: dest = (rhs)] // | (false) - // [shortcurcuit_block: dest = false] + // [shortcircuit_block: dest = false] // // Or: // // [block: If(lhs)] -false-> [else_block: dest = (rhs)] // | (true) - // [shortcurcuit_block: dest = true] + // [shortcircuit_block: dest = true] let (shortcircuit_block, mut else_block, join_block) = ( this.cfg.start_new_block(), @@ -561,7 +561,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::ZstLiteral { .. } | ExprKind::ConstParam { .. } | ExprKind::ThreadLocalRef(_) - | ExprKind::StaticRef { .. } => { + | ExprKind::StaticRef { .. } + | ExprKind::OffsetOf { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { // should be handled above Category::Rvalue(RvalueFunc::Into) => false, diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 8a03ea7e2cc..4536ecf17b8 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -77,7 +77,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | PatKind::Wild | PatKind::Binding { .. } | PatKind::Leaf { .. } - | PatKind::Deref { .. } => self.error_simplifyable(match_pair), + | PatKind::Deref { .. } => self.error_simplifiable(match_pair), } } @@ -173,7 +173,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug_assert_ne!( target_blocks[idx.index()], otherwise_block, - "no canididates for tested discriminant: {:?}", + "no candidates for tested discriminant: {:?}", discr, ); Some((discr.val, target_blocks[idx.index()])) @@ -181,7 +181,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug_assert_eq!( target_blocks[idx.index()], otherwise_block, - "found canididates for untested discriminant: {:?}", + "found candidates for untested discriminant: {:?}", discr, ); None @@ -499,7 +499,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// However, in some cases, the test may just not be relevant to candidate. /// For example, suppose we are testing whether `foo.x == 22`, but in one /// match arm we have `Foo { x: _, ... }`... in that case, the test for - /// what value `x` has has no particular relevance to this candidate. In + /// the value of `x` has no particular relevance to this candidate. In /// such cases, this function just returns None without doing anything. /// This is used by the overall `match_candidates` algorithm to structure /// the match as a whole. See `match_candidates` for more details. @@ -763,8 +763,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate.match_pairs.extend(consequent_match_pairs); } - fn error_simplifyable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> ! { - span_bug!(match_pair.pattern.span, "simplifyable pattern found: {:?}", match_pair.pattern) + fn error_simplifiable<'pat>(&mut self, match_pair: &MatchPair<'pat, 'tcx>) -> ! { + span_bug!(match_pair.pattern.span, "simplifiable pattern found: {:?}", match_pair.pattern) } fn const_range_contains( diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index bc50bcbc3d0..3f006765a71 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -11,7 +11,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{GeneratorKind, Node}; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; @@ -32,43 +32,32 @@ use super::lints; pub(crate) fn mir_built( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> &rustc_data_structures::steal::Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_built(def); - } - - let mut body = mir_build(tcx, def); - if def.const_param_did.is_some() { - assert!(matches!(body.source.instance, ty::InstanceDef::Item(_))); - body.source = MirSource::from_instance(ty::InstanceDef::Item(def.to_global())); - } - - tcx.alloc_steal_mir(body) + tcx.alloc_steal_mir(mir_build(tcx, def)) } /// Construct the MIR for a given `DefId`. -fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> { +fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // Ensure unsafeck and abstract const building is ran before we steal the THIR. - match def { - ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => { - tcx.ensure_with_value().thir_check_unsafety_for_const_arg((did, const_param_did)); - tcx.ensure_with_value().thir_abstract_const_of_const_arg((did, const_param_did)); - } - ty::WithOptConstParam { did, const_param_did: None } => { - tcx.ensure_with_value().thir_check_unsafety(did); - tcx.ensure_with_value().thir_abstract_const(did); - tcx.ensure_with_value().check_match(did); - } - } + tcx.ensure_with_value().thir_check_unsafety(def); + tcx.ensure_with_value().thir_abstract_const(def); + tcx.ensure_with_value().check_match(def); let body = match tcx.thir_body(def) { - Err(error_reported) => construct_error(tcx, def.did, error_reported), + Err(error_reported) => construct_error(tcx, def, error_reported), Ok((thir, expr)) => { // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); + tcx.ensure().check_match(def); + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + tcx.ensure().check_liveness(def); + match thir.body_type { thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, &thir, expr, fn_sig), thir::BodyTy::Const(ty) => construct_const(tcx, def, &thir, expr, ty), @@ -161,8 +150,7 @@ struct Builder<'a, 'tcx> { thir: &'a Thir<'tcx>, cfg: CFG<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, - def_id: DefId, + def_id: LocalDefId, hir_id: hir::HirId, parent_module: DefId, check_overflow: bool, @@ -428,26 +416,26 @@ macro_rules! unpack { fn construct_fn<'tcx>( tcx: TyCtxt<'tcx>, - fn_def: ty::WithOptConstParam<LocalDefId>, + fn_def: LocalDefId, thir: &Thir<'tcx>, expr: ExprId, fn_sig: ty::FnSig<'tcx>, ) -> Body<'tcx> { - let span = tcx.def_span(fn_def.did); - let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did); - let generator_kind = tcx.generator_kind(fn_def.did); + let span = tcx.def_span(fn_def); + let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def); + let generator_kind = tcx.generator_kind(fn_def); // The representation of thir for `-Zunpretty=thir-tree` relies on // the entry expression being the last element of `thir.exprs`. assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body_id = tcx.hir().body_owned_by(fn_def.did); + let body_id = tcx.hir().body_owned_by(fn_def); let span_with_body = tcx.hir().span_with_body(fn_id); let return_ty_span = tcx .hir() .fn_decl_by_hir_id(fn_id) - .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def.did)) + .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def)) .output .span(); @@ -457,7 +445,7 @@ fn construct_fn<'tcx>( }; let mut abi = fn_sig.abi; - if let DefKind::Closure = tcx.def_kind(fn_def.did) { + if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi::Rust; @@ -483,7 +471,7 @@ fn construct_fn<'tcx>( { return custom::build_custom_mir( tcx, - fn_def.did.to_def_id(), + fn_def.to_def_id(), fn_id, thir, expr, @@ -547,12 +535,12 @@ fn construct_fn<'tcx>( fn construct_const<'a, 'tcx>( tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, thir: &'a Thir<'tcx>, expr: ExprId, const_ty: Ty<'tcx>, ) -> Body<'tcx> { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); // Figure out what primary body this item has. let (span, const_ty_span) = match tcx.hir().get(hir_id) { @@ -568,10 +556,10 @@ fn construct_const<'a, 'tcx>( .. }) => (*span, ty.span), Node::AnonConst(_) => { - let span = tcx.def_span(def.did); + let span = tcx.def_span(def); (span, span) } - _ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did), + _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), }; let infcx = tcx.infer_ctxt().build(); @@ -669,7 +657,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn new( thir: &'a Thir<'tcx>, infcx: InferCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, hir_id: hir::HirId, span: Span, arg_count: usize, @@ -688,20 +676,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { check_overflow |= tcx.sess.overflow_checks(); // Constants always need overflow checks. check_overflow |= matches!( - tcx.hir().body_owner_kind(def.did), + tcx.hir().body_owner_kind(def), hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) ); let lint_level = LintLevel::Explicit(hir_id); - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); let mut builder = Builder { thir, tcx, infcx, - region_scope_tree: tcx.region_scope_tree(def.did), + region_scope_tree: tcx.region_scope_tree(def), param_env, - def, - def_id: def.did.to_def_id(), + def_id: def, hir_id, parent_module: tcx.parent_module(hir_id).to_def_id(), check_overflow, @@ -741,7 +728,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Body::new( - MirSource::item(self.def_id), + MirSource::item(self.def_id.to_def_id()), self.cfg.basic_blocks, self.source_scopes, self.local_decls, @@ -779,7 +766,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = self.tcx; self.upvars = tcx - .closure_captures(self.def.did) + .closure_captures(self.def_id) .iter() .zip(capture_tys) .enumerate() diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index f32d2db4e71..4c66c5b8eae 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -86,7 +86,7 @@ use std::mem; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::HirId; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{Expr, LintLevel}; diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 03a7f2d70fa..0506f2bf238 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -117,10 +117,10 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { } /// Handle closures/generators/inline-consts, which is unsafecked with their parent body. - fn visit_inner_body(&mut self, def: ty::WithOptConstParam<LocalDefId>) { + fn visit_inner_body(&mut self, def: LocalDefId) { if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) { let inner_thir = &inner_thir.borrow(); - let hir_context = self.tcx.hir().local_def_id_to_hir_id(def.did); + let hir_context = self.tcx.hir().local_def_id_to_hir_id(def); let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self }; inner_visitor.visit_expr(&inner_thir[expr]); // Unsafe blocks can be used in the inner body, make sure to take it into account @@ -323,6 +323,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { | ExprKind::Box { .. } | ExprKind::If { .. } | ExprKind::InlineAsm { .. } + | ExprKind::OffsetOf { .. } | ExprKind::LogicalOp { .. } | ExprKind::Use { .. } => { // We don't need to save the old value and restore it @@ -396,18 +397,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { movability: _, fake_reads: _, }) => { - let closure_def = if let Some((did, const_param_id)) = - ty::WithOptConstParam::try_lookup(closure_id, self.tcx) - { - ty::WithOptConstParam { did, const_param_did: Some(const_param_id) } - } else { - ty::WithOptConstParam::unknown(closure_id) - }; - self.visit_inner_body(closure_def); + self.visit_inner_body(closure_id); } ExprKind::ConstBlock { did, substs: _ } => { let def_id = did.expect_local(); - self.visit_inner_body(ty::WithOptConstParam::unknown(def_id)); + self.visit_inner_body(def_id); } ExprKind::Field { lhs, .. } => { let lhs = &self.thir[lhs]; @@ -706,14 +700,14 @@ impl UnsafeOpKind { } } -pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { +pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { // THIR unsafeck is gated under `-Z thir-unsafeck` if !tcx.sess.opts.unstable_opts.thir_unsafeck { return; } // Closures and inline consts are handled by their owner, if it has a body - if tcx.is_typeck_child(def.did.to_def_id()) { + if tcx.is_typeck_child(def.to_def_id()) { return; } @@ -726,7 +720,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { return; } - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| { if fn_sig.header.unsafety == hir::Unsafety::Unsafe { BodyUnsafety::Unsafe(fn_sig.span) @@ -734,7 +728,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { BodyUnsafety::Safe } }); - let body_target_features = &tcx.body_codegen_attrs(def.did.to_def_id()).target_features; + let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features; let safety_context = if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }; let mut visitor = UnsafetyVisitor { @@ -746,23 +740,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { body_target_features, assignment_info: None, in_union_destructure: false, - param_env: tcx.param_env(def.did), + param_env: tcx.param_env(def), inside_adt: false, }; visitor.visit_expr(&thir[expr]); } - -pub(crate) fn thir_check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.thir_check_unsafety_for_const_arg(def) - } else { - check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id)) - } -} - -pub(crate) fn thir_check_unsafety_for_const_arg( - tcx: TyCtxt<'_>, - (did, param_did): (LocalDefId, DefId), -) { - check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) -} diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 43e787db41a..dcdeaf008d6 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -384,13 +384,8 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { diag.span_note(span, fluent::mir_build_def_note); } - let is_variant_list_non_exhaustive = match self.ty.kind() { - ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => { - true - } - _ => false, - }; - + let is_variant_list_non_exhaustive = matches!(self.ty.kind(), + ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local()); if is_variant_list_non_exhaustive { diag.note(fluent::mir_build_non_exhaustive_type_note); } else { diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 3f9236c9dd9..2765a107cf0 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -25,7 +25,7 @@ pub mod thir; use rustc_middle::ty::query::Providers; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; fluent_messages! { "../messages.ftl" } @@ -35,7 +35,6 @@ pub fn provide(providers: &mut Providers) { providers.lit_to_mir_constant = build::lit_to_mir_constant; providers.mir_built = build::mir_built; providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; - providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg; providers.thir_body = thir::cx::thir_body; providers.thir_tree = thir::print::thir_tree; providers.thir_flat = thir::print::thir_flat; diff --git a/compiler/rustc_mir_build/src/thir/cx/block.rs b/compiler/rustc_mir_build/src/thir/cx/block.rs index 8aacec53f94..a46ad6423a0 100644 --- a/compiler/rustc_mir_build/src/thir/cx/block.rs +++ b/compiler/rustc_mir_build/src/thir/cx/block.rs @@ -5,7 +5,7 @@ use rustc_middle::middle::region; use rustc_middle::thir::*; use rustc_middle::ty; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::ty::CanonicalUserTypeAnnotation; impl<'tcx> Cx<'tcx> { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 8e2e92e6f6a..f46eb5a0ce1 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -5,7 +5,7 @@ use crate::thir::util::UserAnnotatedTyHelpers; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; @@ -664,6 +664,14 @@ impl<'tcx> Cx<'tcx> { line_spans: asm.line_spans, })), + hir::ExprKind::OffsetOf(_, _) => { + let data = self.typeck_results.offset_of_data(); + let &(container, ref indices) = data.get(expr.hir_id).unwrap(); + let fields = tcx.mk_fields_from_iter(indices.iter().copied()); + + ExprKind::OffsetOf { container, fields } + } + hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results().node_type(anon_const.hir_id); let did = anon_const.def_id.to_def_id(); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 070544446e3..463f639defe 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -20,25 +20,25 @@ use rustc_span::Span; pub(crate) fn thir_body( tcx: TyCtxt<'_>, - owner_def: ty::WithOptConstParam<LocalDefId>, + owner_def: LocalDefId, ) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); - let body = hir.body(hir.body_owned_by(owner_def.did)); + let body = hir.body(hir.body_owned_by(owner_def)); let mut cx = Cx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); } let expr = cx.mirror_expr(&body.value); - let owner_id = hir.local_def_id_to_hir_id(owner_def.did); + let owner_id = hir.local_def_id_to_hir_id(owner_def); if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) { - let closure_env_param = cx.closure_env_param(owner_def.did, owner_id); + let closure_env_param = cx.closure_env_param(owner_def, owner_id); let explicit_params = cx.explicit_params(owner_id, fn_decl, body); cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect(); // The resume argument may be missing, in that case we need to provide it here. // It will always be `()` in this case. - if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() { + if tcx.def_kind(owner_def) == DefKind::Generator && body.params.is_empty() { cx.thir.params.push(Param { ty: tcx.mk_unit(), pat: None, @@ -78,13 +78,12 @@ struct Cx<'tcx> { } impl<'tcx> Cx<'tcx> { - fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> { - let typeck_results = tcx.typeck_opt_const_arg(def); - let did = def.did; + fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> { + let typeck_results = tcx.typeck(def); let hir = tcx.hir(); - let hir_id = hir.local_def_id_to_hir_id(did); + let hir_id = hir.local_def_id_to_hir_id(def); - let body_type = if hir.body_owner_kind(did).is_fn_or_closure() { + let body_type = if hir.body_owner_kind(def).is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) @@ -106,11 +105,11 @@ impl<'tcx> Cx<'tcx> { Cx { tcx, thir: Thir::new(body_type), - param_env: tcx.param_env(def.did), - region_scope_tree: tcx.region_scope_tree(def.did), + param_env: tcx.param_env(def), + region_scope_tree: tcx.region_scope_tree(def), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, - body_owner: did.to_def_id(), + body_owner: def.to_def_id(), adjustment_span: None, apply_adjustments: hir .attrs(hir_id) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index bac46db2b1e..2b52d70af2a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -27,7 +27,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::Span; pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return }; + let Ok((thir, expr)) = tcx.thir_body(def_id) else { return }; let thir = thir.borrow(); let pattern_arena = TypedArena::default(); let mut visitor = MatchVisitor { @@ -671,10 +671,8 @@ fn non_exhaustive_match<'p, 'tcx>( }; }; - let is_variant_list_non_exhaustive = match scrut_ty.kind() { - ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => true, - _ => false, - }; + let is_variant_list_non_exhaustive = matches!(scrut_ty.kind(), + ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local()); adt_defined_here(cx, &mut err, scrut_ty, &witnesses); err.note(&format!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 32d0404bd07..6a7a9a92279 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,5 +1,5 @@ use rustc_hir as hir; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::mir; @@ -156,7 +156,7 @@ impl<'tcx> ConstToPat<'tcx> { if let Some(non_sm_ty) = structural { if !self.type_may_have_partial_eq_impl(cv.ty()) { - // fatal avoids ICE from resolution of non-existent method (rare case). + // fatal avoids ICE from resolution of nonexistent method (rare case). self.tcx() .sess .emit_fatal(TypeNotStructural { span: self.span, non_sm_ty: non_sm_ty }); diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 7c29196447c..9af13781312 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -52,7 +52,7 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::captures::Captures; use rustc_hir::{HirId, RangeEnd}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 70d015a39e4..0a3423bdd37 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -16,7 +16,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::RangeEnd; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::interpret::{ ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar, }; diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ed61d6ee78b..b2f2a64e29c 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::LocalDefId; use std::fmt::{self, Write}; -pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { +pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => { let thir = thir.steal(); @@ -15,7 +15,7 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalD } } -pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { +pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), @@ -519,6 +519,19 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_inline_asm_expr(&**expr, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } + OffsetOf { container, fields } => { + print_indented!(self, "OffsetOf {", depth_lvl); + print_indented!(self, format!("container: {:?}", container), depth_lvl + 1); + print_indented!(self, "fields: [", depth_lvl + 1); + + for field in fields.iter() { + print_indented!(self, format!("{:?}", field), depth_lvl + 2); + print_indented!(self, ",", depth_lvl + 1); + } + + print_indented!(self, "]", depth_lvl + 1); + print_indented!(self, "}", depth_lvl); + } ThreadLocalRef(def_id) => { print_indented!(self, "ThreadLocalRef {", depth_lvl); print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1); diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 68c61a18d72..4a296bb3367 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -13,6 +13,7 @@ tracing = "0.1" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index bd8ec82dffd..2e68c794356 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -1,6 +1,6 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; use rustc_middle::traits::Reveal; diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 2abdee064a6..3e8f792e634 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -12,7 +12,7 @@ use rustc_ast as ast; use rustc_data_structures::work_queue::WorkQueue; use rustc_graphviz as dot; use rustc_hir::def_id::DefId; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::{self, traversal, BasicBlock}; use rustc_middle::mir::{create_dump_file, dump_enabled}; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs index 490be166a91..6a256fae3ca 100644 --- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs +++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs @@ -2,7 +2,7 @@ //! analysis. use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use std::fmt; /// An extension to `fmt::Debug` for data that can be better printed with some auxiliary data `C`. diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index 8fdac7b2cf5..af44a4329bf 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -40,7 +40,7 @@ use crate::framework::BitSetExt; use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use std::iter; /// A [partially ordered set][poset] that has a [least upper bound][lub] for any pair of elements diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index d9aff94fef2..f2263007f6f 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -33,7 +33,7 @@ use std::cmp::Ordering; use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::{self, BasicBlock, Location}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs index 60679b17d6c..0fed305b930 100644 --- a/compiler/rustc_mir_dataflow/src/framework/tests.rs +++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::{self, BasicBlock, Location}; use rustc_middle::ty; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index 4b5324e203a..2a0aff55083 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -3,7 +3,7 @@ //! zero-sized structure. use rustc_index::bit_set::{BitSet, ChunkedBitSet}; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::visit::{MirVisitable, Visitor}; use rustc_middle::mir::{self, Body, Location}; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 43caa2ea973..fc4efb943e6 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -16,8 +16,8 @@ extern crate rustc_middle; use rustc_ast::MetaItem; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def_id::DefId; -use rustc_macros::fluent_messages; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 64ed7a29f6f..096bc0acfcc 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -1,6 +1,6 @@ use crate::move_paths::FxHashMap; use crate::un_derefer::UnDerefer; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::tcx::RvalueInitializationState; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; @@ -360,7 +360,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { | Rvalue::AddressOf(..) | Rvalue::Discriminant(..) | Rvalue::Len(..) - | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} + | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {} } } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 257a42cddc8..ab1a6715361 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -1,6 +1,6 @@ use crate::move_paths::builder::MoveDat; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::*; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_span::Span; @@ -20,7 +20,7 @@ rustc_index::newtype_index! { impl polonius_engine::Atom for MovePathIndex { fn index(self) -> usize { - rustc_index::vec::Idx::index(self) + rustc_index::Idx::index(self) } } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 98bebc9b13b..fdff1ec788d 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -36,7 +36,7 @@ use std::fmt::{Debug, Formatter}; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -366,7 +366,7 @@ where rustc_index::newtype_index!( /// This index uniquely identifies a place. /// - /// Not every place has a `PlaceIndex`, and not every `PlaceIndex` correspondends to a tracked + /// Not every place has a `PlaceIndex`, and not every `PlaceIndex` corresponds to a tracked /// place. However, every tracked place and all places along its projection have a `PlaceIndex`. pub struct PlaceIndex {} ); diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs index e1e354efa1c..fb4705e0754 100644 --- a/compiler/rustc_mir_transform/src/add_call_guards.rs +++ b/compiler/rustc_mir_transform/src/add_call_guards.rs @@ -1,5 +1,5 @@ use crate::MirPass; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs index 896fcd9cdd6..b29ffcc70f9 100644 --- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs +++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::patch::MirPatch; /// they are dropped from an aligned address. /// /// For example, if we have something like -/// ```ignore (ilustrative) +/// ```ignore (illustrative) /// #[repr(packed)] /// struct Foo { /// dealign: u8, @@ -25,7 +25,7 @@ use rustc_middle::mir::patch::MirPatch; /// its address is not aligned. /// /// Instead, we move `foo.data` to a local and drop that: -/// ```ignore (ilustrative) +/// ```ignore (illustrative) /// storage.live(drop_temp) /// drop_temp = foo.data; /// drop(drop_temp) -> next diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 916f2904dda..187d38b385b 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -59,7 +59,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { let basic_blocks = body.basic_blocks.as_mut(); let local_decls = &body.local_decls; let needs_retag = |place: &Place<'tcx>| { - !place.has_deref() // we're not eally interested in stores to "outside" locations, they are hard to keep track of anyway + !place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx) && !local_decls[place.local].is_deref_temp() }; diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index c76dc56065c..e99712eeef8 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -1,7 +1,7 @@ use crate::MirPass; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::*; use rustc_middle::mir::{ interpret::{ConstValue, Scalar}, diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 3d32c586554..57b24c9c552 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -134,7 +134,12 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { // the `self` parameter of a method call (as the terminator of our current // BasicBlock). If so, we emit a more specific lint. let method_did = self.target_local.and_then(|target_local| { - crate::util::find_self_call(self.tcx, &self.body, target_local, loc.block) + rustc_middle::util::find_self_call( + self.tcx, + &self.body, + target_local, + loc.block, + ) }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index d908f6b3a9b..ce6d865a7dc 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -148,7 +148,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { - let def_id = uv.def.def_id_for_type_of(); + let def_id = uv.def; if self.tcx.def_kind(def_id) == DefKind::InlineConst { let local_def_id = def_id.expect_local(); let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = @@ -375,22 +375,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { - unsafety_check_result: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.unsafety_check_result_for_const_arg(def) - } else { - unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - unsafety_check_result_for_const_arg: |tcx, (did, param_did)| { - unsafety_check_result( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - ) - }, - ..*providers - }; + *providers = Providers { unsafety_check_result, ..*providers }; } /// Context information for [`UnusedUnsafeVisitor`] traversal, @@ -492,10 +477,7 @@ fn check_unused_unsafe( unused_unsafes } -fn unsafety_check_result( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &UnsafetyCheckResult { +fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult { debug!("unsafety_violations({:?})", def); // N.B., this borrow is valid because all the consumers of @@ -510,13 +492,13 @@ fn unsafety_check_result( }); } - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); - let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); + let mut checker = UnsafetyChecker::new(body, def, tcx, param_env); checker.visit_body(&body); - let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id())) - .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks)); + let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id())) + .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks)); tcx.arena.alloc(UnsafetyCheckResult { violations: checker.violations, diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 0923824db48..d435d3ee69b 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -24,7 +24,6 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) - | StatementKind::PlaceMention(..) | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) | StatementKind::FakeRead(..) => statement.make_nop(), _ => (), diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 6f0ae4f07ab..f662ce645b0 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -10,19 +10,19 @@ use rustc_middle::{ }; use crate::MirPass; -use rustc_index::{bit_set::BitSet, vec::IndexVec}; +use rustc_index::{bit_set::BitSet, IndexVec}; pub struct ConstDebugInfo; impl<'tcx> MirPass<'tcx> for ConstDebugInfo { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.opts.unstable_opts.unsound_mir_opts && sess.mir_opt_level() > 0 + sess.mir_opt_level() > 0 } fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { trace!("running ConstDebugInfo on {:?}", body.source); - for (local, constant) in find_optimization_oportunities(body) { + for (local, constant) in find_optimization_opportunities(body) { for debuginfo in &mut body.var_debug_info { if let VarDebugInfoContents::Place(p) = debuginfo.value { if p.local == local && p.projection.is_empty() { @@ -45,7 +45,7 @@ struct LocalUseVisitor { local_assignment_locations: IndexVec<Local, Option<Location>>, } -fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Constant<'tcx>)> { +fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Constant<'tcx>)> { let mut visitor = LocalUseVisitor { local_mutating_uses: IndexVec::from_elem(0, &body.local_decls), local_assignment_locations: IndexVec::from_elem(None, &body.local_decls), diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index c0146e3efb0..96bae26e39c 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -7,7 +7,7 @@ use rustc_const_eval::const_eval::CheckAlignment; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{ MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor, }; @@ -826,7 +826,7 @@ impl Visitor<'_> for CanConstProp { | NonMutatingUse(NonMutatingUseContext::AddressOf) | MutatingUse(MutatingUseContext::Borrow) | MutatingUse(MutatingUseContext::AddressOf) => { - trace!("local {:?} can't be propagaged because it's used: {:?}", local, context); + trace!("local {:?} can't be propagated because it's used: {:?}", local, context); self.can_const_prop[local] = ConstPropMode::NoPropagation; } } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 699fe44892b..3a105a2abae 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -493,7 +493,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { cond: &Operand<'tcx>, location: Location, ) -> Option<!> { - let ref value = self.eval_operand(&cond, location)?; + let value = &self.eval_operand(&cond, location)?; trace!("assertion on {:?} should be {:?}", value, expected); let expected = Scalar::from_bool(expected); diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index c155048c98b..3922ed2fbf7 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -1,5 +1,5 @@ use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/coverage/debug.rs b/compiler/rustc_mir_transform/src/coverage/debug.rs index 725883b83fa..e554c470646 100644 --- a/compiler/rustc_mir_transform/src/coverage/debug.rs +++ b/compiler/rustc_mir_transform/src/coverage/debug.rs @@ -292,10 +292,8 @@ impl DebugCounters { } pub fn some_block_label(&self, operand: ExpressionOperandId) -> Option<&String> { - self.some_counters.as_ref().map_or(None, |counters| { - counters - .get(&operand) - .map_or(None, |debug_counter| debug_counter.some_block_label.as_ref()) + self.some_counters.as_ref().and_then(|counters| { + counters.get(&operand).and_then(|debug_counter| debug_counter.some_block_label.as_ref()) }) } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 7391a77b0a6..986d2fd190d 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::dominators::{self, Dominators}; use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode}; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind}; @@ -111,7 +111,7 @@ impl CoverageGraph { if predecessors.len() > 1 { "predecessors.len() > 1".to_owned() } else { - format!("bb {} is not in precessors: {:?}", bb.index(), predecessors) + format!("bb {} is not in predecessors: {:?}", bb.index(), predecessors) } ); } diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 5ecb2d6a631..9b3c06fab50 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -16,7 +16,7 @@ use crate::MirPass; use rustc_data_structures::graph::WithNumNodes; use rustc_data_structures::sync::Lrc; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::hir; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::coverage::*; @@ -577,5 +577,10 @@ fn get_body_span<'tcx>( fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx>) -> u64 { // FIXME(cjgillot) Stop hashing HIR manually here. let owner = hir_body.id().hir_id.owner; - tcx.hir_owner_nodes(owner).unwrap().opt_hash_including_bodies.unwrap().to_smaller_hash() + tcx.hir_owner_nodes(owner) + .unwrap() + .opt_hash_including_bodies + .unwrap() + .to_smaller_hash() + .as_u64() } diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 3bd7f31b45d..bf01b45eb40 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -164,7 +164,6 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool { /// whether that means const mir or runtime mir. For `const fn` this opts for runtime /// mir. fn mir_body(tcx: TyCtxt<'_>, def_id: DefId) -> &mir::Body<'_> { - let id = ty::WithOptConstParam::unknown(def_id); - let def = ty::InstanceDef::Item(id); + let def = ty::InstanceDef::Item(def_id); tcx.instance_mir(def) } diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index 0f6c06e370b..83a335197b3 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -34,7 +34,7 @@ use coverage_test_macros::let_bcb; use itertools::Itertools; use rustc_data_structures::graph::WithNumNodes; use rustc_data_structures::graph::WithSuccessors; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::*; use rustc_middle::ty; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index d4db7e2de40..254b704f9fc 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -70,22 +70,6 @@ struct ConstAnalysis<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, } -impl<'tcx> ConstAnalysis<'_, 'tcx> { - fn eval_discriminant( - &self, - enum_ty: Ty<'tcx>, - variant_index: VariantIdx, - ) -> Option<ScalarTy<'tcx>> { - if !enum_ty.is_enum() { - return None; - } - let discr = enum_ty.discriminant_for_variant(self.tcx, variant_index)?; - let discr_layout = self.tcx.layout_of(self.param_env.and(discr.ty)).ok()?; - let discr_value = Scalar::try_from_uint(discr.val, discr_layout.size)?; - Some(ScalarTy(discr_value, discr.ty)) - } -} - impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { type Value = FlatSet<ScalarTy<'tcx>>; @@ -126,59 +110,55 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { // we must make sure that all `target as Variant#i` are `Top`. state.flood(target.as_ref(), self.map()); - if let Some(target_idx) = self.map().find(target.as_ref()) { - let (variant_target, variant_index) = match **kind { - AggregateKind::Tuple | AggregateKind::Closure(..) => { - (Some(target_idx), None) - } - AggregateKind::Adt(def_id, variant_index, ..) => { - match self.tcx.def_kind(def_id) { - DefKind::Struct => (Some(target_idx), None), - DefKind::Enum => ( - self.map.apply(target_idx, TrackElem::Variant(variant_index)), - Some(variant_index), - ), - _ => (None, None), - } - } - _ => (None, None), - }; - if let Some(variant_target_idx) = variant_target { - for (field_index, operand) in operands.iter().enumerate() { - if let Some(field) = self.map().apply( - variant_target_idx, - TrackElem::Field(FieldIdx::from_usize(field_index)), - ) { - let result = self.handle_operand(operand, state); - state.insert_idx(field, result, self.map()); - } + let Some(target_idx) = self.map().find(target.as_ref()) else { return }; + + let (variant_target, variant_index) = match **kind { + AggregateKind::Tuple | AggregateKind::Closure(..) => (Some(target_idx), None), + AggregateKind::Adt(def_id, variant_index, ..) => { + match self.tcx.def_kind(def_id) { + DefKind::Struct => (Some(target_idx), None), + DefKind::Enum => ( + self.map.apply(target_idx, TrackElem::Variant(variant_index)), + Some(variant_index), + ), + _ => return, } } - if let Some(variant_index) = variant_index - && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant) - { - // We are assigning the discriminant as part of an aggregate. - // This discriminant can only alias a variant field's value if the operand - // had an invalid value for that type. - // Using invalid values is UB, so we are allowed to perform the assignment - // without extra flooding. - let enum_ty = target.ty(self.local_decls, self.tcx).ty; - if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) { - state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map); + _ => return, + }; + if let Some(variant_target_idx) = variant_target { + for (field_index, operand) in operands.iter().enumerate() { + if let Some(field) = self.map().apply( + variant_target_idx, + TrackElem::Field(FieldIdx::from_usize(field_index)), + ) { + let result = self.handle_operand(operand, state); + state.insert_idx(field, result, self.map()); } } } + if let Some(variant_index) = variant_index + && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant) + { + // We are assigning the discriminant as part of an aggregate. + // This discriminant can only alias a variant field's value if the operand + // had an invalid value for that type. + // Using invalid values is UB, so we are allowed to perform the assignment + // without extra flooding. + let enum_ty = target.ty(self.local_decls, self.tcx).ty; + if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) { + state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map); + } + } } Rvalue::CheckedBinaryOp(op, box (left, right)) => { // Flood everything now, so we can use `insert_value_idx` directly later. state.flood(target.as_ref(), self.map()); - let target = self.map().find(target.as_ref()); + let Some(target) = self.map().find(target.as_ref()) else { return }; - let value_target = target - .and_then(|target| self.map().apply(target, TrackElem::Field(0_u32.into()))); - let overflow_target = target - .and_then(|target| self.map().apply(target, TrackElem::Field(1_u32.into()))); + let value_target = self.map().apply(target, TrackElem::Field(0_u32.into())); + let overflow_target = self.map().apply(target, TrackElem::Field(1_u32.into())); if value_target.is_some() || overflow_target.is_some() { let (val, overflow) = self.binary_op(state, *op, left, right); @@ -323,7 +303,7 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> { impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map) -> Self { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); Self { map, tcx, @@ -351,7 +331,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } (FlatSet::Bottom, _) | (_, FlatSet::Bottom) => (FlatSet::Bottom, FlatSet::Bottom), (_, _) => { - // Could attempt some algebraic simplifcations here. + // Could attempt some algebraic simplifications here. (FlatSet::Top, FlatSet::Top) } } @@ -377,6 +357,20 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { } } + fn eval_discriminant( + &self, + enum_ty: Ty<'tcx>, + variant_index: VariantIdx, + ) -> Option<ScalarTy<'tcx>> { + if !enum_ty.is_enum() { + return None; + } + let discr = enum_ty.discriminant_for_variant(self.tcx, variant_index)?; + let discr_layout = self.tcx.layout_of(self.param_env.and(discr.ty)).ok()?; + let discr_value = Scalar::try_from_uint(discr.val, discr_layout.size)?; + Some(ScalarTy(discr_value, discr.ty)) + } + fn wrap_scalar(&self, scalar: Scalar, ty: Ty<'tcx>) -> FlatSet<ScalarTy<'tcx>> { FlatSet::Elem(ScalarTy(scalar, ty)) } @@ -520,21 +514,6 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> { _ => (), } } - - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - match rvalue { - Rvalue::Discriminant(place) => { - match self.state.get_discr(place.as_ref(), self.visitor.map) { - FlatSet::Top => (), - FlatSet::Elem(value) => { - self.visitor.before_effect.insert((location, *place), value); - } - FlatSet::Bottom => (), - } - } - _ => self.super_rvalue(rvalue, location), - } - } } struct DummyMachine; diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 18c407b42d3..7bc5183a00a 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -54,11 +54,10 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS | StatementKind::Coverage(_) | StatementKind::Intrinsic(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(_) | StatementKind::Nop => (), - StatementKind::FakeRead(_) - | StatementKind::PlaceMention(_) - | StatementKind::AscribeUserType(_, _) => { + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase!", &statement.kind) } } diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs index e5c3fa5646a..8ee08c5be34 100644 --- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs +++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitSet; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{Body, Local, Location, Operand, Terminator, TerminatorKind, RETURN_PLACE}; -use rustc_middle::ty::{self, DeducedParamAttrs, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::{self, DeducedParamAttrs, Ty, TyCtxt}; use rustc_session::config::OptLevel; /// A visitor that determines which arguments have been mutated. We can't use the mutability field @@ -198,11 +198,12 @@ pub fn deduced_param_attrs<'tcx>( // see [1]. // // [1]: https://github.com/rust-lang/rust/pull/103172#discussion_r999139997 + let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut deduced_param_attrs = tcx.arena.alloc_from_iter( body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map( |(arg_index, local_decl)| DeducedParamAttrs { read_only: !deduce_read_only.mutable_args.contains(arg_index) - && local_decl.ty.is_freeze(tcx, ParamEnv::reveal_all()), + && local_decl.ty.is_freeze(tcx, param_env), }, ), ); diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index b8a5b92be4a..a39026751a7 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -1,5 +1,5 @@ use crate::MirPass; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{MutVisitor, PlaceContext}; diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 39164917770..78758e2db28 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -69,7 +69,7 @@ //! of this is that such liveness analysis can report more accurate results about whole locals at //! a time. For example, consider: //! -//! ```ignore (syntax-highliting-only) +//! ```ignore (syntax-highlighting-only) //! _1 = u; //! // unrelated code //! _1.f1 = v; @@ -360,7 +360,7 @@ struct FilterInformation<'a, 'body, 'alloc, 'tcx> { } // We first implement some utility functions which we will expose removing candidates according to -// different needs. Throughout the livenss filtering, the `candidates` are only ever accessed +// different needs. Throughout the liveness filtering, the `candidates` are only ever accessed // through these methods, and not directly. impl<'alloc> Candidates<'alloc> { /// Just `Vec::retain`, but the condition is inverted and we add debugging output @@ -582,10 +582,9 @@ impl WriteInfo { | StatementKind::Nop | StatementKind::Coverage(_) | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) => (), - StatementKind::FakeRead(_) - | StatementKind::AscribeUserType(_, _) - | StatementKind::PlaceMention(_) => { + | StatementKind::StorageDead(_) + | StatementKind::PlaceMention(_) => (), + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase", statement) } } diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 85623499439..f31653caa49 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -4,7 +4,7 @@ use crate::MirPass; use rustc_hir::def_id::DefId; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index a702113bd99..1e115be2c2a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -24,7 +24,7 @@ use std::fmt; /// In general, the compiler cannot determine at compile time whether a destructor will run or not. /// /// At a high level, this pass refines Drop to only run the destructor if the -/// target is initialized. The way this is achievied is by inserting drop flags for every variable +/// target is initialized. The way this is achieved is by inserting drop flags for every variable /// that may be dropped, and then using those flags to determine whether a destructor should run. /// Once this is complete, Drop terminators in the MIR correspond to a call to the "drop glue" or /// "drop shim" for the type of the dropped place. diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index c9b24adba0c..db68adc8bc9 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -48,7 +48,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { return false; } - let body = &*tcx.mir_built(ty::WithOptConstParam::unknown(local_def_id)).borrow(); + let body = &*tcx.mir_built(local_def_id).borrow(); let body_ty = tcx.type_of(def_id).skip_binder(); let body_abi = match body_ty.kind() { diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 8601c1b2d71..f26c6de9648 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -3,7 +3,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use rustc_middle::ty::{self, EarlyBinder, GenericArgKind, PredicateKind, SubstsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt}; use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES; use rustc_span::{symbol::sym, Span}; use rustc_target::spec::abi::Abi; @@ -45,14 +45,12 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { // Handle calls to `transmute` if self.tcx.is_diagnostic_item(sym::transmute, def_id) { let arg_ty = args[0].ty(self.body, self.tcx); - for generic_inner_ty in arg_ty.walk() { - if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { - if let Some((fn_id, fn_substs)) = - FunctionItemRefChecker::is_fn_ref(inner_ty) - { - let span = self.nth_arg_span(&args, 0); - self.emit_lint(fn_id, fn_substs, source_info, span); - } + for inner_ty in arg_ty.walk().filter_map(|arg| arg.as_type()) { + if let Some((fn_id, fn_substs)) = + FunctionItemRefChecker::is_fn_ref(inner_ty) + { + let span = self.nth_arg_span(&args, 0); + self.emit_lint(fn_id, fn_substs, source_info, span); } } } else { @@ -82,24 +80,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs(); for (arg_num, arg_def) in arg_defs.iter().enumerate() { // For all types reachable from the argument type in the fn sig - for generic_inner_ty in arg_def.walk() { - if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { - // If the inner type matches the type bound by `Pointer` - if inner_ty == bound_ty { - // Do a substitution using the parameters from the callsite - let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); - if let Some((fn_id, fn_substs)) = - FunctionItemRefChecker::is_fn_ref(subst_ty) - { - let mut span = self.nth_arg_span(args, arg_num); - if span.from_expansion() { - // The operand's ctxt wouldn't display the lint since it's inside a macro so - // we have to use the callsite's ctxt. - let callsite_ctxt = span.source_callsite().ctxt(); - span = span.with_ctxt(callsite_ctxt); - } - self.emit_lint(fn_id, fn_substs, source_info, span); + for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) { + // If the inner type matches the type bound by `Pointer` + if inner_ty == bound_ty { + // Do a substitution using the parameters from the callsite + let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); + if let Some((fn_id, fn_substs)) = + FunctionItemRefChecker::is_fn_ref(subst_ty) + { + let mut span = self.nth_arg_span(args, arg_num); + if span.from_expansion() { + // The operand's ctxt wouldn't display the lint since it's inside a macro so + // we have to use the callsite's ctxt. + let callsite_ctxt = span.source_callsite().ctxt(); + span = span.with_ctxt(callsite_ctxt); } + self.emit_lint(fn_id, fn_substs, source_info, span); } } } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 4c4423721fb..e44dd084b2d 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -59,7 +59,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir::GeneratorKind; use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::dump_mir; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -1399,7 +1399,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( ) -> GeneratorLayout<'tcx> { assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir); - let (body, _) = tcx.mir_promoted(ty::WithOptConstParam::unknown(def_id)); + let (body, _) = tcx.mir_promoted(def_id); let body = body.borrow(); let body = &*body; @@ -1800,7 +1800,7 @@ fn check_must_not_suspend_ty<'tcx>( // FIXME: support adding the attribute to TAITs ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { let mut has_emitted = false; - for &(predicate, _) in tcx.explicit_item_bounds(def) { + for &(predicate, _) in tcx.explicit_item_bounds(def).skip_binder() { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait(ref poly_trait_predicate)) = predicate.kind().skip_binder() @@ -1869,7 +1869,7 @@ fn check_must_not_suspend_ty<'tcx>( }, ) } - // If drop tracking is enabled, we want to look through references, since the referrent + // If drop tracking is enabled, we want to look through references, since the referent // may not be considered live across the await point. ty::Ref(_region, ty, _mutability) => { let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index f0cb317f449..71bdfd5aae1 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -3,7 +3,7 @@ use crate::deref_separator::deref_finder; use rustc_attr::InlineAttr; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; @@ -26,8 +26,6 @@ const CALL_PENALTY: usize = 25; const LANDINGPAD_PENALTY: usize = 50; const RESUME_PENALTY: usize = 45; -const UNKNOWN_SIZE_COST: usize = 10; - const TOP_DOWN_DEPTH_LIMIT: usize = 5; pub struct Inline; @@ -350,14 +348,8 @@ impl<'tcx> Inliner<'tcx> { callsite: &CallSite<'tcx>, callee_attrs: &CodegenFnAttrs, ) -> Result<(), &'static str> { - match callee_attrs.inline { - InlineAttr::Never => return Err("never inline hint"), - InlineAttr::Always | InlineAttr::Hint => {} - InlineAttr::None => { - if self.tcx.sess.mir_opt_level() <= 2 { - return Err("at mir-opt-level=2, only #[inline] is inlined"); - } - } + if let InlineAttr::Never = callee_attrs.inline { + return Err("never inline hint"); } // Only inline local functions if they would be eligible for cross-crate @@ -470,12 +462,6 @@ impl<'tcx> Inliner<'tcx> { } } - // Count up the cost of local variables and temps, if we know the size - // use that, otherwise we use a moderately-large dummy cost. - for v in callee_body.vars_and_temps_iter() { - checker.visit_local_decl(v, &callee_body.local_decls[v]); - } - // Abort if type validation found anything fishy. checker.validation?; @@ -770,14 +756,6 @@ impl<'tcx> Inliner<'tcx> { } } -fn type_size_of<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>, -) -> Option<u64> { - tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes()) -} - /// Verify that the callee body is compatible with the caller. /// /// This visitor mostly computes the inlining cost, @@ -851,24 +829,6 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { self.super_terminator(terminator, location); } - /// Count up the cost of local variables and temps, if we know the size - /// use that, otherwise we use a moderately-large dummy cost. - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - let tcx = self.tcx; - let ptr_size = tcx.data_layout.pointer_size.bytes(); - - let ty = self.instance.subst_mir(tcx, &local_decl.ty); - // Cost of the var is the size in machine-words, if we know - // it. - if let Some(size) = type_size_of(tcx, self.param_env, ty) { - self.cost += ((size + ptr_size - 1) / ptr_size) as usize; - } else { - self.cost += UNKNOWN_SIZE_COST; - } - - self.super_local_decl(local, local_decl) - } - /// This method duplicates code from MIR validation in an attempt to detect type mismatches due /// to normalization failure. fn visit_projection_elem( diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 8aa3c23d019..098ce0391fc 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -13,7 +13,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( tcx: TyCtxt<'tcx>, (root, target): (ty::Instance<'tcx>, LocalDefId), ) -> bool { - trace!(%root, target = %tcx.def_path_str(target.to_def_id())); + trace!(%root, target = %tcx.def_path_str(target)); let param_env = tcx.param_env_reveal_all_normalized(target); assert_ne!( root.def_id().expect_local(), @@ -148,8 +148,7 @@ pub(crate) fn mir_inliner_callees<'tcx>( let guard; let body = match (instance, instance.def_id().as_local()) { (InstanceDef::Item(_), Some(def_id)) => { - let def = ty::WithOptConstParam::unknown(def_id); - steal = tcx.mir_promoted(def).0; + steal = tcx.mir_promoted(def_id).0; guard = steal.borrow(); &*guard } diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 3d06a0a495f..432852a1fdd 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -1,11 +1,9 @@ //! Performs various peephole optimizations. +use crate::simplify::combine_duplicate_switch_targets; use crate::MirPass; use rustc_hir::Mutability; -use rustc_middle::mir::{ - BinOp, Body, CastKind, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, - Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, -}; +use rustc_middle::mir::*; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; @@ -46,7 +44,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine { &mut block.terminator.as_mut().unwrap(), &mut block.statements, ); - ctx.combine_duplicate_switch_targets(&mut block.terminator.as_mut().unwrap()); + combine_duplicate_switch_targets(block.terminator.as_mut().unwrap()); } } } @@ -264,19 +262,6 @@ impl<'tcx> InstCombineContext<'tcx, '_> { terminator.kind = TerminatorKind::Goto { target: destination_block }; } - fn combine_duplicate_switch_targets(&self, terminator: &mut Terminator<'tcx>) { - let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind - else { return }; - - let otherwise = targets.otherwise(); - if targets.iter().any(|t| t.1 == otherwise) { - *targets = SwitchTargets::new( - targets.iter().filter(|t| t.1 != otherwise), - targets.otherwise(), - ); - } - } - fn combine_intrinsic_assert( &self, terminator: &mut Terminator<'tcx>, diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 9447a2ff040..430a6f6cef5 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -120,7 +120,7 @@ impl EnumSizeOpt { fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); - let param_env = tcx.param_env(body_did); + let param_env = tcx.param_env_reveal_all_normalized(body_did); let blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index fc12d423cb0..1d6cd1c15b7 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -23,9 +23,9 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::steal::Steal; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::visit::Visitor as _; use rustc_middle::mir::{ traversal, AnalysisPhase, Body, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, MirPass, @@ -48,6 +48,7 @@ mod add_retag; mod check_const_item_mutation; mod check_packed_ref; pub mod check_unsafety; +mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup pub mod cleanup_post_borrowck; mod const_debuginfo; @@ -111,36 +112,17 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { mir_keys, mir_const, - mir_const_qualif: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.mir_const_qualif_const_arg(def) - } else { - mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - mir_const_qualif_const_arg: |tcx, (did, param_did)| { - mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, + mir_const_qualif, mir_promoted, mir_drops_elaborated_and_const_checked, mir_for_ctfe, - mir_for_ctfe_of_const_arg, mir_generator_witnesses: generator::mir_generator_witnesses, optimized_mir, is_mir_available, is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did), mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable, mir_inliner_callees: inline::cycle::mir_inliner_callees, - promoted_mir: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.promoted_mir_of_const_arg(def) - } else { - promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - promoted_mir_of_const_arg: |tcx, (did, param_did)| { - promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, + promoted_mir, deduced_param_attrs: deduce_param_attrs::deduced_param_attrs, ..*providers }; @@ -234,8 +216,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> { set } -fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs { - let const_kind = tcx.hir().body_const_context(def.did); +fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { + let const_kind = tcx.hir().body_const_context(def); // No need to const-check a non-const `fn`. if const_kind.is_none() { @@ -253,7 +235,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> return Default::default(); } - let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def.did) }; + let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def) }; let mut validator = check_consts::check::Checker::new(&ccx); validator.check_body(); @@ -266,22 +248,14 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> /// Make MIR ready for const evaluation. This is run on all MIR, not just on consts! /// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query). /// We used to have this for pre-miri MIR based const eval. -fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_const(def); - } - +fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { // Unsafety check uses the raw mir, so make sure it is run. if !tcx.sess.opts.unstable_opts.thir_unsafeck { - if let Some(param_did) = def.const_param_did { - tcx.ensure_with_value().unsafety_check_result_for_const_arg((def.did, param_did)); - } else { - tcx.ensure_with_value().unsafety_check_result(def.did); - } + tcx.ensure_with_value().unsafety_check_result(def); } // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. - tcx.ensure_with_value().has_ffi_unwind_calls(def.did); + tcx.ensure_with_value().has_ffi_unwind_calls(def); let mut body = tcx.mir_built(def).steal(); @@ -296,7 +270,7 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal< &Lint(check_const_item_mutation::CheckConstItemMutation), &Lint(function_item_references::FunctionItemReferences), // What we need to do constant evaluation. - &simplify::SimplifyCfg::new("initial"), + &simplify::SimplifyCfg::Initial, &rustc_peek::SanityCheck, // Just a lint ], None, @@ -307,16 +281,12 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal< /// Compute the main MIR body and the list of MIR bodies of the promoteds. fn mir_promoted( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> (&Steal<Body<'_>>, &Steal<IndexVec<Promoted, Body<'_>>>) { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_promoted(def); - } - // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. // Also this means promotion can rely on all const checks having been done. - let const_qualifs = tcx.mir_const_qualif_opt_const_arg(def); + let const_qualifs = tcx.mir_const_qualif(def); let mut body = tcx.mir_const(def).steal(); if let Some(error_reported) = const_qualifs.tainted_by_errors { body.tainted_by_errors = Some(error_reported); @@ -334,11 +304,7 @@ fn mir_promoted( pm::run_passes( tcx, &mut body, - &[ - &promote_pass, - &simplify::SimplifyCfg::new("promote-consts"), - &coverage::InstrumentCoverage, - ], + &[&promote_pass, &simplify::SimplifyCfg::PromoteConsts, &coverage::InstrumentCoverage], Some(MirPhase::Analysis(AnalysisPhase::Initial)), ); @@ -348,38 +314,22 @@ fn mir_promoted( /// Compute the MIR that is used during CTFE (and thus has no optimizations run on it) fn mir_for_ctfe(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &Body<'_> { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.mir_for_ctfe_of_const_arg(def) - } else { - tcx.arena.alloc(inner_mir_for_ctfe(tcx, ty::WithOptConstParam::unknown(def_id))) - } + tcx.arena.alloc(inner_mir_for_ctfe(tcx, def_id)) } -/// Same as `mir_for_ctfe`, but used to get the MIR of a const generic parameter. -/// The docs on `WithOptConstParam` explain this a bit more, but the TLDR is that -/// we'd get cycle errors with `mir_for_ctfe`, because typeck would need to typeck -/// the const parameter while type checking the main body, which in turn would try -/// to type check the main body again. -fn mir_for_ctfe_of_const_arg(tcx: TyCtxt<'_>, (did, param_did): (LocalDefId, DefId)) -> &Body<'_> { - tcx.arena.alloc(inner_mir_for_ctfe( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - )) -} - -fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> { +fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // FIXME: don't duplicate this between the optimized_mir/mir_for_ctfe queries - if tcx.is_constructor(def.did.to_def_id()) { + if tcx.is_constructor(def.to_def_id()) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const // qualification and borrow checking the trouble of special casing // constructors. - return shim::build_adt_ctor(tcx, def.did.to_def_id()); + return shim::build_adt_ctor(tcx, def.to_def_id()); } let context = tcx .hir() - .body_const_context(def.did) + .body_const_context(def) .expect("mir_for_ctfe should not be used for runtime functions"); let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone(); @@ -417,29 +367,19 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) - /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't /// end up missing the source MIR due to stealing happening. -fn mir_drops_elaborated_and_const_checked( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_drops_elaborated_and_const_checked(def); - } - +fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { if tcx.sess.opts.unstable_opts.drop_tracking_mir - && let DefKind::Generator = tcx.def_kind(def.did) + && let DefKind::Generator = tcx.def_kind(def) { - tcx.ensure_with_value().mir_generator_witnesses(def.did); + tcx.ensure_with_value().mir_generator_witnesses(def); } - let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def); + let mir_borrowck = tcx.mir_borrowck(def); - let is_fn_like = tcx.def_kind(def.did).is_fn_like(); + let is_fn_like = tcx.def_kind(def).is_fn_like(); if is_fn_like { - let did = def.did.to_def_id(); - let def = ty::WithOptConstParam::unknown(did); - // Do not compute the mir call graph without said call graph actually being used. if inline::Inline.is_enabled(&tcx.sess) { - tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def)); + tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id())); } } @@ -467,10 +407,7 @@ fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx> pm::run_passes( tcx, body, - &[ - &remove_uninit_drops::RemoveUninitDrops, - &simplify::SimplifyCfg::new("remove-false-edges"), - ], + &[&remove_uninit_drops::RemoveUninitDrops, &simplify::SimplifyCfg::RemoveFalseEdges], None, ); check_consts::post_drop_elaboration::check_live_drops(tcx, &body); // FIXME: make this a MIR lint @@ -492,7 +429,7 @@ fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let passes: &[&dyn MirPass<'tcx>] = &[ &cleanup_post_borrowck::CleanupPostBorrowck, &remove_noop_landing_pads::RemoveNoopLandingPads, - &simplify::SimplifyCfg::new("early-opt"), + &simplify::SimplifyCfg::EarlyOpt, &deref_separator::Derefer, ]; @@ -524,8 +461,11 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Returns the sequence of passes that do the initial cleanup of runtime MIR. fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let passes: &[&dyn MirPass<'tcx>] = - &[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops")]; + let passes: &[&dyn MirPass<'tcx>] = &[ + &lower_intrinsics::LowerIntrinsics, + &remove_place_mention::RemovePlaceMention, + &simplify::SimplifyCfg::ElaborateDrops, + ]; pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup))); @@ -551,7 +491,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, &uninhabited_enum_branching::UninhabitedEnumBranching, - &o1(simplify::SimplifyCfg::new("after-uninhabited-enum-branching")), + &o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching), &inline::Inline, &remove_storage_markers::RemoveStorageMarkers, &remove_zsts::RemoveZsts, @@ -564,23 +504,23 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &multiple_return_terminators::MultipleReturnTerminators, &instcombine::InstCombine, &separate_const_switch::SeparateConstSwitch, - &simplify::SimplifyLocals::new("before-const-prop"), + &simplify::SimplifyLocals::BeforeConstProp, ©_prop::CopyProp, &const_prop::ConstProp, &dataflow_const_prop::DataflowConstProp, // // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &const_debuginfo::ConstDebugInfo, - &o1(simplify_branches::SimplifyConstCondition::new("after-const-prop")), + &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, &dead_store_elimination::DeadStoreElimination, &dest_prop::DestinationPropagation, - &o1(simplify_branches::SimplifyConstCondition::new("final")), + &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), - &o1(simplify::SimplifyCfg::new("final")), + &o1(simplify::SimplifyCfg::Final), &nrvo::RenameReturnPlace, - &simplify::SimplifyLocals::new("final"), + &simplify::SimplifyLocals::Final, &multiple_return_terminators::MultipleReturnTerminators, &deduplicate_blocks::DeduplicateBlocks, &large_enums::EnumSizeOpt { discrepancy: 128 }, @@ -595,7 +535,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Optimize the MIR and prepare it for codegen. fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> { - assert_eq!(ty::WithOptConstParam::try_lookup(did, tcx), None); tcx.arena.alloc(inner_optimized_mir(tcx, did)) } @@ -617,8 +556,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other), } debug!("about to call mir_drops_elaborated..."); - let body = - tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal(); + let body = tcx.mir_drops_elaborated_and_const_checked(did).steal(); let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst); debug!("body: {:#?}", body); run_optimization_passes(tcx, &mut body); @@ -628,15 +566,12 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { /// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for /// constant evaluation once all substitutions become known. -fn promoted_mir( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &IndexVec<Promoted, Body<'_>> { - if tcx.is_constructor(def.did.to_def_id()) { +fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> { + if tcx.is_constructor(def.to_def_id()) { return tcx.arena.alloc(IndexVec::new()); } - let tainted_by_errors = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors; + let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors; let mut promoted = tcx.mir_promoted(def).1.steal(); for body in &mut promoted { diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index c136642dff2..c7d3f6c9f04 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -221,7 +221,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } - sym::transmute => { + sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { span_bug!( diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index 7dc5878e047..6e40dfa0d13 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -3,7 +3,7 @@ use crate::MirPass; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexSlice; +use rustc_index::IndexSlice; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index ce05db5b762..59942dc76f9 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -46,7 +46,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let def_id = body.source.def_id(); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let bbs = body.basic_blocks.as_mut(); let mut should_cleanup = false; diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs index b36c8a0bd53..b3b831bb4ab 100644 --- a/compiler/rustc_mir_transform/src/normalize_array_len.rs +++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs @@ -3,7 +3,7 @@ use crate::ssa::SsaLocals; use crate::MirPass; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs new file mode 100644 index 00000000000..8be1c37572d --- /dev/null +++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs @@ -0,0 +1,23 @@ +//! This pass removes `PlaceMention` statement, which has no effect at codegen. + +use crate::MirPass; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +pub struct RemovePlaceMention; + +impl<'tcx> MirPass<'tcx> for RemovePlaceMention { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + !sess.opts.unstable_opts.mir_keep_place_mention + } + + fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + trace!("Running RemovePlaceMention on {:?}", body.source); + for data in body.basic_blocks.as_mut_preserves_cfg() { + data.statements.retain(|statement| match statement.kind { + StatementKind::PlaceMention(..) | StatementKind::Nop => false, + _ => true, + }) + } + } +} diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index abe6cb285f5..23442f8b97b 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -35,10 +35,22 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { } #[inline] + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _: Location) { + // We have to use `try_normalize_erasing_regions` here, since it's + // possible that we visit impossible-to-satisfy where clauses here, + // see #91745 + if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.literal) { + constant.literal = c; + } + } + + #[inline] fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - *ty = self.tcx.try_normalize_erasing_regions(self.param_env, *ty).unwrap_or(*ty); + if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) { + *ty = t; + } } } diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index ef367faf6a7..2479856b727 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -303,8 +303,7 @@ fn find_determining_place<'tcx>( | Rvalue::NullaryOp(_, _) | Rvalue::ShallowInitBox(_, _) | Rvalue::UnaryOp(_, Operand::Constant(_)) - | Rvalue::Cast(_, Operand::Constant(_), _) - => return None, + | Rvalue::Cast(_, Operand::Constant(_), _) => return None, } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 2787fe2ce42..19d07fab0b9 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_span::Span; use rustc_target::spec::abi::Abi; @@ -95,7 +95,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' &add_moves_for_packed_drops::AddMovesForPackedDrops, &deref_separator::Derefer, &remove_noop_landing_pads::RemoveNoopLandingPads, - &simplify::SimplifyCfg::new("make_shim"), + &simplify::SimplifyCfg::MakeShim, &add_call_guards::CriticalCallEdges, &abort_unwinding_calls::AbortUnwindingCalls, ], @@ -355,7 +355,7 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env); @@ -836,7 +836,7 @@ fn build_call_shim<'tcx>( pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let param_env = tcx.param_env(ctor_id); + let param_env = tcx.param_env_reveal_all_normalized(ctor_id); // Normalize the sig. let sig = tcx diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index c79e1cf0805..7e0cef025f7 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -29,20 +29,38 @@ use crate::MirPass; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_index::vec::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; use smallvec::SmallVec; -pub struct SimplifyCfg { - label: String, +pub enum SimplifyCfg { + Initial, + PromoteConsts, + RemoveFalseEdges, + EarlyOpt, + ElaborateDrops, + Final, + MakeShim, + AfterUninhabitedEnumBranching, } impl SimplifyCfg { - pub fn new(label: &str) -> Self { - SimplifyCfg { label: format!("SimplifyCfg-{}", label) } + pub fn name(&self) -> &'static str { + match self { + SimplifyCfg::Initial => "SimplifyCfg-initial", + SimplifyCfg::PromoteConsts => "SimplifyCfg-promote-consts", + SimplifyCfg::RemoveFalseEdges => "SimplifyCfg-remove-false-edges", + SimplifyCfg::EarlyOpt => "SimplifyCfg-early-opt", + SimplifyCfg::ElaborateDrops => "SimplifyCfg-elaborate-drops", + SimplifyCfg::Final => "SimplifyCfg-final", + SimplifyCfg::MakeShim => "SimplifyCfg-make_shim", + SimplifyCfg::AfterUninhabitedEnumBranching => { + "SimplifyCfg-after-uninhabited-enum-branching" + } + } } } @@ -57,11 +75,11 @@ pub fn simplify_cfg<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { impl<'tcx> MirPass<'tcx> for SimplifyCfg { fn name(&self) -> &str { - &self.label + &self.name() } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body.source); + debug!("SimplifyCfg({:?}) - simplifying {:?}", self.name(), body.source); simplify_cfg(tcx, body); } } @@ -260,6 +278,18 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } +pub fn combine_duplicate_switch_targets(terminator: &mut Terminator<'_>) { + if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind { + let otherwise = targets.otherwise(); + if targets.iter().any(|t| t.1 == otherwise) { + *targets = SwitchTargets::new( + targets.iter().filter(|t| t.1 != otherwise), + targets.otherwise(), + ); + } + } +} + pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { struct OptApplier<'tcx> { tcx: TyCtxt<'tcx>, @@ -280,6 +310,8 @@ pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut B } } + combine_duplicate_switch_targets(terminator); + self.super_terminator(terminator, location); } } @@ -423,19 +455,17 @@ fn save_unreachable_coverage( )); } -pub struct SimplifyLocals { - label: String, -} - -impl SimplifyLocals { - pub fn new(label: &str) -> SimplifyLocals { - SimplifyLocals { label: format!("SimplifyLocals-{}", label) } - } +pub enum SimplifyLocals { + BeforeConstProp, + Final, } impl<'tcx> MirPass<'tcx> for SimplifyLocals { - fn name(&self) -> &str { - &self.label + fn name(&self) -> &'static str { + match &self { + SimplifyLocals::BeforeConstProp => "SimplifyLocals-before-const-prop", + SimplifyLocals::Final => "SimplifyLocals-final", + } } fn is_enabled(&self, sess: &rustc_session::Session) -> bool { diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index 8164b305278..1ff48816986 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -2,24 +2,21 @@ use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -/// A pass that replaces a branch with a goto when its condition is known. -pub struct SimplifyConstCondition { - label: String, -} - -impl SimplifyConstCondition { - pub fn new(label: &str) -> Self { - SimplifyConstCondition { label: format!("SimplifyConstCondition-{}", label) } - } +pub enum SimplifyConstCondition { + AfterConstProp, + Final, } - +/// A pass that replaces a branch with a goto when its condition is known. impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { - fn name(&self) -> &str { - &self.label + fn name(&self) -> &'static str { + match self { + SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop", + SimplifyConstCondition::Final => "SimplifyConstCondition-final", + } } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for block in body.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index dcad1518eb6..113ca2fc5ad 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -37,7 +37,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let opts = helper.find_optimizations(); let mut storage_deads_to_insert = vec![]; let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![]; - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for opt in opts { trace!("SUCCESS: Applying {:?}", opt); // replace terminator with a switchInt that switches on the integer directly diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index c798bd05345..2d77291293d 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,6 +1,6 @@ use crate::MirPass; use rustc_index::bit_set::{BitSet, GrowableBitSet}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index be026402dd5..ec8d42c1652 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -1,7 +1,7 @@ use either::Either; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; @@ -21,7 +21,7 @@ pub struct SsaLocals { /// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to /// actually compute dominators, we can just compare block indices because bb0 is always the first -/// block, and in any body all other blocks are always always dominated by bb0. +/// block, and in any body all other blocks are always dominated by bb0. struct SmallDominators { inner: Option<Dominators<BasicBlock>>, } diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index be0aa0fc4c1..5389b9f52eb 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -109,7 +109,9 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { continue; }; - let layout = tcx.layout_of(tcx.param_env(body.source.def_id()).and(discriminant_ty)); + let layout = tcx.layout_of( + tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty), + ); let allowed_variants = if let Ok(layout) = layout { variant_discriminants(&layout, discriminant_ty, tcx) diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index c8af10576b4..6d3a3bf906e 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -8,11 +8,11 @@ edition = "2021" [dependencies] serde = "1" serde_json = "1" -smallvec = { version = "1.8.1", features = [ "union", "may_dangle" ] } tracing = "0.1" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 7bcff7e07fb..5ac9c8e2073 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -402,7 +402,7 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem< } /// Collect all monomorphized items reachable from `starting_point`, and emit a note diagnostic if a -/// post-monorphization error is encountered during a collection step. +/// post-monomorphization error is encountered during a collection step. #[instrument(skip(tcx, visited, recursion_depths, recursion_limit, inlining_map), level = "debug")] fn collect_items_rec<'tcx>( tcx: TyCtxt<'tcx>, @@ -1230,7 +1230,7 @@ impl<'v> RootCollector<'_, 'v> { DefKind::GlobalAsm => { debug!( "RootCollector: ItemKind::GlobalAsm({})", - self.tcx.def_path_str(id.owner_id.to_def_id()) + self.tcx.def_path_str(id.owner_id) ); self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5000fb71937..aea9f719027 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -10,8 +10,8 @@ extern crate tracing; extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::lang_items::LangItem; -use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; use rustc_middle::ty::query::{Providers, TyCtxtAt}; diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 769e12f77bf..bd24deb590a 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -16,17 +16,20 @@ use super::PartitioningCx; use crate::collector::InliningMap; use crate::partitioning::merging; use crate::partitioning::{ - MonoItemPlacement, Partitioner, PostInliningPartitioning, PreInliningPartitioning, + MonoItemPlacement, Partition, PostInliningPartitioning, PreInliningPartitioning, }; pub struct DefaultPartitioning; -impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { - fn place_root_mono_items( +impl<'tcx> Partition<'tcx> for DefaultPartitioning { + fn place_root_mono_items<I>( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, - ) -> PreInliningPartitioning<'tcx> { + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>, + { let mut roots = FxHashSet::default(); let mut codegen_units = FxHashMap::default(); let is_incremental_build = cx.tcx.sess.opts.incremental.is_some(); @@ -267,7 +270,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( match mono_item { MonoItem::Fn(instance) => { let def_id = match instance.def { - ty::InstanceDef::Item(def) => def.did, + ty::InstanceDef::Item(def) => def, ty::InstanceDef::VTableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::FnPtrShim(..) @@ -421,10 +424,9 @@ fn mono_item_visibility<'tcx>( }; let def_id = match instance.def { - InstanceDef::Item(def) => def.did, - InstanceDef::DropGlue(def_id, Some(_)) => def_id, + InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, - // We match the visiblity of statics here + // We match the visibility of statics here InstanceDef::ThreadLocalShim(def_id) => { return static_visibility(tcx, can_be_internalized, def_id); } diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 18aa0742c09..993e35c7fd2 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -118,18 +118,81 @@ use crate::errors::{ CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode, UnknownPartitionStrategy, }; +enum Partitioner { + Default(default::DefaultPartitioning), + // Other partitioning strategies can go here. + Unknown, +} + +impl<'tcx> Partition<'tcx> for Partitioner { + fn place_root_mono_items<I>( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>, + { + match self { + Partitioner::Default(partitioner) => partitioner.place_root_mono_items(cx, mono_items), + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn merge_codegen_units( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: &mut PreInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.merge_codegen_units(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn place_inlined_mono_items( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: PreInliningPartitioning<'tcx>, + ) -> PostInliningPartitioning<'tcx> { + match self { + Partitioner::Default(partitioner) => { + partitioner.place_inlined_mono_items(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn internalize_symbols( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + post_inlining_partitioning: &mut PostInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.internalize_symbols(cx, post_inlining_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } +} + pub struct PartitioningCx<'a, 'tcx> { tcx: TyCtxt<'tcx>, target_cgu_count: usize, inlining_map: &'a InliningMap<'tcx>, } -trait Partitioner<'tcx> { - fn place_root_mono_items( +trait Partition<'tcx> { + fn place_root_mono_items<I>( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, - ) -> PreInliningPartitioning<'tcx>; + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>; fn merge_codegen_units( &mut self, @@ -150,26 +213,27 @@ trait Partitioner<'tcx> { ); } -fn get_partitioner<'tcx>(tcx: TyCtxt<'tcx>) -> Box<dyn Partitioner<'tcx>> { +fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner { let strategy = match &tcx.sess.opts.unstable_opts.cgu_partitioning_strategy { None => "default", Some(s) => &s[..], }; match strategy { - "default" => Box::new(default::DefaultPartitioning), - _ => { - tcx.sess.emit_fatal(UnknownPartitionStrategy); - } + "default" => Partitioner::Default(default::DefaultPartitioning), + _ => Partitioner::Unknown, } } -pub fn partition<'tcx>( +pub fn partition<'tcx, I>( tcx: TyCtxt<'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, + mono_items: &mut I, max_cgu_count: usize, inlining_map: &InliningMap<'tcx>, -) -> Vec<CodegenUnit<'tcx>> { +) -> Vec<CodegenUnit<'tcx>> +where + I: Iterator<Item = MonoItem<'tcx>>, +{ let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); let mut partitioner = get_partitioner(tcx); @@ -182,7 +246,9 @@ pub fn partition<'tcx>( partitioner.place_root_mono_items(cx, mono_items) }; - initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut initial_partitioning.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter()); @@ -202,7 +268,9 @@ pub fn partition<'tcx>( partitioner.place_inlined_mono_items(cx, initial_partitioning) }; - post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut post_inlining.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter()); @@ -380,7 +448,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co || { let mut codegen_units = partition( tcx, - &mut items.iter().cloned(), + &mut items.iter().copied(), tcx.sess.codegen_units(), &inlining_map, ); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 63263a642ac..ddc62d9c390 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -232,7 +232,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> { /// a closure, generator or constant). #[instrument(level = "debug", skip(self, def_id, substs))] fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) { - let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)); + let instance = ty::InstanceDef::Item(def_id); let unused = self.tcx.unused_generic_params(instance); debug!(?self.unused_parameters, ?unused); for (i, arg) in substs.iter().enumerate() { @@ -272,10 +272,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { // Avoid considering `T` unused when constants are of the form: // `<Self as Foo<T>>::foo::promoted[p]` if let Some(p) = promoted { - if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self { + if self.def_id == def && !self.tcx.generics_of(def).has_self { // If there is a promoted, don't look at the substs - since it will always contain // the generic parameters, instead, traverse the promoted MIR. - let promoted = self.tcx.promoted_mir(def.did); + let promoted = self.tcx.promoted_mir(def); self.visit_body(&promoted[p]); } } @@ -305,9 +305,9 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> { ControlFlow::Continue(()) } ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) - if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) => + if matches!(self.tcx.def_kind(def), DefKind::AnonConst) => { - self.visit_child_body(def.did, substs); + self.visit_child_body(def, substs); ControlFlow::Continue(()) } _ => c.super_visit_with(self), diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 3eb158c817c..1bd9f66290d 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 9e856c9f212..ad9b20f9c76 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -67,7 +67,7 @@ pub(crate) fn parse_token_trees<'a>( match token_trees { Ok(stream) if unmatched_delims.is_empty() => Ok(stream), _ => { - // Return error if there are unmatched delimiters or unclosng delimiters. + // Return error if there are unmatched delimiters or unclosed delimiters. // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch // because the delimiter mismatch is more likely to be the root cause of error diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 17466cd0e6d..507f6e4182e 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -20,7 +20,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_session::parse::ParseSess; use rustc_span::{FileName, SourceFile, Span}; diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index e3e7c63e344..e1db19557cf 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -45,10 +45,10 @@ impl<'a> Parser<'a> { Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span: prev_outer_attr_sp.unwrap(), }) - } else if let Some(prev_outer_attr_sp) = prev_outer_attr_sp { - Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) } else { - None + prev_outer_attr_sp.map(|prev_outer_attr_sp| { + InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp } + }) }; let inner_parse_policy = InnerAttrPolicy::Forbidden(inner_error_reason); just_parsed_doc_comment = false; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 6422b8ac1ba..f5fef6ad019 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2577,14 +2577,12 @@ impl<'a> Parser<'a> { } fn recover_self_param(&mut self) -> bool { - match self - .parse_outer_attributes() - .and_then(|_| self.parse_self_param()) - .map_err(|e| e.cancel()) - { - Ok(Some(_)) => true, - _ => false, - } + matches!( + self.parse_outer_attributes() + .and_then(|_| self.parse_self_param()) + .map_err(|e| e.cancel()), + Ok(Some(_)) + ) } } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 7a4d53ed8bb..adb0d372a40 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -20,12 +20,10 @@ impl<'a> Parser<'a> { pub fn nonterminal_may_begin_with(kind: NonterminalKind, token: &Token) -> bool { /// Checks whether the non-terminal may contain a single (non-keyword) identifier. fn may_be_ident(nt: &token::Nonterminal) -> bool { - match *nt { - token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) => { - false - } - _ => true, - } + !matches!( + *nt, + token::NtItem(_) | token::NtBlock(_) | token::NtVis(_) | token::NtLifetime(_) + ) } match kind { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 72402a20090..2f397e303e5 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -68,7 +68,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta } } else { // The non-error case can happen with e.g. `#[foo = 1+1]`. The error case can - // happen with e.g. `#[foo = include_str!("non-existent-file.rs")]`; in that + // happen with e.g. `#[foo = include_str!("nonexistent-file.rs")]`; in that // case we delay the error because an earlier error will have already been // reported. let msg = format!("unexpected expression: `{}`", pprust::expr_to_string(expr)); diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index 44f991f8c15..0413b5b4fb9 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -12,6 +12,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index b354dca7cc4..055682a1509 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -627,9 +627,9 @@ passes_attr_application_struct_enum_union = attribute should be applied to a struct, enum, or union .label = not a struct, enum, or union -passes_attr_application_struct_enum_function_union = - attribute should be applied to a struct, enum, function, or union - .label = not a struct, enum, function, or union +passes_attr_application_struct_enum_function_method_union = + attribute should be applied to a struct, enum, function, associated function, or union + .label = not a struct, enum, function, associated function, or union passes_transparent_incompatible = transparent {$target} cannot have other repr hints diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 80a93da2b45..085a28626ea 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1728,7 +1728,9 @@ impl CheckAttrVisitor<'_> { } } sym::align => { - if let (Target::Fn, false) = (target, self.tcx.features().fn_align) { + if let (Target::Fn | Target::Method(MethodKind::Inherent), false) = + (target, self.tcx.features().fn_align) + { feature_err( &self.tcx.sess.parse_sess, sym::fn_align, @@ -1739,10 +1741,14 @@ impl CheckAttrVisitor<'_> { } match target { - Target::Struct | Target::Union | Target::Enum | Target::Fn => continue, + Target::Struct + | Target::Union + | Target::Enum + | Target::Fn + | Target::Method(_) => continue, _ => { self.tcx.sess.emit_err( - errors::AttrApplication::StructEnumFunctionUnion { + errors::AttrApplication::StructEnumFunctionMethodUnion { hint_span: hint.span(), span, }, diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 5cfe691df17..3ae5b45d330 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -237,6 +237,37 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } + fn handle_offset_of(&mut self, expr: &'tcx hir::Expr<'tcx>) { + let data = self.typeck_results().offset_of_data(); + let &(container, ref indices) = + data.get(expr.hir_id).expect("no offset_of_data for offset_of"); + + let body_did = self.typeck_results().hir_owner.to_def_id(); + let param_env = self.tcx.param_env(body_did); + + let mut current_ty = container; + + for &index in indices { + match current_ty.kind() { + ty::Adt(def, subst) => { + let field = &def.non_enum_variant().fields[index]; + + self.insert_def_id(field.did); + let field_ty = field.ty(self.tcx, subst); + + current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty); + } + // we don't need to mark tuple fields as live, + // but we may need to mark subfields + ty::Tuple(tys) => { + current_ty = + self.tcx.normalize_erasing_regions(param_env, tys[index.as_usize()]); + } + _ => span_bug!(expr.span, "named field access on non-ADT"), + } + } + } + fn mark_live_symbols(&mut self) { let mut scanned = LocalDefIdSet::default(); while let Some(id) = self.worklist.pop() { @@ -405,6 +436,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { hir::ExprKind::Closure(cls) => { self.insert_def_id(cls.def_id.to_def_id()); } + hir::ExprKind::OffsetOf(..) => { + self.handle_offset_of(expr); + } _ => (), } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 139ba8c9677..e8603b3a2f1 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -1355,8 +1355,8 @@ pub enum AttrApplication { #[label] span: Span, }, - #[diag(passes_attr_application_struct_enum_function_union, code = "E0517")] - StructEnumFunctionUnion { + #[diag(passes_attr_application_struct_enum_function_method_union, code = "E0517")] + StructEnumFunctionMethodUnion { #[primary_span] hint_span: Span, #[label] diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 47e032758f2..dc5e454074d 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -302,7 +302,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { [ ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index, - Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err + Path, AddrOf, Break, Continue, Ret, InlineAsm, OffsetOf, Struct, Repeat, Yield, + Err ] ); hir_visit::walk_expr(self, e) @@ -568,7 +569,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let, If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign, AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, - InlineAsm, FormatArgs, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err + InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err ] ); ast_visit::walk_expr(self, e) diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index b7e07aff42b..eca3bae9a1c 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -19,7 +19,7 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty::query::Providers; mod check_attr; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index a8471ce3b6f..7d8f6add632 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -90,14 +90,15 @@ use rustc_errors::Applicability; use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::DUMMY_SP; use rustc_span::{BytePos, Span}; use std::collections::VecDeque; @@ -137,14 +138,9 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String { } } -fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { - let local_def_id = match def_id.as_local() { - None => return, - Some(def_id) => def_id, - }; - +fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Don't run unused pass for #[derive()] - let parent = tcx.local_parent(local_def_id); + let parent = tcx.local_parent(def_id); if let DefKind::Impl { .. } = tcx.def_kind(parent) && tcx.has_attr(parent, sym::automatically_derived) { @@ -152,12 +148,12 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { } // Don't run unused pass for #[naked] - if tcx.has_attr(def_id, sym::naked) { + if tcx.has_attr(def_id.to_def_id(), sym::naked) { return; } let mut maps = IrMaps::new(tcx); - let body_id = tcx.hir().body_owned_by(local_def_id); + let body_id = tcx.hir().body_owned_by(def_id); let hir_id = tcx.hir().body_owner(body_id); let body = tcx.hir().body(body_id); @@ -173,7 +169,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { maps.visit_body(body); // compute liveness - let mut lsets = Liveness::new(&mut maps, local_def_id); + let mut lsets = Liveness::new(&mut maps, def_id); let entry_ln = lsets.compute(&body, hir_id); lsets.log_liveness(entry_ln, body_id.hir_id); @@ -331,7 +327,7 @@ impl<'tcx> IrMaps<'tcx> { pats.extend(inner_pat.iter()); } Struct(_, fields, _) => { - let (short, not_short): (Vec<_>, _) = + let (short, not_short): (Vec<hir::PatField<'_>>, _) = fields.iter().partition(|f| f.is_shorthand); shorthand_field_ids.extend(short.iter().map(|f| f.pat.hir_id)); pats.extend(not_short.iter().map(|f| f.pat)); @@ -473,6 +469,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) @@ -591,8 +588,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> bool { - let successor = self.successors[ln].unwrap(); - self.assigned_on_entry(successor, var) + match self.successors[ln] { + Some(successor) => self.assigned_on_entry(successor, var), + None => { + self.ir.tcx.sess.delay_span_bug(DUMMY_SP, "no successor"); + true + } + } } fn write_vars<F>(&self, wr: &mut dyn Write, mut test: F) -> io::Result<()> @@ -1129,7 +1131,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) - | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ, + | hir::ExprKind::Path(hir::QPath::LangItem(..)) + | hir::ExprKind::OffsetOf(..) => succ, // Note that labels have been resolved, so we don't need to look // at the label ident @@ -1418,6 +1421,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::Closure { .. } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index c398467f03e..cf8d9300a11 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -203,6 +203,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { | ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) + | ExprKind::OffsetOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) => { diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml index fa27bfc61d1..c930b3365fd 100644 --- a/compiler/rustc_plugin_impl/Cargo.toml +++ b/compiler/rustc_plugin_impl/Cargo.toml @@ -12,6 +12,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_lint = { path = "../rustc_lint" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_ast = { path = "../rustc_ast" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs index 672189e22cf..faa7495ef9f 100644 --- a/compiler/rustc_plugin_impl/src/lib.rs +++ b/compiler/rustc_plugin_impl/src/lib.rs @@ -12,8 +12,8 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_lint::LintStore; -use rustc_macros::fluent_messages; mod errors; pub mod load; diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index 744cb77dd00..08c4067705c 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -9,6 +9,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index dcebfca08fa..c607c7fd5f4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -17,12 +17,12 @@ use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; -use rustc_macros::fluent_messages; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; @@ -269,7 +269,7 @@ where // and are visited by shallow visitors. self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: tcx.explicit_item_bounds(def_id), + predicates: tcx.explicit_item_bounds(def_id).skip_binder(), })?; } } @@ -1784,7 +1784,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn bounds(&mut self) -> &mut Self { self.visit_predicates(ty::GenericPredicates { parent: None, - predicates: self.tcx.explicit_item_bounds(self.item_def_id), + predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(), }); self } diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 30477c7bd44..c0f2d7803d4 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -1,12 +1,13 @@ use crate::QueryCtxt; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; +use rustc_data_structures::stable_hasher::Hash64; use rustc_data_structures::sync::{HashMapExt, Lock, Lrc, RwLock}; use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unord::UnordSet; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathHash; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::dep_graph::{DepNodeIndex, SerializedDepNodeIndex}; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::mir::{self, interpret}; @@ -138,7 +139,7 @@ impl AbsoluteBytePos { /// is the only thing available when decoding the cache's [Footer]. #[derive(Encodable, Decodable, Clone, Debug)] struct EncodedSourceFileId { - file_name_hash: u64, + file_name_hash: Hash64, stable_crate_id: StableCrateId, } @@ -168,13 +169,12 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { // Decode the *position* of the footer, which can be found in the // last 8 bytes of the file. - decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE); - let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder).0 as usize; - + let footer_pos = decoder + .with_position(decoder.len() - IntEncodedWithFixedSize::ENCODED_SIZE, |decoder| { + IntEncodedWithFixedSize::decode(decoder).0 as usize + }); // Decode the file footer, which contains all the lookup tables, etc. - decoder.set_position(footer_pos); - - decode_tagged(&mut decoder, TAG_FILE_FOOTER) + decoder.with_position(footer_pos, |decoder| decode_tagged(decoder, TAG_FILE_FOOTER)) }; Self { @@ -299,7 +299,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { interpret_alloc_index.reserve(new_n - n); for idx in n..new_n { let id = encoder.interpret_allocs[idx]; - let pos = encoder.position() as u32; + let pos: u32 = encoder.position().try_into().unwrap(); interpret_alloc_index.push(pos); interpret::specialized_encode_alloc_id(&mut encoder, tcx, id); } @@ -521,29 +521,13 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> { } } -trait DecoderWithPosition: Decoder { - fn position(&self) -> usize; -} - -impl<'a> DecoderWithPosition for MemDecoder<'a> { - fn position(&self) -> usize { - self.position() - } -} - -impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> { - fn position(&self) -> usize { - self.opaque.position() - } -} - // Decodes something that was encoded with `encode_tagged()` and verify that the // tag matches and the correct amount of bytes was read. fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> V where T: Decodable<D> + Eq + std::fmt::Debug, V: Decodable<D>, - D: DecoderWithPosition, + D: Decoder, { let start_pos = decoder.position(); @@ -567,16 +551,6 @@ impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> { self.tcx } - #[inline] - fn position(&self) -> usize { - self.opaque.position() - } - - #[inline] - fn peek_byte(&self) -> u8 { - self.opaque.data[self.opaque.position()] - } - fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx> where F: FnOnce(&mut Self) -> Ty<'tcx>, @@ -599,9 +573,9 @@ impl<'a, 'tcx> TyDecoder for CacheDecoder<'a, 'tcx> { where F: FnOnce(&mut Self) -> R, { - debug_assert!(pos < self.opaque.data.len()); + debug_assert!(pos < self.opaque.len()); - let new_opaque = MemDecoder::new(self.opaque.data, pos); + let new_opaque = MemDecoder::new(self.opaque.data(), pos); let old_opaque = mem::replace(&mut self.opaque, new_opaque); let r = f(self); self.opaque = old_opaque; @@ -667,7 +641,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId { #[cfg(debug_assertions)] { use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; - let local_hash: u64 = decoder.tcx.with_stable_hashing_context(|mut hcx| { + let local_hash = decoder.tcx.with_stable_hashing_context(|mut hcx| { let mut hasher = StableHasher::new(); expn_id.expn_data().hash_stable(&mut hcx, &mut hasher); hasher.finish() @@ -742,17 +716,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol { SYMBOL_OFFSET => { // read str offset let pos = d.read_usize(); - let old_pos = d.opaque.position(); - // move to str ofset and read - d.opaque.set_position(pos); - let s = d.read_str(); - let sym = Symbol::intern(s); - - // restore position - d.opaque.set_position(old_pos); - - sym + // move to str offset and read + d.opaque.with_position(pos, |d| { + let s = d.read_str(); + Symbol::intern(s) + }) } SYMBOL_PREINTERNED => { let symbol_index = d.read_u32(); @@ -806,7 +775,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId> } } -impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> { +impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> + for &'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>> +{ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { RefDecodable::decode(d) } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index afbead7d1ae..32222df25d4 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -5,7 +5,7 @@ use crate::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex}; use crate::profiling_support::QueryKeyStringCache; use crate::{on_disk_cache, Queries}; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; use rustc_errors::{Diagnostic, Handler}; use rustc_middle::dep_graph::{ @@ -342,7 +342,7 @@ pub(crate) fn create_query_frame< let mut hasher = StableHasher::new(); std::mem::discriminant(&kind).hash_stable(&mut hcx, &mut hasher); key.hash_stable(&mut hcx, &mut hasher); - hasher.finish::<u64>() + hasher.finish::<Hash64>() }) }; let ty_adt_id = key.ty_adt_id(); diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 579a789244b..08b588a8c94 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; -use rustc_middle::ty::{TyCtxt, WithOptConstParam}; +use rustc_middle::ty::TyCtxt; use rustc_query_system::query::QueryCache; use std::fmt::Debug; use std::io::Write; @@ -151,37 +151,6 @@ impl SpecIntoSelfProfilingString for LocalDefId { } } -impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> { - fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { - // We print `WithOptConstParam` values as tuples to make them shorter - // and more readable, without losing information: - // - // "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }" - // becomes "(foo::bar, foo::baz)" and - // "WithOptConstParam { did: foo::bar, const_param_did: None }" - // becomes "(foo::bar, _)". - - let did = StringComponent::Ref(self.did.to_self_profile_string(builder)); - - let const_param_did = if let Some(const_param_did) = self.const_param_did { - let const_param_did = builder.def_id_to_string_id(const_param_did); - StringComponent::Ref(const_param_did) - } else { - StringComponent::Value("_") - }; - - let components = [ - StringComponent::Value("("), - did, - StringComponent::Value(", "), - const_param_did, - StringComponent::Value(")"), - ]; - - builder.profiler.alloc_string(&components[..]) - } -} - impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1) where T0: SpecIntoSelfProfilingString, diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 12b4a114313..e02cf38b671 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -7,11 +7,11 @@ edition = "2021" [dependencies] parking_lot = "0.11" -rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl index 870e824039c..0d01123ad88 100644 --- a/compiler/rustc_query_system/messages.ftl +++ b/compiler/rustc_query_system/messages.ftl @@ -1,4 +1,4 @@ -query_system_reentrant = internal compiler error: re-entrant incremental verify failure, suppressing message +query_system_reentrant = internal compiler error: reentrant incremental verify failure, suppressing message query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node} .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index a9a2e6dd04c..b9922b26afc 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -6,7 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use smallvec::{smallvec, SmallVec}; use std::assert_matches::assert_matches; @@ -249,7 +249,7 @@ impl<K: DepKind> DepGraph<K> { /// get an ICE. Normally, we would have tried (and failed) to mark /// some other query green (e.g. `item_children`) which was used /// to obtain `C`, which would prevent us from ever trying to force - /// a non-existent `D`. + /// a nonexistent `D`. /// /// It might be possible to enforce that all `DepNode`s read during /// deserialization already exist in the previous `DepGraph`. In diff --git a/compiler/rustc_query_system/src/dep_graph/query.rs b/compiler/rustc_query_system/src/dep_graph/query.rs index 27b3b5e1366..5cbc6bf8f8a 100644 --- a/compiler/rustc_query_system/src/dep_graph/query.rs +++ b/compiler/rustc_query_system/src/dep_graph/query.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::implementation::{Direction, Graph, NodeIndex, INCOMING}; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use super::{DepKind, DepNode, DepNodeIndex}; @@ -24,10 +24,7 @@ impl<K: DepKind> DepGraphQuery<K> { pub fn push(&mut self, index: DepNodeIndex, node: DepNode<K>, edges: &[DepNodeIndex]) { let source = self.graph.add_node(node); - if index.index() >= self.dep_index_to_index.len() { - self.dep_index_to_index.resize(index.index() + 1, None); - } - self.dep_index_to_index[index] = Some(source); + self.dep_index_to_index.insert(index, source); self.indices.insert(node, source); for &target in edges.iter() { diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 3d19a84915a..edddfda6242 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::Lock; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable}; use smallvec::SmallVec; @@ -94,21 +94,19 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>> { #[instrument(level = "debug", skip(d))] fn decode(d: &mut MemDecoder<'a>) -> SerializedDepGraph<K> { - let start_position = d.position(); - // The last 16 bytes are the node count and edge count. debug!("position: {:?}", d.position()); - d.set_position(d.data.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE); + let (node_count, edge_count) = + d.with_position(d.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| { + debug!("position: {:?}", d.position()); + let node_count = IntEncodedWithFixedSize::decode(d).0 as usize; + let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize; + (node_count, edge_count) + }); debug!("position: {:?}", d.position()); - let node_count = IntEncodedWithFixedSize::decode(d).0 as usize; - let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize; debug!(?node_count, ?edge_count); - debug!("position: {:?}", d.position()); - d.set_position(start_position); - debug!("position: {:?}", d.position()); - let mut nodes = IndexVec::with_capacity(node_count); let mut fingerprints = IndexVec::with_capacity(node_count); let mut edge_list_indices = IndexVec::with_capacity(node_count); diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 0bc811eb044..8865ecf3e05 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -75,7 +75,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile { ref normalized_pos, } = *self; - (name_hash as u64).hash_stable(hcx, hasher); + name_hash.hash_stable(hcx, hasher); src_hash.hash_stable(hcx, hasher); diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index bb812b006e9..8c9e9cfad60 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -16,7 +16,7 @@ extern crate rustc_data_structures; extern crate rustc_macros; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod cache; pub mod dep_graph; diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 29f6a07e81b..9a09f516ec9 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -5,7 +5,7 @@ use rustc_data_structures::sharded; #[cfg(parallel_compiler)] use rustc_data_structures::sharded::Sharded; use rustc_data_structures::sync::Lock; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index c8d77938510..bb9ea50a1ea 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -63,7 +63,7 @@ pub trait QueryConfig<Qcx: QueryContext>: Copy { fn handle_cycle_error(self) -> HandleCycleError; fn hash_result(self) -> HashResult<Self::Value>; - // Just here for convernience and checking that the key matches the kind, don't override this. + // Just here for convenience and checking that the key matches the kind, don't override this. fn construct_dep_node(self, tcx: Qcx::DepContext, key: &Self::Key) -> DepNode<Qcx::DepKind> { DepNode::construct(tcx, self.dep_kind(), key) } diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs index 312b0e1688d..fa1f51b04da 100644 --- a/compiler/rustc_query_system/src/query/mod.rs +++ b/compiler/rustc_query_system/src/query/mod.rs @@ -16,6 +16,7 @@ pub use self::config::{HashResult, QueryConfig, TryLoadFromDisk}; use crate::dep_graph::DepKind; use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex}; +use rustc_data_structures::stable_hasher::Hash64; use rustc_data_structures::sync::Lock; use rustc_errors::Diagnostic; use rustc_hir::def::DefKind; @@ -37,7 +38,7 @@ pub struct QueryStackFrame<D: DepKind> { /// This hash is used to deterministically pick /// a query to remove cycles in the parallel compiler. #[cfg(parallel_compiler)] - hash: u64, + hash: Hash64, } impl<D: DepKind> QueryStackFrame<D> { @@ -49,7 +50,7 @@ impl<D: DepKind> QueryStackFrame<D> { def_kind: Option<DefKind>, dep_kind: D, ty_adt_id: Option<DefId>, - _hash: impl FnOnce() -> u64, + _hash: impl FnOnce() -> Hash64, ) -> Self { Self { description, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 20310483d7e..bce01debc53 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -410,9 +410,28 @@ where // as its feeding query had. So if the fed query is red, so is its feeder, which will // get evaluated first, and re-feed the query. if let Some((cached_result, _)) = cache.lookup(&key) { - panic!( - "fed query later has its value computed. The already cached value: {}", - (query.format_value())(&cached_result) + let Some(hasher) = query.hash_result() else { + panic!( + "no_hash fed query later has its value computed.\n\ + Remove `no_hash` modifier to allow recomputation.\n\ + The already cached value: {}", + (query.format_value())(&cached_result) + ); + }; + + let (old_hash, new_hash) = qcx.dep_context().with_stable_hashing_context(|mut hcx| { + (hasher(&mut hcx, &cached_result), hasher(&mut hcx, &result)) + }); + let formatter = query.format_value(); + debug_assert_eq!( + old_hash, + new_hash, + "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ + computed={:#?}\nfed={:#?}", + query.dep_kind(), + key, + formatter(&result), + formatter(&cached_result), ); } } @@ -573,7 +592,7 @@ where // from disk. Re-hashing results is fairly expensive, so we can't // currently afford to verify every hash. This subset should still // give us some coverage of potential bugs though. - let try_verify = prev_fingerprint.as_value().1 % 32 == 0; + let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0; if std::intrinsics::unlikely( try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich, ) { @@ -691,7 +710,7 @@ fn incremental_verify_ich_failed<Tcx>( // which may result in another fingerprint mismatch while we're in the middle // of processing this one. To avoid a double-panic (which kills the process // before we can print out the query static), we print out a terse - // but 'safe' message if we detect a re-entrant call to this method. + // but 'safe' message if we detect a reentrant call to this method. thread_local! { static INSIDE_VERIFY_PANIC: Cell<bool> = const { Cell::new(false) }; }; diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 5c4ec44d2b8..1c16d85f1b9 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -16,6 +16,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 01f002c9408..192badcbc37 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -223,3 +223,6 @@ resolve_remove_surrounding_derive = resolve_add_as_non_derive = add as non-Derive macro `#[{$macro_path}]` + +resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it + .help = you can define integration tests in a directory named `tests` diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index ff0f1f55975..967c9e22fb2 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -197,10 +197,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) { - // Query `module_children` is not used because hashing spans in its result is expensive. - let children = - Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess)); - for child in children { + for child in self.tcx.module_children(module.def_id()) { let parent_scope = ParentScope::module(module, self); BuildReducedGraphVisitor { r: self, parent_scope } .build_reduced_graph_for_external_crate_res(child); @@ -929,9 +926,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) { + fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) { let parent = self.parent_scope.module; - let ModChild { ident, res, vis, span, .. } = child; + let ModChild { ident, res, vis, ref reexport_chain } = *child; + let span = self.r.def_span( + reexport_chain + .first() + .and_then(|reexport| reexport.id()) + .unwrap_or_else(|| res.def_id()), + ); let res = res.expect_non_local(); let expansion = self.parent_scope.expansion; // Record primary definitions. diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 0c9d306081e..4b7048eac04 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -663,15 +663,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Ident::with_dummy_span(name), Namespace::ValueNS, &parent_scope, - &|res: Res| match res { - Res::Def( - DefKind::Ctor(CtorOf::Variant, CtorKind::Const) - | DefKind::Ctor(CtorOf::Struct, CtorKind::Const) - | DefKind::Const - | DefKind::AssocConst, - _, - ) => true, - _ => false, + &|res: Res| { + matches!( + res, + Res::Def( + DefKind::Ctor(CtorOf::Variant, CtorKind::Const) + | DefKind::Ctor(CtorOf::Struct, CtorKind::Const) + | DefKind::Const + | DefKind::AssocConst, + _, + ) + ) }, ); @@ -1867,15 +1869,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(LexicalScopeBinding::Item(name_binding)) => Some(name_binding.span), _ => None, }; - let suggestion = if let Some(span) = match_span { - Some(( + let suggestion = match_span.map(|span| { + ( vec![(span, String::from(""))], format!("`{}` is defined here, but is not a type", ident), Applicability::MaybeIncorrect, - )) - } else { - None - }; + ) + }); (format!("use of undeclared type `{}`", ident), suggestion) } else { diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index bed579f6b92..87067189a77 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -175,7 +175,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { /// to not update anything and we can skip it. /// /// We are checking this condition only if the correct value of private visibility is - /// cheaply available, otherwise it does't make sense performance-wise. + /// cheaply available, otherwise it doesn't make sense performance-wise. /// /// `None` is returned if the update can be skipped, /// and cheap private visibility is returned otherwise. diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index afa796cb645..6197af105a9 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -22,7 +22,7 @@ pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(cra #[derive(Diagnostic)] #[diag(resolve_crate_may_not_be_imported)] -pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span); +pub(crate) struct CrateMayNotBeImported(#[primary_span] pub(crate) Span); #[derive(Diagnostic)] #[diag(resolve_crate_root_imports_must_be_named_explicitly)] @@ -508,3 +508,12 @@ pub(crate) struct RemoveSurroundingDerive { pub(crate) struct AddAsNonDerive<'a> { pub(crate) macro_path: &'a str, } + +#[derive(Diagnostic)] +#[diag(resolve_proc_macro_same_crate)] +pub(crate) struct ProcMacroSameCrate { + #[primary_span] + pub(crate) span: Span, + #[help] + pub(crate) is_test: bool, +} diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 3c22d51c3d4..d7c518fbdd0 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1276,13 +1276,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { next_binding = binding; } - reexports.push(ModChild { - ident, - res, - vis: binding.vis, - span: binding.span, - reexport_chain, - }); + reexports.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); } }); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 90a2fa89cd2..a97857e05e2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1079,7 +1079,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, for rib in self.lifetime_ribs.iter().rev() { match rib.kind { // We are inside a `PolyTraitRef`. The lifetimes are - // to be intoduced in that (maybe implicit) `for<>` binder. + // to be introduced in that (maybe implicit) `for<>` binder. LifetimeRibKind::Generics { binder, kind: LifetimeBinderKind::PolyTrait, @@ -3803,7 +3803,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // use std::u8; // bring module u8 in scope // fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 // u8::max_value() // OK, resolves to associated function <u8>::max_value, - // // not to non-existent std::u8::max_value + // // not to nonexistent std::u8::max_value // } // // Such behavior is required for backward compatibility. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 37fbfad2de6..e824a6ddc07 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -91,7 +91,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str /// Description of an elided lifetime. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] pub(super) struct MissingLifetime { - /// Used to overwrite the resolution with the suggestion, to avoid cascasing errors. + /// Used to overwrite the resolution with the suggestion, to avoid cascading errors. pub id: NodeId, /// Where to suggest adding the lifetime. pub span: Span, @@ -408,7 +408,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } let Some(path_last_segment) = path.last() else { return }; let item_str = path_last_segment.ident; - // Emit help message for fake-self from other languages (e.g., `this` in Javascript). + // Emit help message for fake-self from other languages (e.g., `this` in JavaScript). if ["this", "my"].contains(&item_str.as_str()) { err.span_suggestion_short( span, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b820d56b8af..125f5ce7611 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -33,14 +33,14 @@ use rustc_errors::{ Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage, }; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_hir::TraitCandidate; -use rustc_index::vec::IndexVec; -use rustc_macros::fluent_messages; +use rustc_index::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 22b014c0651..2211fb56ccd 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,7 +1,7 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. -use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; +use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; use crate::Namespace::*; use crate::{BuiltinMacroState, Determinacy}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; @@ -513,10 +513,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(def_id) = def_id.as_local() { self.unused_macros.remove(&def_id); if self.proc_macro_stubs.contains(&def_id) { - self.tcx.sess.span_err( - path.span, - "can't use a procedural macro from the same crate that defines it", - ); + self.tcx.sess.emit_err(errors::ProcMacroSameCrate { + span: path.span, + is_test: self.tcx.sess.is_test_crate(), + }); } } } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 9eae99be2e9..d433391f272 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -367,6 +367,7 @@ fn preprocess_link(link: &str) -> Box<str> { let link = link.strip_suffix("{}").unwrap_or(link); let link = link.strip_suffix("[]").unwrap_or(link); let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link }; + let link = link.trim(); strip_generics_from_path(link).unwrap_or_else(|_| link.into()) } diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index 7dad9aa01fa..e568b9e6786 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -1,3 +1,6 @@ +use crate::opaque::MemDecoder; +use crate::serialize::Decoder; + /// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type pub const fn max_leb128_len<T>() -> usize { // The longest LEB128 encoding for an integer uses 7 bits per byte. @@ -50,21 +53,19 @@ impl_write_unsigned_leb128!(write_usize_leb128, usize); macro_rules! impl_read_unsigned_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] - pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty { + pub fn $fn_name(decoder: &mut MemDecoder<'_>) -> $int_ty { // The first iteration of this loop is unpeeled. This is a // performance win because this code is hot and integer values less // than 128 are very common, typically occurring 50-80% or more of // the time, even for u64 and u128. - let byte = slice[*position]; - *position += 1; + let byte = decoder.read_u8(); if (byte & 0x80) == 0 { return byte as $int_ty; } let mut result = (byte & 0x7F) as $int_ty; let mut shift = 7; loop { - let byte = slice[*position]; - *position += 1; + let byte = decoder.read_u8(); if (byte & 0x80) == 0 { result |= (byte as $int_ty) << shift; return result; @@ -127,14 +128,13 @@ impl_write_signed_leb128!(write_isize_leb128, isize); macro_rules! impl_read_signed_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] - pub fn $fn_name(slice: &[u8], position: &mut usize) -> $int_ty { + pub fn $fn_name(decoder: &mut MemDecoder<'_>) -> $int_ty { let mut result = 0; let mut shift = 0; let mut byte; loop { - byte = slice[*position]; - *position += 1; + byte = decoder.read_u8(); result |= <$int_ty>::from(byte & 0x7F) << shift; shift += 7; diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs index 1f8d2336c4e..ce8503918b4 100644 --- a/compiler/rustc_serialize/src/lib.rs +++ b/compiler/rustc_serialize/src/lib.rs @@ -16,6 +16,7 @@ Core encoding and decoding interfaces. #![feature(maybe_uninit_slice)] #![feature(new_uninit)] #![feature(allocator_api)] +#![feature(ptr_sub_ptr)] #![cfg_attr(test, feature(test))] #![allow(rustc::internal)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 53e5c896736..b7976ea3b1c 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -2,7 +2,9 @@ use crate::leb128::{self, largest_max_leb128_len}; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fs::File; use std::io::{self, Write}; +use std::marker::PhantomData; use std::mem::MaybeUninit; +use std::ops::Range; use std::path::Path; use std::ptr; @@ -510,39 +512,126 @@ impl Encoder for FileEncoder { // Decoder // ----------------------------------------------------------------------------- +// Conceptually, `MemDecoder` wraps a `&[u8]` with a cursor into it that is always valid. +// This is implemented with three pointers, two which represent the original slice and a +// third that is our cursor. +// It is an invariant of this type that start <= current <= end. +// Additionally, the implementation of this type never modifies start and end. pub struct MemDecoder<'a> { - pub data: &'a [u8], - position: usize, + start: *const u8, + current: *const u8, + end: *const u8, + _marker: PhantomData<&'a u8>, } impl<'a> MemDecoder<'a> { #[inline] pub fn new(data: &'a [u8], position: usize) -> MemDecoder<'a> { - MemDecoder { data, position } + let Range { start, end } = data.as_ptr_range(); + MemDecoder { start, current: data[position..].as_ptr(), end, _marker: PhantomData } } #[inline] - pub fn position(&self) -> usize { - self.position + pub fn data(&self) -> &'a [u8] { + // SAFETY: This recovers the original slice, only using members we never modify. + unsafe { std::slice::from_raw_parts(self.start, self.len()) } } #[inline] - pub fn set_position(&mut self, pos: usize) { - self.position = pos + pub fn len(&self) -> usize { + // SAFETY: This recovers the length of the original slice, only using members we never modify. + unsafe { self.end.sub_ptr(self.start) } + } + + #[inline] + pub fn remaining(&self) -> usize { + // SAFETY: This type guarantees current <= end. + unsafe { self.end.sub_ptr(self.current) } + } + + #[cold] + #[inline(never)] + fn decoder_exhausted() -> ! { + panic!("MemDecoder exhausted") } #[inline] - pub fn advance(&mut self, bytes: usize) { - self.position += bytes; + fn read_byte(&mut self) -> u8 { + if self.current == self.end { + Self::decoder_exhausted(); + } + // SAFETY: This type guarantees current <= end, and we just checked current == end. + unsafe { + let byte = *self.current; + self.current = self.current.add(1); + byte + } + } + + #[inline] + fn read_array<const N: usize>(&mut self) -> [u8; N] { + self.read_raw_bytes(N).try_into().unwrap() + } + + // The trait method doesn't have a lifetime parameter, and we need a version of this + // that definitely returns a slice based on the underlying storage as opposed to + // the Decoder itself in order to implement read_str efficiently. + #[inline] + fn read_raw_bytes_inherent(&mut self, bytes: usize) -> &'a [u8] { + if bytes > self.remaining() { + Self::decoder_exhausted(); + } + // SAFETY: We just checked if this range is in-bounds above. + unsafe { + let slice = std::slice::from_raw_parts(self.current, bytes); + self.current = self.current.add(bytes); + slice + } + } + + /// While we could manually expose manipulation of the decoder position, + /// all current users of that method would need to reset the position later, + /// incurring the bounds check of set_position twice. + #[inline] + pub fn with_position<F, T>(&mut self, pos: usize, func: F) -> T + where + F: Fn(&mut MemDecoder<'a>) -> T, + { + struct SetOnDrop<'a, 'guarded> { + decoder: &'guarded mut MemDecoder<'a>, + current: *const u8, + } + impl Drop for SetOnDrop<'_, '_> { + fn drop(&mut self) { + self.decoder.current = self.current; + } + } + + if pos >= self.len() { + Self::decoder_exhausted(); + } + let previous = self.current; + // SAFETY: We just checked if this add is in-bounds above. + unsafe { + self.current = self.start.add(pos); + } + let guard = SetOnDrop { current: previous, decoder: self }; + func(guard.decoder) } } macro_rules! read_leb128 { - ($dec:expr, $fun:ident) => {{ leb128::$fun($dec.data, &mut $dec.position) }}; + ($dec:expr, $fun:ident) => {{ leb128::$fun($dec) }}; } impl<'a> Decoder for MemDecoder<'a> { #[inline] + fn position(&self) -> usize { + // SAFETY: This type guarantees start <= current + unsafe { self.current.sub_ptr(self.start) } + } + + #[inline] fn read_u128(&mut self) -> u128 { read_leb128!(self, read_u128_leb128) } @@ -559,17 +648,12 @@ impl<'a> Decoder for MemDecoder<'a> { #[inline] fn read_u16(&mut self) -> u16 { - let bytes = [self.data[self.position], self.data[self.position + 1]]; - let value = u16::from_le_bytes(bytes); - self.position += 2; - value + u16::from_le_bytes(self.read_array()) } #[inline] fn read_u8(&mut self) -> u8 { - let value = self.data[self.position]; - self.position += 1; - value + self.read_byte() } #[inline] @@ -594,17 +678,12 @@ impl<'a> Decoder for MemDecoder<'a> { #[inline] fn read_i16(&mut self) -> i16 { - let bytes = [self.data[self.position], self.data[self.position + 1]]; - let value = i16::from_le_bytes(bytes); - self.position += 2; - value + i16::from_le_bytes(self.read_array()) } #[inline] fn read_i8(&mut self) -> i8 { - let value = self.data[self.position]; - self.position += 1; - value as i8 + self.read_byte() as i8 } #[inline] @@ -625,22 +704,26 @@ impl<'a> Decoder for MemDecoder<'a> { } #[inline] - fn read_str(&mut self) -> &'a str { + fn read_str(&mut self) -> &str { let len = self.read_usize(); - let sentinel = self.data[self.position + len]; - assert!(sentinel == STR_SENTINEL); - let s = unsafe { - std::str::from_utf8_unchecked(&self.data[self.position..self.position + len]) - }; - self.position += len + 1; - s + let bytes = self.read_raw_bytes_inherent(len + 1); + assert!(bytes[len] == STR_SENTINEL); + unsafe { std::str::from_utf8_unchecked(&bytes[..len]) } } #[inline] - fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] { - let start = self.position; - self.position += bytes; - &self.data[start..self.position] + fn read_raw_bytes(&mut self, bytes: usize) -> &[u8] { + self.read_raw_bytes_inherent(bytes) + } + + #[inline] + fn peek_byte(&self) -> u8 { + if self.current == self.end { + Self::decoder_exhausted(); + } + // SAFETY: This type guarantees current is inbounds or one-past-the-end, which is end. + // Since we just checked current == end, the current pointer must be inbounds. + unsafe { *self.current } } } diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs index 527abc23727..a6d9c7b7d42 100644 --- a/compiler/rustc_serialize/src/serialize.rs +++ b/compiler/rustc_serialize/src/serialize.rs @@ -84,6 +84,8 @@ pub trait Decoder { fn read_char(&mut self) -> char; fn read_str(&mut self) -> &str; fn read_raw_bytes(&mut self, len: usize) -> &[u8]; + fn peek_byte(&self) -> u8; + fn position(&self) -> usize; } /// Trait for types that can be serialized diff --git a/compiler/rustc_serialize/tests/leb128.rs b/compiler/rustc_serialize/tests/leb128.rs index 314c07db981..7872e778431 100644 --- a/compiler/rustc_serialize/tests/leb128.rs +++ b/compiler/rustc_serialize/tests/leb128.rs @@ -3,6 +3,7 @@ use rustc_serialize::leb128::*; use std::mem::MaybeUninit; +use rustc_serialize::Decoder; macro_rules! impl_test_unsigned_leb128 { ($test_name:ident, $write_fn_name:ident, $read_fn_name:ident, $int_ty:ident) => { @@ -28,12 +29,12 @@ macro_rules! impl_test_unsigned_leb128 { stream.extend($write_fn_name(&mut buf, x)); } - let mut position = 0; + let mut decoder = rustc_serialize::opaque::MemDecoder::new(&stream, 0); for &expected in &values { - let actual = $read_fn_name(&stream, &mut position); + let actual = $read_fn_name(&mut decoder); assert_eq!(expected, actual); } - assert_eq!(stream.len(), position); + assert_eq!(stream.len(), decoder.position()); } }; } @@ -74,12 +75,12 @@ macro_rules! impl_test_signed_leb128 { stream.extend($write_fn_name(&mut buf, x)); } - let mut position = 0; + let mut decoder = rustc_serialize::opaque::MemDecoder::new(&stream, 0); for &expected in &values { - let actual = $read_fn_name(&stream, &mut position); + let actual = $read_fn_name(&mut decoder); assert_eq!(expected, actual); } - assert_eq!(stream.len(), position); + assert_eq!(stream.len(), decoder.position()); } }; } diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 9e337dde995..3477b97438c 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -10,10 +10,10 @@ tracing = "0.1" rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } -rustc_index = { path = "../rustc_index" } rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 40879db49de..7fdbd48d563 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -227,28 +227,29 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> { ))?; // if `dir` points target's dir, move up to the sysroot - if dir.ends_with(crate::config::host_triple()) { + let mut sysroot_dir = if dir.ends_with(crate::config::host_triple()) { dir.parent() // chop off `$target` .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| { - // chop off `lib` (this could be also $arch dir if the host sysroot uses a - // multi-arch layout like Debian or Ubuntu) - match p.parent() { - Some(p) => match p.file_name() { - Some(f) if f == "lib" => p.parent(), // first chop went for $arch, so chop again for `lib` - _ => Some(p), - }, - None => None, - } - }) + .and_then(|p| p.parent()) // chop off `lib` .map(|s| s.to_owned()) - .ok_or(format!( - "Could not move 3 levels upper using `parent()` on {}", - dir.display() - )) + .ok_or_else(|| { + format!("Could not move 3 levels upper using `parent()` on {}", dir.display()) + })? } else { - Ok(dir.to_owned()) + dir.to_owned() + }; + + // On multiarch linux systems, there will be multiarch directory named + // with the architecture(e.g `x86_64-linux-gnu`) under the `lib` directory. + // Which cause us to mistakenly end up in the lib directory instead of the sysroot directory. + if sysroot_dir.ends_with("lib") { + sysroot_dir = + sysroot_dir.parent().map(|real_sysroot| real_sysroot.to_owned()).ok_or_else( + || format!("Could not move to parent path of {}", sysroot_dir.display()), + )? } + + Ok(sysroot_dir) } // Use env::args().next() to get the path of the executable without diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 968728905e7..590a68c6600 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -19,7 +19,7 @@ pub mod errors; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod cgu_reuse_tracker; pub mod utils; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 631dd0a2146..d9f03fe1407 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1452,9 +1452,9 @@ options! { fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), - flatten_format_args: bool = (false, parse_bool, [TRACKED], + flatten_format_args: bool = (true, parse_bool, [TRACKED], "flatten nested format_args!() and literals into a simplified format_args!() call \ - (default: no)"), + (default: yes)"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable (default: no)"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], @@ -1558,6 +1558,9 @@ options! { "use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \ enabled, overriding all other checks. Passes that are not specified are enabled or \ disabled by other flags as usual."), + mir_keep_place_mention: bool = (false, parse_bool, [TRACKED], + "keep place mention MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ + (default: no)"), #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 340bb158e17..14a8e8ff727 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -811,7 +811,7 @@ impl Session { } pub fn generate_proc_macro_decls_symbol(&self, stable_crate_id: StableCrateId) -> String { - format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.to_u64()) + format!("__rustc_proc_macro_decls_{:08x}__", stable_crate_id.as_u64()) } pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch<'_> { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 4dad3c6bce7..09cb6fd22d5 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -128,6 +128,18 @@ fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir stable_mir::mir::Place { local: place.local.as_usize() } } +fn rustc_unwind_to_unwind( + unwind: &rustc_middle::mir::UnwindAction, +) -> stable_mir::mir::UnwindAction { + use rustc_middle::mir::UnwindAction; + match unwind { + UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, + UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, + UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, + UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), + } +} + fn rustc_terminator_to_terminator( terminator: &rustc_middle::mir::Terminator<'_>, ) -> stable_mir::mir::Terminator { @@ -151,7 +163,15 @@ fn rustc_terminator_to_terminator( Return => Terminator::Return, Unreachable => Terminator::Unreachable, Drop { .. } => todo!(), - Call { .. } => todo!(), + Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { + Terminator::Call { + func: rustc_op_to_op(func), + args: args.iter().map(|arg| rustc_op_to_op(arg)).collect(), + destination: rustc_place_to_place(destination), + target: target.map(|t| t.as_usize()), + unwind: rustc_unwind_to_unwind(unwind), + } + } Assert { .. } => todo!(), Yield { .. } => todo!(), GeneratorDrop => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index c504065c993..bd5e6b68a12 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -33,7 +33,7 @@ pub enum Terminator { args: Vec<Operand>, destination: Place, target: Option<usize>, - cleanup: Option<usize>, + unwind: UnwindAction, }, Assert { cond: Operand, @@ -45,6 +45,14 @@ pub enum Terminator { } #[derive(Clone, Debug)] +pub enum UnwindAction { + Continue, + Unreachable, + Terminate, + Cleanup(usize), +} + +#[derive(Clone, Debug)] pub enum Statement { Assign(Place, Operand), Nop, diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index b2c58caff2e..8c58b52a5dc 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -1,12 +1,11 @@ use crate::{HashStableContext, Symbol}; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::unhash::Unhasher; use rustc_data_structures::AtomicRef; -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use std::borrow::Borrow; use std::fmt; use std::hash::{BuildHasherDefault, Hash, Hasher}; @@ -105,20 +104,20 @@ impl DefPathHash { /// originates from. #[inline] pub fn stable_crate_id(&self) -> StableCrateId { - StableCrateId(self.0.as_value().0) + StableCrateId(self.0.split().0) } /// Returns the crate-local part of the [DefPathHash]. /// /// Used for tests. #[inline] - pub fn local_hash(&self) -> u64 { - self.0.as_value().1 + pub fn local_hash(&self) -> Hash64 { + self.0.split().1 } /// Builds a new [DefPathHash] with the given [StableCrateId] and /// `local_hash`, where `local_hash` must be unique within its crate. - pub fn new(stable_crate_id: StableCrateId, local_hash: u64) -> DefPathHash { + pub fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> DefPathHash { DefPathHash(Fingerprint::new(stable_crate_id.0, local_hash)) } } @@ -129,13 +128,6 @@ impl Default for DefPathHash { } } -impl Borrow<Fingerprint> for DefPathHash { - #[inline] - fn borrow(&self) -> &Fingerprint { - &self.0 - } -} - /// A [`StableCrateId`] is a 64-bit hash of a crate name, together with all /// `-Cmetadata` arguments, and some other data. It is to [`CrateNum`] what [`DefPathHash`] is to /// [`DefId`]. It is stable across compilation sessions. @@ -147,15 +139,11 @@ impl Borrow<Fingerprint> for DefPathHash { /// /// For more information on the possibility of hash collisions in rustc, /// see the discussion in [`DefId`]. -#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] -#[derive(HashStable_Generic, Encodable, Decodable)] -pub struct StableCrateId(pub(crate) u64); +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(Hash, HashStable_Generic, Encodable, Decodable)] +pub struct StableCrateId(pub(crate) Hash64); impl StableCrateId { - pub fn to_u64(self) -> u64 { - self.0 - } - /// Computes the stable ID for a crate with the given name and /// `-Cmetadata` arguments. pub fn new(crate_name: Symbol, is_exe: bool, mut metadata: Vec<String>) -> StableCrateId { @@ -197,6 +185,17 @@ impl StableCrateId { StableCrateId(hasher.finish()) } + + #[inline] + pub fn as_u64(self) -> u64 { + self.0.as_u64() + } +} + +impl fmt::LowerHex for StableCrateId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.0, f) + } } rustc_index::newtype_index! { diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 08c4414034a..c669b64dd2c 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -33,10 +33,10 @@ use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::HashingControls; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_data_structures::unhash::UnhashMap; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; @@ -123,15 +123,15 @@ impl ExpnHash { /// originates from. #[inline] pub fn stable_crate_id(self) -> StableCrateId { - StableCrateId(self.0.as_value().0) + StableCrateId(self.0.split().0) } /// Returns the crate-local part of the [ExpnHash]. /// /// Used for tests. #[inline] - pub fn local_hash(self) -> u64 { - self.0.as_value().1 + pub fn local_hash(self) -> Hash64 { + self.0.split().1 } #[inline] @@ -141,7 +141,7 @@ impl ExpnHash { /// Builds a new [ExpnHash] with the given [StableCrateId] and /// `local_hash`, where `local_hash` must be unique within its crate. - fn new(stable_crate_id: StableCrateId, local_hash: u64) -> ExpnHash { + fn new(stable_crate_id: StableCrateId, local_hash: Hash64) -> ExpnHash { ExpnHash(Fingerprint::new(stable_crate_id.0, local_hash)) } } @@ -350,7 +350,7 @@ pub struct HygieneData { /// would have collisions without a disambiguator. /// The keys of this map are always computed with `ExpnData.disambiguator` /// set to 0. - expn_data_disambiguators: FxHashMap<u64, u32>, + expn_data_disambiguators: FxHashMap<Hash64, u32>, } impl HygieneData { @@ -1040,7 +1040,7 @@ impl ExpnData { } #[inline] - fn hash_expn(&self, ctx: &mut impl HashStableContext) -> u64 { + fn hash_expn(&self, ctx: &mut impl HashStableContext) -> Hash64 { let mut hasher = StableHasher::new(); self.hash_stable(ctx, &mut hasher); hasher.finish() diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index aa8859ed1a3..8a900ca427e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -59,7 +59,7 @@ pub mod fatal_error; pub mod profiling; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash128, Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; use std::borrow::Cow; @@ -282,22 +282,22 @@ impl RealFileName { pub enum FileName { Real(RealFileName), /// Call to `quote!`. - QuoteExpansion(u64), + QuoteExpansion(Hash64), /// Command line. - Anon(u64), + Anon(Hash64), /// Hack in `src/librustc_ast/parse.rs`. // FIXME(jseyfried) - MacroExpansion(u64), - ProcMacroSourceCode(u64), + MacroExpansion(Hash64), + ProcMacroSourceCode(Hash64), /// Strings provided as `--cfg [cfgspec]` stored in a `crate_cfg`. - CfgSpec(u64), + CfgSpec(Hash64), /// Strings provided as crate attributes in the CLI. - CliCrateAttr(u64), + CliCrateAttr(Hash64), /// Custom sources for explicit parser calls from plugins and drivers. Custom(String), DocTest(PathBuf, isize), /// Post-substitution inline assembly from LLVM. - InlineAsm(u64), + InlineAsm(Hash64), } impl From<PathBuf> for FileName { @@ -1044,17 +1044,26 @@ impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Use the global `SourceMap` to print the span. If that's not // available, fall back to printing the raw values. - with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { - write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) - } else { - f.debug_struct("Span") - .field("lo", &self.lo()) - .field("hi", &self.hi()) - .field("ctxt", &self.ctxt()) - .finish() - } - }) + + fn fallback(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Span") + .field("lo", &span.lo()) + .field("hi", &span.hi()) + .field("ctxt", &span.ctxt()) + .finish() + } + + if SESSION_GLOBALS.is_set() { + with_session_globals(|session_globals| { + if let Some(source_map) = &*session_globals.source_map.borrow() { + write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) + } else { + fallback(*self, f) + } + }) + } else { + fallback(*self, f) + } } } @@ -1343,7 +1352,7 @@ pub struct SourceFile { /// Locations of characters removed during normalization. pub normalized_pos: Vec<NormalizedPos>, /// A hash of the filename, used for speeding up hashing in incremental compilation. - pub name_hash: u128, + pub name_hash: Hash128, /// Indicates which crate this `SourceFile` was imported from. pub cnum: CrateNum, } @@ -1472,7 +1481,7 @@ impl<D: Decoder> Decodable<D> for SourceFile { }; let multibyte_chars: Vec<MultiByteChar> = Decodable::decode(d); let non_narrow_chars: Vec<NonNarrowChar> = Decodable::decode(d); - let name_hash: u128 = Decodable::decode(d); + let name_hash = Decodable::decode(d); let normalized_pos: Vec<NormalizedPos> = Decodable::decode(d); let cnum: CrateNum = Decodable::decode(d); SourceFile { @@ -1514,7 +1523,7 @@ impl SourceFile { let name_hash = { let mut hasher: StableHasher = StableHasher::new(); name.hash(&mut hasher); - hasher.finish::<u128>() + hasher.finish() }; let end_pos = start_pos.to_usize() + src.len(); assert!(end_pos <= u32::MAX as usize); @@ -1663,10 +1672,11 @@ impl SourceFile { if let Some(ref src) = self.src { Some(Cow::from(get_until_newline(src, begin))) - } else if let Some(src) = self.external_src.borrow().get_source() { - Some(Cow::Owned(String::from(get_until_newline(src, begin)))) } else { - None + self.external_src + .borrow() + .get_source() + .map(|src| Cow::Owned(String::from(get_until_newline(src, begin)))) } } @@ -2159,9 +2169,7 @@ where }; Hash::hash(&TAG_VALID_SPAN, hasher); - // We truncate the stable ID hash and line and column numbers. The chances - // of causing a collision this way should be minimal. - Hash::hash(&(file.name_hash as u64), hasher); + Hash::hash(&file.name_hash, hasher); // Hash both the length and the end location (line/column) of a span. If we // hash only the length, for example, then two otherwise equal spans with diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 88e3674f899..1294a8b8e6b 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -13,7 +13,7 @@ pub use crate::hygiene::{ExpnData, ExpnKind}; pub use crate::*; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::StableHasher; +use rustc_data_structures::stable_hasher::{Hash128, Hash64, StableHasher}; use rustc_data_structures::sync::{AtomicU32, Lrc, MappedReadGuard, ReadGuard, RwLock}; use std::cmp; use std::hash::Hash; @@ -138,7 +138,7 @@ impl FileLoader for RealFileLoader { pub struct StableSourceFileId { /// A hash of the source file's [`FileName`]. This is hash so that it's size /// is more predictable than if we included the actual [`FileName`] value. - pub file_name_hash: u64, + pub file_name_hash: Hash64, /// The [`CrateNum`] of the crate this source file was originally parsed for. /// We cannot include this information in the hash because at the time @@ -331,7 +331,7 @@ impl SourceMap { &self, filename: FileName, src_hash: SourceFileHash, - name_hash: u128, + name_hash: Hash128, source_len: usize, cnum: CrateNum, file_local_lines: Lock<SourceFileLines>, @@ -483,7 +483,7 @@ impl SourceMap { self.span_to_string(sp, FileNameDisplayPreference::Remapped) } - /// Format the span location suitable for pretty printing anotations with relative line numbers + /// Format the span location suitable for pretty printing annotations with relative line numbers pub fn span_to_relative_line_string(&self, sp: Span, relative_to: Span) -> String { if self.files.borrow().source_files.is_empty() || sp.is_dummy() || relative_to.is_dummy() { return "no-location".to_string(); @@ -777,7 +777,7 @@ impl SourceMap { /// Given a 'Span', tries to tell if it's wrapped by "<>" or "()" /// the algorithm searches if the next character is '>' or ')' after skipping white space - /// then searches the previous charactoer to match '<' or '(' after skipping white space + /// then searches the previous character to match '<' or '(' after skipping white space /// return true if wrapped by '<>' or '()' pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool { self.span_to_source(span, |src, start_index, end_index| { @@ -906,10 +906,8 @@ impl SourceMap { let snippet = if let Some(ref src) = local_begin.sf.src { Some(&src[start_index..]) - } else if let Some(src) = src.get_source() { - Some(&src[start_index..]) } else { - None + src.get_source().map(|src| &src[start_index..]) }; match snippet { diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index c600298c51a..1eea0f63ca0 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -181,19 +181,23 @@ impl Span { #[inline] pub fn ctxt(self) -> SyntaxContext { let ctxt_or_tag = self.ctxt_or_tag as u32; - if ctxt_or_tag <= MAX_CTXT { - if self.len_or_tag == LEN_TAG || self.len_or_tag & PARENT_MASK == 0 { - // Inline format or interned format with inline ctxt. - SyntaxContext::from_u32(ctxt_or_tag) + // Check for interned format. + if self.len_or_tag == LEN_TAG { + if ctxt_or_tag == CTXT_TAG { + // Fully interned format. + let index = self.base_or_index; + with_span_interner(|interner| interner.spans[index as usize].ctxt) } else { - // Inline format or interned format with inline parent. - // We know that the SyntaxContext is root. - SyntaxContext::root() + // Interned format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } + } else if self.len_or_tag & PARENT_MASK == 0 { + // Inline format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } else { - // Interned format. - let index = self.base_or_index; - with_span_interner(|interner| interner.spans[index as usize].ctxt) + // Inline format with inline parent. + // We know that the SyntaxContext is root. + SyntaxContext::root() } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6bfae377152..70b9088de50 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -204,6 +204,7 @@ symbols! { HashSet, Hasher, Implied, + IndexOutput, Input, Into, IntoDiagnostic, @@ -1036,6 +1037,7 @@ symbols! { object_safe_for_dispatch, of, offset, + offset_of, omit_gdb_pretty_printer_section, on, on_unimplemented, @@ -1503,6 +1505,7 @@ symbols! { transmute_generic_consts, transmute_opts, transmute_trait, + transmute_unchecked, transparent, transparent_enums, transparent_unions, @@ -1986,8 +1989,9 @@ impl Interner { name } - // Get the symbol as a string. `Symbol::as_str()` should be used in - // preference to this function. + /// Get the symbol as a string. + /// + /// [`Symbol::as_str()`] should be used in preference to this function. fn get(&self, symbol: Symbol) -> &str { self.0.lock().strings[symbol.0.as_usize()] } diff --git a/compiler/rustc_span/src/tests.rs b/compiler/rustc_span/src/tests.rs index 5b3915c3338..a242ad6d1d7 100644 --- a/compiler/rustc_span/src/tests.rs +++ b/compiler/rustc_span/src/tests.rs @@ -3,8 +3,12 @@ use super::*; #[test] fn test_lookup_line() { let source = "abcdefghijklm\nabcdefghij\n...".to_owned(); - let sf = - SourceFile::new(FileName::Anon(0), source, BytePos(3), SourceFileHashAlgorithm::Sha256); + let sf = SourceFile::new( + FileName::Anon(Hash64::ZERO), + source, + BytePos(3), + SourceFileHashAlgorithm::Sha256, + ); sf.lines(|lines| assert_eq!(lines, &[BytePos(3), BytePos(17), BytePos(28)])); assert_eq!(sf.lookup_line(BytePos(0)), None); diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 4e447eab02e..052ef8bb94c 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -15,6 +15,7 @@ twox-hash = "1.6.3" rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 5cbca81926b..6a0ca06f69c 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_hir::def_id::CrateNum; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::ty::print::{PrettyPrinter, Print, Printer}; @@ -93,7 +93,7 @@ fn get_symbol_hash<'tcx>( item_type: Ty<'tcx>, instantiating_crate: Option<CrateNum>, -) -> u64 { +) -> Hash64 { let def_id = instance.def_id(); let substs = instance.substs; debug!("get_symbol_hash(def_id={:?}, parameters={:?})", def_id, substs); @@ -138,7 +138,7 @@ fn get_symbol_hash<'tcx>( }); // 64 bits should be enough to avoid collisions. - hasher.finish::<u64>() + hasher.finish::<Hash64>() }) } @@ -176,7 +176,7 @@ impl SymbolPath { } } - fn finish(mut self, hash: u64) -> String { + fn finish(mut self, hash: Hash64) -> String { self.finalize_pending_component(); // E = end name-sequence let _ = write!(self.result, "17h{hash:016x}E"); diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c2fd3304f2b..c97406868b6 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -101,9 +101,9 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_macros::fluent_messages; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index b4d5b7f3621..985b2210745 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -83,7 +83,7 @@ impl SymbolNamesTest<'_> { tcx.sess.emit_err(TestOutput { span: attr.span, kind: Kind::DefPath, - content: with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id())), + content: with_no_trimmed_paths!(tcx.def_path_str(def_id)), }); } } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 1a679f32ca5..a9152b8113f 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -406,7 +406,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { // Crate disambiguator and name s.push('C'); - s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).to_u64())); + s.push_str(&to_disambiguator(tcx.stable_crate_id(def_path.krate).as_u64())); let crate_name = tcx.crate_name(def_path.krate).to_string(); let _ = write!(s, "{}{}", crate_name.len(), &crate_name); @@ -814,16 +814,10 @@ fn transform_substs<'tcx>( substs: SubstsRef<'tcx>, options: TransformTyOptions, ) -> SubstsRef<'tcx> { - let substs = substs.iter().map(|subst| { - if let GenericArgKind::Type(ty) = subst.unpack() { - if is_c_void_ty(tcx, ty) { - tcx.mk_unit().into() - } else { - transform_ty(tcx, ty, options).into() - } - } else { - subst - } + let substs = substs.iter().map(|subst| match subst.unpack() { + GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(), + GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(), + _ => subst, }); tcx.mk_substs_from_iter(substs) } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index ee883285531..2235524129e 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -731,7 +731,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { fn path_crate(self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { self.push("C"); let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id(); - self.push_disambiguator(stable_crate_id.to_u64()); + self.push_disambiguator(stable_crate_id.as_u64()); let name = self.tcx.crate_name(cnum); self.push_ident(name.as_str()); Ok(self) diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml index 4e7a8d166ae..dff22fad4ec 100644 --- a/compiler/rustc_target/Cargo.toml +++ b/compiler/rustc_target/Cargo.toml @@ -11,7 +11,6 @@ rustc_fs_util = { path = "../rustc_fs_util" } rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_feature = { path = "../rustc_feature" } -rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_target/src/abi/call/avr.rs b/compiler/rustc_target/src/abi/call/avr.rs index e20f01355a4..b01dac8c70d 100644 --- a/compiler/rustc_target/src/abi/call/avr.rs +++ b/compiler/rustc_target/src/abi/call/avr.rs @@ -10,7 +10,7 @@ //! > self-consistent and sensible LLVM IR generation, but does not //! > conform to any particular ABI. //! > -//! > - Doxygen Doxumentation of `clang::DefaultABIInfo` +//! > - Doxygen Documentation of `clang::DefaultABIInfo` //! //! This calling convention may not match AVR-GCC in all cases. //! diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8d2e92cc76c..589cd3cf96b 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -124,6 +124,21 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { { Ty::is_unit(self) } + + pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size + where + Ty: TyAbiInterface<'a, C>, + { + let mut layout = self; + let mut offset = Size::ZERO; + + for index in indices { + offset += layout.fields.offset(index); + layout = layout.field(cx, index); + } + + offset + } } impl<'a, Ty> TyAndLayout<'a, Ty> { diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs new file mode 100644 index 00000000000..7ace1647ded --- /dev/null +++ b/compiler/rustc_target/src/asm/loongarch.rs @@ -0,0 +1,131 @@ +use super::{InlineAsmArch, InlineAsmType}; +use rustc_macros::HashStable_Generic; +use rustc_span::Symbol; +use std::fmt; + +def_reg_class! { + LoongArch LoongArchInlineAsmRegClass { + reg, + freg, + } +} + +impl LoongArchInlineAsmRegClass { + pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { + &[] + } + + pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { + None + } + + pub fn suggest_modifier( + self, + _arch: InlineAsmArch, + _ty: InlineAsmType, + ) -> Option<(char, &'static str)> { + None + } + + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { + None + } + + pub fn supported_types( + self, + arch: InlineAsmArch, + ) -> &'static [(InlineAsmType, Option<Symbol>)] { + match (self, arch) { + (Self::reg, InlineAsmArch::LoongArch64) => types! { _: I8, I16, I32, I64, F32, F64; }, + (Self::reg, _) => types! { _: I8, I16, I32, F32; }, + (Self::freg, _) => types! { _: F32, F64; }, + } + } +} + +// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp#79> +def_regs! { + LoongArch LoongArchInlineAsmReg LoongArchInlineAsmRegClass { + r1: reg = ["$r1","$ra"], + r4: reg = ["$r4","$a0"], + r5: reg = ["$r5","$a1"], + r6: reg = ["$r6","$a2"], + r7: reg = ["$r7","$a3"], + r8: reg = ["$r8","$a4"], + r9: reg = ["$r9","$a5"], + r10: reg = ["$r10","$a6"], + r11: reg = ["$r11","$a7"], + r12: reg = ["$r12","$t0"], + r13: reg = ["$r13","$t1"], + r14: reg = ["$r14","$t2"], + r15: reg = ["$r15","$t3"], + r16: reg = ["$r16","$t4"], + r17: reg = ["$r17","$t5"], + r18: reg = ["$r18","$t6"], + r19: reg = ["$r19","$t7"], + r20: reg = ["$r20","$t8"], + r23: reg = ["$r23","$s0"], + r24: reg = ["$r24","$s1"], + r25: reg = ["$r25","$s2"], + r26: reg = ["$r26","$s3"], + r27: reg = ["$r27","$s4"], + r28: reg = ["$r28","$s5"], + r29: reg = ["$r29","$s6"], + r30: reg = ["$r30","$s7"], + f0: freg = ["$f0","$fa0"], + f1: freg = ["$f1","$fa1"], + f2: freg = ["$f2","$fa2"], + f3: freg = ["$f3","$fa3"], + f4: freg = ["$f4","$fa4"], + f5: freg = ["$f5","$fa5"], + f6: freg = ["$f6","$fa6"], + f7: freg = ["$f7","$fa7"], + f8: freg = ["$f8","$ft0"], + f9: freg = ["$f9","$ft1"], + f10: freg = ["$f10","$ft2"], + f11: freg = ["$f11","$ft3"], + f12: freg = ["$f12","$ft4"], + f13: freg = ["$f13","$ft5"], + f14: freg = ["$f14","$ft6"], + f15: freg = ["$f15","$ft7"], + f16: freg = ["$f16","$ft8"], + f17: freg = ["$f17","$ft9"], + f18: freg = ["$f18","$ft10"], + f19: freg = ["$f19","$ft11"], + f20: freg = ["$f20","$ft12"], + f21: freg = ["$f21","$ft13"], + f22: freg = ["$f22","$ft14"], + f23: freg = ["$f23","$ft15"], + f24: freg = ["$f24","$fs0"], + f25: freg = ["$f25","$fs1"], + f26: freg = ["$f26","$fs2"], + f27: freg = ["$f27","$fs3"], + f28: freg = ["$f28","$fs4"], + f29: freg = ["$f29","$fs5"], + f30: freg = ["$f30","$fs6"], + f31: freg = ["$f31","$fs7"], + #error = ["$r0","$zero"] => + "constant zero cannot be used as an operand for inline asm", + #error = ["$r2","$tp"] => + "reserved for TLS", + #error = ["$r3","$sp"] => + "the stack pointer cannot be used as an operand for inline asm", + #error = ["$r21"] => + "reserved by the ABI", + #error = ["$r22","$fp"] => + "the frame pointer cannot be used as an operand for inline asm", + #error = ["$r31","$s8"] => + "$r31 is used internally by LLVM and cannot be used as an operand for inline asm", + } +} + +impl LoongArchInlineAsmReg { + pub fn emit( + self, + out: &mut dyn fmt::Write, + _arch: InlineAsmArch, + _modifier: Option<char>, + ) -> fmt::Result { + out.write_str(self.name()) + } +} diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs index 3f9c850b352..266691b2c88 100644 --- a/compiler/rustc_target/src/asm/mod.rs +++ b/compiler/rustc_target/src/asm/mod.rs @@ -168,6 +168,7 @@ mod arm; mod avr; mod bpf; mod hexagon; +mod loongarch; mod m68k; mod mips; mod msp430; @@ -184,6 +185,7 @@ pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass}; pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass}; pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass}; pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass}; +pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass}; pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass}; pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass}; pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass}; @@ -205,6 +207,7 @@ pub enum InlineAsmArch { RiscV64, Nvptx64, Hexagon, + LoongArch64, Mips, Mips64, PowerPC, @@ -234,6 +237,7 @@ impl FromStr for InlineAsmArch { "powerpc" => Ok(Self::PowerPC), "powerpc64" => Ok(Self::PowerPC64), "hexagon" => Ok(Self::Hexagon), + "loongarch64" => Ok(Self::LoongArch64), "mips" => Ok(Self::Mips), "mips64" => Ok(Self::Mips64), "s390x" => Ok(Self::S390x), @@ -259,6 +263,7 @@ pub enum InlineAsmReg { Nvptx(NvptxInlineAsmReg), PowerPC(PowerPCInlineAsmReg), Hexagon(HexagonInlineAsmReg), + LoongArch(LoongArchInlineAsmReg), Mips(MipsInlineAsmReg), S390x(S390xInlineAsmReg), SpirV(SpirVInlineAsmReg), @@ -280,6 +285,7 @@ impl InlineAsmReg { Self::RiscV(r) => r.name(), Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), + Self::LoongArch(r) => r.name(), Self::Mips(r) => r.name(), Self::S390x(r) => r.name(), Self::Bpf(r) => r.name(), @@ -298,6 +304,7 @@ impl InlineAsmReg { Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()), Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()), Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()), + Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()), Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()), Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()), Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()), @@ -324,6 +331,7 @@ impl InlineAsmReg { Self::PowerPC(PowerPCInlineAsmReg::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?), + InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?), InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmReg::parse(name)?) } @@ -354,6 +362,9 @@ impl InlineAsmReg { Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), + Self::LoongArch(r) => { + r.validate(arch, reloc_model, target_features, target, is_clobber) + } Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber), @@ -379,6 +390,7 @@ impl InlineAsmReg { Self::RiscV(r) => r.emit(out, arch, modifier), Self::PowerPC(r) => r.emit(out, arch, modifier), Self::Hexagon(r) => r.emit(out, arch, modifier), + Self::LoongArch(r) => r.emit(out, arch, modifier), Self::Mips(r) => r.emit(out, arch, modifier), Self::S390x(r) => r.emit(out, arch, modifier), Self::Bpf(r) => r.emit(out, arch, modifier), @@ -397,6 +409,7 @@ impl InlineAsmReg { Self::RiscV(_) => cb(self), Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))), Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))), + Self::LoongArch(_) => cb(self), Self::Mips(_) => cb(self), Self::S390x(_) => cb(self), Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))), @@ -418,6 +431,7 @@ pub enum InlineAsmRegClass { Nvptx(NvptxInlineAsmRegClass), PowerPC(PowerPCInlineAsmRegClass), Hexagon(HexagonInlineAsmRegClass), + LoongArch(LoongArchInlineAsmRegClass), Mips(MipsInlineAsmRegClass), S390x(S390xInlineAsmRegClass), SpirV(SpirVInlineAsmRegClass), @@ -440,6 +454,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.name(), Self::PowerPC(r) => r.name(), Self::Hexagon(r) => r.name(), + Self::LoongArch(r) => r.name(), Self::Mips(r) => r.name(), Self::S390x(r) => r.name(), Self::SpirV(r) => r.name(), @@ -464,6 +479,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx), Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC), Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon), + Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch), Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips), Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x), Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV), @@ -495,6 +511,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.suggest_modifier(arch, ty), Self::PowerPC(r) => r.suggest_modifier(arch, ty), Self::Hexagon(r) => r.suggest_modifier(arch, ty), + Self::LoongArch(r) => r.suggest_modifier(arch, ty), Self::Mips(r) => r.suggest_modifier(arch, ty), Self::S390x(r) => r.suggest_modifier(arch, ty), Self::SpirV(r) => r.suggest_modifier(arch, ty), @@ -522,6 +539,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.default_modifier(arch), Self::PowerPC(r) => r.default_modifier(arch), Self::Hexagon(r) => r.default_modifier(arch), + Self::LoongArch(r) => r.default_modifier(arch), Self::Mips(r) => r.default_modifier(arch), Self::S390x(r) => r.default_modifier(arch), Self::SpirV(r) => r.default_modifier(arch), @@ -548,6 +566,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.supported_types(arch), Self::PowerPC(r) => r.supported_types(arch), Self::Hexagon(r) => r.supported_types(arch), + Self::LoongArch(r) => r.supported_types(arch), Self::Mips(r) => r.supported_types(arch), Self::S390x(r) => r.supported_types(arch), Self::SpirV(r) => r.supported_types(arch), @@ -575,6 +594,7 @@ impl InlineAsmRegClass { Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?) } InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?), + InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?), InlineAsmArch::Mips | InlineAsmArch::Mips64 => { Self::Mips(MipsInlineAsmRegClass::parse(name)?) } @@ -601,6 +621,7 @@ impl InlineAsmRegClass { Self::Nvptx(r) => r.valid_modifiers(arch), Self::PowerPC(r) => r.valid_modifiers(arch), Self::Hexagon(r) => r.valid_modifiers(arch), + Self::LoongArch(r) => r.valid_modifiers(arch), Self::Mips(r) => r.valid_modifiers(arch), Self::S390x(r) => r.valid_modifiers(arch), Self::SpirV(r) => r.valid_modifiers(arch), @@ -760,6 +781,11 @@ pub fn allocatable_registers( hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map); map } + InlineAsmArch::LoongArch64 => { + let mut map = loongarch::regclass_map(); + loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map); + map + } InlineAsmArch::Mips | InlineAsmArch::Mips64 => { let mut map = mips::regclass_map(); mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map); diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 5c6dcc0aba9..4c7f64b2078 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -19,6 +19,7 @@ pub enum Arch { I386, I686, X86_64, + X86_64h, X86_64_sim, X86_64_macabi, Arm64_macabi, @@ -36,6 +37,7 @@ impl Arch { I386 => "i386", I686 => "i686", X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64h => "x86_64h", } } @@ -44,13 +46,13 @@ impl Arch { Armv7 | Armv7k | Armv7s => "arm", Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", I386 | I686 => "x86", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", }) } fn target_abi(self) -> &'static str { match self { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 => "", + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... @@ -67,6 +69,10 @@ impl Arch { Arm64_32 => "apple-s4", I386 | I686 => "yonah", X86_64 | X86_64_sim => "core2", + // Note: `core-avx2` is slightly more advanced than `x86_64h`, see + // comments (and disabled features) in `x86_64h_apple_darwin` for + // details. + X86_64h => "core-avx2", X86_64_macabi => "core2", Arm64_macabi => "apple-a12", Arm64_sim => "apple-a12", @@ -182,8 +188,13 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> { } fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { - // Note: Arm64_sim is not included since macOS has no simulator. - if matches!(arch, Arm64 | Arm64_macabi) { (11, 0) } else { (10, 7) } + match arch { + // Note: Arm64_sim is not included since macOS has no simulator. + Arm64 | Arm64_macabi => (11, 0), + // x86_64h-apple-darwin only supports macOS 10.8 and later + X86_64h => (10, 8), + _ => (10, 7), + } } fn macos_deployment_target(arch: Arch) -> (u32, u32) { @@ -227,7 +238,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> // of the linking environment that's wrong and reversed. match arch { Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim - | Arm64_sim => { + | X86_64h | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs index ebd74012dcd..9bcd56bed00 100644 --- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs @@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); + base.cpu = "M68020".into(); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4e5a821f0f6..10d38c34919 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1112,6 +1112,7 @@ supported_targets! { ("aarch64-apple-darwin", aarch64_apple_darwin), ("x86_64-apple-darwin", x86_64_apple_darwin), + ("x86_64h-apple-darwin", x86_64h_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia @@ -2285,13 +2286,13 @@ impl Target { } } } ); - ($key_name:ident, falliable_list) => ( { + ($key_name:ident, fallible_list) => ( { let name = (stringify!($key_name)).replace("_", "-"); obj.remove(&name).and_then(|j| { if let Some(v) = j.as_array() { match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() { Ok(l) => { base.$key_name = l }, - // FIXME: `falliable_list` can't re-use the `key!` macro for list + // FIXME: `fallible_list` can't re-use the `key!` macro for list // elements and the error messages from that macro, so it has a bad // generic message instead Err(_) => return Some(Err( @@ -2610,7 +2611,7 @@ impl Target { key!(has_thumb_interworking, bool); key!(debuginfo_kind, DebuginfoKind)?; key!(split_debuginfo, SplitDebuginfo)?; - key!(supported_split_debuginfo, falliable_list)?; + key!(supported_split_debuginfo, fallible_list)?; key!(supported_sanitizers, SanitizerSet)?; key!(default_adjusted_cabi, Option<Abi>)?; key!(generate_arange_section, bool); diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index 4dcf47fe465..2220b9326c9 100644 --- a/compiler/rustc_target/src/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs @@ -12,7 +12,7 @@ // // We have opted for these instead of one target per processor (e.g., `cortex-m0`, `cortex-m3`, // etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost -// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them. +// nonexistent from the POV of codegen so it doesn't make sense to have separate targets for them. // And if differences exist between two processors under the same target, rustc flags can be used to // optimize for one processor or the other. // diff --git a/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs new file mode 100644 index 00000000000..54f7490b2c0 --- /dev/null +++ b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs @@ -0,0 +1,44 @@ +use super::apple_base::{macos_llvm_target, opts, Arch}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{StackProbeType, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::X86_64h; + let mut base = opts("macos", arch); + base.max_atomic_width = Some(128); + base.frame_pointer = FramePointer::Always; + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); + base.stack_probes = StackProbeType::X86; + base.supported_sanitizers = + SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; + + // x86_64h is core2-avx without a few of the features which would otherwise + // be guaranteed, so we need to disable those. This imitates clang's logic: + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L77-L78 + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L133-L141 + // + // FIXME: Sadly, turning these off here disables them in such a way that they + // aren't re-enabled by `-Ctarget-cpu=native` (on a machine that has them). + // It would be nice if this were not the case, but fixing it seems tricky + // (and given that the main use-case for this target is for use in universal + // binaries, probably not that important). + base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into(); + // Double-check that the `cpu` is what we expect (if it's not the list above + // may need updating). + assert_eq!( + base.cpu, "core-avx2", + "you need to adjust the feature list in x86_64h-apple-darwin if you change this", + ); + + Target { + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), + arch: arch.target_arch(), + options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, + } +} diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index d3eba43b47e..83605627d6f 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -14,6 +14,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } @@ -24,4 +25,3 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -itertools = "0.10.1" diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index f866cb016e2..ed3994be987 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -37,7 +37,7 @@ extern crate rustc_middle; extern crate smallvec; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod errors; pub mod infer; diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 10d817f75ac..bacb0e32efc 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -51,7 +51,7 @@ pub(super) enum CandidateSource { BuiltinImpl, /// An assumption from the environment. /// - /// More precicely we've used the `n-th` assumption in the `param_env`. + /// More precisely we've used the `n-th` assumption in the `param_env`. /// /// ## Examples /// @@ -241,7 +241,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule, // object bound, alias bound, etc. We are unable to determine this until we can at - // least structually resolve the type one layer. + // least structurally resolve the type one layer. if goal.predicate.self_ty().is_ty_var() { return vec![Candidate { source: CandidateSource::BuiltinImpl, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index c29b5b04e00..bd52957d162 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> { pub(super) search_graph: &'a mut SearchGraph<'tcx>, pub(super) nested_goals: NestedGoals<'tcx>, + + // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`? + // + // If so, then it can no longer be used to make a canonical query response, + // since subsequent calls to `try_evaluate_added_goals` have possibly dropped + // ambiguous goals. Instead, a probe needs to be introduced somewhere in the + // evaluation code. + tainted: Result<(), NoSolution>, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { max_input_universe: ty::UniverseIndex::ROOT, var_values: CanonicalVarValues::dummy(), nested_goals: NestedGoals::new(), + tainted: Ok(()), }; let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal); @@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { max_input_universe: canonical_goal.max_universe, search_graph, nested_goals: NestedGoals::new(), + tainted: Ok(()), }; ecx.compute_goal(goal) }) @@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }, ); + if response.is_err() { + self.tainted = Err(NoSolution); + } + self.nested_goals = goals; response } @@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { max_input_universe: self.max_input_universe, search_graph: self.search_graph, nested_goals: self.nested_goals.clone(), + tainted: self.tainted, }; self.infcx.probe(|_| f(&mut ecx)) } @@ -649,7 +664,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME(transmutability): This really should be returning nested goals for `Answer::If*` match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( ObligationCause::dummy(), - ty::Binder::dummy(src_and_dst), + src_and_dst, scope, assume, ) { diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index ada868705c7..226d29687e3 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -11,12 +11,13 @@ use super::{CanonicalGoal, Certainty, EvalCtxt, Goal}; use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer}; use crate::solve::{CanonicalResponse, QueryResult, Response}; +use rustc_index::IndexVec; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData}; -use rustc_middle::ty::{self, GenericArgKind}; +use rustc_middle::ty::{self, BoundVar, GenericArgKind}; use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; @@ -50,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { certainty: Certainty, ) -> QueryResult<'tcx> { let goals_certainty = self.try_evaluate_added_goals()?; + assert_eq!( + self.tainted, + Ok(()), + "EvalCtxt is tainted -- nested goals may have been dropped in a \ + previous call to `try_evaluate_added_goals!`" + ); + let certainty = certainty.unify_with(goals_certainty); let external_constraints = self.compute_external_query_constraints()?; @@ -139,25 +147,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // // We therefore instantiate the existential variable in the canonical response with the // inference variable of the input right away, which is more performant. - let mut opt_values = vec![None; response.variables.len()]; + let mut opt_values = IndexVec::from_elem_n(None, response.variables.len()); for (original_value, result_value) in iter::zip(original_values, var_values.var_values) { match result_value.unpack() { GenericArgKind::Type(t) => { if let &ty::Bound(debruijn, b) = t.kind() { assert_eq!(debruijn, ty::INNERMOST); - opt_values[b.var.index()] = Some(*original_value); + opt_values[b.var] = Some(*original_value); } } GenericArgKind::Lifetime(r) => { if let ty::ReLateBound(debruijn, br) = *r { assert_eq!(debruijn, ty::INNERMOST); - opt_values[br.var.index()] = Some(*original_value); + opt_values[br.var] = Some(*original_value); } } GenericArgKind::Const(c) => { - if let ty::ConstKind::Bound(debrujin, b) = c.kind() { - assert_eq!(debrujin, ty::INNERMOST); - opt_values[b.index()] = Some(*original_value); + if let ty::ConstKind::Bound(debruijn, b) = c.kind() { + assert_eq!(debruijn, ty::INNERMOST); + opt_values[b] = Some(*original_value); } } } @@ -176,11 +184,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // As an optimization we sometimes avoid creating a new inference variable here. // // All new inference variables we create start out in the current universe of the caller. - // This is conceptionally wrong as these inference variables would be able to name + // This is conceptually wrong as these inference variables would be able to name // more placeholders then they should be able to. However the inference variables have // to "come from somewhere", so by equating them with the original values of the caller // later on, we pull them down into their correct universe again. - if let Some(v) = opt_values[index] { + if let Some(v) = opt_values[BoundVar::from_usize(index)] { v } else { self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe) diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 14cb43b89c3..f0840e0443c 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -73,7 +73,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal.predicate.projection_ty, assumption_projection_pred.projection_ty, )?; - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.add_goals(requirements); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) @@ -114,7 +115,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { .into_iter() .map(|pred| goal.with(tcx, pred)), ); - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } else { @@ -198,7 +200,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const { let identity_substs = ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id); - let did = ty::WithOptConstParam::unknown(assoc_def.item.def_id); + let did = assoc_def.item.def_id; let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs)); ty.map_bound(|ty| tcx.mk_const(kind, ty).into()) @@ -206,7 +208,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty.map_bound(|ty| ty.into()) }; - ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))?; + ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs)) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -375,7 +378,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ), }; - ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -513,7 +517,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; ecx.probe(|ecx| { - ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs index d1b4fa554c5..e6941af7b57 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs @@ -10,7 +10,7 @@ //! before then or if I still haven't done that before January 2023. use super::StackDepth; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::traits::solve::{CanonicalGoal, QueryResult}; rustc_index::newtype_index! { diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 050269fa973..c1904352574 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -6,7 +6,7 @@ pub(super) use overflow::OverflowHandler; use self::cache::ProvisionalEntry; use cache::ProvisionalCache; use overflow::OverflowData; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::dep_graph::DepKind; use rustc_middle::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index abd11a15ac2..c97473e6241 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -86,8 +86,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ) -> QueryResult<'tcx> { if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() && poly_trait_pred.def_id() == goal.predicate.def_id() + && poly_trait_pred.polarity() == goal.predicate.polarity { - // FIXME: Constness and polarity + // FIXME: Constness ecx.probe(|ecx| { let assumption_trait_pred = ecx.instantiate_binder_with_infer(poly_trait_pred); @@ -111,6 +112,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ) -> QueryResult<'tcx> { if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() && poly_trait_pred.def_id() == goal.predicate.def_id() + && poly_trait_pred.polarity() == goal.predicate.polarity { // FIXME: Constness and polarity ecx.probe(|ecx| { @@ -147,6 +149,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + if let Some(result) = ecx.disqualify_auto_trait_candidate_due_to_possible_impl(goal) { return result; } @@ -161,6 +167,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + let tcx = ecx.tcx(); ecx.probe(|ecx| { @@ -176,6 +186,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + ecx.probe_and_evaluate_goal_for_constituent_tys( goal, structural_traits::instantiate_constituent_tys_for_sized_trait, @@ -186,6 +200,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + ecx.probe_and_evaluate_goal_for_constituent_tys( goal, structural_traits::instantiate_constituent_tys_for_copy_clone_trait, @@ -196,6 +214,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + if goal.predicate.self_ty().has_non_region_infer() { return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); } @@ -217,6 +239,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + if let ty::FnPtr(..) = goal.predicate.self_ty().kind() { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { @@ -229,6 +255,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { goal: Goal<'tcx, Self>, goal_kind: ty::ClosureKind, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + let tcx = ecx.tcx(); let tupled_inputs_and_output = match structural_traits::extract_tupled_inputs_and_output_from_callable( @@ -259,6 +289,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + if let ty::Tuple(..) = goal.predicate.self_ty().kind() { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } else { @@ -268,8 +302,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_pointee_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, - _goal: Goal<'tcx, Self>, + goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -277,6 +315,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + let ty::Generator(def_id, _, _) = *goal.predicate.self_ty().kind() else { return Err(NoSolution); }; @@ -297,6 +339,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + let self_ty = goal.predicate.self_ty(); let ty::Generator(def_id, substs, _) = *self_ty.kind() else { return Err(NoSolution); @@ -326,6 +372,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + let tcx = ecx.tcx(); let a_ty = goal.predicate.self_ty(); let b_ty = goal.predicate.trait_ref.substs.type_at(1); @@ -447,6 +497,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> Vec<CanonicalResponse<'tcx>> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return vec![]; + } + let tcx = ecx.tcx(); let a_ty = goal.predicate.self_ty(); @@ -521,8 +575,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { fn consider_builtin_discriminant_kind_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, - _goal: Goal<'tcx, Self>, + goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + // `DiscriminantKind` is automatically implemented for every type. ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -531,6 +589,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + if !goal.param_env.is_const() { // `Destruct` is automatically implemented for every type in // non-const environments. @@ -545,6 +607,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { + if goal.predicate.polarity != ty::ImplPolarity::Positive { + return Err(NoSolution); + } + // `rustc_transmute` does not have support for type or const params if goal.has_non_region_placeholders() { return Err(NoSolution); @@ -591,7 +657,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Some(self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)) } - // These types cannot be structurally decomposed into constitutent + // These types cannot be structurally decomposed into constituent // types, and therefore have no built-in auto impl. ty::Dynamic(..) | ty::Param(..) @@ -645,12 +711,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Handling opaques here is kinda sus. Especially because we // simplify them to PlaceholderSimplifiedType. | ty::Alias(ty::Opaque, _) => { - if let Some(def_id) = self.tcx().find_map_relevant_impl( + let mut disqualifying_impl = None; + self.tcx().for_each_relevant_impl_treating_projections( goal.predicate.def_id(), goal.predicate.self_ty(), TreatProjections::NextSolverLookup, - Some, - ) { + |impl_def_id| { + disqualifying_impl = Some(impl_def_id); + }, + ); + if let Some(def_id) = disqualifying_impl { debug!(?def_id, ?goal, "disqualified auto-trait implementation"); // No need to actually consider the candidate here, // since we do that in `consider_impl_candidate`. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 182d995c4eb..e82672e8368 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -591,7 +591,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { fn evaluate_nested_obligations( &self, ty: Ty<'_>, - nested: impl Iterator<Item = Obligation<'tcx, ty::Predicate<'tcx>>>, + nested: impl Iterator<Item = PredicateObligation<'tcx>>, computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>, fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>, predicates: &mut VecDeque<ty::PolyTraitPredicate<'tcx>>, @@ -796,10 +796,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())), Ok(None) => { let tcx = self.tcx; - let def_id = unevaluated.def.did; let reported = tcx.sess.emit_err(UnableToConstructConstantValue { - span: tcx.def_span(def_id), + span: tcx.def_span(unevaluated.def), unevaluated: unevaluated, }); Err(ErrorHandled::Reported(reported)) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 345e84990ed..9d99d30d45c 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -44,7 +44,7 @@ pub fn is_const_evaluatable<'tcx>( let ct = tcx.expand_abstract_consts(unexpanded_ct); let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() { - tcx.def_kind(uv.def.did) == DefKind::AnonConst + tcx.def_kind(uv.def) == DefKind::AnonConst } else { false }; @@ -119,7 +119,7 @@ pub fn is_const_evaluatable<'tcx>( tcx.sess .struct_span_fatal( // Slightly better span than just using `span` alone - if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def.did) } else { span }, + if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, "failed to evaluate generic const expression", ) .note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index cef982fcb41..ce187fbdf84 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -15,8 +15,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::normalize::QueryNormalizeExt as _; use crate::traits::specialize::to_pretty_impl_header; use crate::traits::NormalizeExt; -use on_unimplemented::OnUnimplementedNote; -use on_unimplemented::TypeErrCtxtExt as _; +use on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, @@ -32,7 +31,6 @@ use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fast_reject::TreatProjections; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ @@ -467,7 +465,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors") + self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fulfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -707,42 +705,25 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { conversion on the error value using the `From` trait" .to_owned(), ), - Some(None), + Some(AppendConstMessage::Default), ) } else { (message, note, append_const_msg) }; - let err_msg = message - .and_then(|cannot_do_this| { - match (predicate_is_const, append_const_msg) { - // do nothing if predicate is not const - (false, _) => Some(cannot_do_this), - // suggested using default post message - (true, Some(None)) => { - Some(format!("{cannot_do_this} in const contexts")) - } - // overridden post message - (true, Some(Some(post_message))) => { - Some(format!("{cannot_do_this}{post_message}")) - } - // fallback to generic message - (true, None) => None, - } - }) - .unwrap_or_else(|| { - format!( - "the trait bound `{}` is not satisfied{}", - trait_predicate, post_message, - ) - }); + let err_msg = self.get_standard_error_message( + &trait_predicate, + message, + predicate_is_const, + append_const_msg, + post_message, + ); let (err_msg, safe_transmute_explanation) = if Some(trait_ref.def_id()) == self.tcx.lang_items().transmute_trait() { // Recompute the safe transmute reason and use that for the error reporting self.get_safe_transmute_error_and_reason( - trait_predicate, obligation.clone(), trait_ref, span, @@ -764,22 +745,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() { - match obligation.cause.code().peel_derives() { - ObligationCauseCode::RustCall => { - err.set_primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); - } - ObligationCauseCode::BindingObligation(def_id, _) - | ObligationCauseCode::ItemObligation(def_id) - if tcx.is_fn_trait(*def_id) => - { - err.code(rustc_errors::error_code!(E0059)); - err.set_primary_message(format!( - "type parameter to bare `{}` trait must be a tuple", - tcx.def_path_str(*def_id) - )); - } - _ => {} - } + self.add_tuple_trait_message( + &obligation.cause.code().peel_derives(), + &mut err, + ); } if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait() @@ -789,33 +758,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details"); } - let explanation = if let ObligationCauseCode::MainFunctionType = - obligation.cause.code() - { - "consider using `()`, or a `Result`".to_owned() - } else { - let ty_desc = match trait_ref.skip_binder().self_ty().kind() { - ty::FnDef(_, _) => Some("fn item"), - ty::Closure(_, _) => Some("closure"), - _ => None, - }; + let explanation = get_explanation_based_on_obligation( + &obligation, + trait_ref, + &trait_predicate, + pre_message, + ); - match ty_desc { - Some(desc) => format!( - "{}the trait `{}` is not implemented for {} `{}`", - pre_message, - trait_predicate.print_modifiers_and_trait_path(), - desc, - trait_ref.skip_binder().self_ty(), - ), - None => format!( - "{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_predicate.print_modifiers_and_trait_path(), - trait_ref.skip_binder().self_ty(), - ), - } - }; self.check_for_binding_assigned_block_without_tail_expression( &obligation, &mut err, @@ -852,28 +801,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty); } - let mut unsatisfied_const = false; - if trait_predicate.is_const_if_const() && obligation.param_env.is_const() { - let non_const_predicate = trait_ref.without_const(); - let non_const_obligation = Obligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env.without_const(), - predicate: non_const_predicate.to_predicate(tcx), - recursion_depth: obligation.recursion_depth, - }; - if self.predicate_may_hold(&non_const_obligation) { - unsatisfied_const = true; - err.span_note( - span, - &format!( - "the trait `{}` is implemented for `{}`, \ - but that implementation is not `const`", - non_const_predicate.print_modifiers_and_trait_path(), - trait_ref.skip_binder().self_ty(), - ), - ); - } - } + let UnsatisfiedConst(unsatisfied_const) = self + .maybe_add_note_for_unsatisfied_const( + &obligation, + trait_ref, + &trait_predicate, + &mut err, + span, + ); if let Some((msg, span)) = type_def { err.span_label(span, &msg); @@ -971,137 +906,16 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ); } - let body_def_id = obligation.cause.body_id; - // Try to report a help message - if is_fn_trait - && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( - obligation.param_env, - trait_ref.self_ty(), - trait_predicate.skip_binder().constness, - trait_predicate.skip_binder().polarity, - ) - { - // If the type implements `Fn`, `FnMut`, or `FnOnce`, suppress the following - // suggestion to add trait bounds for the type, since we only typically implement - // these traits once. - - // Note if the `FnMut` or `FnOnce` is less general than the trait we're trying - // to implement. - let selected_kind = - self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id()) - .expect("expected to map DefId to ClosureKind"); - if !implemented_kind.extends(selected_kind) { - err.note( - &format!( - "`{}` implements `{}`, but it must implement `{}`, which is more general", - trait_ref.skip_binder().self_ty(), - implemented_kind, - selected_kind - ) - ); - } - - // Note any argument mismatches - let given_ty = params.skip_binder(); - let expected_ty = trait_ref.skip_binder().substs.type_at(1); - if let ty::Tuple(given) = given_ty.kind() - && let ty::Tuple(expected) = expected_ty.kind() - { - if expected.len() != given.len() { - // Note number of types that were expected and given - err.note( - &format!( - "expected a closure taking {} argument{}, but one taking {} argument{} was given", - given.len(), - pluralize!(given.len()), - expected.len(), - pluralize!(expected.len()), - ) - ); - } else if !self.same_type_modulo_infer(given_ty, expected_ty) { - // Print type mismatch - let (expected_args, given_args) = - self.cmp(given_ty, expected_ty); - err.note_expected_found( - &"a closure with arguments", - expected_args, - &"a closure with arguments", - given_args, - ); - } - } - } else if !trait_ref.has_non_region_infer() - && self.predicate_can_apply(obligation.param_env, trait_predicate) - { - // If a where-clause may be useful, remind the - // user that they can add it. - // - // don't display an on-unimplemented note, as - // these notes will often be of the form - // "the type `T` can't be frobnicated" - // which is somewhat confusing. - self.suggest_restricting_param_bound( - &mut err, - trait_predicate, - None, - obligation.cause.body_id, - ); - } else if !suggested && !unsatisfied_const { - // Can't show anything else useful, try to find similar impls. - let impl_candidates = self.find_similar_impl_candidates(trait_predicate); - if !self.report_similar_impl_candidates( - &impl_candidates, - trait_ref, - body_def_id, - &mut err, - true, - ) { - // This is *almost* equivalent to - // `obligation.cause.code().peel_derives()`, but it gives us the - // trait predicate for that corresponding root obligation. This - // lets us get a derived obligation from a type parameter, like - // when calling `string.strip_suffix(p)` where `p` is *not* an - // implementer of `Pattern<'_>`. - let mut code = obligation.cause.code(); - let mut trait_pred = trait_predicate; - let mut peeled = false; - while let Some((parent_code, parent_trait_pred)) = code.parent() { - code = parent_code; - if let Some(parent_trait_pred) = parent_trait_pred { - trait_pred = parent_trait_pred; - peeled = true; - } - } - let def_id = trait_pred.def_id(); - // Mention *all* the `impl`s for the *top most* obligation, the - // user might have meant to use one of them, if any found. We skip - // auto-traits or fundamental traits that might not be exactly what - // the user might expect to be presented with. Instead this is - // useful for less general traits. - if peeled - && !self.tcx.trait_is_auto(def_id) - && !self.tcx.lang_items().iter().any(|(_, id)| id == def_id) - { - let trait_ref = trait_pred.to_poly_trait_ref(); - let impl_candidates = - self.find_similar_impl_candidates(trait_pred); - self.report_similar_impl_candidates( - &impl_candidates, - trait_ref, - body_def_id, - &mut err, - true, - ); - } - } - - self.maybe_suggest_convert_to_slice( - &mut err, - trait_ref, - impl_candidates.as_slice(), - span, - ); - } + self.try_to_add_help_message( + &obligation, + trait_ref, + &trait_predicate, + &mut err, + span, + is_fn_trait, + suggested, + unsatisfied_const, + ); // Changing mutability doesn't make a difference to whether we have // an `Unsize` impl (Fixes ICE in #71036) @@ -1196,59 +1010,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => { let found_kind = self.closure_kind(closure_substs).unwrap(); - let closure_span = self.tcx.def_span(closure_def_id); - let mut err = struct_span_err!( - self.tcx.sess, - closure_span, - E0525, - "expected a closure that implements the `{}` trait, \ - but this closure only implements `{}`", - kind, - found_kind - ); - - err.span_label( - closure_span, - format!("this closure implements `{}`, not `{}`", found_kind, kind), - ); - err.span_label( - obligation.cause.span, - format!("the requirement to implement `{}` derives from here", kind), - ); - - // Additional context information explaining why the closure only implements - // a particular trait. - if let Some(typeck_results) = &self.typeck_results { - let hir_id = self - .tcx - .hir() - .local_def_id_to_hir_id(closure_def_id.expect_local()); - match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) { - (ty::ClosureKind::FnOnce, Some((span, place))) => { - err.span_label( - *span, - format!( - "closure is `FnOnce` because it moves the \ - variable `{}` out of its environment", - ty::place_to_string_for_capture(tcx, place) - ), - ); - } - (ty::ClosureKind::FnMut, Some((span, place))) => { - err.span_label( - *span, - format!( - "closure is `FnMut` because it mutates the \ - variable `{}` here", - ty::place_to_string_for_capture(tcx, place) - ), - ); - } - _ => {} - } - } - - err + self.report_closure_error(&obligation, closure_def_id, found_kind, kind) } ty::PredicateKind::WellFormed(ty) => { @@ -1329,117 +1091,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { found_trait_ref, expected_trait_ref, terr @ TypeError::CyclicTy(_), - ) => { - let self_ty = found_trait_ref.self_ty().skip_binder(); - let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { - ( - ObligationCause::dummy_with_span(tcx.def_span(def_id)), - TypeError::CyclicTy(self_ty), - ) - } else { - (obligation.cause.clone(), terr) - }; - self.report_and_explain_type_error( - TypeTrace::poly_trait_refs(&cause, true, expected_trait_ref, found_trait_ref), - terr, - ) - } + ) => self.report_type_parameter_mismatch_cyclic_type_error( + &obligation, + found_trait_ref, + expected_trait_ref, + terr, + ), OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => { - let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); - let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); - - if expected_trait_ref.self_ty().references_error() { - return; - } - - let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else { - return; - }; - - let found_did = match *found_trait_ty.kind() { - ty::Closure(did, _) - | ty::Foreign(did) - | ty::FnDef(did, _) - | ty::Generator(did, ..) => Some(did), - ty::Adt(def, _) => Some(def.did()), - _ => None, - }; - - let found_node = found_did.and_then(|did| self.tcx.hir().get_if_local(did)); - let found_span = found_did.and_then(|did| self.tcx.hir().span_if_local(did)); - - if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { - // We check closures twice, with obligations flowing in different directions, - // but we want to complain about them only once. - return; - } - - self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); - - let mut not_tupled = false; - - let found = match found_trait_ref.skip_binder().substs.type_at(1).kind() { - ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], - _ => { - not_tupled = true; - vec![ArgKind::empty()] - } - }; - - let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); - let expected = match expected_ty.kind() { - ty::Tuple(ref tys) => { - tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect() - } - _ => { - not_tupled = true; - vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())] - } - }; - - // If this is a `Fn` family trait and either the expected or found - // is not tupled, then fall back to just a regular mismatch error. - // This shouldn't be common unless manually implementing one of the - // traits manually, but don't make it more confusing when it does - // happen. - if Some(expected_trait_ref.def_id()) != tcx.lang_items().gen_trait() && not_tupled { - self.report_and_explain_type_error( - TypeTrace::poly_trait_refs( - &obligation.cause, - true, - expected_trait_ref, - found_trait_ref, - ), - ty::error::TypeError::Mismatch, - ) - } else if found.len() == expected.len() { - self.report_closure_arg_mismatch( - span, - found_span, - found_trait_ref, - expected_trait_ref, - obligation.cause.code(), - found_node, - obligation.param_env, - ) - } else { - let (closure_span, closure_arg_span, found) = found_did - .and_then(|did| { - let node = self.tcx.hir().get_if_local(did)?; - let (found_span, closure_arg_span, found) = - self.get_fn_like_arguments(node)?; - Some((Some(found_span), closure_arg_span, found)) - }) - .unwrap_or((found_span, None, found)); - - self.report_arg_count_mismatch( - span, - closure_span, - expected, - found, - found_trait_ty.is_closure(), - closure_arg_span, - ) + match self.report_type_parameter_mismatch_error( + &obligation, + span, + found_trait_ref, + expected_trait_ref, + ) { + Some(err) => err, + None => return, } } @@ -1454,45 +1120,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } SelectionError::NotConstEvaluatable(NotConstEvaluatable::MentionsParam) => { - if !self.tcx.features().generic_const_exprs { - let mut err = self.tcx.sess.struct_span_err( - span, - "constant expression depends on a generic parameter", - ); - // FIXME(const_generics): we should suggest to the user how they can resolve this - // issue. However, this is currently not actually possible - // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). - // - // Note that with `feature(generic_const_exprs)` this case should not - // be reachable. - err.note("this may fail depending on what value the parameter takes"); - err.emit(); - return; - } - - match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::ConstEvaluatable(ct) => { - let ty::ConstKind::Unevaluated(uv) = ct.kind() else { - bug!("const evaluatable failed for non-unevaluated const `{ct:?}`"); - }; - let mut err = - self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); - let const_span = self.tcx.def_span(uv.def.did); - match self.tcx.sess.source_map().span_to_snippet(const_span) { - Ok(snippet) => err.help(&format!( - "try adding a `where` bound using this expression: `where [(); {}]:`", - snippet - )), - _ => err.help("consider adding a `where` bound using this expression"), - }; - err - } - _ => { - span_bug!( - span, - "unexpected non-ConstEvaluatable predicate, this should not be reachable" - ) - } + match self.report_not_const_evaluatable_error(&obligation, span) { + Some(err) => err, + None => return, } } @@ -1564,6 +1194,14 @@ trait InferCtxtPrivExt<'tcx> { other: bool, ) -> bool; + fn report_similar_impl_candidates_for_root_obligation( + &self, + obligation: &PredicateObligation<'tcx>, + trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, + body_def_id: LocalDefId, + err: &mut Diagnostic, + ); + /// Gets the parent trait chain start fn get_parent_trait_ref( &self, @@ -1627,13 +1265,86 @@ trait InferCtxtPrivExt<'tcx> { cause_code: &ObligationCauseCode<'tcx>, ) -> bool; + fn get_standard_error_message( + &self, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + message: Option<String>, + predicate_is_const: bool, + append_const_msg: Option<AppendConstMessage>, + post_message: String, + ) -> String; + fn get_safe_transmute_error_and_reason( &self, - trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - obligation: Obligation<'tcx, ty::Predicate<'tcx>>, - trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + obligation: PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, span: Span, ) -> (String, Option<String>); + + fn add_tuple_trait_message( + &self, + obligation_cause_code: &ObligationCauseCode<'tcx>, + err: &mut Diagnostic, + ); + + fn try_to_add_help_message( + &self, + obligation: &PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + err: &mut Diagnostic, + span: Span, + is_fn_trait: bool, + suggested: bool, + unsatisfied_const: bool, + ); + + fn add_help_message_for_fn_trait( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + err: &mut Diagnostic, + implemented_kind: ty::ClosureKind, + params: ty::Binder<'tcx, Ty<'tcx>>, + ); + + fn maybe_add_note_for_unsatisfied_const( + &self, + obligation: &PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + err: &mut Diagnostic, + span: Span, + ) -> UnsatisfiedConst; + + fn report_closure_error( + &self, + obligation: &PredicateObligation<'tcx>, + closure_def_id: DefId, + found_kind: ty::ClosureKind, + kind: ty::ClosureKind, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; + + fn report_type_parameter_mismatch_cyclic_type_error( + &self, + obligation: &PredicateObligation<'tcx>, + found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + terr: TypeError<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>; + + fn report_type_parameter_mismatch_error( + &self, + obligation: &PredicateObligation<'tcx>, + span: Span, + found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; + + fn report_not_const_evaluatable_error( + &self, + obligation: &PredicateObligation<'tcx>, + span: Span, + ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>>; } impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { @@ -1773,7 +1484,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .tcx .mk_const( ty::UnevaluatedConst { - def: ty::WithOptConstParam::unknown(data.projection_ty.def_id), + def: data.projection_ty.def_id, substs: data.projection_ty.substs, }, ct.ty(), @@ -1838,57 +1549,61 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }); let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}"); - let secondary_span = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self - .tcx - .opt_associated_item(proj.projection_ty.def_id) - .and_then(|trait_assoc_item| { - self.tcx - .trait_of_item(proj.projection_ty.def_id) - .map(|id| (trait_assoc_item, id)) - }) - .and_then(|(trait_assoc_item, id)| { - let trait_assoc_ident = trait_assoc_item.ident(self.tcx); - self.tcx.find_map_relevant_impl( - id, - proj.projection_ty.self_ty(), - TreatProjections::ForLookup, - |did| { - self.tcx - .associated_items(did) - .in_definition_order() - .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident) - }, - ) - }) - .and_then(|item| match self.tcx.hir().get_if_local(item.def_id) { - Some( - hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Type(_, Some(ty)), - .. - }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Type(ty), - .. - }), - ) => Some(( - ty.span, - with_forced_trimmed_paths!(format!( - "type mismatch resolving `{}`", - self.resolve_vars_if_possible(predicate) - .print(FmtPrinter::new_with_limit( - self.tcx, - Namespace::TypeNS, - rustc_session::Limit(5), - )) - .unwrap() - .into_buffer() - )), + let secondary_span = (|| { + let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = + predicate.kind().skip_binder() + else { + return None; + }; + + let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?; + let trait_assoc_ident = trait_assoc_item.ident(self.tcx); + + let mut associated_items = vec![]; + self.tcx.for_each_relevant_impl( + self.tcx.trait_of_item(proj.projection_ty.def_id)?, + proj.projection_ty.self_ty(), + |impl_def_id| { + associated_items.extend( + self.tcx + .associated_items(impl_def_id) + .in_definition_order() + .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident), + ); + }, + ); + + let [associated_item]: &[ty::AssocItem] = &associated_items[..] else { + return None; + }; + match self.tcx.hir().get_if_local(associated_item.def_id) { + Some( + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Type(ty), + .. + }), + ) => Some(( + ty.span, + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.resolve_vars_if_possible(predicate) + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(5), + )) + .unwrap() + .into_buffer() )), - _ => None, - }), - _ => None, - }; + )), + _ => None, + } + })(); + self.note_type_err( &mut diag, &obligation.cause, @@ -2058,7 +1773,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if candidates.iter().any(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })) { // If any of the candidates is a perfect match, we don't want to show all of them. // This is particularly relevant for the case of numeric types (as they all have the - // same cathegory). + // same category). candidates.retain(|c| matches!(c.similarity, CandidateSimilarity::Exact { .. })); } candidates @@ -2197,6 +1912,51 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { report(normalized_impl_candidates, err) } + fn report_similar_impl_candidates_for_root_obligation( + &self, + obligation: &PredicateObligation<'tcx>, + trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, + body_def_id: LocalDefId, + err: &mut Diagnostic, + ) { + // This is *almost* equivalent to + // `obligation.cause.code().peel_derives()`, but it gives us the + // trait predicate for that corresponding root obligation. This + // lets us get a derived obligation from a type parameter, like + // when calling `string.strip_suffix(p)` where `p` is *not* an + // implementer of `Pattern<'_>`. + let mut code = obligation.cause.code(); + let mut trait_pred = trait_predicate; + let mut peeled = false; + while let Some((parent_code, parent_trait_pred)) = code.parent() { + code = parent_code; + if let Some(parent_trait_pred) = parent_trait_pred { + trait_pred = parent_trait_pred; + peeled = true; + } + } + let def_id = trait_pred.def_id(); + // Mention *all* the `impl`s for the *top most* obligation, the + // user might have meant to use one of them, if any found. We skip + // auto-traits or fundamental traits that might not be exactly what + // the user might expect to be presented with. Instead this is + // useful for less general traits. + if peeled + && !self.tcx.trait_is_auto(def_id) + && !self.tcx.lang_items().iter().any(|(_, id)| id == def_id) + { + let trait_ref = trait_pred.to_poly_trait_ref(); + let impl_candidates = self.find_similar_impl_candidates(trait_pred); + self.report_similar_impl_candidates( + &impl_candidates, + trait_ref, + body_def_id, + err, + true, + ); + } + } + /// Gets the parent trait chain start fn get_parent_trait_ref( &self, @@ -2230,14 +1990,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>, ) -> bool { - let get_trait_impl = |trait_def_id| { - self.tcx.find_map_relevant_impl( + let get_trait_impls = |trait_def_id| { + let mut trait_impls = vec![]; + self.tcx.for_each_relevant_impl( trait_def_id, trait_ref.skip_binder().self_ty(), - TreatProjections::ForLookup, - Some, - ) + |impl_def_id| { + trait_impls.push(impl_def_id); + }, + ); + trait_impls }; + let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); let traits_with_same_path: std::collections::BTreeSet<_> = self .tcx @@ -2247,17 +2011,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .collect(); let mut suggested = false; for trait_with_same_path in traits_with_same_path { - if let Some(impl_def_id) = get_trait_impl(trait_with_same_path) { - let impl_span = self.tcx.def_span(impl_def_id); - err.span_help(impl_span, "trait impl with same name found"); - let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); - let crate_msg = format!( - "perhaps two different versions of crate `{}` are being used?", - trait_crate - ); - err.note(&crate_msg); - suggested = true; + let trait_impls = get_trait_impls(trait_with_same_path); + if trait_impls.is_empty() { + continue; } + let impl_spans: Vec<_> = + trait_impls.iter().map(|impl_def_id| self.tcx.def_span(*impl_def_id)).collect(); + err.span_help( + impl_spans, + format!("trait impl{} with same name found", pluralize!(trait_impls.len())), + ); + let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); + let crate_msg = format!( + "perhaps two different versions of crate `{}` are being used?", + trait_crate + ); + err.note(&crate_msg); + suggested = true; } suggested } @@ -2919,20 +2689,52 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { false } + fn get_standard_error_message( + &self, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + message: Option<String>, + predicate_is_const: bool, + append_const_msg: Option<AppendConstMessage>, + post_message: String, + ) -> String { + message + .and_then(|cannot_do_this| { + match (predicate_is_const, append_const_msg) { + // do nothing if predicate is not const + (false, _) => Some(cannot_do_this), + // suggested using default post message + (true, Some(AppendConstMessage::Default)) => { + Some(format!("{cannot_do_this} in const contexts")) + } + // overridden post message + (true, Some(AppendConstMessage::Custom(custom_msg))) => { + Some(format!("{cannot_do_this}{custom_msg}")) + } + // fallback to generic message + (true, None) => None, + } + }) + .unwrap_or_else(|| { + format!("the trait bound `{}` is not satisfied{}", trait_predicate, post_message) + }) + } + fn get_safe_transmute_error_and_reason( &self, - trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - obligation: Obligation<'tcx, ty::Predicate<'tcx>>, - trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + obligation: PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, span: Span, ) -> (String, Option<String>) { - let src_and_dst = trait_predicate.map_bound(|p| rustc_transmute::Types { - dst: p.trait_ref.substs.type_at(0), - src: p.trait_ref.substs.type_at(1), - }); - let scope = trait_ref.skip_binder().substs.type_at(2); + // Erase regions because layout code doesn't particularly care about regions. + let trait_ref = self.tcx.erase_regions(self.tcx.erase_late_bound_regions(trait_ref)); + + let src_and_dst = rustc_transmute::Types { + dst: trait_ref.substs.type_at(0), + src: trait_ref.substs.type_at(1), + }; + let scope = trait_ref.substs.type_at(2); let Some(assume) = - rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, trait_ref.skip_binder().substs.const_at(3)) else { + rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, trait_ref.substs.const_at(3)) else { span_bug!(span, "Unable to construct rustc_transmute::Assume where it was previously possible"); }; match rustc_transmute::TransmuteTypeEnv::new(self.infcx).is_transmutable( @@ -2942,8 +2744,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { assume, ) { rustc_transmute::Answer::No(reason) => { - let dst = trait_ref.skip_binder().substs.type_at(0); - let src = trait_ref.skip_binder().substs.type_at(1); + let dst = trait_ref.substs.type_at(0); + let src = trait_ref.substs.type_at(1); let custom_err_msg = format!( "`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`" ); @@ -2978,8 +2780,449 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { _ => span_bug!(span, "Unsupported rustc_transmute::Reason variant"), } } + + fn add_tuple_trait_message( + &self, + obligation_cause_code: &ObligationCauseCode<'tcx>, + err: &mut Diagnostic, + ) { + match obligation_cause_code { + ObligationCauseCode::RustCall => { + err.set_primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); + } + ObligationCauseCode::BindingObligation(def_id, _) + | ObligationCauseCode::ItemObligation(def_id) + if self.tcx.is_fn_trait(*def_id) => + { + err.code(rustc_errors::error_code!(E0059)); + err.set_primary_message(format!( + "type parameter to bare `{}` trait must be a tuple", + self.tcx.def_path_str(*def_id) + )); + } + _ => {} + } + } + + fn try_to_add_help_message( + &self, + obligation: &PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + err: &mut Diagnostic, + span: Span, + is_fn_trait: bool, + suggested: bool, + unsatisfied_const: bool, + ) { + let body_def_id = obligation.cause.body_id; + // Try to report a help message + if is_fn_trait + && let Ok((implemented_kind, params)) = self.type_implements_fn_trait( + obligation.param_env, + trait_ref.self_ty(), + trait_predicate.skip_binder().constness, + trait_predicate.skip_binder().polarity, + ) + { + self.add_help_message_for_fn_trait(trait_ref, err, implemented_kind, params); + } else if !trait_ref.has_non_region_infer() + && self.predicate_can_apply(obligation.param_env, *trait_predicate) + { + // If a where-clause may be useful, remind the + // user that they can add it. + // + // don't display an on-unimplemented note, as + // these notes will often be of the form + // "the type `T` can't be frobnicated" + // which is somewhat confusing. + self.suggest_restricting_param_bound( + err, + *trait_predicate, + None, + obligation.cause.body_id, + ); + } else if !suggested && !unsatisfied_const { + // Can't show anything else useful, try to find similar impls. + let impl_candidates = self.find_similar_impl_candidates(*trait_predicate); + if !self.report_similar_impl_candidates( + &impl_candidates, + trait_ref, + body_def_id, + err, + true, + ) { + self.report_similar_impl_candidates_for_root_obligation(&obligation, *trait_predicate, body_def_id, err); + } + + self.maybe_suggest_convert_to_slice( + err, + trait_ref, + impl_candidates.as_slice(), + span, + ); + } + } + + fn add_help_message_for_fn_trait( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + err: &mut Diagnostic, + implemented_kind: ty::ClosureKind, + params: ty::Binder<'tcx, Ty<'tcx>>, + ) { + // If the type implements `Fn`, `FnMut`, or `FnOnce`, suppress the following + // suggestion to add trait bounds for the type, since we only typically implement + // these traits once. + + // Note if the `FnMut` or `FnOnce` is less general than the trait we're trying + // to implement. + let selected_kind = self + .tcx + .fn_trait_kind_from_def_id(trait_ref.def_id()) + .expect("expected to map DefId to ClosureKind"); + if !implemented_kind.extends(selected_kind) { + err.note(&format!( + "`{}` implements `{}`, but it must implement `{}`, which is more general", + trait_ref.skip_binder().self_ty(), + implemented_kind, + selected_kind + )); + } + + // Note any argument mismatches + let given_ty = params.skip_binder(); + let expected_ty = trait_ref.skip_binder().substs.type_at(1); + if let ty::Tuple(given) = given_ty.kind() + && let ty::Tuple(expected) = expected_ty.kind() + { + if expected.len() != given.len() { + // Note number of types that were expected and given + err.note( + &format!( + "expected a closure taking {} argument{}, but one taking {} argument{} was given", + given.len(), + pluralize!(given.len()), + expected.len(), + pluralize!(expected.len()), + ) + ); + } else if !self.same_type_modulo_infer(given_ty, expected_ty) { + // Print type mismatch + let (expected_args, given_args) = + self.cmp(given_ty, expected_ty); + err.note_expected_found( + &"a closure with arguments", + expected_args, + &"a closure with arguments", + given_args, + ); + } + } + } + + fn maybe_add_note_for_unsatisfied_const( + &self, + obligation: &PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + err: &mut Diagnostic, + span: Span, + ) -> UnsatisfiedConst { + let mut unsatisfied_const = UnsatisfiedConst(false); + if trait_predicate.is_const_if_const() && obligation.param_env.is_const() { + let non_const_predicate = trait_ref.without_const(); + let non_const_obligation = Obligation { + cause: obligation.cause.clone(), + param_env: obligation.param_env.without_const(), + predicate: non_const_predicate.to_predicate(self.tcx), + recursion_depth: obligation.recursion_depth, + }; + if self.predicate_may_hold(&non_const_obligation) { + unsatisfied_const = UnsatisfiedConst(true); + err.span_note( + span, + &format!( + "the trait `{}` is implemented for `{}`, \ + but that implementation is not `const`", + non_const_predicate.print_modifiers_and_trait_path(), + trait_ref.skip_binder().self_ty(), + ), + ); + } + } + unsatisfied_const + } + + fn report_closure_error( + &self, + obligation: &PredicateObligation<'tcx>, + closure_def_id: DefId, + found_kind: ty::ClosureKind, + kind: ty::ClosureKind, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { + let closure_span = self.tcx.def_span(closure_def_id); + let mut err = struct_span_err!( + self.tcx.sess, + closure_span, + E0525, + "expected a closure that implements the `{}` trait, \ + but this closure only implements `{}`", + kind, + found_kind + ); + + err.span_label( + closure_span, + format!("this closure implements `{}`, not `{}`", found_kind, kind), + ); + err.span_label( + obligation.cause.span, + format!("the requirement to implement `{}` derives from here", kind), + ); + + // Additional context information explaining why the closure only implements + // a particular trait. + if let Some(typeck_results) = &self.typeck_results { + let hir_id = self.tcx.hir().local_def_id_to_hir_id(closure_def_id.expect_local()); + match (found_kind, typeck_results.closure_kind_origins().get(hir_id)) { + (ty::ClosureKind::FnOnce, Some((span, place))) => { + err.span_label( + *span, + format!( + "closure is `FnOnce` because it moves the \ + variable `{}` out of its environment", + ty::place_to_string_for_capture(self.tcx, place) + ), + ); + } + (ty::ClosureKind::FnMut, Some((span, place))) => { + err.span_label( + *span, + format!( + "closure is `FnMut` because it mutates the \ + variable `{}` here", + ty::place_to_string_for_capture(self.tcx, place) + ), + ); + } + _ => {} + } + } + + err + } + + fn report_type_parameter_mismatch_cyclic_type_error( + &self, + obligation: &PredicateObligation<'tcx>, + found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + terr: TypeError<'tcx>, + ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { + let self_ty = found_trait_ref.self_ty().skip_binder(); + let (cause, terr) = if let ty::Closure(def_id, _) = self_ty.kind() { + ( + ObligationCause::dummy_with_span(self.tcx.def_span(def_id)), + TypeError::CyclicTy(self_ty), + ) + } else { + (obligation.cause.clone(), terr) + }; + self.report_and_explain_type_error( + TypeTrace::poly_trait_refs(&cause, true, expected_trait_ref, found_trait_ref), + terr, + ) + } + + fn report_type_parameter_mismatch_error( + &self, + obligation: &PredicateObligation<'tcx>, + span: Span, + found_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + expected_trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { + let found_trait_ref = self.resolve_vars_if_possible(found_trait_ref); + let expected_trait_ref = self.resolve_vars_if_possible(expected_trait_ref); + + if expected_trait_ref.self_ty().references_error() { + return None; + } + + let Some(found_trait_ty) = found_trait_ref.self_ty().no_bound_vars() else { + return None; + }; + + let found_did = match *found_trait_ty.kind() { + ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) | ty::Generator(did, ..) => { + Some(did) + } + ty::Adt(def, _) => Some(def.did()), + _ => None, + }; + + let found_node = found_did.and_then(|did| self.tcx.hir().get_if_local(did)); + let found_span = found_did.and_then(|did| self.tcx.hir().span_if_local(did)); + + if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { + // We check closures twice, with obligations flowing in different directions, + // but we want to complain about them only once. + return None; + } + + self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); + + let mut not_tupled = false; + + let found = match found_trait_ref.skip_binder().substs.type_at(1).kind() { + ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], + _ => { + not_tupled = true; + vec![ArgKind::empty()] + } + }; + + let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); + let expected = match expected_ty.kind() { + ty::Tuple(ref tys) => { + tys.iter().map(|t| ArgKind::from_expected_ty(t, Some(span))).collect() + } + _ => { + not_tupled = true; + vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())] + } + }; + + // If this is a `Fn` family trait and either the expected or found + // is not tupled, then fall back to just a regular mismatch error. + // This shouldn't be common unless manually implementing one of the + // traits manually, but don't make it more confusing when it does + // happen. + Some( + if Some(expected_trait_ref.def_id()) != self.tcx.lang_items().gen_trait() && not_tupled + { + self.report_and_explain_type_error( + TypeTrace::poly_trait_refs( + &obligation.cause, + true, + expected_trait_ref, + found_trait_ref, + ), + ty::error::TypeError::Mismatch, + ) + } else if found.len() == expected.len() { + self.report_closure_arg_mismatch( + span, + found_span, + found_trait_ref, + expected_trait_ref, + obligation.cause.code(), + found_node, + obligation.param_env, + ) + } else { + let (closure_span, closure_arg_span, found) = found_did + .and_then(|did| { + let node = self.tcx.hir().get_if_local(did)?; + let (found_span, closure_arg_span, found) = + self.get_fn_like_arguments(node)?; + Some((Some(found_span), closure_arg_span, found)) + }) + .unwrap_or((found_span, None, found)); + + self.report_arg_count_mismatch( + span, + closure_span, + expected, + found, + found_trait_ty.is_closure(), + closure_arg_span, + ) + }, + ) + } + + fn report_not_const_evaluatable_error( + &self, + obligation: &PredicateObligation<'tcx>, + span: Span, + ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { + if !self.tcx.features().generic_const_exprs { + let mut err = self + .tcx + .sess + .struct_span_err(span, "constant expression depends on a generic parameter"); + // FIXME(const_generics): we should suggest to the user how they can resolve this + // issue. However, this is currently not actually possible + // (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083). + // + // Note that with `feature(generic_const_exprs)` this case should not + // be reachable. + err.note("this may fail depending on what value the parameter takes"); + err.emit(); + return None; + } + + match obligation.predicate.kind().skip_binder() { + ty::PredicateKind::ConstEvaluatable(ct) => { + let ty::ConstKind::Unevaluated(uv) = ct.kind() else { + bug!("const evaluatable failed for non-unevaluated const `{ct:?}`"); + }; + let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); + let const_span = self.tcx.def_span(uv.def); + match self.tcx.sess.source_map().span_to_snippet(const_span) { + Ok(snippet) => err.help(&format!( + "try adding a `where` bound using this expression: `where [(); {}]:`", + snippet + )), + _ => err.help("consider adding a `where` bound using this expression"), + }; + Some(err) + } + _ => { + span_bug!( + span, + "unexpected non-ConstEvaluatable predicate, this should not be reachable" + ) + } + } + } } +struct UnsatisfiedConst(pub bool); + +fn get_explanation_based_on_obligation<'tcx>( + obligation: &PredicateObligation<'tcx>, + trait_ref: ty::PolyTraitRef<'tcx>, + trait_predicate: &ty::PolyTraitPredicate<'tcx>, + pre_message: String, +) -> String { + if let ObligationCauseCode::MainFunctionType = obligation.cause.code() { + "consider using `()`, or a `Result`".to_owned() + } else { + let ty_desc = match trait_ref.skip_binder().self_ty().kind() { + ty::FnDef(_, _) => Some("fn item"), + ty::Closure(_, _) => Some("closure"), + _ => None, + }; + + match ty_desc { + Some(desc) => format!( + "{}the trait `{}` is not implemented for {} `{}`", + pre_message, + trait_predicate.print_modifiers_and_trait_path(), + desc, + trait_ref.skip_binder().self_ty(), + ), + None => format!( + "{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_predicate.print_modifiers_and_trait_path(), + trait_ref.skip_binder().self_ty(), + ), + } + } +} /// Crude way of getting back an `Expr` from a `Span`. pub struct FindExprBySpan<'hir> { pub span: Span, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index a9c4e126816..88525e1b720 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -327,7 +327,7 @@ pub struct OnUnimplementedDirective { pub label: Option<OnUnimplementedFormatString>, pub note: Option<OnUnimplementedFormatString>, pub parent_label: Option<OnUnimplementedFormatString>, - pub append_const_msg: Option<Option<Symbol>>, + pub append_const_msg: Option<AppendConstMessage>, } /// For the `#[rustc_on_unimplemented]` attribute @@ -337,11 +337,21 @@ pub struct OnUnimplementedNote { pub label: Option<String>, pub note: Option<String>, pub parent_label: Option<String>, - /// Append a message for `~const Trait` errors. `None` means not requested and - /// should fallback to a generic message, `Some(None)` suggests using the default - /// appended message, `Some(Some(s))` suggests use the `s` message instead of the - /// default one.. - pub append_const_msg: Option<Option<Symbol>>, + // If none, should fall back to a generic message + pub append_const_msg: Option<AppendConstMessage>, +} + +/// Append a message for `~const Trait` errors. +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub enum AppendConstMessage { + Default, + Custom(Symbol), +} + +impl Default for AppendConstMessage { + fn default() -> Self { + AppendConstMessage::Default + } } impl<'tcx> OnUnimplementedDirective { @@ -419,10 +429,10 @@ impl<'tcx> OnUnimplementedDirective { } } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { if let Some(msg) = item.value_str() { - append_const_msg = Some(Some(msg)); + append_const_msg = Some(AppendConstMessage::Custom(msg)); continue; } else if item.is_word() { - append_const_msg = Some(None); + append_const_msg = Some(AppendConstMessage::Default); continue; } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fb75ec76729..c969e5d4975 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -386,7 +386,7 @@ pub trait TypeErrCtxtExt<'tcx> { fn maybe_suggest_convert_to_slice( &self, err: &mut Diagnostic, - trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + trait_ref: ty::PolyTraitRef<'tcx>, candidate_impls: &[ImplCandidate<'tcx>], span: Span, ); @@ -1381,7 +1381,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } - // Issue #104961, we need to add parentheses properly for compond expressions + // Issue #104961, we need to add parentheses properly for compound expressions // for example, `x.starts_with("hi".to_string() + "you")` // should be `x.starts_with(&("hi".to_string() + "you"))` let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; }; @@ -3848,7 +3848,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { fn maybe_suggest_convert_to_slice( &self, err: &mut Diagnostic, - trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>, + trait_ref: ty::PolyTraitRef<'tcx>, candidate_impls: &[ImplCandidate<'tcx>], span: Span, ) { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 26cadab3e9f..43196d1e629 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -540,8 +540,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { use ty::ConstKind::Unevaluated; match (c1.kind(), c2.kind()) { (Unevaluated(a), Unevaluated(b)) - if a.def.did == b.def.did - && tcx.def_kind(a.def.did) == DefKind::AssocConst => + if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst => { if let Ok(new_obligations) = infcx .at(&obligation.cause, obligation.param_env) diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index af567c07438..63949843aed 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -14,7 +14,7 @@ use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; pub enum CopyImplementationError<'tcx> { - InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>), + InfringingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>, InfringingFieldsReason<'tcx>)>), NotAnAdt, HasDestructor, } @@ -125,7 +125,7 @@ pub fn type_allowed_to_implement_copy<'tcx>( } if !infringing.is_empty() { - return Err(CopyImplementationError::InfrigingFields(infringing)); + return Err(CopyImplementationError::InfringingFields(infringing)); } if adt.has_dtor(tcx) { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8a203dec86b..4c9df5d9d0a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -203,7 +203,7 @@ fn do_normalize_predicates<'tcx>( } }; - debug!("do_normalize_predictes: normalized predicates = {:?}", predicates); + debug!("do_normalize_predicates: normalized predicates = {:?}", predicates); // We can use the `elaborated_env` here; the region code only // cares about declarations like `'a: 'b`. @@ -450,7 +450,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI { return ControlFlow::Break(()); } - r.super_visit_with(self) + ControlFlow::Continue(()) } fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::ConstKind::Param(param) = ct.kind() diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index b8ad1925e4e..73e2efc3b00 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -297,8 +297,8 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span tcx.associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .flat_map(|item| tcx.explicit_item_bounds(item.def_id)) - .filter_map(|pred_span| predicate_references_self(tcx, *pred_span)) + .flat_map(|item| tcx.explicit_item_bounds(item.def_id).subst_identity_iter_copied()) + .filter_map(|pred_span| predicate_references_self(tcx, pred_span)) .collect() } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 826fc63ca06..ea45412e47f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1272,14 +1272,29 @@ fn project<'cx, 'tcx>( ProjectionCandidateSet::Single(candidate) => { Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate))) } - ProjectionCandidateSet::None => Ok(Projected::NoProgress( - // FIXME(associated_const_generics): this may need to change in the future? - // need to investigate whether or not this is fine. - selcx - .tcx() - .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) - .into(), - )), + ProjectionCandidateSet::None => { + let tcx = selcx.tcx(); + let term = match tcx.def_kind(obligation.predicate.def_id) { + DefKind::AssocTy | DefKind::ImplTraitPlaceholder => tcx + .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) + .into(), + DefKind::AssocConst => tcx + .mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new( + obligation.predicate.def_id, + obligation.predicate.substs, + )), + tcx.type_of(obligation.predicate.def_id) + .subst(tcx, obligation.predicate.substs), + ) + .into(), + kind => { + bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id)) + } + }; + + Ok(Projected::NoProgress(term)) + } // Error occurred while trying to processing impls. ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)), // Inherent ambiguity that prevents us from even enumerating the @@ -2131,9 +2146,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( let ty = tcx.type_of(assoc_ty.item.def_id); let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst); let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const { - let identity_substs = - crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); - let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id); + let did = assoc_ty.item.def_id; + let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did); let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs)); ty.map_bound(|ty| tcx.mk_const(kind, ty).into()) } else { @@ -2277,11 +2291,10 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( obligation.param_env, cause.clone(), obligation.recursion_depth + 1, - tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id) - .map_bound(|tys| { - tys.map_or_else(|guar| tcx.ty_error(guar), |tys| tys[&obligation.predicate.def_id]) - }) - .subst(tcx, impl_fn_substs), + tcx.collect_return_position_impl_trait_in_trait_tys(impl_fn_def_id).map_or_else( + |guar| tcx.ty_error(guar), + |tys| tys[&obligation.predicate.def_id].subst(tcx, impl_fn_substs), + ), &mut obligations, ); diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index b63da28e274..baa2fbb6751 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -32,14 +32,8 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, - mut canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, + canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Fallible<CanonicalQueryResponse<'tcx, ()>> { - match canonicalized.value.value.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { - canonicalized.value.param_env.remap_constness_with(pred.constness); - } - _ => canonicalized.value.param_env = canonicalized.value.param_env.without_const(), - } tcx.type_op_prove_predicate(canonicalized) } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 1f5bbc178f7..1db9b8ce92e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -11,7 +11,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections}; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::traits; @@ -775,7 +775,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - if obligation.has_non_region_param() { + if obligation.predicate.has_non_region_param() { return; } @@ -875,12 +875,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Adt(..) => { - // Find a custom `impl Drop` impl, if it exists - let relevant_impl = self.tcx().find_map_relevant_impl( + let mut relevant_impl = None; + self.tcx().for_each_relevant_impl( self.tcx().require_lang_item(LangItem::Drop, None), obligation.predicate.skip_binder().trait_ref.self_ty(), - TreatProjections::ForLookup, - Some, + |impl_def_id| { + if let Some(old_impl_def_id) = relevant_impl { + self.tcx() + .sess + .struct_span_err( + self.tcx().def_span(impl_def_id), + "multiple drop impls found", + ) + .span_note(self.tcx().def_span(old_impl_def_id), "other impl here") + .delay_as_bug(); + } + + relevant_impl = Some(impl_def_id); + }, ); if let Some(impl_def_id) = relevant_impl { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 5e60bc01bb6..3bba11262f5 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -275,33 +275,35 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> { debug!(?obligation, "confirm_transmutability_candidate"); - let predicate = obligation.predicate; - - let type_at = |i| predicate.map_bound(|p| p.trait_ref.substs.type_at(i)); - let const_at = |i| predicate.skip_binder().trait_ref.substs.const_at(i); - - let src_and_dst = predicate.map_bound(|p| rustc_transmute::Types { - dst: p.trait_ref.substs.type_at(0), - src: p.trait_ref.substs.type_at(1), - }); - - let scope = type_at(2).skip_binder(); - - let Some(assume) = - rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)) else { - return Err(Unimplemented); - }; - - let cause = obligation.cause.clone(); + // We erase regions here because transmutability calls layout queries, + // which does not handle inference regions and doesn't particularly + // care about other regions. Erasing late-bound regions is equivalent + // to instantiating the binder with placeholders then erasing those + // placeholder regions. + let predicate = + self.tcx().erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate)); + + let Some(assume) = rustc_transmute::Assume::from_const( + self.infcx.tcx, + obligation.param_env, + predicate.trait_ref.substs.const_at(3) + ) else { + return Err(Unimplemented); + }; let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx); - - let maybe_transmutable = transmute_env.is_transmutable(cause, src_and_dst, scope, assume); - - use rustc_transmute::Answer; + let maybe_transmutable = transmute_env.is_transmutable( + obligation.cause.clone(), + rustc_transmute::Types { + dst: predicate.trait_ref.substs.type_at(0), + src: predicate.trait_ref.substs.type_at(1), + }, + predicate.trait_ref.substs.type_at(2), + assume, + ); match maybe_transmutable { - Answer::Yes => Ok(ImplSourceBuiltinData { nested: vec![] }), + rustc_transmute::Answer::Yes => Ok(ImplSourceBuiltinData { nested: vec![] }), _ => Err(Unimplemented), } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6bb53418bea..081e4d7cfa4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -888,7 +888,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let c1 = tcx.expand_abstract_consts(c1); let c2 = tcx.expand_abstract_consts(c2); debug!( - "evalaute_predicate_recursively: equating consts:\nc1= {:?}\nc2= {:?}", + "evaluate_predicate_recursively: equating consts:\nc1= {:?}\nc2= {:?}", c1, c2 ); @@ -896,8 +896,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { use ty::ConstKind::Unevaluated; match (c1.kind(), c2.kind()) { (Unevaluated(a), Unevaluated(b)) - if a.def.did == b.def.did - && tcx.def_kind(a.def.did) == DefKind::AssocConst => + if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst => { if let Ok(InferOk { obligations, value: () }) = self .infcx diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 20357d4d250..7792ceabe7e 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -243,16 +243,11 @@ pub fn get_vtable_index_of_object_method<'tcx, N>( ) -> Option<usize> { // Count number of methods preceding the one we are selecting and // add them to the total offset. - if let Some(index) = tcx - .own_existential_vtable_entries(object.upcast_trait_ref.def_id()) + tcx.own_existential_vtable_entries(object.upcast_trait_ref.def_id()) .iter() .copied() .position(|def_id| def_id == method_def_id) - { - Some(object.vtable_base + index) - } else { - None - } + .map(|index| object.vtable_base + index) } pub fn closure_trait_ref_and_return_type<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3d026506a5a..40e19abc0d0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -170,29 +170,20 @@ pub fn predicate_obligations<'tcx>( ty::PredicateKind::WellFormed(arg) => { wf.compute(arg); } - ty::PredicateKind::ObjectSafe(_) => {} - ty::PredicateKind::ClosureKind(..) => {} - ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => { - wf.compute(a.into()); - wf.compute(b.into()); - } - ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { - wf.compute(a.into()); - wf.compute(b.into()); - } + ty::PredicateKind::ConstEvaluatable(ct) => { wf.compute(ct.into()); } - ty::PredicateKind::ConstEquate(c1, c2) => { - wf.compute(c1.into()); - wf.compute(c2.into()); - } - ty::PredicateKind::Ambiguous => {} - ty::PredicateKind::TypeWellFormedFromEnv(..) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } - ty::PredicateKind::AliasRelate(..) => { - bug!("We should only wf check where clauses and `AliasRelate` is not a `Clause`") + + ty::PredicateKind::ObjectSafe(_) + | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous + | ty::PredicateKind::AliasRelate(..) + | ty::PredicateKind::TypeWellFormedFromEnv(..) => { + bug!("We should only wf check where clauses, unexpected predicate: {predicate:?}") } } @@ -487,7 +478,7 @@ impl<'tcx> WfPredicates<'tcx> { match ct.kind() { ty::ConstKind::Unevaluated(uv) => { if !ct.has_escaping_bound_vars() { - let obligations = self.nominal_obligations(uv.def.did, uv.substs); + let obligations = self.nominal_obligations(uv.def, uv.substs); self.out.extend(obligations); let predicate = diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index eff6fb26dd4..dfd6fbff7c9 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -8,7 +8,6 @@ tracing = "0.1" rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_hir = { path = "../rustc_hir" } -rustc_index = { path = "../rustc_index" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 9683e48478e..c319b2e31c7 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -50,12 +50,11 @@ impl<'tcx> RustIrDatabase<'tcx> { where ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option<T>>, { - let bounds = self.interner.tcx.bound_explicit_item_bounds(def_id); - bounds - .0 - .iter() - .map(|(bound, _)| bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars)) - .filter_map(|bound| LowerInto::<Option<_>>::lower_into(bound, self.interner)) + self.interner + .tcx + .explicit_item_bounds(def_id) + .subst_iter_copied(self.interner.tcx, &bound_vars) + .filter_map(|(bound, _)| LowerInto::<Option<_>>::lower_into(bound, self.interner)) .collect() } } @@ -506,15 +505,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0); - let explicit_item_bounds = self.interner.tcx.bound_explicit_item_bounds(opaque_ty_id.0); + let explicit_item_bounds = self.interner.tcx.explicit_item_bounds(opaque_ty_id.0); let bounds = explicit_item_bounds - .0 - .iter() + .subst_iter_copied(self.interner.tcx, &bound_vars) .map(|(bound, _)| { - explicit_item_bounds.rebind(*bound).subst(self.interner.tcx, &bound_vars) - }) - .map(|bound| { bound.fold_with(&mut ReplaceOpaqueTyFolder { tcx: self.interner.tcx, opaque_ty_id, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 2be72879b7b..4d225e36b22 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -60,6 +60,20 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst } } +impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> + for &'tcx ty::List<Ty<'tcx>> +{ + fn lower_into( + self, + interner: RustInterner<'tcx>, + ) -> chalk_ir::Substitution<RustInterner<'tcx>> { + chalk_ir::Substitution::from_iter( + interner, + self.iter().map(|ty| GenericArg::from(ty).lower_into(interner)), + ) + } +} + impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> { fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> { interner @@ -351,9 +365,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { ty::GeneratorWitness(_) => unimplemented!(), ty::GeneratorWitnessMIR(..) => unimplemented!(), ty::Never => chalk_ir::TyKind::Never, - ty::Tuple(types) => { - chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner)) - } + ty::Tuple(types) => chalk_ir::TyKind::Tuple(types.len(), types.lower_into(interner)), ty::Alias(ty::Projection, ty::AliasTy { def_id, substs, .. }) => { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { associated_ty_id: chalk_ir::AssocTypeId(def_id), @@ -435,7 +447,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { TyKind::GeneratorWitness(..) => unimplemented!(), TyKind::Never => ty::Never, TyKind::Tuple(_len, substitution) => { - ty::Tuple(substitution.lower_into(interner).try_as_type_list().unwrap()) + ty::Tuple(substitution.lower_into(interner).into_type_list(interner.tcx)) } TyKind::Slice(ty) => ty::Slice(ty.lower_into(interner)), TyKind::Raw(mutbl, ty) => ty::RawPtr(ty::TypeAndMut { @@ -998,7 +1010,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> { _ => (), }; - r.super_visit_with(self) + ControlFlow::Continue(()) } } @@ -1048,7 +1060,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> { _ => (), }; - r.super_fold_with(self) + r } } @@ -1142,7 +1154,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { } }, - _ => r.super_fold_with(self), + _ => r, } } } @@ -1223,6 +1235,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for PlaceholdersCollector { _ => (), }; - r.super_visit_with(self) + ControlFlow::Continue(()) } } diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index e0fd487b3d3..19622112f2a 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -89,6 +89,7 @@ fn relate_mir_and_user_substs<'tcx>( def_id: hir::def_id::DefId, user_substs: UserSubsts<'tcx>, ) -> Result<(), NoSolution> { + let param_env = param_env.without_const(); let UserSubsts { user_self_ty, substs } = user_substs; let tcx = ocx.infcx.tcx; let cause = ObligationCause::dummy_with_span(span); diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 2a89494c80b..a6d88b1342a 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -196,7 +196,7 @@ pub(crate) mod rustc { fn from(err: LayoutError<'tcx>) -> Self { match err { LayoutError::Unknown(..) => Self::Unknown, - err @ _ => unimplemented!("{:?}", err), + err => unimplemented!("{:?}", err), } } } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index a93a42987ed..8be02c1d988 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -64,7 +64,6 @@ mod rustc { use rustc_infer::infer::InferCtxt; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::traits::ObligationCause; - use rustc_middle::ty::Binder; use rustc_middle::ty::Const; use rustc_middle::ty::ParamEnv; use rustc_middle::ty::Ty; @@ -92,15 +91,13 @@ mod rustc { pub fn is_transmutable( &mut self, cause: ObligationCause<'tcx>, - src_and_dst: Binder<'tcx, Types<'tcx>>, + types: Types<'tcx>, scope: Ty<'tcx>, assume: crate::Assume, ) -> crate::Answer<crate::layout::rustc::Ref<'tcx>> { - let src = src_and_dst.map_bound(|types| types.src).skip_binder(); - let dst = src_and_dst.map_bound(|types| types.dst).skip_binder(); crate::maybe_transmutable::MaybeTransmutableQuery::new( - src, - dst, + types.src, + types.dst, scope, assume, self.infcx.tcx, diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 52fbd3ae047..51885c9b47e 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -9,6 +9,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index b67607a4db6..b08a92570ed 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -132,7 +132,7 @@ fn recurse_build<'tcx>( tcx.mk_const(val, node.ty) } &ExprKind::NamedConst { def_id, substs, user_ty: _ } => { - let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = ty::UnevaluatedConst::new(def_id, substs); tcx.mk_const(uneval, node.ty) } ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty), @@ -256,6 +256,7 @@ fn recurse_build<'tcx>( ExprKind::VarRef { .. } | ExprKind::UpvarRef { .. } | ExprKind::StaticRef { .. } + | ExprKind::OffsetOf { .. } | ExprKind::ThreadLocalRef(_) => { error(GenericConstantTooComplexSub::OperationNotSupported(node.span))? } @@ -347,6 +348,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { | thir::ExprKind::ZstLiteral { .. } | thir::ExprKind::StaticRef { .. } | thir::ExprKind::InlineAsm(_) + | thir::ExprKind::OffsetOf { .. } | thir::ExprKind::ThreadLocalRef(_) | thir::ExprKind::Yield { .. } => false, } @@ -391,52 +393,36 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. pub fn thir_abstract_const( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> { - if tcx.features().generic_const_exprs { - match tcx.def_kind(def.did) { - // FIXME(generic_const_exprs): We currently only do this for anonymous constants, - // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether - // we want to look into them or treat them as opaque projections. - // - // Right now we do neither of that and simply always fail to unify them. - DefKind::AnonConst | DefKind::InlineConst => (), - _ => return Ok(None), - } - - let body = tcx.thir_body(def)?; - let (body, body_id) = (&*body.0.borrow(), body.1); + if !tcx.features().generic_const_exprs { + return Ok(None); + } - let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; - visit::walk_expr(&mut is_poly_vis, &body[body_id]); - if !is_poly_vis.is_poly { - return Ok(None); - } + match tcx.def_kind(def) { + // FIXME(generic_const_exprs): We currently only do this for anonymous constants, + // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether + // we want to look into them or treat them as opaque projections. + // + // Right now we do neither of that and simply always fail to unify them. + DefKind::AnonConst | DefKind::InlineConst => (), + _ => return Ok(None), + } - let root_span = body.exprs[body_id].span; + let body = tcx.thir_body(def)?; + let (body, body_id) = (&*body.0.borrow(), body.1); - Some(recurse_build(tcx, body, body_id, root_span)).transpose() - } else { - Ok(None) + let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; + visit::walk_expr(&mut is_poly_vis, &body[body_id]); + if !is_poly_vis.is_poly { + return Ok(None); } + + let root_span = body.exprs[body_id].span; + + Some(recurse_build(tcx, body, body_id, root_span)).transpose() } pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { - destructure_const, - thir_abstract_const: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.thir_abstract_const_of_const_arg(def) - } else { - thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - thir_abstract_const_of_const_arg: |tcx, (did, param_did)| { - thir_abstract_const( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - ) - }, - ..*providers - }; + *providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 0a6c118093e..21cc3c9517e 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,5 @@ use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; @@ -14,54 +14,26 @@ fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, substs)) = key.into_parts(); - if let Some(did) = did.as_local() { - if let Some(param_did) = tcx.opt_const_param_of(did) { - return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs))); - } - } - - inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs))) -} - -fn resolve_instance_of_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, const_param_did, substs)) = key.into_parts(); - inner_resolve_instance( - tcx, - param_env.and(( - ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) }, - substs, - )), - ) -} - -fn inner_resolve_instance<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { let (param_env, (def, substs)) = key.into_parts(); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) { + let result = if let Some(trait_def_id) = tcx.trait_of_item(def) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); resolve_associated_item( tcx, - def.did, + def, param_env, trait_def_id, tcx.normalize_erasing_regions(param_env, substs), ) } else { - let ty = tcx.type_of(def.def_id_for_type_of()); + let ty = tcx.type_of(def); let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def.did) + ty::InstanceDef::Intrinsic(def) } ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { let ty = substs.type_at(0); @@ -206,15 +178,11 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } traits::ImplSource::Generator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - generator_data.generator_def_id, - )), + def: ty::InstanceDef::Item(generator_data.generator_def_id), substs: generator_data.substs, }), traits::ImplSource::Future(future_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - future_data.generator_def_id, - )), + def: ty::InstanceDef::Item(future_data.generator_def_id), substs: future_data.substs, }), traits::ImplSource::Closure(closure_data) => { @@ -234,15 +202,12 @@ fn resolve_associated_item<'tcx>( _ => None, }, traits::ImplSource::Object(ref data) => { - if let Some(index) = traits::get_vtable_index_of_object_method(tcx, data, trait_item_id) - { - Some(Instance { + traits::get_vtable_index_of_object_method(tcx, data, trait_item_id).map(|index| { + Instance { def: ty::InstanceDef::Virtual(trait_item_id, index), substs: rcvr_substs, - }) - } else { - None - } + } + }) } traits::ImplSource::Builtin(..) => { let lang_items = tcx.lang_items(); @@ -301,6 +266,5 @@ fn resolve_associated_item<'tcx>( } pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers }; + *providers = ty::query::Providers { resolve_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 63ef1c72417..f7c75583f60 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,7 +1,7 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index a5311dbd1b7..ed513cb3c7f 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -285,7 +285,7 @@ pub(super) fn sanity_check_layout<'tcx>( { // These are never actually accessed anyway, so we can skip the coherence check // for them. They also fail that check, since they have - // `Aggregate`/`Uninhbaited` ABI even when the main type is + // `Aggregate`/`Uninhabited` ABI even when the main type is // `Scalar`/`ScalarPair`. (Note that sometimes, variants with fields have size // 0, and sometimes, variants without fields have non-0 size.) continue; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 2613445f39b..9d5a72a73cd 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -19,7 +19,7 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty::query::Providers; mod abi; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index de7fd003176..5f436f7c9fd 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -243,7 +243,7 @@ fn drop_tys_helper<'tcx>( } else { let field_tys = adt_def.all_fields().map(|field| { let r = tcx.type_of(field.did).subst(tcx, substs); - debug!("drop_tys_helper: Subst into {:?} with {:?} gettng {:?}", field, substs, r); + debug!("drop_tys_helper: Subst into {:?} with {:?} getting {:?}", field, substs, r); r }); if only_significant { diff --git a/compiler/rustc_ty_utils/src/structural_match.rs b/compiler/rustc_ty_utils/src/structural_match.rs index a55bb7e7e90..9cb0fc10594 100644 --- a/compiler/rustc_ty_utils/src/structural_match.rs +++ b/compiler/rustc_ty_utils/src/structural_match.rs @@ -13,7 +13,7 @@ use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; /// Note that this does *not* recursively check if the substructure of `adt_ty` /// implements the traits. fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool { - let ref infcx = tcx.infer_ctxt().build(); + let infcx = &tcx.infer_ctxt().build(); let cause = ObligationCause::dummy(); let ocx = ObligationCtxt::new(infcx); diff --git a/compiler/rustc_type_ir/src/codec.rs b/compiler/rustc_type_ir/src/codec.rs index ee249050cc6..3b638934629 100644 --- a/compiler/rustc_type_ir/src/codec.rs +++ b/compiler/rustc_type_ir/src/codec.rs @@ -27,10 +27,13 @@ pub trait TyEncoder: Encoder { const CLEAR_CROSS_CRATE: bool; fn position(&self) -> usize; + fn type_shorthands(&mut self) -> &mut FxHashMap<<Self::I as Interner>::Ty, usize>; + fn predicate_shorthands( &mut self, ) -> &mut FxHashMap<<Self::I as Interner>::PredicateKind, usize>; + fn encode_alloc_id(&mut self, alloc_id: &<Self::I as Interner>::AllocId); } @@ -40,10 +43,6 @@ pub trait TyDecoder: Decoder { fn interner(&self) -> Self::I; - fn peek_byte(&self) -> u8; - - fn position(&self) -> usize; - fn cached_ty_for_shorthand<F>( &mut self, shorthand: usize, diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 3a053d4c6a9..371c6119122 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -16,8 +16,10 @@ //! - Types of interest, for which the methods delegate to the folder. //! - All other types, including generic containers like `Vec` and `Option`. //! It defines a "skeleton" of how they should be folded. -//! - `TypeSuperFoldable`. This is implemented only for each type of interest, -//! and defines the folding "skeleton" for these types. +//! - `TypeSuperFoldable`. This is implemented only for recursive types of +//! interest, and defines the folding "skeleton" for these types. (This +//! excludes `Region` because it is non-recursive, i.e. it never contains +//! other types of interest.) //! - `TypeFolder`/`FallibleTypeFolder`. One of these is implemented for each //! folder. This defines how types of interest are folded. //! @@ -72,9 +74,9 @@ pub trait TypeFoldable<I: Interner>: TypeVisitable<I> { // This trait is implemented for types of interest. pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> { - /// Provides a default fold for a type of interest. This should only be - /// called within `TypeFolder` methods, when a non-custom traversal is - /// desired for the value of the type of interest passed to that method. + /// Provides a default fold for a recursive type of interest. This should + /// only be called within `TypeFolder` methods, when a non-custom traversal + /// is desired for the value of the type of interest passed to that method. /// For example, in `MyFolder::try_fold_ty(ty)`, it is valid to call /// `ty.try_super_fold_with(self)`, but any other folding should be done /// with `xyz.try_fold_with(self)`. @@ -118,11 +120,11 @@ pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = !> { t.super_fold_with(self) } - fn fold_region(&mut self, r: I::Region) -> I::Region - where - I::Region: TypeSuperFoldable<I>, - { - r.super_fold_with(self) + // The default region folder is a no-op because `Region` is non-recursive + // and has no `super_visit_with` method to call. That also explains the + // lack of `I::Region: TypeSuperFoldable<I>` bound on this method. + fn fold_region(&mut self, r: I::Region) -> I::Region { + r } fn fold_const(&mut self, c: I::Const) -> I::Const @@ -167,11 +169,11 @@ pub trait FallibleTypeFolder<I: Interner>: Sized { t.try_super_fold_with(self) } - fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error> - where - I::Region: TypeSuperFoldable<I>, - { - r.try_super_fold_with(self) + // The default region folder is a no-op because `Region` is non-recursive + // and has no `super_visit_with` method to call. That also explains the + // lack of `I::Region: TypeSuperFoldable<I>` bound on this method. + fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Self::Error> { + Ok(r) } fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Self::Error> @@ -216,10 +218,7 @@ where Ok(self.fold_ty(t)) } - fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> - where - I::Region: TypeSuperFoldable<I>, - { + fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> { Ok(self.fold_region(r)) } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index a3c98ae007e..95237dda8c2 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -537,7 +537,7 @@ pub struct FloatVarValue(pub FloatTy); rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. - #[debug_format = "_#{}t"] + #[debug_format = "?{}t"] pub struct TyVid {} } @@ -739,13 +739,13 @@ impl fmt::Debug for FloatVarValue { impl fmt::Debug for IntVid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}i", self.index) + write!(f, "?{}i", self.index) } } impl fmt::Debug for FloatVid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "_#{}f", self.index) + write!(f, "?{}f", self.index) } } diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index 6c181039730..8c3cb228322 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -33,144 +33,3 @@ macro_rules! TrivialTypeTraversalImpls { )+ }; } - -macro_rules! EnumTypeTraversalImpl { - (impl<$($p:tt),*> TypeFoldable<$tcx:tt> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::fold::TypeFoldable<$tcx> for $s - $(where $($wc)*)* - { - fn try_fold_with<V: $crate::fold::FallibleTypeFolder<$tcx>>( - self, - folder: &mut V, - ) -> ::std::result::Result<Self, V::Error> { - EnumTypeTraversalImpl!(@FoldVariants(self, folder) input($($variants)*) output()) - } - } - }; - - (impl<$($p:tt),*> TypeVisitable<$tcx:tt> for $s:path { - $($variants:tt)* - } $(where $($wc:tt)*)*) => { - impl<$($p),*> $crate::visit::TypeVisitable<$tcx> for $s - $(where $($wc)*)* - { - fn visit_with<V: $crate::visit::TypeVisitor<$tcx>>( - &self, - visitor: &mut V, - ) -> ::std::ops::ControlFlow<V::BreakTy> { - EnumTypeTraversalImpl!(@VisitVariants(self, visitor) input($($variants)*) output()) - } - } - }; - - (@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => { - Ok(match $this { - $($output)* - }) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant ( $($variant_arg),* ) => { - $variant ( - $($crate::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),* - ) - } - $($output)* - ) - ) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant { $($variant_arg),* } => { - $variant { - $($variant_arg: $crate::fold::TypeFoldable::fold_with( - $variant_arg, $folder - )?),* } - } - $($output)* - ) - ) - }; - - (@FoldVariants($this:expr, $folder:expr) - input( ($variant:path), $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @FoldVariants($this, $folder) - input($($input)*) - output( - $variant => { $variant } - $($output)* - ) - ) - }; - - (@VisitVariants($this:expr, $visitor:expr) input() output($($output:tt)*)) => { - match $this { - $($output)* - } - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path) ( $($variant_arg:ident),* ) , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant ( $($variant_arg),* ) => { - $($crate::visit::TypeVisitable::visit_with( - $variant_arg, $visitor - )?;)* - ::std::ops::ControlFlow::Continue(()) - } - $($output)* - ) - ) - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path) { $($variant_arg:ident),* $(,)? } , $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant { $($variant_arg),* } => { - $($crate::visit::TypeVisitable::visit_with( - $variant_arg, $visitor - )?;)* - ::std::ops::ControlFlow::Continue(()) - } - $($output)* - ) - ) - }; - - (@VisitVariants($this:expr, $visitor:expr) - input( ($variant:path), $($input:tt)*) - output( $($output:tt)*) ) => { - EnumTypeTraversalImpl!( - @VisitVariants($this, $visitor) - input($($input)*) - output( - $variant => { ::std::ops::ControlFlow::Continue(()) } - $($output)* - ) - ) - }; -} diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs index 3ebe241042f..54c1ab5a275 100644 --- a/compiler/rustc_type_ir/src/structural_impls.rs +++ b/compiler/rustc_type_ir/src/structural_impls.rs @@ -6,7 +6,7 @@ use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; use rustc_data_structures::functor::IdFunctor; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use std::ops::ControlFlow; use std::rc::Rc; @@ -70,30 +70,40 @@ impl<I: Interner, A: TypeVisitable<I>, B: TypeVisitable<I>, C: TypeVisitable<I>> } } -EnumTypeTraversalImpl! { - impl<I, T> TypeFoldable<I> for Option<T> { - (Some)(a), - (None), - } where I: Interner, T: TypeFoldable<I> +impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Option<T> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(match self { + Some(v) => Some(v.try_fold_with(folder)?), + None => None, + }) + } } -EnumTypeTraversalImpl! { - impl<I, T> TypeVisitable<I> for Option<T> { - (Some)(a), - (None), - } where I: Interner, T: TypeVisitable<I> + +impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Option<T> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + match self { + Some(v) => v.visit_with(visitor), + None => ControlFlow::Continue(()), + } + } } -EnumTypeTraversalImpl! { - impl<I, T, E> TypeFoldable<I> for Result<T, E> { - (Ok)(a), - (Err)(a), - } where I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>, +impl<I: Interner, T: TypeFoldable<I>, E: TypeFoldable<I>> TypeFoldable<I> for Result<T, E> { + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(match self { + Ok(v) => Ok(v.try_fold_with(folder)?), + Err(e) => Err(e.try_fold_with(folder)?), + }) + } } -EnumTypeTraversalImpl! { - impl<I, T, E> TypeVisitable<I> for Result<T, E> { - (Ok)(a), - (Err)(a), - } where I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>, + +impl<I: Interner, T: TypeVisitable<I>, E: TypeVisitable<I>> TypeVisitable<I> for Result<T, E> { + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + match self { + Ok(v) => v.visit_with(visitor), + Err(e) => e.visit_with(visitor), + } + } } impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Rc<T> { diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 62e699eefd7..4c1f2dd0e53 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -203,6 +203,10 @@ pub enum TyKind<I: Interner> { /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables /// back to inference variables in a new inference context when inside of the query. /// + /// It is conventional to render anonymous bound types like `^N` or `^D_N`, + /// where `N` is the bound variable's anonymous index into the binder, and + /// `D` is the debruijn index, or totally omitted if the debruijn index is zero. + /// /// See the `rustc-dev-guide` for more details about /// [higher-ranked trait bounds][1] and [canonical queries][2]. /// @@ -212,6 +216,12 @@ pub enum TyKind<I: Interner> { /// A placeholder type, used during higher ranked subtyping to instantiate /// bound variables. + /// + /// It is conventional to render anonymous placeholer types like `!N` or `!U_N`, + /// where `N` is the placeholder variable's anonymous index (which corresponds + /// to the bound variable's index from the binder from which it was instantiated), + /// and `U` is the universe index in which it is instantiated, or totally omitted + /// if the universe index is zero. Placeholder(I::PlaceholderType), /// A type variable used during type checking. diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 62239fd2006..878c7aec6c1 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -13,8 +13,11 @@ //! - Types of interest, for which the methods delegate to the visitor. //! - All other types, including generic containers like `Vec` and `Option`. //! It defines a "skeleton" of how they should be visited. -//! - `TypeSuperVisitable`. This is implemented only for each type of interest, -//! and defines the visiting "skeleton" for these types. +//! - `TypeSuperVisitable`. This is implemented only for recursive types of +//! interest, and defines the visiting "skeleton" for these types. (This +//! excludes `Region` because it is non-recursive, i.e. it never contains +//! other types of interest.) +//! //! - `TypeVisitor`. This is implemented for each visitor. This defines how //! types of interest are visited. //! @@ -62,12 +65,13 @@ pub trait TypeVisitable<I: Interner>: fmt::Debug + Clone { fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; } +// This trait is implemented for types of interest. pub trait TypeSuperVisitable<I: Interner>: TypeVisitable<I> { - /// Provides a default visit for a type of interest. This should only be - /// called within `TypeVisitor` methods, when a non-custom traversal is - /// desired for the value of the type of interest passed to that method. - /// For example, in `MyVisitor::visit_ty(ty)`, it is valid to call - /// `ty.super_visit_with(self)`, but any other visiting should be done + /// Provides a default visit for a recursive type of interest. This should + /// only be called within `TypeVisitor` methods, when a non-custom + /// traversal is desired for the value of the type of interest passed to + /// that method. For example, in `MyVisitor::visit_ty(ty)`, it is valid to + /// call `ty.super_visit_with(self)`, but any other visiting should be done /// with `xyz.visit_with(self)`. fn super_visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; } @@ -92,11 +96,11 @@ pub trait TypeVisitor<I: Interner>: Sized { t.super_visit_with(self) } - fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> - where - I::Region: TypeSuperVisitable<I>, - { - r.super_visit_with(self) + // The default region visitor is a no-op because `Region` is non-recursive + // and has no `super_visit_with` method to call. That also explains the + // lack of `I::Region: TypeSuperVisitable<I>` bound. + fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> { + ControlFlow::Continue(()) } fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7f88327bf19..ad86c193098 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -576,8 +576,7 @@ impl<T, A: Allocator> Box<T, A> { /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> { + pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -809,9 +808,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn assume_init(self) -> Box<T, A> { + pub unsafe fn assume_init(self) -> Box<T, A> { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } @@ -844,9 +842,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// } /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn write(mut boxed: Self, value: T) -> Box<T, A> { + pub fn write(mut boxed: Self, value: T) -> Box<T, A> { unsafe { (*boxed).write(value); boxed.assume_init() @@ -1090,9 +1087,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let (leaked, alloc) = Box::into_unique(b); (leaked.as_ptr(), alloc) } @@ -1102,10 +1098,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] #[doc(hidden)] - pub const fn into_unique(b: Self) -> (Unique<T>, A) { + pub fn into_unique(b: Self) -> (Unique<T>, A) { // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a // raw pointer for the type system. Turning it directly into a raw pointer would not be // recognized as "releasing" the unique pointer to permit aliased raw accesses, @@ -1163,9 +1158,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// assert_eq!(*static_ref, [4, 2, 3]); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn leak<'a>(b: Self) -> &'a mut T + pub fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { @@ -1234,8 +1228,7 @@ impl<T: Default> Default for Box<T> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Box<[T]> { +impl<T> Default for Box<[T]> { #[inline] fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); @@ -1245,8 +1238,7 @@ impl<T> const Default for Box<[T]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Box<str> { +impl Default for Box<str> { #[inline] fn default() -> Self { // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`. @@ -1443,8 +1435,7 @@ impl<T> From<T> for Box<T> { } #[stable(feature = "pin", since = "1.33.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>> +impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>> where A: 'static, { @@ -1880,8 +1871,7 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { +impl<T: ?Sized, A: Allocator> Deref for Box<T, A> { type Target = T; fn deref(&self) -> &T { @@ -1890,8 +1880,7 @@ impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> { +impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> { fn deref_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index ad48315fd70..f83c8f83cc9 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; use core::ptr::{self, NonNull}; @@ -202,9 +202,7 @@ impl<H> WithHeader<H> { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::<T>() == 0 && mem::size_of::<H>() == 0 - ); + debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -249,9 +247,7 @@ impl<H> WithHeader<H> { alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); } else { debug_assert!( - value_offset == 0 - && mem::size_of::<H>() == 0 - && self.value_layout.size() == 0 + value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0 ); } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 1743a155c5a..0cb7e82beb0 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -18,9 +18,10 @@ use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; use core::marker::PhantomData; use core::mem; -use core::ptr::NonNull; +use core::ptr::{NonNull, Unique}; use super::SpecExtend; +use crate::alloc::{Allocator, Global}; use crate::boxed::Box; #[cfg(test)] @@ -47,11 +48,15 @@ mod tests; #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")] #[rustc_insignificant_dtor] -pub struct LinkedList<T> { +pub struct LinkedList< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { head: Option<NonNull<Node<T>>>, tail: Option<NonNull<Node<T>>>, len: usize, - marker: PhantomData<Box<Node<T>>>, + alloc: A, + marker: PhantomData<Box<Node<T>, A>>, } struct Node<T> { @@ -81,6 +86,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> { head: self.head, tail: self.tail, len: self.len, + alloc: Global, marker: PhantomData, })) .field(&self.len) @@ -117,6 +123,7 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> { head: self.head, tail: self.tail, len: self.len, + alloc: Global, marker: PhantomData, })) .field(&self.len) @@ -132,12 +139,15 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> { /// [`into_iter`]: LinkedList::into_iter #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter<T> { - list: LinkedList<T>, +pub struct IntoIter< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + list: LinkedList<T, A>, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<T: fmt::Debug> fmt::Debug for IntoIter<T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.list).finish() } @@ -148,22 +158,25 @@ impl<T> Node<T> { Node { next: None, prev: None, element } } - fn into_element(self: Box<Self>) -> T { + fn into_element<A: Allocator>(self: Box<Self, A>) -> T { self.element } } // private methods -impl<T> LinkedList<T> { +impl<T, A: Allocator> LinkedList<T, A> { /// Adds the given node to the front of the list. + /// + /// # Safety + /// `node` must point to a valid node that was boxed using the list's allocator. #[inline] - fn push_front_node(&mut self, mut node: Box<Node<T>>) { + unsafe fn push_front_node(&mut self, node: Unique<Node<T>>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. unsafe { - node.next = self.head; - node.prev = None; - let node = Some(Box::leak(node).into()); + (*node.as_ptr()).next = self.head; + (*node.as_ptr()).prev = None; + let node = Some(NonNull::from(node)); match self.head { None => self.tail = node, @@ -178,11 +191,11 @@ impl<T> LinkedList<T> { /// Removes and returns the node at the front of the list. #[inline] - fn pop_front_node(&mut self) -> Option<Box<Node<T>>> { + fn pop_front_node(&mut self) -> Option<Box<Node<T>, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. self.head.map(|node| unsafe { - let node = Box::from_raw(node.as_ptr()); + let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.head = node.next; match self.head { @@ -197,14 +210,17 @@ impl<T> LinkedList<T> { } /// Adds the given node to the back of the list. + /// + /// # Safety + /// `node` must point to a valid node that was boxed using the list's allocator. #[inline] - fn push_back_node(&mut self, mut node: Box<Node<T>>) { + unsafe fn push_back_node(&mut self, node: Unique<Node<T>>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. unsafe { - node.next = None; - node.prev = self.tail; - let node = Some(Box::leak(node).into()); + (*node.as_ptr()).next = None; + (*node.as_ptr()).prev = self.tail; + let node = Some(NonNull::from(node)); match self.tail { None => self.head = node, @@ -219,11 +235,11 @@ impl<T> LinkedList<T> { /// Removes and returns the node at the back of the list. #[inline] - fn pop_back_node(&mut self) -> Option<Box<Node<T>>> { + fn pop_back_node(&mut self) -> Option<Box<Node<T>, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. self.tail.map(|node| unsafe { - let node = Box::from_raw(node.as_ptr()); + let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.tail = node.prev; match self.tail { @@ -321,7 +337,10 @@ impl<T> LinkedList<T> { &mut self, split_node: Option<NonNull<Node<T>>>, at: usize, - ) -> Self { + ) -> Self + where + A: Clone, + { // The split node is the new head node of the second part if let Some(mut split_node) = split_node { let first_part_head; @@ -342,6 +361,7 @@ impl<T> LinkedList<T> { head: first_part_head, tail: first_part_tail, len: at, + alloc: self.alloc.clone(), marker: PhantomData, }; @@ -351,7 +371,7 @@ impl<T> LinkedList<T> { first_part } else { - mem::replace(self, LinkedList::new()) + mem::replace(self, LinkedList::new_in(self.alloc.clone())) } } @@ -360,7 +380,10 @@ impl<T> LinkedList<T> { &mut self, split_node: Option<NonNull<Node<T>>>, at: usize, - ) -> Self { + ) -> Self + where + A: Clone, + { // The split node is the new tail node of the first part and owns // the head of the second part. if let Some(mut split_node) = split_node { @@ -382,6 +405,7 @@ impl<T> LinkedList<T> { head: second_part_head, tail: second_part_tail, len: self.len - at, + alloc: self.alloc.clone(), marker: PhantomData, }; @@ -391,7 +415,7 @@ impl<T> LinkedList<T> { second_part } else { - mem::replace(self, LinkedList::new()) + mem::replace(self, LinkedList::new_in(self.alloc.clone())) } } } @@ -420,7 +444,7 @@ impl<T> LinkedList<T> { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub const fn new() -> Self { - LinkedList { head: None, tail: None, len: 0, marker: PhantomData } + LinkedList { head: None, tail: None, len: 0, alloc: Global, marker: PhantomData } } /// Moves all elements from `other` to the end of the list. @@ -471,7 +495,26 @@ impl<T> LinkedList<T> { } } } +} +impl<T, A: Allocator> LinkedList<T, A> { + /// Constructs an empty `LinkedList<T, A>`. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::LinkedList; + /// + /// let list: LinkedList<u32, _> = LinkedList::new_in(System); + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub const fn new_in(alloc: A) -> Self { + LinkedList { head: None, tail: None, len: 0, alloc, marker: PhantomData } + } /// Provides a forward iterator. /// /// # Examples @@ -532,7 +575,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_front(&self) -> Cursor<'_, T> { + pub fn cursor_front(&self) -> Cursor<'_, T, A> { Cursor { index: 0, current: self.head, list: self } } @@ -542,7 +585,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T, A> { CursorMut { index: 0, current: self.head, list: self } } @@ -552,7 +595,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_back(&self) -> Cursor<'_, T> { + pub fn cursor_back(&self) -> Cursor<'_, T, A> { Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } } @@ -562,7 +605,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T, A> { CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } } @@ -638,7 +681,15 @@ impl<T> LinkedList<T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - *self = Self::new(); + // We need to drop the nodes while keeping self.alloc + // We can do this by moving (head, tail, len) into a new list that borrows self.alloc + drop(LinkedList { + head: self.head.take(), + tail: self.tail.take(), + len: mem::take(&mut self.len), + alloc: &self.alloc, + marker: PhantomData, + }); } /// Returns `true` if the `LinkedList` contains an element equal to the @@ -790,7 +841,12 @@ impl<T> LinkedList<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn push_front(&mut self, elt: T) { - self.push_front_node(Box::new(Node::new(elt))); + let node = Box::new_in(Node::new(elt), &self.alloc); + let node_ptr = Unique::from(Box::leak(node)); + // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc + unsafe { + self.push_front_node(node_ptr); + } } /// Removes the first element and returns it, or `None` if the list is @@ -833,7 +889,12 @@ impl<T> LinkedList<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn push_back(&mut self, elt: T) { - self.push_back_node(Box::new(Node::new(elt))); + let node = Box::new_in(Node::new(elt), &self.alloc); + let node_ptr = Unique::from(Box::leak(node)); + // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc + unsafe { + self.push_back_node(node_ptr); + } } /// Removes the last element from a list and returns it, or `None` if @@ -883,13 +944,16 @@ impl<T> LinkedList<T> { /// assert_eq!(split.pop_front(), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn split_off(&mut self, at: usize) -> LinkedList<T> { + pub fn split_off(&mut self, at: usize) -> LinkedList<T, A> + where + A: Clone, + { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::take(self); + return mem::replace(self, Self::new_in(self.alloc.clone())); } else if at == len { - return Self::new(); + return Self::new_in(self.alloc.clone()); } // Below, we iterate towards the `i-1`th node, either from the start or the end, @@ -987,7 +1051,7 @@ impl<T> LinkedList<T> { /// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 9, 11, 13, 15]); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F> + pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1000,11 +1064,11 @@ impl<T> LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T> Drop for LinkedList<T> { +unsafe impl<#[may_dangle] T, A: Allocator> Drop for LinkedList<T, A> { fn drop(&mut self) { - struct DropGuard<'a, T>(&'a mut LinkedList<T>); + struct DropGuard<'a, T, A: Allocator>(&'a mut LinkedList<T, A>); - impl<'a, T> Drop for DropGuard<'a, T> { + impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> { fn drop(&mut self) { // Continue the same loop we do below. This only runs when a destructor has // panicked. If another one panics this will abort. @@ -1012,11 +1076,10 @@ unsafe impl<#[may_dangle] T> Drop for LinkedList<T> { } } - while let Some(node) = self.pop_front_node() { - let guard = DropGuard(self); - drop(node); - mem::forget(guard); - } + // Wrap self so that if a destructor panics, we can try to keep looping + let guard = DropGuard(self); + while guard.0.pop_front_node().is_some() {} + mem::forget(guard); } } @@ -1159,14 +1222,18 @@ impl<T> Default for IterMut<'_, T> { /// /// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] -pub struct Cursor<'a, T: 'a> { +pub struct Cursor< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { index: usize, current: Option<NonNull<Node<T>>>, - list: &'a LinkedList<T>, + list: &'a LinkedList<T, A>, } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T> Clone for Cursor<'_, T> { +impl<T, A: Allocator> Clone for Cursor<'_, T, A> { fn clone(&self) -> Self { let Cursor { index, current, list } = *self; Cursor { index, current, list } @@ -1174,7 +1241,7 @@ impl<T> Clone for Cursor<'_, T> { } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for Cursor<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish() } @@ -1191,20 +1258,24 @@ impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> { /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. #[unstable(feature = "linked_list_cursors", issue = "58533")] -pub struct CursorMut<'a, T: 'a> { +pub struct CursorMut< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { index: usize, current: Option<NonNull<Node<T>>>, - list: &'a mut LinkedList<T>, + list: &'a mut LinkedList<T, A>, } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T: fmt::Debug> fmt::Debug for CursorMut<'_, T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for CursorMut<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("CursorMut").field(&self.list).field(&self.index()).finish() } } -impl<'a, T> Cursor<'a, T> { +impl<'a, T, A: Allocator> Cursor<'a, T, A> { /// Returns the cursor position index within the `LinkedList`. /// /// This returns `None` if the cursor is currently pointing to the @@ -1321,7 +1392,7 @@ impl<'a, T> Cursor<'a, T> { } } -impl<'a, T> CursorMut<'a, T> { +impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// Returns the cursor position index within the `LinkedList`. /// /// This returns `None` if the cursor is currently pointing to the @@ -1426,7 +1497,7 @@ impl<'a, T> CursorMut<'a, T> { /// `CursorMut` is frozen for the lifetime of the `Cursor`. #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn as_cursor(&self) -> Cursor<'_, T> { + pub fn as_cursor(&self) -> Cursor<'_, T, A> { Cursor { list: self.list, current: self.current, index: self.index } } } @@ -1434,6 +1505,51 @@ impl<'a, T> CursorMut<'a, T> { // Now the list editing operations impl<'a, T> CursorMut<'a, T> { + /// Inserts the elements from the given `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the start of the `LinkedList`. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_after(&mut self, list: LinkedList<T>) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, + }; + self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); + if self.current.is_none() { + // The "ghost" non-element's index has changed. + self.index = self.list.len; + } + } + } + + /// Inserts the elements from the given `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the end of the `LinkedList`. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_before(&mut self, list: LinkedList<T>) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, + }; + self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); + self.index += splice_len; + } + } +} + +impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// Inserts a new element into the `LinkedList` after the current one. /// /// If the cursor is pointing at the "ghost" non-element then the new element is @@ -1441,7 +1557,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new(Node::new(item))).into(); + let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); let node_next = match self.current { None => self.list.head, Some(node) => node.as_ref().next, @@ -1461,7 +1577,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new(Node::new(item))).into(); + let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); let node_prev = match self.current { None => self.list.tail, Some(node) => node.as_ref().prev, @@ -1497,7 +1613,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is currently pointing to the "ghost" non-element then no element /// is removed and `None` is returned. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T>> { + pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T, A>> + where + A: Clone, + { let mut unlinked_node = self.current?; unsafe { self.current = unlinked_node.as_ref().next; @@ -1509,54 +1628,12 @@ impl<'a, T> CursorMut<'a, T> { head: Some(unlinked_node), tail: Some(unlinked_node), len: 1, + alloc: self.list.alloc.clone(), marker: PhantomData, }) } } - /// Inserts the elements from the given `LinkedList` after the current one. - /// - /// If the cursor is pointing at the "ghost" non-element then the new elements are - /// inserted at the start of the `LinkedList`. - #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn splice_after(&mut self, list: LinkedList<T>) { - unsafe { - let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { - Some(parts) => parts, - _ => return, - }; - let node_next = match self.current { - None => self.list.head, - Some(node) => node.as_ref().next, - }; - self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); - if self.current.is_none() { - // The "ghost" non-element's index has changed. - self.index = self.list.len; - } - } - } - - /// Inserts the elements from the given `LinkedList` before the current one. - /// - /// If the cursor is pointing at the "ghost" non-element then the new elements are - /// inserted at the end of the `LinkedList`. - #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn splice_before(&mut self, list: LinkedList<T>) { - unsafe { - let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { - Some(parts) => parts, - _ => return, - }; - let node_prev = match self.current { - None => self.list.tail, - Some(node) => node.as_ref().prev, - }; - self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); - self.index += splice_len; - } - } - /// Splits the list into two after the current element. This will return a /// new list consisting of everything after the cursor, with the original /// list retaining everything before. @@ -1564,7 +1641,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_after(&mut self) -> LinkedList<T> { + pub fn split_after(&mut self) -> LinkedList<T, A> + where + A: Clone, + { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; if self.index == self.list.len { // The "ghost" non-element's index has changed to 0. @@ -1580,7 +1660,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_before(&mut self) -> LinkedList<T> { + pub fn split_before(&mut self) -> LinkedList<T, A> + where + A: Clone, + { let split_off_idx = self.index; self.index = 0; unsafe { self.list.split_off_before_node(self.current, split_off_idx) } @@ -1722,11 +1805,15 @@ impl<'a, T> CursorMut<'a, T> { /// An iterator produced by calling `drain_filter` on LinkedList. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -pub struct DrainFilter<'a, T: 'a, F: 'a> -where +pub struct DrainFilter< + 'a, + T: 'a, + F: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> where F: FnMut(&mut T) -> bool, { - list: &'a mut LinkedList<T>, + list: &'a mut LinkedList<T, A>, it: Option<NonNull<Node<T>>>, pred: F, idx: usize, @@ -1734,7 +1821,7 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<T, F> Iterator for DrainFilter<'_, T, F> +impl<T, F, A: Allocator> Iterator for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1763,16 +1850,16 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<T, F> Drop for DrainFilter<'_, T, F> +impl<T, F, A: Allocator> Drop for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - struct DropGuard<'r, 'a, T, F>(&'r mut DrainFilter<'a, T, F>) + struct DropGuard<'r, 'a, T, F, A: Allocator>(&'r mut DrainFilter<'a, T, F, A>) where F: FnMut(&mut T) -> bool; - impl<'r, 'a, T, F> Drop for DropGuard<'r, 'a, T, F> + impl<'r, 'a, T, F, A: Allocator> Drop for DropGuard<'r, 'a, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1800,7 +1887,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Iterator for IntoIter<T> { +impl<T, A: Allocator> Iterator for IntoIter<T, A> { type Item = T; #[inline] @@ -1815,7 +1902,7 @@ impl<T> Iterator for IntoIter<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> DoubleEndedIterator for IntoIter<T> { +impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> { #[inline] fn next_back(&mut self) -> Option<T> { self.list.pop_back() @@ -1823,10 +1910,10 @@ impl<T> DoubleEndedIterator for IntoIter<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> ExactSizeIterator for IntoIter<T> {} +impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {} #[stable(feature = "fused", since = "1.26.0")] -impl<T> FusedIterator for IntoIter<T> {} +impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl<T> Default for IntoIter<T> { @@ -1852,19 +1939,19 @@ impl<T> FromIterator<T> for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> IntoIterator for LinkedList<T> { +impl<T, A: Allocator> IntoIterator for LinkedList<T, A> { type Item = T; - type IntoIter = IntoIter<T>; + type IntoIter = IntoIter<T, A>; /// Consumes the list into an iterator yielding elements by value. #[inline] - fn into_iter(self) -> IntoIter<T> { + fn into_iter(self) -> IntoIter<T, A> { IntoIter { list: self } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a LinkedList<T> { +impl<'a, T, A: Allocator> IntoIterator for &'a LinkedList<T, A> { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1874,7 +1961,7 @@ impl<'a, T> IntoIterator for &'a LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a mut LinkedList<T> { +impl<'a, T, A: Allocator> IntoIterator for &'a mut LinkedList<T, A> { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -1884,7 +1971,7 @@ impl<'a, T> IntoIterator for &'a mut LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Extend<T> for LinkedList<T> { +impl<T, A: Allocator> Extend<T> for LinkedList<T, A> { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { <Self as SpecExtend<I>>::spec_extend(self, iter); } @@ -1895,7 +1982,7 @@ impl<T> Extend<T> for LinkedList<T> { } } -impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> { +impl<I: IntoIterator, A: Allocator> SpecExtend<I> for LinkedList<I::Item, A> { default fn spec_extend(&mut self, iter: I) { iter.into_iter().for_each(move |elt| self.push_back(elt)); } @@ -1908,7 +1995,7 @@ impl<T> SpecExtend<LinkedList<T>> for LinkedList<T> { } #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> { +impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for LinkedList<T, A> { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } @@ -1920,7 +2007,7 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialEq> PartialEq for LinkedList<T> { +impl<T: PartialEq, A: Allocator> PartialEq for LinkedList<T, A> { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.iter().eq(other) } @@ -1931,17 +2018,17 @@ impl<T: PartialEq> PartialEq for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Eq> Eq for LinkedList<T> {} +impl<T: Eq, A: Allocator> Eq for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialOrd> PartialOrd for LinkedList<T> { +impl<T: PartialOrd, A: Allocator> PartialOrd for LinkedList<T, A> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.iter().partial_cmp(other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Ord> Ord for LinkedList<T> { +impl<T: Ord, A: Allocator> Ord for LinkedList<T, A> { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other) @@ -1949,9 +2036,11 @@ impl<T: Ord> Ord for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Clone> Clone for LinkedList<T> { +impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> { fn clone(&self) -> Self { - self.iter().cloned().collect() + let mut list = Self::new_in(self.alloc.clone()); + list.extend(self.iter().cloned()); + list } fn clone_from(&mut self, other: &Self) { @@ -1969,14 +2058,14 @@ impl<T: Clone> Clone for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: fmt::Debug> fmt::Debug for LinkedList<T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for LinkedList<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self).finish() } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Hash> Hash for LinkedList<T> { +impl<T: Hash, A: Allocator> Hash for LinkedList<T, A> { fn hash<H: Hasher>(&self, state: &mut H) { state.write_length_prefix(self.len()); for elt in self { @@ -2016,10 +2105,10 @@ fn assert_covariance() { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Send> Send for LinkedList<T> {} +unsafe impl<T: Send, A: Allocator + Send> Send for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Sync> Sync for LinkedList<T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<T: Sync> Send for Iter<'_, T> {} @@ -2034,13 +2123,13 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {} unsafe impl<T: Sync> Sync for IterMut<'_, T> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Send for Cursor<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Send for Cursor<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Sync for Cursor<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for Cursor<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Send> Send for CursorMut<'_, T> {} +unsafe impl<T: Send, A: Allocator + Send> Send for CursorMut<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Sync for CursorMut<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for CursorMut<'_, T, A> {} diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 1da86e1a46a..e03b501ae4d 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -551,8 +551,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[unstable(feature = "fmt_internals", issue = "none")] -pub use core::fmt::rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::Alignment; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index aa240c37e84..a002421aeef 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,7 +106,6 @@ #![feature(coerce_unsized)] #![feature(const_align_of_val)] #![feature(const_box)] -#![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_eval_select)] #![feature(const_maybe_uninit_as_mut_ptr)] @@ -174,7 +173,6 @@ #![feature(associated_type_bounds)] #![feature(c_unwind)] #![feature(cfg_sanitize)] -#![feature(const_deref)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_ptr_write)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index be41919b9dc..cf16a3424a0 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2247,8 +2247,7 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for String { +impl Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 9d8e309a978..5d9772b878b 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -39,6 +39,7 @@ use crate::sync::Arc; /// use std::sync::Arc; /// use std::task::{Context, Poll, Wake}; /// use std::thread::{self, Thread}; +/// use core::pin::pin; /// /// /// A waker that wakes up the current thread when called. /// struct ThreadWaker(Thread); @@ -52,7 +53,7 @@ use crate::sync::Arc; /// /// Run a future to completion on the current thread. /// fn block_on<T>(fut: impl Future<Output = T>) -> T { /// // Pin the future so it can be polled. -/// let mut fut = Box::pin(fut); +/// let mut fut = pin!(fut); /// /// // Create a new context to be passed to the future. /// let t = thread::current(); diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 2b1a787cc54..3091efabd68 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { let unyielded_ptr = this.iter.as_slice().as_ptr(); // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move { + if !T::IS_ZST { let start_ptr = source_vec.as_mut_ptr().add(start); // memmove back unyielded elements @@ -197,7 +195,7 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { } } - let iter = mem::replace(&mut self.iter, (&mut []).iter()); + let iter = mem::take(&mut self.iter); let drop_len = iter.len(); let mut vec = self.vec; diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index 8c03f1692d9..650f9213890 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -1,5 +1,5 @@ use crate::alloc::{Allocator, Global}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ptr; use core::slice; @@ -96,9 +96,7 @@ where unsafe { // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move && this.idx < this.old_len && this.del > 0 { + if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { let ptr = this.vec.as_mut_ptr(); let src = ptr.add(this.idx); let dst = src.sub(this.del); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 3736a6e0b0e..765c095e37b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3022,8 +3022,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Vec<T> { +impl<T> Default for Vec<T> { /// Creates an empty `Vec<T>`. /// /// The vector will not allocate until elements are pushed onto it. diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index 68ebd8e35ee..4cacee0414d 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -61,7 +61,7 @@ fn box_deref_lval() { pub struct ConstAllocator; -unsafe impl const Allocator for ConstAllocator { +unsafe impl Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { match layout.size() { 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs index 49b837becbc..4e7d7fc833e 100644 --- a/library/alloc/tests/const_fns.rs +++ b/library/alloc/tests/const_fns.rs @@ -1,13 +1,16 @@ // Test const functions in the library pub const MY_VEC: Vec<usize> = Vec::new(); -pub const MY_VEC2: Vec<usize> = Default::default(); + +// FIXME(#110395) +// pub const MY_VEC2: Vec<usize> = Default::default(); pub const MY_STRING: String = String::new(); -pub const MY_STRING2: String = Default::default(); -pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); -pub const MY_BOXED_STR: Box<str> = Default::default(); +// pub const MY_STRING2: String = Default::default(); + +// pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); +// pub const MY_BOXED_STR: Box<str> = Default::default(); use std::collections::{BTreeMap, BTreeSet}; @@ -23,11 +26,11 @@ pub const SET_IS_EMPTY: bool = SET.is_empty(); #[test] fn test_const() { - assert_eq!(MY_VEC, MY_VEC2); - assert_eq!(MY_STRING, MY_STRING2); + assert_eq!(MY_VEC, /* MY_VEC */ vec![]); + assert_eq!(MY_STRING, /* MY_STRING2 */ String::default()); - assert_eq!(MY_VEC, *MY_BOXED_SLICE); - assert_eq!(MY_STRING, *MY_BOXED_STR); + // assert_eq!(MY_VEC, *MY_BOXED_SLICE); + // assert_eq!(MY_STRING, *MY_BOXED_STR); assert_eq!(MAP_LEN, 0); assert_eq!(SET_LEN, 0); diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 0667cd7bc07..0eca4c9bb07 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -3,7 +3,6 @@ #![feature(assert_matches)] #![feature(btree_drain_filter)] #![feature(cow_is_borrowed)] -#![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_heap)] #![feature(const_mut_refs)] @@ -33,7 +32,6 @@ #![feature(slice_partition_dedup)] #![feature(string_remove_matches)] #![feature(const_btree_len)] -#![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(const_str_from_utf8)] #![feature(panic_update_hook)] diff --git a/library/backtrace b/library/backtrace -Subproject 07872f28cd8a65c3c7428811548dc85f1f2fb05 +Subproject 8ad84ca5ad88ade697637387e7cb4d7c3cf4bde diff --git a/library/core/benches/num/flt2dec/strategy/grisu.rs b/library/core/benches/num/flt2dec/strategy/grisu.rs index 6bea5e55d37..17d6b474ad2 100644 --- a/library/core/benches/num/flt2dec/strategy/grisu.rs +++ b/library/core/benches/num/flt2dec/strategy/grisu.rs @@ -81,3 +81,30 @@ fn bench_big_exact_inf(b: &mut Bencher) { format_exact(black_box(&decoded), &mut buf, i16::MIN); }); } + +#[bench] +fn bench_one_exact_inf(b: &mut Bencher) { + let decoded = decode_finite(1.0); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(black_box(&decoded), &mut buf, i16::MIN); + }); +} + +#[bench] +fn bench_trailing_zero_exact_inf(b: &mut Bencher) { + let decoded = decode_finite(250.000000000000000000000000); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(black_box(&decoded), &mut buf, i16::MIN); + }); +} + +#[bench] +fn bench_halfway_point_exact_inf(b: &mut Bencher) { + let decoded = decode_finite(1.00000000000000011102230246251565404236316680908203125); + let mut buf = [MaybeUninit::new(0); 1024]; + b.iter(|| { + format_exact(black_box(&decoded), &mut buf, i16::MIN); + }); +} diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index ac3d84718d5..59730303734 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -231,9 +231,8 @@ impl Layout { /// Returns an error if the combination of `self.size()` and the given /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> { + pub fn align_to(&self, align: usize) -> Result<Self, LayoutError> { Layout::from_size_align(self.size(), cmp::max(self.align(), align)) } @@ -315,9 +314,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { // This cannot overflow. Quoting from the invariant of Layout: // > `size`, when rounded up to the nearest multiple of `align`, // > must not overflow isize (i.e., the rounded value must be @@ -376,9 +374,8 @@ impl Layout { /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { + pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = cmp::max(self.align, next.align); let pad = self.padding_needed_for(next.align()); @@ -403,9 +400,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> { + pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> { let size = self.size().checked_mul(n).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(size, self.align) @@ -418,9 +414,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> { + pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> { let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(new_size, self.align) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index ff390322d55..d6ae2b8213f 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -105,7 +105,6 @@ impl fmt::Display for AllocError { /// /// [*currently allocated*]: #currently-allocated-memory #[unstable(feature = "allocator_api", issue = "32838")] -#[const_trait] pub unsafe trait Allocator { /// Attempts to allocate a block of memory. /// diff --git a/library/core/src/any.rs b/library/core/src/any.rs index c27646b8f33..bb93ea509d8 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -662,8 +662,7 @@ impl dyn Any + Send + Sync { /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! -#[derive(Clone, Copy, Debug, Hash, Eq)] -#[derive_const(PartialEq, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] pub struct TypeId { t: u64, diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 73e2c2cfbbe..587877dff55 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -3,8 +3,9 @@ use crate::num::NonZeroUsize; use crate::{ fmt, + intrinsics::transmute_unchecked, iter::{self, ExactSizeIterator, FusedIterator, TrustedLen}, - mem::{self, MaybeUninit}, + mem::MaybeUninit, ops::{IndexRange, Range}, ptr, }; @@ -63,18 +64,11 @@ impl<T, const N: usize> IntoIterator for [T; N] { // an array of `T`. // // With that, this initialization satisfies the invariants. - - // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it - // works with const generics: - // `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)` // - // Until then, we can use `mem::transmute_copy` to create a bitwise copy - // as a different type, then forget `array` so that it is not dropped. - unsafe { - let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) }; - mem::forget(self); - iter - } + // FIXME: If normal `transmute` ever gets smart enough to allow this + // directly, use it instead of `transmute_unchecked`. + let data: [MaybeUninit<T>; N] = unsafe { transmute_unchecked(self) }; + IntoIter { data, alive: IndexRange::zero_to(N) } } } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 1643842d607..98c87b2c393 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -148,8 +148,7 @@ impl Error for TryFromSliceError { } #[stable(feature = "try_from_slice_error", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<Infallible> for TryFromSliceError { +impl From<Infallible> for TryFromSliceError { fn from(x: Infallible) -> TryFromSliceError { match x {} } @@ -172,16 +171,14 @@ impl<T, const N: usize> AsMut<[T]> for [T; N] { } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T, const N: usize> const Borrow<[T]> for [T; N] { +impl<T, const N: usize> Borrow<[T]> for [T; N] { fn borrow(&self) -> &[T] { self } } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T, const N: usize> const BorrowMut<[T]> for [T; N] { +impl<T, const N: usize> BorrowMut<[T]> for [T; N] { fn borrow_mut(&mut self) -> &mut [T] { self } @@ -336,10 +333,9 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] { } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I, const N: usize> const Index<I> for [T; N] +impl<T, I, const N: usize> Index<I> for [T; N] where - [T]: ~const Index<I>, + [T]: Index<I>, { type Output = <[T] as Index<I>>::Output; @@ -350,10 +346,9 @@ where } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I, const N: usize> const IndexMut<I> for [T; N] +impl<T, I, const N: usize> IndexMut<I> for [T; N] where - [T]: ~const IndexMut<I>, + [T]: IndexMut<I>, { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -435,8 +430,7 @@ impl<T: Copy> SpecArrayClone for T { macro_rules! array_impl_default { {$n:expr, $t:ident $($ts:ident)*} => { #[stable(since = "1.4.0", feature = "array_default")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<T> const Default for [T; $n] where T: ~const Default { + impl<T> Default for [T; $n] where T: Default { fn default() -> [T; $n] { [$t::default(), $($ts::default()),*] } @@ -445,8 +439,7 @@ macro_rules! array_impl_default { }; {$n:expr,} => { #[stable(since = "1.4.0", feature = "array_default")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<T> const Default for [T; $n] { + impl<T> Default for [T; $n] { fn default() -> [T; $n] { [] } } }; diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index db1c505ba38..03cdff9b13b 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,7 +1,5 @@ //! impl bool {} -use crate::marker::Destruct; - impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), /// or `None` otherwise. @@ -31,12 +29,8 @@ impl bool { /// assert_eq!(a, 2); /// ``` #[stable(feature = "bool_to_option", since = "1.62.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then_some<T>(self, t: T) -> Option<T> - where - T: ~const Destruct, - { + pub fn then_some<T>(self, t: T) -> Option<T> { if self { Some(t) } else { None } } @@ -61,13 +55,8 @@ impl bool { /// assert_eq!(a, 1); /// ``` #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then<T, F>(self, f: F) -> Option<T> - where - F: ~const FnOnce() -> T, - F: ~const Destruct, - { + pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> { if self { Some(f()) } else { None } } } diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 4a8302ee404..efc9ada3891 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -154,7 +154,6 @@ /// [`String`]: ../../std/string/struct.String.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Borrow"] -#[const_trait] pub trait Borrow<Borrowed: ?Sized> { /// Immutably borrows from an owned value. /// @@ -185,7 +184,6 @@ pub trait Borrow<Borrowed: ?Sized> { /// an underlying type by providing a mutable reference. See [`Borrow<T>`] /// for more information on borrowing as another type. #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> { /// Mutably borrows from an owned value. /// @@ -207,8 +205,7 @@ pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for T { +impl<T: ?Sized> Borrow<T> for T { #[rustc_diagnostic_item = "noop_method_borrow"] fn borrow(&self) -> &T { self @@ -216,32 +213,28 @@ impl<T: ?Sized> const Borrow<T> for T { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const BorrowMut<T> for T { +impl<T: ?Sized> BorrowMut<T> for T { fn borrow_mut(&mut self) -> &mut T { self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for &T { +impl<T: ?Sized> Borrow<T> for &T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for &mut T { +impl<T: ?Sized> Borrow<T> for &mut T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const BorrowMut<T> for &mut T { +impl<T: ?Sized> BorrowMut<T> for &mut T { fn borrow_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index d728dc03817..bcca8d924cd 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -370,8 +370,7 @@ impl<T: Ord + Copy> Ord for Cell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Cell<T> { +impl<T> From<T> for Cell<T> { /// Creates a new `Cell<T>` containing the given value. fn from(t: T) -> Cell<T> { Cell::new(t) @@ -1318,8 +1317,7 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for RefCell<T> { +impl<T> From<T> for RefCell<T> { /// Creates a new `RefCell<T>` containing the given value. fn from(t: T) -> RefCell<T> { RefCell::new(t) @@ -2126,8 +2124,7 @@ impl<T: Default> Default for UnsafeCell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for UnsafeCell<T> { +impl<T> From<T> for UnsafeCell<T> { /// Creates a new `UnsafeCell<T>` containing the given value. fn from(t: T) -> UnsafeCell<T> { UnsafeCell::new(t) @@ -2226,8 +2223,7 @@ impl<T: Default> Default for SyncUnsafeCell<T> { } #[unstable(feature = "sync_unsafe_cell", issue = "95439")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for SyncUnsafeCell<T> { +impl<T> From<T> for SyncUnsafeCell<T> { /// Creates a new `SyncUnsafeCell<T>` containing the given value. fn from(t: T) -> SyncUnsafeCell<T> { SyncUnsafeCell::new(t) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 44adcfa1a94..1b213f6a294 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -63,6 +63,34 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> { LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } + /// Consumes this `LazyCell` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(lazy_cell)] + /// #![feature(lazy_cell_consume)] + /// + /// use std::cell::LazyCell; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = LazyCell::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string())); + /// ``` + #[unstable(feature = "lazy_cell_consume", issue = "109736")] + pub fn into_inner(this: Self) -> Result<T, F> { + match this.state.into_inner() { + State::Init(data) => Ok(data), + State::Uninit(f) => Err(f), + State::Poisoned => panic!("LazyCell instance has previously been poisoned"), + } + } + /// Forces the evaluation of this lazy value and returns a reference to /// the result. /// diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 5dc2d523198..a7cd59e50fc 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -284,8 +284,7 @@ impl<T: PartialEq> PartialEq for OnceCell<T> { impl<T: Eq> Eq for OnceCell<T> {} #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for OnceCell<T> { +impl<T> From<T> for OnceCell<T> { /// Creates a new `OnceCell<T>` which already contains the given `value`. #[inline] fn from(value: T) -> Self { diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 136bbcb8b21..b84e4b35b1c 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -27,8 +27,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { } #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u32 { +impl From<char> for u32 { /// Converts a [`char`] into a [`u32`]. /// /// # Examples @@ -47,8 +46,7 @@ impl const From<char> for u32 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u64 { +impl From<char> for u64 { /// Converts a [`char`] into a [`u64`]. /// /// # Examples @@ -69,8 +67,7 @@ impl const From<char> for u64 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u128 { +impl From<char> for u128 { /// Converts a [`char`] into a [`u128`]. /// /// # Examples @@ -123,8 +120,7 @@ impl TryFrom<char> for u8 { /// for a superset of Windows-1252 that fills the remaining blanks with corresponding /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<u8> for char { +impl From<u8> for char { /// Converts a [`u8`] into a [`char`]. /// /// # Examples diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 398437d9a02..a6d6230d3a6 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,8 +36,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::marker::Destruct; - /// A common trait for the ability to explicitly duplicate an object. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while @@ -106,7 +104,6 @@ use crate::marker::Destruct; #[lang = "clone"] #[rustc_diagnostic_item = "Clone"] #[rustc_trivial_field_reads] -#[const_trait] pub trait Clone: Sized { /// Returns a copy of the value. /// @@ -129,10 +126,7 @@ pub trait Clone: Sized { /// allocations. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn clone_from(&mut self, source: &Self) - where - Self: ~const Destruct, - { + fn clone_from(&mut self, source: &Self) { *self = source.clone() } } @@ -182,8 +176,7 @@ mod impls { ($($t:ty)*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for $t { + impl Clone for $t { #[inline(always)] fn clone(&self) -> Self { *self @@ -201,8 +194,7 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for ! { + impl Clone for ! { #[inline] fn clone(&self) -> Self { *self @@ -210,8 +202,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for *const T { + impl<T: ?Sized> Clone for *const T { #[inline(always)] fn clone(&self) -> Self { *self @@ -219,8 +210,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for *mut T { + impl<T: ?Sized> Clone for *mut T { #[inline(always)] fn clone(&self) -> Self { *self @@ -229,8 +219,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for &T { + impl<T: ?Sized> Clone for &T { #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 55331475aff..87ec35c040f 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -25,8 +25,6 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; -use crate::marker::Destruct; - use self::Ordering::*; /// Trait for equality comparisons. @@ -212,7 +210,6 @@ use self::Ordering::*; label = "no implementation for `{Self} == {Rhs}`", append_const_msg )] -#[const_trait] #[rustc_diagnostic_item = "PartialEq"] pub trait PartialEq<Rhs: ?Sized = Self> { /// This method tests for `self` and `other` values to be equal, and is used @@ -324,17 +321,13 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> { /// ``` /// use std::cmp::Ordering; /// -/// let result = 1.cmp(&2); -/// assert_eq!(Ordering::Less, result); +/// assert_eq!(1.cmp(&2), Ordering::Less); /// -/// let result = 1.cmp(&1); -/// assert_eq!(Ordering::Equal, result); +/// assert_eq!(1.cmp(&1), Ordering::Equal); /// -/// let result = 2.cmp(&1); -/// assert_eq!(Ordering::Greater, result); +/// assert_eq!(2.cmp(&1), Ordering::Greater); /// ``` -#[derive(Clone, Copy, Eq, Debug, Hash)] -#[derive_const(PartialOrd, Ord, PartialEq)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] #[stable(feature = "rust1", since = "1.0.0")] #[repr(i8)] pub enum Ordering { @@ -604,8 +597,7 @@ impl Ordering { pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T); #[stable(feature = "reverse_cmp_key", since = "1.19.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> { +impl<T: PartialOrd> PartialOrd for Reverse<T> { #[inline] fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> { other.0.partial_cmp(&self.0) @@ -763,7 +755,6 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -#[const_trait] pub trait Ord: Eq + PartialOrd<Self> { /// This method returns an [`Ordering`] between `self` and `other`. /// @@ -790,8 +781,8 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert_eq!(2, 1.max(2)); - /// assert_eq!(2, 2.max(2)); + /// assert_eq!(1.max(2), 2); + /// assert_eq!(2.max(2), 2); /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] @@ -799,7 +790,6 @@ pub trait Ord: Eq + PartialOrd<Self> { fn max(self, other: Self) -> Self where Self: Sized, - Self: ~const Destruct, { max_by(self, other, Ord::cmp) } @@ -811,8 +801,8 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert_eq!(1, 1.min(2)); - /// assert_eq!(2, 2.min(2)); + /// assert_eq!(1.min(2), 1); + /// assert_eq!(2.min(2), 2); /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] @@ -820,7 +810,6 @@ pub trait Ord: Eq + PartialOrd<Self> { fn min(self, other: Self) -> Self where Self: Sized, - Self: ~const Destruct, { min_by(self, other, Ord::cmp) } @@ -837,17 +826,16 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert!((-3).clamp(-2, 1) == -2); - /// assert!(0.clamp(-2, 1) == 0); - /// assert!(2.clamp(-2, 1) == 1); + /// assert_eq!((-3).clamp(-2, 1), -2); + /// assert_eq!(0.clamp(-2, 1), 0); + /// assert_eq!(2.clamp(-2, 1), 1); /// ``` #[must_use] #[stable(feature = "clamp", since = "1.50.0")] fn clamp(self, min: Self, max: Self) -> Self where Self: Sized, - Self: ~const Destruct, - Self: ~const PartialOrd, + Self: PartialOrd, { assert!(min <= max); if self < min { @@ -1035,7 +1023,6 @@ pub macro Ord($item:item) { label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", append_const_msg )] -#[const_trait] #[rustc_diagnostic_item = "PartialOrd"] pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// This method returns an ordering between `self` and `other` values if one exists. @@ -1070,11 +1057,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 < 2.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 < 1.0; - /// assert_eq!(result, false); + /// assert_eq!(1.0 < 1.0, false); + /// assert_eq!(1.0 < 2.0, true); + /// assert_eq!(2.0 < 1.0, false); /// ``` #[inline] #[must_use] @@ -1089,11 +1074,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 <= 2.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 <= 2.0; - /// assert_eq!(result, true); + /// assert_eq!(1.0 <= 1.0, true); + /// assert_eq!(1.0 <= 2.0, true); + /// assert_eq!(2.0 <= 1.0, false); /// ``` #[inline] #[must_use] @@ -1107,11 +1090,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 > 2.0; - /// assert_eq!(result, false); - /// - /// let result = 2.0 > 2.0; - /// assert_eq!(result, false); + /// assert_eq!(1.0 > 1.0, false); + /// assert_eq!(1.0 > 2.0, false); + /// assert_eq!(2.0 > 1.0, true); /// ``` #[inline] #[must_use] @@ -1126,11 +1107,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 2.0 >= 1.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 >= 2.0; - /// assert_eq!(result, true); + /// assert_eq!(1.0 >= 1.0, true); + /// assert_eq!(1.0 >= 2.0, false); + /// assert_eq!(2.0 >= 1.0, true); /// ``` #[inline] #[must_use] @@ -1160,15 +1139,14 @@ pub macro PartialOrd($item:item) { /// ``` /// use std::cmp; /// -/// assert_eq!(1, cmp::min(1, 2)); -/// assert_eq!(2, cmp::min(2, 2)); +/// assert_eq!(cmp::min(1, 2), 1); +/// assert_eq!(cmp::min(2, 2), 2); /// ``` #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")] -pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { +pub fn min<T: Ord>(v1: T, v2: T) -> T { v1.min(v2) } @@ -1181,18 +1159,16 @@ pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1); -/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); +/// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, 1); +/// +/// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, -2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, -{ +pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v1, Ordering::Greater => v2, @@ -1208,20 +1184,17 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1); -/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2); +/// let result = cmp::min_by_key(-2, 1, |x: &i32| x.abs()); +/// assert_eq!(result, 1); +/// +/// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs()); +/// assert_eq!(result, -2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, - K: ~const Destruct, -{ - min_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2))) +pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) } /// Compares and returns the maximum of two values. @@ -1235,15 +1208,14 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(2, cmp::max(1, 2)); -/// assert_eq!(2, cmp::max(2, 2)); +/// assert_eq!(cmp::max(1, 2), 2); +/// assert_eq!(cmp::max(2, 2), 2); /// ``` #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")] -pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { +pub fn max<T: Ord>(v1: T, v2: T) -> T { v1.max(v2) } @@ -1256,18 +1228,16 @@ pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); -/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2); +/// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, -2); +/// +/// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ; +/// assert_eq!(result, 2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, -{ +pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v2, Ordering::Greater => v1, @@ -1283,20 +1253,17 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2); -/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2); +/// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs()); +/// assert_eq!(result, -2); +/// +/// let result = cmp::max_by_key(-2, 2, |x: &i32| x.abs()); +/// assert_eq!(result, 2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, - K: ~const Destruct, -{ - max_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2))) +pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) } // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types @@ -1307,8 +1274,7 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for $t { + impl PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } #[inline] @@ -1318,8 +1284,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for () { + impl PartialEq for () { #[inline] fn eq(&self, _other: &()) -> bool { true @@ -1346,8 +1311,7 @@ mod impls { macro_rules! partial_ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for $t { + impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { match (*self <= *other, *self >= *other) { @@ -1370,8 +1334,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for () { + impl PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option<Ordering> { Some(Equal) @@ -1379,8 +1342,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for bool { + impl PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option<Ordering> { Some(self.cmp(other)) @@ -1392,8 +1354,7 @@ mod impls { macro_rules! ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for $t { + impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { Some(self.cmp(other)) @@ -1409,8 +1370,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for $t { + impl Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { // The order here is important to generate more optimal assembly. @@ -1424,8 +1384,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for () { + impl Ord for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal @@ -1433,8 +1392,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for bool { + impl Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { // Casting to i8's and converting the difference to an Ordering generates @@ -1453,8 +1411,7 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for ! { + impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } @@ -1464,16 +1421,14 @@ mod impls { impl Eq for ! {} #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for ! { + impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for ! { + impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self } @@ -1482,10 +1437,9 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A + impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A where - A: ~const PartialEq<B>, + A: PartialEq<B>, { #[inline] fn eq(&self, other: &&B) -> bool { @@ -1497,10 +1451,9 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<A: ?Sized, B: ?Sized> const PartialOrd<&B> for &A + impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A where - A: ~const PartialOrd<B>, + A: PartialOrd<B>, { #[inline] fn partial_cmp(&self, other: &&B) -> Option<Ordering> { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 5888e2960bb..3ae787cac71 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -214,7 +214,6 @@ pub const fn identity<T>(x: T) -> T { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")] -#[const_trait] pub trait AsRef<T: ?Sized> { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -366,7 +365,6 @@ pub trait AsRef<T: ?Sized> { /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] -#[const_trait] pub trait AsMut<T: ?Sized> { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -443,7 +441,6 @@ pub trait AsMut<T: ?Sized> { /// [`Vec`]: ../../std/vec/struct.Vec.html #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Into<T>: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -539,7 +536,6 @@ pub trait Into<T>: Sized { all(_Self = "&str", T = "std::string::String"), note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] -#[const_trait] pub trait From<T>: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] @@ -564,7 +560,6 @@ pub trait From<T>: Sized { /// [`Into`], see there for details. #[rustc_diagnostic_item = "TryInto"] #[stable(feature = "try_from", since = "1.34.0")] -#[const_trait] pub trait TryInto<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -641,7 +636,6 @@ pub trait TryInto<T>: Sized { /// [`try_from`]: TryFrom::try_from #[rustc_diagnostic_item = "TryFrom"] #[stable(feature = "try_from", since = "1.34.0")] -#[const_trait] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -658,10 +652,9 @@ pub trait TryFrom<T>: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsRef<U> for &T +impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where - T: ~const AsRef<U>, + T: AsRef<U>, { #[inline] fn as_ref(&self) -> &U { @@ -671,10 +664,9 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsRef<U> for &mut T +impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where - T: ~const AsRef<U>, + T: AsRef<U>, { #[inline] fn as_ref(&self) -> &U { @@ -692,10 +684,9 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsMut<U> for &mut T +impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where - T: ~const AsMut<U>, + T: AsMut<U>, { #[inline] fn as_mut(&mut self) -> &mut U { @@ -713,10 +704,9 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const Into<U> for T +impl<T, U> Into<U> for T where - U: ~const From<T>, + U: From<T>, { /// Calls `U::from(self)`. /// @@ -730,8 +720,7 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for T { +impl<T> From<T> for T { /// Returns the argument unchanged. #[inline(always)] fn from(t: T) -> T { @@ -748,8 +737,7 @@ impl<T> const From<T> for T { #[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<!> for T { +impl<T> From<!> for T { fn from(t: !) -> T { t } @@ -757,10 +745,9 @@ impl<T> const From<!> for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const TryInto<U> for T +impl<T, U> TryInto<U> for T where - U: ~const TryFrom<T>, + U: TryFrom<T>, { type Error = U::Error; @@ -773,10 +760,9 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const TryFrom<U> for T +impl<T, U> TryFrom<U> for T where - U: ~const Into<T>, + U: Into<T>, { type Error = Infallible; @@ -876,8 +862,7 @@ impl AsMut<str> for str { pub enum Infallible {} #[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Infallible { +impl Clone for Infallible { fn clone(&self) -> Infallible { match *self {} } @@ -929,8 +914,7 @@ impl Ord for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<!> for Infallible { +impl From<!> for Infallible { fn from(x: !) -> Self { x } diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index a74a56bc5b2..56ab63be27d 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -44,8 +44,7 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); macro_rules! impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] @@ -170,8 +169,7 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0" // bool -> Float #[stable(feature = "float_from_bool", since = "1.68.0")] -#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] -impl const From<bool> for f32 { +impl From<bool> for f32 { /// Converts `bool` to `f32` losslessly. The resulting value is positive /// `0.0` for `false` and `1.0` for `true` values. /// @@ -190,8 +188,7 @@ impl const From<bool> for f32 { } } #[stable(feature = "float_from_bool", since = "1.68.0")] -#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] -impl const From<bool> for f64 { +impl From<bool> for f64 { /// Converts `bool` to `f64` losslessly. The resulting value is positive /// `0.0` for `false` and `1.0` for `true` values. /// @@ -214,8 +211,7 @@ impl const From<bool> for f64 { macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -233,8 +229,7 @@ macro_rules! try_from_unbounded { macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -256,8 +251,7 @@ macro_rules! try_from_lower_bounded { macro_rules! try_from_upper_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -279,8 +273,7 @@ macro_rules! try_from_upper_bounded { macro_rules! try_from_both_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -431,8 +424,7 @@ use crate::num::NonZeroUsize; macro_rules! nzint_impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index d96b53de0a3..09dbc95810f 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -99,7 +99,6 @@ /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "Default")] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Default: Sized { /// Returns the "default value" for a type. /// @@ -190,8 +189,7 @@ pub macro Default($item:item) { macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $t { + impl Default for $t { #[inline] #[doc = $doc] fn default() -> $t { diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 4a5306ccaa7..bd2b2c36c43 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -324,14 +324,15 @@ impl CStr { /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA"); /// ``` /// - #[rustc_allow_const_fn_unstable(const_slice_index)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] #[rustc_const_stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { let nul_pos = memchr::memchr(0, bytes); match nul_pos { Some(nul_pos) => { - let subslice = &bytes[..nul_pos + 1]; + // FIXME(const-hack) replace with range index + // SAFETY: nul_pos + 1 <= bytes.len() + let subslice = unsafe { crate::slice::from_raw_parts(bytes.as_ptr(), nul_pos + 1) }; // SAFETY: We know there is a nul byte at nul_pos, so this slice // (ending at the nul byte) is a well-formed C string. Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) }) @@ -536,7 +537,8 @@ impl CStr { pub const fn is_empty(&self) -> bool { // SAFETY: We know there is at least one byte; for empty strings it // is the NUL terminator. - (unsafe { self.inner.get_unchecked(0) }) == &0 + // FIXME(const-hack): use get_unchecked + unsafe { *self.inner.as_ptr() == 0 } } /// Converts this C string to a byte slice. @@ -560,8 +562,7 @@ impl CStr { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] - pub const fn to_bytes(&self) -> &[u8] { + pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); // SAFETY: to_bytes_with_nul returns slice with length at least 1 unsafe { bytes.get_unchecked(..bytes.len() - 1) } @@ -612,8 +613,7 @@ impl CStr { /// assert_eq!(cstr.to_str(), Ok("foo")); /// ``` #[stable(feature = "cstr_to_str", since = "1.4.0")] - #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] - pub const fn to_str(&self) -> Result<&str, str::Utf8Error> { + pub fn to_str(&self) -> Result<&str, str::Utf8Error> { // N.B., when `CStr` is changed to perform the length check in `.to_bytes()` // instead of in `from_ptr()`, it may be worth considering if this should // be rewritten to do the UTF-8 check inline with the length calculation diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index fcda097f01f..a901ae72669 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -18,6 +18,7 @@ mod float; #[cfg(no_fp_fmt_parse)] mod nofloat; mod num; +mod rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Alignment")] @@ -38,12 +39,6 @@ pub enum Alignment { #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; -#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] -#[doc(hidden)] -pub mod rt { - pub mod v1; -} - /// The type returned by formatter methods. /// /// # Examples @@ -227,7 +222,7 @@ impl<W: Write + ?Sized> Write for &mut W { pub struct Formatter<'a> { flags: u32, fill: char, - align: rt::v1::Alignment, + align: rt::Alignment, width: Option<usize>, precision: Option<usize>, @@ -248,7 +243,7 @@ impl<'a> Formatter<'a> { Formatter { flags: 0, fill: ' ', - align: rt::v1::Alignment::Unknown, + align: rt::Alignment::Unknown, width: None, precision: None, buf, @@ -433,17 +428,15 @@ impl<'a> Arguments<'a> { /// An `UnsafeArg` is required because the following invariants must be held /// in order for this function to be safe: /// 1. The `pieces` slice must be at least as long as `fmt`. - /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a - /// valid index of `args`. - /// 3. Every [`rt::v1::Count::Param`] within `fmt` must contain a valid index of - /// `args`. + /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`. + /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`. #[doc(hidden)] #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] pub fn new_v1_formatted( pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>], - fmt: &'a [rt::v1::Argument], + fmt: &'a [rt::Placeholder], _unsafe_arg: UnsafeArg, ) -> Arguments<'a> { Arguments { pieces, fmt: Some(fmt), args } @@ -505,7 +498,7 @@ pub struct Arguments<'a> { pieces: &'a [&'static str], // Placeholder specs, or `None` if all specs are default (as in "{}{}"). - fmt: Option<&'a [rt::v1::Argument]>, + fmt: Option<&'a [rt::Placeholder]>, // Dynamic arguments for interpolation, to be interleaved with string // pieces. (Every argument is preceded by a string piece.) @@ -1281,15 +1274,15 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Ok(()) } -unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result { - fmt.fill = arg.format.fill; - fmt.align = arg.format.align; - fmt.flags = arg.format.flags; +unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[ArgumentV1<'_>]) -> Result { + fmt.fill = arg.fill; + fmt.align = arg.align; + fmt.flags = arg.flags; // SAFETY: arg and args come from the same Arguments, // which guarantees the indexes are always within bounds. unsafe { - fmt.width = getcount(args, &arg.format.width); - fmt.precision = getcount(args, &arg.format.precision); + fmt.width = getcount(args, &arg.width); + fmt.precision = getcount(args, &arg.precision); } // Extract the correct argument @@ -1302,11 +1295,11 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV (value.formatter)(value.value, fmt) } -unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> { +unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::Count) -> Option<usize> { match *cnt { - rt::v1::Count::Is(n) => Some(n), - rt::v1::Count::Implied => None, - rt::v1::Count::Param(i) => { + rt::Count::Is(n) => Some(n), + rt::Count::Implied => None, + rt::Count::Param(i) => { debug_assert!(i < args.len()); // SAFETY: cnt and args come from the same Arguments, // which guarantees this index is always within bounds. @@ -1449,9 +1442,9 @@ impl<'a> Formatter<'a> { // is zero Some(min) if self.sign_aware_zero_pad() => { let old_fill = crate::mem::replace(&mut self.fill, '0'); - let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right); + let old_align = crate::mem::replace(&mut self.align, rt::Alignment::Right); write_prefix(self, sign, prefix)?; - let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; + let post_padding = self.padding(min - width, Alignment::Right)?; self.buf.write_str(buf)?; post_padding.write(self)?; self.fill = old_fill; @@ -1460,7 +1453,7 @@ impl<'a> Formatter<'a> { } // Otherwise, the sign and prefix goes after the padding Some(min) => { - let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; + let post_padding = self.padding(min - width, Alignment::Right)?; write_prefix(self, sign, prefix)?; self.buf.write_str(buf)?; post_padding.write(self) @@ -1535,7 +1528,7 @@ impl<'a> Formatter<'a> { // If we're under both the maximum and the minimum width, then fill // up the minimum width with the specified string + some alignment. else { - let align = rt::v1::Alignment::Left; + let align = Alignment::Left; let post_padding = self.padding(width - chars_count, align)?; self.buf.write_str(s)?; post_padding.write(self) @@ -1550,17 +1543,19 @@ impl<'a> Formatter<'a> { pub(crate) fn padding( &mut self, padding: usize, - default: rt::v1::Alignment, + default: Alignment, ) -> result::Result<PostPadding, Error> { let align = match self.align { - rt::v1::Alignment::Unknown => default, - _ => self.align, + rt::Alignment::Unknown => default, + rt::Alignment::Left => Alignment::Left, + rt::Alignment::Right => Alignment::Right, + rt::Alignment::Center => Alignment::Center, }; let (pre_pad, post_pad) = match align { - rt::v1::Alignment::Left => (0, padding), - rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0), - rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), + Alignment::Left => (0, padding), + Alignment::Right => (padding, 0), + Alignment::Center => (padding / 2, (padding + 1) / 2), }; for _ in 0..pre_pad { @@ -1580,7 +1575,6 @@ impl<'a> Formatter<'a> { let mut formatted = formatted.clone(); let old_fill = self.fill; let old_align = self.align; - let mut align = old_align; if self.sign_aware_zero_pad() { // a sign always goes first let sign = formatted.sign; @@ -1589,9 +1583,8 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = ""; width = width.saturating_sub(sign.len()); - align = rt::v1::Alignment::Right; self.fill = '0'; - self.align = rt::v1::Alignment::Right; + self.align = rt::Alignment::Right; } // remaining parts go through the ordinary padding process. @@ -1600,7 +1593,7 @@ impl<'a> Formatter<'a> { // no padding self.write_formatted_parts(&formatted) } else { - let post_padding = self.padding(width - len, align)?; + let post_padding = self.padding(width - len, Alignment::Right)?; self.write_formatted_parts(&formatted)?; post_padding.write(self) }; @@ -1788,10 +1781,10 @@ impl<'a> Formatter<'a> { #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub fn align(&self) -> Option<Alignment> { match self.align { - rt::v1::Alignment::Left => Some(Alignment::Left), - rt::v1::Alignment::Right => Some(Alignment::Right), - rt::v1::Alignment::Center => Some(Alignment::Center), - rt::v1::Alignment::Unknown => None, + rt::Alignment::Left => Some(Alignment::Left), + rt::Alignment::Right => Some(Alignment::Right), + rt::Alignment::Center => Some(Alignment::Center), + rt::Alignment::Unknown => None, } } diff --git a/library/core/src/fmt/rt/v1.rs b/library/core/src/fmt/rt.rs index 6d70796f707..2c1a767691b 100644 --- a/library/core/src/fmt/rt/v1.rs +++ b/library/core/src/fmt/rt.rs @@ -1,20 +1,12 @@ -//! This is an internal module used by the ifmt! runtime. These structures are -//! emitted to static arrays to precompile format strings ahead of time. -//! -//! These definitions are similar to their `ct` equivalents, but differ in that -//! these can be statically allocated and are slightly optimized for the runtime #![allow(missing_debug_implementations)] +#![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] + +//! These are the lang items used by format_args!(). #[lang = "format_placeholder"] #[derive(Copy, Clone)] -// FIXME: Rename this to Placeholder -pub struct Argument { +pub struct Placeholder { pub position: usize, - pub format: FormatSpec, -} - -#[derive(Copy, Clone)] -pub struct FormatSpec { pub fill: char, pub align: Alignment, pub flags: u32, @@ -22,7 +14,7 @@ pub struct FormatSpec { pub width: Count, } -impl Argument { +impl Placeholder { #[inline(always)] pub const fn new( position: usize, @@ -32,7 +24,7 @@ impl Argument { precision: Count, width: Count, ) -> Self { - Self { position, format: FormatSpec { fill, align, flags, precision, width } } + Self { position, fill, align, flags, precision, width } } } diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 4e7bae7bcb0..a73b5b610a4 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -86,8 +86,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; -use crate::intrinsics::const_eval_select; -use crate::marker::{self, Destruct}; +use crate::marker; #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] @@ -184,7 +183,6 @@ mod sip; /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Hash"] -#[const_trait] pub trait Hash { /// Feeds this value into the given [`Hasher`]. /// @@ -199,7 +197,7 @@ pub trait Hash { /// println!("Hash is {:x}!", hasher.finish()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - fn hash<H: ~const Hasher>(&self, state: &mut H); + fn hash<H: Hasher>(&self, state: &mut H); /// Feeds a slice of this type into the given [`Hasher`]. /// @@ -236,25 +234,13 @@ pub trait Hash { /// [`hash`]: Hash::hash /// [`hash_slice`]: Hash::hash_slice #[stable(feature = "hash_slice", since = "1.3.0")] - fn hash_slice<H: ~const Hasher>(data: &[Self], state: &mut H) + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized, { - //FIXME(const_trait_impl): revert to only a for loop - fn rt<T: Hash, H: Hasher>(data: &[T], state: &mut H) { - for piece in data { - piece.hash(state) - } - } - const fn ct<T: ~const Hash, H: ~const Hasher>(data: &[T], state: &mut H) { - let mut i = 0; - while i < data.len() { - data[i].hash(state); - i += 1; - } + for piece in data { + piece.hash(state) } - // SAFETY: same behavior, CT just uses while instead of for - unsafe { const_eval_select((data, state), ct, rt) }; } } @@ -327,7 +313,6 @@ pub use macros::Hash; /// [`write_u8`]: Hasher::write_u8 /// [`write_u32`]: Hasher::write_u32 #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Hasher { /// Returns the hash value for the values written so far. /// @@ -573,8 +558,7 @@ pub trait Hasher { } #[stable(feature = "indirect_hasher_impl", since = "1.22.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl<H: ~const Hasher + ?Sized> const Hasher for &mut H { +impl<H: Hasher + ?Sized> Hasher for &mut H { fn finish(&self) -> u64 { (**self).finish() } @@ -654,7 +638,6 @@ impl<H: ~const Hasher + ?Sized> const Hasher for &mut H { /// [`build_hasher`]: BuildHasher::build_hasher /// [`HashMap`]: ../../std/collections/struct.HashMap.html #[stable(since = "1.7.0", feature = "build_hasher")] -#[const_trait] pub trait BuildHasher { /// Type of the hasher that will be created. #[stable(since = "1.7.0", feature = "build_hasher")] @@ -715,10 +698,10 @@ pub trait BuildHasher { /// ); /// ``` #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")] - fn hash_one<T: ~const Hash + ~const Destruct>(&self, x: T) -> u64 + fn hash_one<T: Hash>(&self, x: T) -> u64 where Self: Sized, - Self::Hasher: ~const Hasher + ~const Destruct, + Self::Hasher: Hasher, { let mut hasher = self.build_hasher(); x.hash(&mut hasher); @@ -782,8 +765,7 @@ impl<H> fmt::Debug for BuildHasherDefault<H> { } #[stable(since = "1.7.0", feature = "build_hasher")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl<H: ~const Default + Hasher> const BuildHasher for BuildHasherDefault<H> { +impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> { type Hasher = H; fn build_hasher(&self) -> H { @@ -799,8 +781,7 @@ impl<H> Clone for BuildHasherDefault<H> { } #[stable(since = "1.7.0", feature = "build_hasher")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<H> const Default for BuildHasherDefault<H> { +impl<H> Default for BuildHasherDefault<H> { fn default() -> BuildHasherDefault<H> { BuildHasherDefault(marker::PhantomData) } @@ -825,15 +806,14 @@ mod impls { macro_rules! impl_write { ($(($ty:ident, $meth:ident),)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for $ty { + impl Hash for $ty { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.$meth(*self) } #[inline] - fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) { + fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { let newlen = mem::size_of_val(data); let ptr = data.as_ptr() as *const u8; // SAFETY: `ptr` is valid and aligned, as this macro is only used @@ -862,37 +842,33 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for bool { + impl Hash for bool { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u8(*self as u8) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for char { + impl Hash for char { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u32(*self as u32) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for str { + impl Hash for str { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_str(self); } } #[stable(feature = "never_hash", since = "1.29.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for ! { + impl Hash for ! { #[inline] - fn hash<H: ~const Hasher>(&self, _: &mut H) { + fn hash<H: Hasher>(&self, _: &mut H) { *self } } @@ -900,10 +876,9 @@ mod impls { macro_rules! impl_hash_tuple { () => ( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for () { + impl Hash for () { #[inline] - fn hash<H: ~const Hasher>(&self, _state: &mut H) {} + fn hash<H: Hasher>(&self, _state: &mut H) {} } ); @@ -911,11 +886,10 @@ mod impls { maybe_tuple_doc! { $($name)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { + impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case)] #[inline] - fn hash<S: ~const Hasher>(&self, state: &mut S) { + fn hash<S: Hasher>(&self, state: &mut S) { let ($(ref $name,)+) = *self; $($name.hash(state);)+ } @@ -958,29 +932,26 @@ mod impls { impl_hash_tuple! { T B C D E F G H I J K L } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ~const Hash> const Hash for [T] { + impl<T: Hash> Hash for [T] { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_length_prefix(self.len()); Hash::hash_slice(self, state) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ?Sized + ~const Hash> const Hash for &T { + impl<T: ?Sized + Hash> Hash for &T { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ?Sized + ~const Hash> const Hash for &mut T { + impl<T: ?Sized + Hash> Hash for &mut T { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); } } diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 7f8287bf56f..6b9f2e84257 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -118,7 +118,7 @@ macro_rules! load_int_le { /// Safety: this performs unchecked indexing of `buf` at `start..start+len`, so /// that must be in-bounds. #[inline] -const unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { +unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { debug_assert!(len < 8); let mut i = 0; // current byte index (from LSB) in the output u64 let mut out = 0; @@ -225,8 +225,7 @@ impl<S: Sip> Hasher<S> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const super::Hasher for SipHasher { +impl super::Hasher for SipHasher { #[inline] fn write(&mut self, msg: &[u8]) { self.0.hasher.write(msg) @@ -244,8 +243,7 @@ impl const super::Hasher for SipHasher { } #[unstable(feature = "hashmap_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const super::Hasher for SipHasher13 { +impl super::Hasher for SipHasher13 { #[inline] fn write(&mut self, msg: &[u8]) { self.hasher.write(msg) @@ -262,7 +260,7 @@ impl const super::Hasher for SipHasher13 { } } -impl<S: ~const Sip> const super::Hasher for Hasher<S> { +impl<S: Sip> super::Hasher for Hasher<S> { // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined // for this type. We could add them, copy the `short_write` implementation // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*` @@ -342,7 +340,7 @@ impl<S: ~const Sip> const super::Hasher for Hasher<S> { } } -impl<S: Sip> const Clone for Hasher<S> { +impl<S: Sip> Clone for Hasher<S> { #[inline] fn clone(&self) -> Hasher<S> { Hasher { @@ -366,7 +364,6 @@ impl<S: Sip> Default for Hasher<S> { } #[doc(hidden)] -#[const_trait] trait Sip { fn c_rounds(_: &mut State); fn d_rounds(_: &mut State); @@ -375,7 +372,7 @@ trait Sip { #[derive(Debug, Clone, Default)] struct Sip13Rounds; -impl const Sip for Sip13Rounds { +impl Sip for Sip13Rounds { #[inline] fn c_rounds(state: &mut State) { compress!(state); @@ -392,7 +389,7 @@ impl const Sip for Sip13Rounds { #[derive(Debug, Clone, Default)] struct Sip24Rounds; -impl const Sip for Sip24Rounds { +impl Sip for Sip24Rounds { #[inline] fn c_rounds(state: &mut State) { compress!(state); diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index a205565773a..75c104ce2fa 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -73,8 +73,8 @@ use crate::intrinsics; /// ``` /// /// While using `unreachable_unchecked()` is perfectly sound in the following -/// example, the compiler is able to prove that a division by zero is not -/// possible. Benchmarking reveals that `unreachable_unchecked()` provides +/// example, as the compiler is able to prove that a division by zero is not +/// possible, benchmarking reveals that `unreachable_unchecked()` provides /// no benefit over using [`unreachable!`], while the latter does not introduce /// the possibility of Undefined Behavior. /// @@ -217,17 +217,14 @@ pub fn spin_loop() { /// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The /// extent to which it can block optimisations may vary depending upon the platform and code-gen /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the -/// identity function. +/// identity function. As such, it **must not be relied upon to control critical program behavior.** +/// This _immediately_ precludes any direct use of this function for cryptographic or security +/// purposes. /// /// [`std::convert::identity`]: crate::convert::identity /// /// # When is this useful? /// -/// First and foremost: `black_box` does _not_ guarantee any exact behavior and, in some cases, may -/// do nothing at all. As such, it **must not be relied upon to control critical program behavior.** -/// This _immediately_ precludes any direct use of this function for cryptographic or security -/// purposes. -/// /// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be /// relied upon for benchmarking, and should be used there. It will try to ensure that the /// compiler doesn't optimize away part of the intended test code based on context. For diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 5d4c9ba7395..5774107f520 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -1,23 +1,10 @@ // implements the unary operator "op &T" // based on "op T" where T is expected to be `Copy`able macro_rules! forward_ref_unop { - (impl const $imp:ident, $method:ident for $t:ty) => { - forward_ref_unop!(impl const $imp, $method for $t, + (impl $imp:ident, $method:ident for $t:ty) => { + forward_ref_unop!(impl $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp for &$t { - type Output = <$t as $imp>::Output; - - #[inline] - fn $method(self) -> <$t as $imp>::Output { - $imp::$method(*self) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] impl $imp for &$t { @@ -34,45 +21,10 @@ macro_rules! forward_ref_unop { // implements binary operators "&T op U", "T op &U", "&T op &U" // based on "T op U" where T and U are expected to be `Copy`able macro_rules! forward_ref_binop { - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_binop!(impl const $imp, $method for $t, $u, + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_binop!(impl $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl<'a> const $imp<$u> for &'a $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(self, *other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for &$t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, *other) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl<'a> $imp<$u> for &'a $t { @@ -113,21 +65,6 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_op_assign!(impl const $imp, $method for $t, $u, - #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); - }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - #[inline] - fn $method(&mut self, other: &$u) { - $imp::$method(self, *other); - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl $imp<&$u> for $t { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index a7c100e1b23..39edfd8265b 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1376,6 +1376,20 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn transmute<Src, Dst>(src: Src) -> Dst; + /// Like [`transmute`], but even less checked at compile-time: rather than + /// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's + /// **Undefined Behaviour** at runtime. + /// + /// Prefer normal `transmute` where possible, for the extra checking, since + /// both do exactly the same thing at runtime, if they both compile. + /// + /// This is not expected to ever be exposed directly to users, rather it + /// may eventually be exposed through some more-constrained API. + #[cfg(not(bootstrap))] + #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] + #[rustc_nounwind] + pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst; + /// Returns `true` if the actual type given as `T` requires drop /// glue; returns `false` if the actual type provided for `T` /// implements `Copy`. @@ -2519,7 +2533,9 @@ pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool { pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool { let src_usize = src.addr(); let dst_usize = dst.addr(); - let size = mem::size_of::<T>().checked_mul(count).unwrap(); + let size = mem::size_of::<T>() + .checked_mul(count) + .expect("is_nonoverlapping: `size_of::<T>() * count` overflows a usize"); let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize }; // If the absolute distance between the ptrs is at least as big as the size of the buffer, // they do not overlap. @@ -2796,3 +2812,11 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) { write_bytes(dst, val, count) } } + +/// Polyfill for bootstrap +#[cfg(bootstrap)] +pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst { + use crate::mem::*; + // SAFETY: It's a transmute -- the caller promised it's fine. + unsafe { transmute_copy(&ManuallyDrop::new(src)) } +} diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 617dfd12383..243df015f9a 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -81,8 +81,7 @@ impl<T> Clone for Empty<T> { // not #[derive] because that adds a Default bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Empty<T> { +impl<T> Default for Empty<T> { fn default() -> Empty<T> { Empty(marker::PhantomData) } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e099700e3e7..76b3a32880d 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -228,7 +228,6 @@ pub trait FromIterator<A>: Sized { #[rustc_diagnostic_item = "IntoIterator"] #[rustc_skip_array_during_method_dispatch] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait IntoIterator { /// The type of the elements being iterated over. #[stable(feature = "rust1", since = "1.0.0")] @@ -264,7 +263,7 @@ pub trait IntoIterator { #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl<I: Iterator> const IntoIterator for I { +impl<I: Iterator> IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 02877604248..dabfce14474 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -70,7 +70,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[doc(notable_trait)] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] -#[const_trait] pub trait Iterator { /// The type of the elements being iterated over. #[rustc_diagnostic_item = "IteratorItem"] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 04243544b83..24a9d81d037 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -112,11 +112,7 @@ #![feature(const_caller_location)] #![feature(const_cell_into_inner)] #![feature(const_char_from_u32_unchecked)] -#![feature(const_clone)] -#![feature(const_cmp)] -#![feature(const_convert)] #![feature(const_cstr_methods)] -#![feature(const_default_impls)] #![feature(const_discriminant)] #![feature(const_eval_select)] #![feature(const_exact_div)] @@ -131,14 +127,11 @@ #![feature(const_intrinsic_forget)] #![feature(const_ipv4)] #![feature(const_ipv6)] -#![feature(const_is_char_boundary)] #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_maybe_uninit_uninit_array)] #![feature(const_nonnull_new)] -#![feature(const_num_from_num)] -#![feature(const_ops)] #![feature(const_option)] #![feature(const_option_ext)] #![feature(const_pin)] @@ -151,7 +144,6 @@ #![feature(const_ptr_write)] #![feature(const_raw_ptr_comparison)] #![feature(const_replace)] -#![feature(const_result_drop)] #![feature(const_size_of_val)] #![feature(const_size_of_val_raw)] #![feature(const_slice_from_raw_parts_mut)] @@ -161,7 +153,6 @@ #![feature(const_slice_split_at_mut)] #![feature(const_str_from_utf8_unchecked_mut)] #![feature(const_swap)] -#![feature(const_trait_impl)] #![feature(const_transmute_copy)] #![feature(const_try)] #![feature(const_type_id)] @@ -207,9 +198,9 @@ #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_refs_to_cell)] +#![feature(const_trait_impl)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] -#![feature(derive_const)] #![feature(doc_cfg)] #![feature(doc_cfg_hide)] #![feature(doc_notable_trait)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 3cd4f5104ce..e85c0c0a688 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -732,8 +732,7 @@ impl<T: ?Sized> Clone for PhantomData<T> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T: ?Sized> const Default for PhantomData<T> { +impl<T: ?Sized> Default for PhantomData<T> { fn default() -> Self { Self } @@ -858,8 +857,8 @@ impl<T: ?Sized> Unpin for *mut T {} #[unstable(feature = "const_trait_impl", issue = "67792")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] -#[const_trait] #[rustc_deny_explicit_impl] +#[const_trait] pub trait Destruct {} /// A marker for tuple types. diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 3d719afe49e..5f3d66e3773 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -146,8 +146,7 @@ impl<T: ?Sized> ManuallyDrop<T> { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for ManuallyDrop<T> { +impl<T: ?Sized> Deref for ManuallyDrop<T> { type Target = T; #[inline(always)] fn deref(&self) -> &T { @@ -156,8 +155,7 @@ impl<T: ?Sized> const Deref for ManuallyDrop<T> { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const DerefMut for ManuallyDrop<T> { +impl<T: ?Sized> DerefMut for ManuallyDrop<T> { #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 9c6d48675a6..2588b7d2bef 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -945,14 +945,10 @@ impl<T> MaybeUninit<T> { // * `MaybeUninit<T>` and T are guaranteed to have the same layout // * `MaybeUninit` does not drop, so there are no double-frees // And thus the conversion is safe - let ret = unsafe { + unsafe { intrinsics::assert_inhabited::<[T; N]>(); - (&array as *const _ as *const [T; N]).read() - }; - - // FIXME: required to avoid `~const Destruct` bound - super::forget(array); - ret + intrinsics::transmute_unchecked(array) + } } /// Assuming all the elements are initialized, get a slice to them. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 30ec73cabf8..7d2f2971523 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1279,3 +1279,45 @@ pub trait SizedTypeProperties: Sized { #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] impl<T> SizedTypeProperties for T {} + +/// Expands to the offset in bytes of a field from the beginning of the given type. +/// +/// Only structs, unions and tuples are supported. +/// +/// Nested field accesses may be used, but not array indexes like in `C`'s `offsetof`. +/// +/// Note that the output of this macro is not stable, except for `#[repr(C)]` types. +/// +/// # Examples +/// +/// ``` +/// #![feature(offset_of)] +/// +/// use std::mem; +/// #[repr(C)] +/// struct FieldStruct { +/// first: u8, +/// second: u16, +/// third: u8 +/// } +/// +/// assert_eq!(mem::offset_of!(FieldStruct, first), 0); +/// assert_eq!(mem::offset_of!(FieldStruct, second), 2); +/// assert_eq!(mem::offset_of!(FieldStruct, third), 4); +/// +/// #[repr(C)] +/// struct NestedA { +/// b: NestedB +/// } +/// +/// #[repr(C)] +/// struct NestedB(u8); +/// +/// assert_eq!(mem::offset_of!(NestedA, b.0), 0); +/// ``` +#[unstable(feature = "offset_of", issue = "106655")] +#[rustc_builtin_macro] +#[cfg(not(bootstrap))] +pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) { + /* compiler built-in */ +} diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index b53a330fa56..87ae30619c6 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -81,8 +81,7 @@ impl Assume { // FIXME(jswrenn): This const op is not actually usable. Why? // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 #[unstable(feature = "transmutability", issue = "99571")] -#[rustc_const_unstable(feature = "transmutability", issue = "99571")] -impl const core::ops::Add for Assume { +impl core::ops::Add for Assume { type Output = Assume; fn add(self, other_assumptions: Assume) -> Assume { @@ -93,8 +92,7 @@ impl const core::ops::Add for Assume { // FIXME(jswrenn): This const op is not actually usable. Why? // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 #[unstable(feature = "transmutability", issue = "99571")] -#[rustc_const_unstable(feature = "transmutability", issue = "99571")] -impl const core::ops::Sub for Assume { +impl core::ops::Sub for Assume { type Output = Assume; fn sub(self, other_assumptions: Assume) -> Assume { diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 1bae4efe7d9..2ad0f1dc506 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -26,15 +26,14 @@ impl Error for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<Infallible> for TryFromIntError { +impl From<Infallible> for TryFromIntError { fn from(x: Infallible) -> TryFromIntError { match x {} } } #[unstable(feature = "never_type", issue = "35121")] -impl const From<!> for TryFromIntError { +impl From<!> for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From<Infallible> for TryFromIntError` above will keep working diff --git a/library/core/src/num/flt2dec/strategy/grisu.rs b/library/core/src/num/flt2dec/strategy/grisu.rs index ed3e0edaff2..b9f0d114c6a 100644 --- a/library/core/src/num/flt2dec/strategy/grisu.rs +++ b/library/core/src/num/flt2dec/strategy/grisu.rs @@ -487,6 +487,22 @@ pub fn format_exact_opt<'a>( let vint = (v.f >> e) as u32; let vfrac = v.f & ((1 << e) - 1); + let requested_digits = buf.len(); + + const POW10_UP_TO_9: [u32; 10] = + [1, 10, 100, 1000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000]; + + // We deviate from the original algorithm here and do some early checks to determine if we can satisfy requested_digits. + // If we determine that we can't, we exit early and avoid most of the heavy lifting that the algorithm otherwise does. + // + // When vfrac is zero, we can easily determine if vint can satisfy requested digits: + // If requested_digits >= 11, vint is not able to exhaust the count by itself since 10^(11 -1) > u32 max value >= vint. + // If vint < 10^(requested_digits - 1), vint cannot exhaust the count. + // Otherwise, vint might be able to exhaust the count and we need to execute the rest of the code. + if (vfrac == 0) && ((requested_digits >= 11) || (vint < POW10_UP_TO_9[requested_digits - 1])) { + return None; + } + // both old `v` and new `v` (scaled by `10^-k`) has an error of < 1 ulp (Theorem 5.1). // as we don't know the error is positive or negative, we use two approximations // spaced equally and have the maximal error of 2 ulps (same to the shortest case). diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index aec15212d7f..17715c9291f 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -785,7 +785,7 @@ macro_rules! int_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shl(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -833,7 +833,7 @@ macro_rules! int_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shr(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked absolute value. Computes `self.abs()`, returning `None` if @@ -2603,13 +2603,16 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(const_cmp)] pub const fn signum(self) -> Self { // Picking the right way to phrase this is complicated // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>) // so delegate it to `Ord` which is already producing -1/0/+1 // exactly like we need and can be the place to deal with the complexity. - self.cmp(&0) as _ + + // FIXME(const-hack): replace with cmp + if self < 0 { -1 } + else if self == 0 { 0 } + else { 1 } } /// Returns `true` if `self` is positive and `false` if the number is zero or diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 9b812bbfc23..fdd7be625ed 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -225,6 +225,23 @@ macro_rules! widening_impl { }; } +macro_rules! conv_rhs_for_unchecked_shift { + ($SelfT:ty, $x:expr) => {{ + #[inline] + fn conv(x: u32) -> $SelfT { + // FIXME(const-hack) replace with `.try_into().ok().unwrap_unchecked()`. + // SAFETY: Any legal shift amount must be losslessly representable in the self type. + unsafe { x.try_into().ok().unwrap_unchecked() } + } + #[inline] + const fn const_conv(x: u32) -> $SelfT { + x as _ + } + + intrinsics::const_eval_select(($x,), const_conv, conv) + }}; +} + impl i8 { int_impl! { Self = i8, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index ecfb735fad1..fc9b07d29e2 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,7 +1,7 @@ //! Definitions of integer that is known not to equal zero. use crate::fmt; -use crate::ops::{BitOr, BitOrAssign, Div, Rem}; +use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem}; use crate::str::FromStr; use super::from_str_radix; @@ -96,8 +96,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "from_nonzero", since = "1.31.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Ty> for $Int { + impl From<$Ty> for $Int { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { @@ -106,8 +105,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $Ty { + impl BitOr for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { @@ -118,8 +116,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Int> for $Ty { + impl BitOr<$Int> for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: $Int) -> Self::Output { @@ -131,8 +128,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Ty> for $Int { + impl BitOr<$Ty> for $Int { type Output = $Ty; #[inline] fn bitor(self, rhs: $Ty) -> Self::Output { @@ -144,8 +140,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $Ty { + impl BitOrAssign for $Ty { #[inline] fn bitor_assign(&mut self, rhs: Self) { *self = *self | rhs; @@ -153,8 +148,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$Int> for $Ty { + impl BitOrAssign<$Int> for $Ty { #[inline] fn bitor_assign(&mut self, rhs: $Int) { *self = *self | rhs; @@ -276,8 +270,7 @@ macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div<$Ty> for $Int { + impl Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -290,8 +283,7 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem<$Ty> for $Int { + impl Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] @@ -672,8 +664,7 @@ macro_rules! nonzero_signed_operations { /// assert_eq!(pos, pos.wrapping_abs()); /// assert_eq!(pos, neg.wrapping_abs()); /// assert_eq!(min, min.wrapping_abs()); - /// # // FIXME: add once Neg is implemented? - /// # // assert_eq!(max, (-max).wrapping_abs()); + /// assert_eq!(max, (-max).wrapping_abs()); /// # Some(()) /// # } /// ``` @@ -876,6 +867,20 @@ macro_rules! nonzero_signed_operations { unsafe { $Ty::new_unchecked(result) } } } + + #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] + impl Neg for $Ty { + type Output = $Ty; + + #[inline] + fn neg(self) -> $Ty { + // SAFETY: negation of nonzero cannot yield zero values. + unsafe { $Ty::new_unchecked(self.get().neg()) } + } + } + + forward_ref_unop! { impl Neg, neg for $Ty, + #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] } )+ } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 114deeea387..6f6b6dbb80b 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -939,7 +939,7 @@ macro_rules! uint_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shl(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -987,7 +987,7 @@ macro_rules! uint_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shr(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 5353d900e76..ed354a2e50b 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -87,8 +87,7 @@ impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> { macro_rules! sh_impl_signed { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -100,22 +99,20 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -127,26 +124,24 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } macro_rules! sh_impl_unsigned { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -154,22 +149,20 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -177,18 +170,17 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } @@ -217,8 +209,7 @@ sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } macro_rules! wrapping_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for Wrapping<$t> { + impl Add for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -226,32 +217,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_add(other.0)) } } - forward_ref_binop! { impl const Add, add for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for Wrapping<$t> { + impl AddAssign for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign<$t> for Wrapping<$t> { + impl AddAssign<$t> for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: $t) { *self = *self + Wrapping(other); } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for Wrapping<$t> { + impl Sub for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -259,32 +247,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_sub(other.0)) } } - forward_ref_binop! { impl const Sub, sub for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for Wrapping<$t> { + impl SubAssign for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign<$t> for Wrapping<$t> { + impl SubAssign<$t> for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: $t) { *self = *self - Wrapping(other); } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for Wrapping<$t> { + impl Mul for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -296,28 +281,25 @@ macro_rules! wrapping_impl { #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for Wrapping<$t> { + impl MulAssign for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign<$t> for Wrapping<$t> { + impl MulAssign<$t> for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: $t) { *self = *self * Wrapping(other); } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_div", since = "1.3.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for Wrapping<$t> { + impl Div for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -325,32 +307,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_div(other.0)) } } - forward_ref_binop! { impl const Div, div for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for Wrapping<$t> { + impl DivAssign for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign<$t> for Wrapping<$t> { + impl DivAssign<$t> for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: $t) { *self = *self / Wrapping(other); } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_impls", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for Wrapping<$t> { + impl Rem for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -358,32 +337,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_rem(other.0)) } } - forward_ref_binop! { impl const Rem, rem for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for Wrapping<$t> { + impl RemAssign for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign<$t> for Wrapping<$t> { + impl RemAssign<$t> for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: $t) { *self = *self % Wrapping(other); } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for Wrapping<$t> { + impl Not for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -391,12 +367,11 @@ macro_rules! wrapping_impl { Wrapping(!self.0) } } - forward_ref_unop! { impl const Not, not for Wrapping<$t>, + forward_ref_unop! { impl Not, not for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for Wrapping<$t> { + impl BitXor for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -404,32 +379,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 ^ other.0) } } - forward_ref_binop! { impl const BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for Wrapping<$t> { + impl BitXorAssign for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign<$t> for Wrapping<$t> { + impl BitXorAssign<$t> for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: $t) { *self = *self ^ Wrapping(other); } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for Wrapping<$t> { + impl BitOr for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -437,32 +409,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 | other.0) } } - forward_ref_binop! { impl const BitOr, bitor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for Wrapping<$t> { + impl BitOrAssign for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$t> for Wrapping<$t> { + impl BitOrAssign<$t> for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: $t) { *self = *self | Wrapping(other); } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for Wrapping<$t> { + impl BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -470,39 +439,36 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } - forward_ref_binop! { impl const BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for Wrapping<$t> { + impl BitAndAssign for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign<$t> for Wrapping<$t> { + impl BitAndAssign<$t> for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: $t) { *self = *self & Wrapping(other); } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_neg", since = "1.10.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for Wrapping<$t> { + impl Neg for Wrapping<$t> { type Output = Self; #[inline] fn neg(self) -> Self { Wrapping(0) - self } } - forward_ref_unop! { impl const Neg, neg for Wrapping<$t>, + forward_ref_unop! { impl Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } )*) diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index 0c7ee9630c6..1501dc4e38b 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -73,7 +73,6 @@ append_const_msg )] #[doc(alias = "+")] -#[const_trait] pub trait Add<Rhs = Self> { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -95,8 +94,7 @@ pub trait Add<Rhs = Self> { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for $t { + impl Add for $t { type Output = $t; #[inline] @@ -104,7 +102,7 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } - forward_ref_binop! { impl const Add, add for $t, $t } + forward_ref_binop! { impl Add, add for $t, $t } )*) } @@ -183,7 +181,6 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } append_const_msg )] #[doc(alias = "-")] -#[const_trait] pub trait Sub<Rhs = Self> { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -205,8 +202,7 @@ pub trait Sub<Rhs = Self> { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for $t { + impl Sub for $t { type Output = $t; #[inline] @@ -214,7 +210,7 @@ macro_rules! sub_impl { fn sub(self, other: $t) -> $t { self - other } } - forward_ref_binop! { impl const Sub, sub for $t, $t } + forward_ref_binop! { impl Sub, sub for $t, $t } )*) } @@ -314,7 +310,6 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } label = "no implementation for `{Self} * {Rhs}`" )] #[doc(alias = "*")] -#[const_trait] pub trait Mul<Rhs = Self> { /// The resulting type after applying the `*` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -336,8 +331,7 @@ pub trait Mul<Rhs = Self> { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for $t { + impl Mul for $t { type Output = $t; #[inline] @@ -345,7 +339,7 @@ macro_rules! mul_impl { fn mul(self, other: $t) -> $t { self * other } } - forward_ref_binop! { impl const Mul, mul for $t, $t } + forward_ref_binop! { impl Mul, mul for $t, $t } )*) } @@ -449,7 +443,6 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } label = "no implementation for `{Self} / {Rhs}`" )] #[doc(alias = "/")] -#[const_trait] pub trait Div<Rhs = Self> { /// The resulting type after applying the `/` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -477,15 +470,14 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*)*) } @@ -497,15 +489,14 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*) } @@ -553,7 +544,6 @@ div_impl_float! { f32 f64 } label = "no implementation for `{Self} % {Rhs}`" )] #[doc(alias = "%")] -#[const_trait] pub trait Rem<Rhs = Self> { /// The resulting type after applying the `%` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -581,15 +571,14 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*)*) } @@ -616,15 +605,14 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*) } @@ -669,7 +657,6 @@ rem_impl_float! { f32 f64 } #[lang = "neg"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "-")] -#[const_trait] pub trait Neg { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -692,8 +679,7 @@ pub trait Neg { macro_rules! neg_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for $t { + impl Neg for $t { type Output = $t; #[inline] @@ -701,7 +687,7 @@ macro_rules! neg_impl { fn neg(self) -> $t { -self } } - forward_ref_unop! { impl const Neg, neg for $t } + forward_ref_unop! { impl Neg, neg for $t } )*) } @@ -744,7 +730,6 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "+")] #[doc(alias = "+=")] -#[const_trait] pub trait AddAssign<Rhs = Self> { /// Performs the `+=` operation. /// @@ -762,14 +747,13 @@ pub trait AddAssign<Rhs = Self> { macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for $t { + impl AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn add_assign(&mut self, other: $t) { *self += other } } - forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } )+) } @@ -812,7 +796,6 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "-")] #[doc(alias = "-=")] -#[const_trait] pub trait SubAssign<Rhs = Self> { /// Performs the `-=` operation. /// @@ -830,14 +813,13 @@ pub trait SubAssign<Rhs = Self> { macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for $t { + impl SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn sub_assign(&mut self, other: $t) { *self -= other } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } )+) } @@ -871,7 +853,6 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "*")] #[doc(alias = "*=")] -#[const_trait] pub trait MulAssign<Rhs = Self> { /// Performs the `*=` operation. /// @@ -889,14 +870,13 @@ pub trait MulAssign<Rhs = Self> { macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for $t { + impl MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn mul_assign(&mut self, other: $t) { *self *= other } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } )+) } @@ -930,7 +910,6 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "/")] #[doc(alias = "/=")] -#[const_trait] pub trait DivAssign<Rhs = Self> { /// Performs the `/=` operation. /// @@ -948,13 +927,12 @@ pub trait DivAssign<Rhs = Self> { macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for $t { + impl DivAssign for $t { #[inline] fn div_assign(&mut self, other: $t) { *self /= other } } - forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } )+) } @@ -992,7 +970,6 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "%")] #[doc(alias = "%=")] -#[const_trait] pub trait RemAssign<Rhs = Self> { /// Performs the `%=` operation. /// @@ -1010,13 +987,12 @@ pub trait RemAssign<Rhs = Self> { macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for $t { + impl RemAssign for $t { #[inline] fn rem_assign(&mut self, other: $t) { *self %= other } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } )+) } diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 327009801d1..c70f4a3da2e 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -31,7 +31,6 @@ #[lang = "not"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "!")] -#[const_trait] pub trait Not { /// The resulting type after applying the `!` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -55,23 +54,21 @@ pub trait Not { macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for $t { + impl Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } - forward_ref_unop! { impl const Not, not for $t } + forward_ref_unop! { impl Not, not for $t } )*) } not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[stable(feature = "not_never", since = "1.60.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] -impl const Not for ! { +impl Not for ! { type Output = !; #[inline] @@ -144,7 +141,6 @@ impl const Not for ! { message = "no implementation for `{Self} & {Rhs}`", label = "no implementation for `{Self} & {Rhs}`" )] -#[const_trait] pub trait BitAnd<Rhs = Self> { /// The resulting type after applying the `&` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -168,15 +164,14 @@ pub trait BitAnd<Rhs = Self> { macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for $t { + impl BitAnd for $t { type Output = $t; #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } - forward_ref_binop! { impl const BitAnd, bitand for $t, $t } + forward_ref_binop! { impl BitAnd, bitand for $t, $t } )*) } @@ -246,7 +241,6 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} | {Rhs}`", label = "no implementation for `{Self} | {Rhs}`" )] -#[const_trait] pub trait BitOr<Rhs = Self> { /// The resulting type after applying the `|` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -270,15 +264,14 @@ pub trait BitOr<Rhs = Self> { macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $t { + impl BitOr for $t { type Output = $t; #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } - forward_ref_binop! { impl const BitOr, bitor for $t, $t } + forward_ref_binop! { impl BitOr, bitor for $t, $t } )*) } @@ -348,7 +341,6 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} ^ {Rhs}`", label = "no implementation for `{Self} ^ {Rhs}`" )] -#[const_trait] pub trait BitXor<Rhs = Self> { /// The resulting type after applying the `^` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -372,15 +364,14 @@ pub trait BitXor<Rhs = Self> { macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for $t { + impl BitXor for $t { type Output = $t; #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } - forward_ref_binop! { impl const BitXor, bitxor for $t, $t } + forward_ref_binop! { impl BitXor, bitxor for $t, $t } )*) } @@ -449,7 +440,6 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} << {Rhs}`", label = "no implementation for `{Self} << {Rhs}`" )] -#[const_trait] pub trait Shl<Rhs = Self> { /// The resulting type after applying the `<<` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -471,8 +461,7 @@ pub trait Shl<Rhs = Self> { macro_rules! shl_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for $t { + impl Shl<$f> for $t { type Output = $t; #[inline] @@ -482,7 +471,7 @@ macro_rules! shl_impl { } } - forward_ref_binop! { impl const Shl, shl for $t, $f } + forward_ref_binop! { impl Shl, shl for $t, $f } }; } @@ -569,7 +558,6 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } message = "no implementation for `{Self} >> {Rhs}`", label = "no implementation for `{Self} >> {Rhs}`" )] -#[const_trait] pub trait Shr<Rhs = Self> { /// The resulting type after applying the `>>` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -591,8 +579,7 @@ pub trait Shr<Rhs = Self> { macro_rules! shr_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for $t { + impl Shr<$f> for $t { type Output = $t; #[inline] @@ -602,7 +589,7 @@ macro_rules! shr_impl { } } - forward_ref_binop! { impl const Shr, shr for $t, $f } + forward_ref_binop! { impl Shr, shr for $t, $f } }; } @@ -698,7 +685,6 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } message = "no implementation for `{Self} &= {Rhs}`", label = "no implementation for `{Self} &= {Rhs}`" )] -#[const_trait] pub trait BitAndAssign<Rhs = Self> { /// Performs the `&=` operation. /// @@ -728,13 +714,12 @@ pub trait BitAndAssign<Rhs = Self> { macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for $t { + impl BitAndAssign for $t { #[inline] fn bitand_assign(&mut self, other: $t) { *self &= other } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t } )+) } @@ -771,7 +756,6 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} |= {Rhs}`", label = "no implementation for `{Self} |= {Rhs}`" )] -#[const_trait] pub trait BitOrAssign<Rhs = Self> { /// Performs the `|=` operation. /// @@ -801,13 +785,12 @@ pub trait BitOrAssign<Rhs = Self> { macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $t { + impl BitOrAssign for $t { #[inline] fn bitor_assign(&mut self, other: $t) { *self |= other } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t } )+) } @@ -844,7 +827,6 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} ^= {Rhs}`", label = "no implementation for `{Self} ^= {Rhs}`" )] -#[const_trait] pub trait BitXorAssign<Rhs = Self> { /// Performs the `^=` operation. /// @@ -874,13 +856,12 @@ pub trait BitXorAssign<Rhs = Self> { macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for $t { + impl BitXorAssign for $t { #[inline] fn bitxor_assign(&mut self, other: $t) { *self ^= other } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t } )+) } @@ -915,7 +896,6 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} <<= {Rhs}`", label = "no implementation for `{Self} <<= {Rhs}`" )] -#[const_trait] pub trait ShlAssign<Rhs = Self> { /// Performs the `<<=` operation. /// @@ -937,8 +917,7 @@ pub trait ShlAssign<Rhs = Self> { macro_rules! shl_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for $t { + impl ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shl_assign(&mut self, other: $f) { @@ -946,7 +925,7 @@ macro_rules! shl_assign_impl { } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f } }; } @@ -999,7 +978,6 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } message = "no implementation for `{Self} >>= {Rhs}`", label = "no implementation for `{Self} >>= {Rhs}`" )] -#[const_trait] pub trait ShrAssign<Rhs = Self> { /// Performs the `>>=` operation. /// @@ -1021,8 +999,7 @@ pub trait ShrAssign<Rhs = Self> { macro_rules! shr_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for $t { + impl ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shr_assign(&mut self, other: $f) { @@ -1030,7 +1007,7 @@ macro_rules! shr_assign_impl { } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f } }; } diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 117706fb4b2..e10c438ef43 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -97,8 +97,7 @@ pub enum ControlFlow<B, C = ()> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<B, C> const ops::Try for ControlFlow<B, C> { +impl<B, C> ops::Try for ControlFlow<B, C> { type Output = C; type Residual = ControlFlow<B, convert::Infallible>; @@ -117,8 +116,7 @@ impl<B, C> const ops::Try for ControlFlow<B, C> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<B, C> const ops::FromResidual for ControlFlow<B, C> { +impl<B, C> ops::FromResidual for ControlFlow<B, C> { #[inline] fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self { match residual { @@ -128,8 +126,7 @@ impl<B, C> const ops::FromResidual for ControlFlow<B, C> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<B, C> const ops::Residual<C> for ControlFlow<B, convert::Infallible> { +impl<B, C> ops::Residual<C> for ControlFlow<B, convert::Infallible> { type TryType = ControlFlow<B, C>; } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index c67867f4436..08c35b6dac3 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -61,7 +61,6 @@ #[doc(alias = "&*")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Deref"] -#[const_trait] pub trait Deref { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] @@ -77,8 +76,7 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for &T { +impl<T: ?Sized> Deref for &T { type Target = T; #[rustc_diagnostic_item = "noop_method_deref"] @@ -91,8 +89,7 @@ impl<T: ?Sized> const Deref for &T { impl<T: ?Sized> !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for &mut T { +impl<T: ?Sized> Deref for &mut T { type Target = T; fn deref(&self) -> &T { @@ -170,7 +167,6 @@ impl<T: ?Sized> const Deref for &mut T { #[lang = "deref_mut"] #[doc(alias = "*")] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait DerefMut: Deref { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index b7e1aee9d84..67c8245f0bf 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -254,10 +254,9 @@ mod impls { use crate::marker::Tuple; #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const Fn<A> for &F + impl<A: Tuple, F: ?Sized> Fn<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { extern "rust-call" fn call(&self, args: A) -> F::Output { (**self).call(args) @@ -265,10 +264,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnMut<A> for &F + impl<A: Tuple, F: ?Sized> FnMut<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (**self).call(args) @@ -276,10 +274,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F + impl<A: Tuple, F: ?Sized> FnOnce<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { type Output = F::Output; @@ -289,10 +286,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F + impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F where - F: ~const FnMut<A>, + F: FnMut<A>, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (*self).call_mut(args) @@ -300,10 +296,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F + impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F where - F: ~const FnMut<A>, + F: FnMut<A>, { type Output = F::Output; extern "rust-call" fn call_once(self, args: A) -> F::Output { diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs index 228efb0bc0a..1f1784ec9b2 100644 --- a/library/core/src/ops/index.rs +++ b/library/core/src/ops/index.rs @@ -55,10 +55,10 @@ #[doc(alias = "]")] #[doc(alias = "[")] #[doc(alias = "[]")] -#[const_trait] pub trait Index<Idx: ?Sized> { /// The returned type after indexing. #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_diagnostic_item = "IndexOutput"] type Output: ?Sized; /// Performs the indexing (`container[index]`) operation. @@ -164,8 +164,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] -#[const_trait] -pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> { +pub trait IndexMut<Idx: ?Sized>: Index<Idx> { /// Performs the mutable indexing (`container[index]`) operation. /// /// # Panics diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index b8ab2656473..ba5e6ddc752 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -96,7 +96,7 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { +impl<Idx: PartialOrd<Idx>> Range<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -116,11 +116,10 @@ impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -143,8 +142,7 @@ impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { /// assert!( (f32::NAN..5.0).is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { !(self.start < self.end) } } @@ -201,7 +199,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeFrom<Idx> { +impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -216,11 +214,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeFrom<Idx> { /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -283,7 +280,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeTo<Idx> { +impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -298,11 +295,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeTo<Idx> { /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -474,7 +470,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { +impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -505,11 +501,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { /// assert!(!r.contains(&3) && !r.contains(&5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -541,9 +536,8 @@ impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { /// assert!(r.is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] #[inline] - pub const fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { self.exhausted || !(self.start <= self.end) } } @@ -605,7 +599,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeToInclusive<Idx> { +impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -620,11 +614,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeToInclusive<Idx> { /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -765,7 +758,6 @@ impl<T: Clone> Bound<&T> { /// `RangeBounds` is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] -#[const_trait] pub trait RangeBounds<T: ?Sized> { /// Start index bound. /// @@ -818,8 +810,8 @@ pub trait RangeBounds<T: ?Sized> { #[stable(feature = "range_contains", since = "1.35.0")] fn contains<U>(&self, item: &U) -> bool where - T: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<T>, + T: PartialOrd<U>, + U: ?Sized + PartialOrd<T>, { (match self.start_bound() { Included(start) => start <= item, @@ -836,8 +828,7 @@ pub trait RangeBounds<T: ?Sized> { use self::Bound::{Excluded, Included, Unbounded}; #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T: ?Sized> const RangeBounds<T> for RangeFull { +impl<T: ?Sized> RangeBounds<T> for RangeFull { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -847,8 +838,7 @@ impl<T: ?Sized> const RangeBounds<T> for RangeFull { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeFrom<T> { +impl<T> RangeBounds<T> for RangeFrom<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -858,8 +848,7 @@ impl<T> const RangeBounds<T> for RangeFrom<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeTo<T> { +impl<T> RangeBounds<T> for RangeTo<T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -869,8 +858,7 @@ impl<T> const RangeBounds<T> for RangeTo<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for Range<T> { +impl<T> RangeBounds<T> for Range<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -880,8 +868,7 @@ impl<T> const RangeBounds<T> for Range<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeInclusive<T> { +impl<T> RangeBounds<T> for RangeInclusive<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -897,8 +884,7 @@ impl<T> const RangeBounds<T> for RangeInclusive<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeToInclusive<T> { +impl<T> RangeBounds<T> for RangeToInclusive<T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -908,8 +894,7 @@ impl<T> const RangeBounds<T> for RangeToInclusive<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for (Bound<T>, Bound<T>) { +impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) { fn start_bound(&self) -> Bound<&T> { match *self { (Included(ref start), _) => Included(start), @@ -928,8 +913,7 @@ impl<T> const RangeBounds<T> for (Bound<T>, Bound<T>) { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<'a, T: ?Sized + 'a> const RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { +impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { fn start_bound(&self) -> Bound<&T> { self.0 } @@ -940,8 +924,7 @@ impl<'a, T: ?Sized + 'a> const RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeFrom<&T> { +impl<T> RangeBounds<T> for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -951,8 +934,7 @@ impl<T> const RangeBounds<T> for RangeFrom<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeTo<&T> { +impl<T> RangeBounds<T> for RangeTo<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -962,8 +944,7 @@ impl<T> const RangeBounds<T> for RangeTo<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for Range<&T> { +impl<T> RangeBounds<T> for Range<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -973,8 +954,7 @@ impl<T> const RangeBounds<T> for Range<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeInclusive<&T> { +impl<T> RangeBounds<T> for RangeInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -984,8 +964,7 @@ impl<T> const RangeBounds<T> for RangeInclusive<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeToInclusive<&T> { +impl<T> RangeBounds<T> for RangeToInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index c254803fbf6..b4f69d0b213 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -128,8 +128,7 @@ use crate::ops::ControlFlow; )] #[doc(alias = "?")] #[lang = "Try"] -#[const_trait] -pub trait Try: ~const FromResidual { +pub trait Try: FromResidual { /// The type of the value produced by `?` when *not* short-circuiting. #[unstable(feature = "try_trait_v2", issue = "84277")] type Output; @@ -305,7 +304,6 @@ pub trait Try: ~const FromResidual { )] #[rustc_diagnostic_item = "FromResidual"] #[unstable(feature = "try_trait_v2", issue = "84277")] -#[const_trait] pub trait FromResidual<R = <Self as Try>::Residual> { /// Constructs the type from a compatible `Residual` type. /// @@ -358,11 +356,10 @@ where /// and in the other direction, /// `<Result<Infallible, E> as Residual<T>>::TryType = Result<T, E>`. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[const_trait] pub trait Residual<O> { /// The "return" type of this meta-function. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] - type TryType: ~const Try<Output = O, Residual = Self>; + type TryType: Try<Output = O, Residual = Self>; } #[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")] @@ -389,16 +386,14 @@ impl<T> NeverShortCircuit<T> { } #[inline] - pub fn wrap_mut_2<A, B>( - mut f: impl ~const FnMut(A, B) -> T, - ) -> impl ~const FnMut(A, B) -> Self { - const move |a, b| NeverShortCircuit(f(a, b)) + pub fn wrap_mut_2<A, B>(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { + move |a, b| NeverShortCircuit(f(a, b)) } } pub(crate) enum NeverShortCircuitResidual {} -impl<T> const Try for NeverShortCircuit<T> { +impl<T> Try for NeverShortCircuit<T> { type Output = T; type Residual = NeverShortCircuitResidual; @@ -413,14 +408,14 @@ impl<T> const Try for NeverShortCircuit<T> { } } -impl<T> const FromResidual for NeverShortCircuit<T> { +impl<T> FromResidual for NeverShortCircuit<T> { #[inline] fn from_residual(never: NeverShortCircuitResidual) -> Self { match never {} } } -impl<T> const Residual<T> for NeverShortCircuitResidual { +impl<T> Residual<T> for NeverShortCircuitResidual { type TryType = NeverShortCircuit<T>; } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 057053297cd..82e7e69215e 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -547,7 +547,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; -use crate::marker::Destruct; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ @@ -967,11 +966,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Some(x) => x, None => default, @@ -989,11 +984,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_else<F>(self, f: F) -> T + pub fn unwrap_or_else<F>(self, f: F) -> T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { match self { Some(x) => x, @@ -1022,10 +1015,9 @@ impl<T> Option<T> { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_default(self) -> T + pub fn unwrap_or_default(self) -> T where - T: ~const Default, + T: Default, { match self { Some(x) => x, @@ -1089,11 +1081,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map<U, F>(self, f: F) -> Option<U> + pub fn map<U, F>(self, f: F) -> Option<U> where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(x) => Some(f(x)), @@ -1118,11 +1108,9 @@ impl<T> Option<T> { /// ``` #[inline] #[unstable(feature = "result_option_inspect", issue = "91345")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn inspect<F>(self, f: F) -> Self + pub fn inspect<F>(self, f: F) -> Self where - F: ~const FnOnce(&T), - F: ~const Destruct, + F: FnOnce(&T), { if let Some(ref x) = self { f(x); @@ -1151,12 +1139,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or<U, F>(self, default: U, f: F) -> U + pub fn map_or<U, F>(self, default: U, f: F) -> U where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1180,13 +1165,10 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U + pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U where - D: ~const FnOnce() -> U, - D: ~const Destruct, - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + D: FnOnce() -> U, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1217,11 +1199,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or<E>(self, err: E) -> Result<T, E> - where - E: ~const Destruct, - { + pub fn ok_or<E>(self, err: E) -> Result<T, E> { match self { Some(v) => Ok(v), None => Err(err), @@ -1246,11 +1224,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E> + pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E> where - F: ~const FnOnce() -> E, - F: ~const Destruct, + F: FnOnce() -> E, { match self { Some(v) => Ok(v), @@ -1274,10 +1250,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref(&self) -> Option<&T::Target> + pub fn as_deref(&self) -> Option<&T::Target> where - T: ~const Deref, + T: Deref, { match self.as_ref() { Some(t) => Some(t.deref()), @@ -1301,10 +1276,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> + pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> where - T: ~const DerefMut, + T: DerefMut, { match self.as_mut() { Some(t) => Some(t.deref_mut()), @@ -1388,12 +1362,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and<U>(self, optb: Option<U>) -> Option<U> - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn and<U>(self, optb: Option<U>) -> Option<U> { match self { Some(_) => optb, None => None, @@ -1430,11 +1399,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and_then<U, F>(self, f: F) -> Option<U> + pub fn and_then<U, F>(self, f: F) -> Option<U> where - F: ~const FnOnce(T) -> Option<U>, - F: ~const Destruct, + F: FnOnce(T) -> Option<U>, { match self { Some(x) => f(x), @@ -1468,12 +1435,9 @@ impl<T> Option<T> { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn filter<P>(self, predicate: P) -> Self + pub fn filter<P>(self, predicate: P) -> Self where - T: ~const Destruct, - P: ~const FnOnce(&T) -> bool, - P: ~const Destruct, + P: FnOnce(&T) -> bool, { if let Some(x) = self { if predicate(&x) { @@ -1512,11 +1476,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or(self, optb: Option<T>) -> Option<T> - where - T: ~const Destruct, - { + pub fn or(self, optb: Option<T>) -> Option<T> { match self { Some(x) => Some(x), None => optb, @@ -1538,11 +1498,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or_else<F>(self, f: F) -> Option<T> + pub fn or_else<F>(self, f: F) -> Option<T> where - F: ~const FnOnce() -> Option<T>, - F: ~const Destruct, + F: FnOnce() -> Option<T>, { match self { Some(x) => Some(x), @@ -1573,11 +1531,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn xor(self, optb: Option<T>) -> Option<T> - where - T: ~const Destruct, - { + pub fn xor(self, optb: Option<T>) -> Option<T> { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1611,11 +1565,7 @@ impl<T> Option<T> { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn insert(&mut self, value: T) -> &mut T { *self = Some(value); // SAFETY: the code above just filled the option @@ -1644,11 +1594,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn get_or_insert(&mut self, value: T) -> &mut T { if let None = *self { *self = Some(value); } @@ -1679,12 +1625,11 @@ impl<T> Option<T> { /// ``` #[inline] #[unstable(feature = "option_get_or_insert_default", issue = "82901")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_default(&mut self) -> &mut T + pub fn get_or_insert_default(&mut self) -> &mut T where - T: ~const Default, + T: Default, { - const fn default<T: ~const Default>() -> T { + fn default<T: Default>() -> T { T::default() } @@ -1710,11 +1655,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T + pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { if let None = *self { // the compiler isn't smart enough to know that we are not dropping a `T` @@ -1794,12 +1737,7 @@ impl<T> Option<T> { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)> - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn zip<U>(self, other: Option<U>) -> Option<(T, U)> { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1835,13 +1773,9 @@ impl<T> Option<T> { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R> + pub fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R> where - F: ~const FnOnce(T, U) -> R, - F: ~const Destruct, - T: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T, U) -> R, { match (self, other) { (Some(a), Some(b)) => Some(f(a, b)), @@ -1867,12 +1801,7 @@ impl<T, U> Option<(T, U)> { /// ``` #[inline] #[stable(feature = "unzip_option", since = "1.66.0")] - #[rustc_const_unstable(feature = "const_option", issue = "67441")] - pub const fn unzip(self) -> (Option<T>, Option<U>) - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn unzip(self) -> (Option<T>, Option<U>) { match self { Some((a, b)) => (Some(a), Some(b)), None => (None, None), @@ -1922,10 +1851,9 @@ impl<T> Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option<T> + pub fn cloned(self) -> Option<T> where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -1974,10 +1902,9 @@ impl<T> Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option<T> + pub fn cloned(self) -> Option<T> where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -2030,10 +1957,9 @@ const fn expect_failed(msg: &str) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T> const Clone for Option<T> +impl<T> Clone for Option<T> where - T: ~const Clone + ~const Destruct, + T: Clone, { #[inline] fn clone(&self) -> Self { @@ -2053,8 +1979,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Option<T> { +impl<T> Default for Option<T> { /// Returns [`None`][Option::None]. /// /// # Examples @@ -2114,8 +2039,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> { } #[stable(since = "1.12.0", feature = "option_from")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Option<T> { +impl<T> From<T> for Option<T> { /// Moves `val` into a new [`Some`]. /// /// # Examples @@ -2131,8 +2055,7 @@ impl<T> const From<T> for Option<T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a Option<T>> for Option<&'a T> { +impl<'a, T> From<&'a Option<T>> for Option<&'a T> { /// Converts from `&Option<T>` to `Option<&T>`. /// /// # Examples @@ -2159,8 +2082,7 @@ impl<'a, T> const From<&'a Option<T>> for Option<&'a T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a mut Option<T>> for Option<&'a mut T> { +impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> { /// Converts from `&mut Option<T>` to `Option<&mut T>` /// /// # Examples @@ -2507,8 +2429,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const ops::Try for Option<T> { +impl<T> ops::Try for Option<T> { type Output = T; type Residual = Option<convert::Infallible>; @@ -2527,8 +2448,7 @@ impl<T> const ops::Try for Option<T> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const ops::FromResidual for Option<T> { +impl<T> ops::FromResidual for Option<T> { #[inline] fn from_residual(residual: Option<convert::Infallible>) -> Self { match residual { @@ -2546,8 +2466,7 @@ impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<T> const ops::Residual<T> for Option<convert::Infallible> { +impl<T> ops::Residual<T> for Option<convert::Infallible> { type TryType = Option<T>; } diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index efe6d4183e3..bbf7199fffa 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -9,8 +9,7 @@ use crate::{cmp, fmt, hash, mem, num}; /// Note that particularly large alignments, while representable in this type, /// are likely not to be supported by actual allocators and linkers. #[unstable(feature = "ptr_alignment_type", issue = "102070")] -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(transparent)] pub struct Alignment(AlignmentEnum); @@ -170,7 +169,7 @@ impl From<Alignment> for usize { #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl const cmp::Ord for Alignment { +impl cmp::Ord for Alignment { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { self.as_nonzero().get().cmp(&other.as_nonzero().get()) @@ -179,7 +178,7 @@ impl const cmp::Ord for Alignment { #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl const cmp::PartialOrd for Alignment { +impl cmp::PartialOrd for Alignment { #[inline] fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) @@ -201,8 +200,7 @@ type AlignmentEnum = AlignmentEnum32; #[cfg(target_pointer_width = "64")] type AlignmentEnum = AlignmentEnum64; -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u16)] enum AlignmentEnum16 { _Align1Shl0 = 1 << 0, @@ -223,8 +221,7 @@ enum AlignmentEnum16 { _Align1Shl15 = 1 << 15, } -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u32)] enum AlignmentEnum32 { _Align1Shl0 = 1 << 0, @@ -261,8 +258,7 @@ enum AlignmentEnum32 { _Align1Shl31 = 1 << 31, } -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u64)] enum AlignmentEnum64 { _Align1Shl0 = 1 << 0, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 839afc57f85..603bd887333 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -132,8 +132,8 @@ impl<T: ?Sized> *const T { /// ``` #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( - since = "1.67", - note = "replaced by the `exposed_addr` method, or update your code \ + since = "1.67.0", + note = "replaced by the `expose_addr` method, or update your code \ to follow the strict provenance rules using its APIs" )] #[inline(always)] @@ -161,7 +161,7 @@ impl<T: ?Sized> *const T { /// ``` #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( - since = "1.67", + since = "1.67.0", note = "replaced by the `ptr::from_exposed_addr` function, or update \ your code to follow the strict provenance rules using its APIs" )] @@ -1650,11 +1650,10 @@ impl<T> *const [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output + pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked(self) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 818f1a919d0..555d58fad84 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1764,7 +1764,12 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz // miracles, given the situations this case has to deal with. // SAFETY: a is power-of-two hence non-zero. stride == 0 case is handled above. - let gcdpow = unsafe { cttz_nonzero(stride).min(cttz_nonzero(a)) }; + // FIXME(const-hack) replace with min + let gcdpow = unsafe { + let x = cttz_nonzero(stride); + let y = cttz_nonzero(a); + if x < y { x } else { y } + }; // SAFETY: gcdpow has an upper-bound that’s at most the number of bits in a usize. let gcd = unsafe { unchecked_shl(1usize, gcdpow) }; // SAFETY: gcd is always greater or equal to 1. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index ece5244e9a9..24b66c549a6 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -138,8 +138,8 @@ impl<T: ?Sized> *mut T { /// ``` #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( - since = "1.67", - note = "replaced by the `exposed_addr` method, or update your code \ + since = "1.67.0", + note = "replaced by the `expose_addr` method, or update your code \ to follow the strict provenance rules using its APIs" )] #[inline(always)] @@ -167,7 +167,7 @@ impl<T: ?Sized> *mut T { /// ``` #[unstable(feature = "ptr_to_from_bits", issue = "91126")] #[deprecated( - since = "1.67", + since = "1.67.0", note = "replaced by the `ptr::from_exposed_addr_mut` function, or \ update your code to follow the strict provenance rules using its APIs" )] @@ -2036,11 +2036,10 @@ impl<T> *mut [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline(always)] - pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output + pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked_mut(self) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index a46804c186c..506d891d989 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -676,11 +676,10 @@ impl<T> NonNull<[T]> { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output> + pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output> where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. // As a consequence, the resulting pointer cannot be null. @@ -689,8 +688,7 @@ impl<T> NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T: ?Sized> const Clone for NonNull<T> { +impl<T: ?Sized> Clone for NonNull<T> { #[inline(always)] fn clone(&self) -> Self { *self @@ -756,8 +754,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<Unique<T>> for NonNull<T> { +impl<T: ?Sized> From<Unique<T>> for NonNull<T> { #[inline] fn from(unique: Unique<T>) -> Self { // SAFETY: A Unique pointer cannot be null, so the conditions for @@ -767,8 +764,7 @@ impl<T: ?Sized> const From<Unique<T>> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<&mut T> for NonNull<T> { +impl<T: ?Sized> From<&mut T> for NonNull<T> { /// Converts a `&mut T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. @@ -780,8 +776,7 @@ impl<T: ?Sized> const From<&mut T> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<&T> for NonNull<T> { +impl<T: ?Sized> From<&T> for NonNull<T> { /// Converts a `&T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 64616142b41..a853f15edb7 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -70,7 +70,8 @@ impl<T: Sized> Unique<T> { #[must_use] #[inline] pub const fn dangling() -> Self { - Self::from(NonNull::dangling()) + // FIXME(const-hack) replace with `From` + Unique { pointer: NonNull::dangling(), _marker: PhantomData } } } @@ -134,13 +135,14 @@ impl<T: ?Sized> Unique<T> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub const fn cast<U>(self) -> Unique<U> { - Unique::from(self.pointer.cast()) + // FIXME(const-hack): replace with `From` + // SAFETY: is `NonNull` + unsafe { Unique::new_unchecked(self.pointer.cast().as_ptr()) } } } #[unstable(feature = "ptr_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T: ?Sized> const Clone for Unique<T> { +impl<T: ?Sized> Clone for Unique<T> { #[inline] fn clone(&self) -> Self { *self @@ -171,7 +173,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> const From<&mut T> for Unique<T> { +impl<T: ?Sized> From<&mut T> for Unique<T> { /// Converts a `&mut T` to a `Unique<T>`. /// /// This conversion is infallible since references cannot be null. @@ -182,7 +184,7 @@ impl<T: ?Sized> const From<&mut T> for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> const From<NonNull<T>> for Unique<T> { +impl<T: ?Sized> From<NonNull<T>> for Unique<T> { /// Converts a `NonNull<T>` to a `Unique<T>`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 241602c0e18..28cb02989ec 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -489,7 +489,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; -use crate::marker::Destruct; use crate::ops::{self, ControlFlow, Deref, DerefMut}; use crate::{convert, fmt, hint}; @@ -629,16 +628,10 @@ impl<T, E> Result<T, E> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn ok(self) -> Option<T> - where - E: ~const Destruct, - { + pub fn ok(self) -> Option<T> { match self { Ok(x) => Some(x), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(x) => None, + Err(_) => None, } } @@ -658,15 +651,9 @@ impl<T, E> Result<T, E> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn err(self) -> Option<E> - where - T: ~const Destruct, - { + pub fn err(self) -> Option<E> { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => None, + Ok(_) => None, Err(x) => Some(x), } } @@ -1287,18 +1274,10 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.and(y), Ok("different result type")); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E> - where - T: ~const Destruct, - U: ~const Destruct, - E: ~const Destruct, - { + pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => res, + Ok(_) => res, Err(e) => Err(e), } } @@ -1370,19 +1349,11 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.or(y), Ok(2)); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F> - where - T: ~const Destruct, - E: ~const Destruct, - F: ~const Destruct, - { + pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> { match self { Ok(v) => Ok(v), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => res, + Err(_) => res, } } @@ -1430,18 +1401,11 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - E: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Ok(t) => t, - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => default, + Err(_) => default, } } @@ -1704,11 +1668,10 @@ fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T, E> const Clone for Result<T, E> +impl<T, E> Clone for Result<T, E> where - T: ~const Clone + ~const Destruct, - E: ~const Clone + ~const Destruct, + T: Clone, + E: Clone, { #[inline] fn clone(&self) -> Self { @@ -1971,8 +1934,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, E> const ops::Try for Result<T, E> { +impl<T, E> ops::Try for Result<T, E> { type Output = T; type Residual = Result<convert::Infallible, E>; @@ -1991,10 +1953,7 @@ impl<T, E> const ops::Try for Result<T, E> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, E, F: ~const From<E>> const ops::FromResidual<Result<convert::Infallible, E>> - for Result<T, F> -{ +impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Result<T, F> { #[inline] #[track_caller] fn from_residual(residual: Result<convert::Infallible, E>) -> Self { @@ -2013,7 +1972,6 @@ impl<T, E, F: From<E>> ops::FromResidual<ops::Yeet<E>> for Result<T, F> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<T, E> const ops::Residual<T> for Result<convert::Infallible, E> { +impl<T, E> ops::Residual<T> for Result<convert::Infallible, E> { type TryType = Result<T, E>; } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 3539353240a..6ef9f9c95e8 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -7,10 +7,9 @@ use crate::ops; use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I> const ops::Index<I> for [T] +impl<T, I> ops::Index<I> for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { type Output = I::Output; @@ -21,10 +20,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I> const ops::IndexMut<I> for [T] +impl<T, I> ops::IndexMut<I> for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -162,7 +160,6 @@ mod private_slice_index { message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" )] -#[const_trait] pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] @@ -211,7 +208,7 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for usize { +unsafe impl<T> SliceIndex<[T]> for usize { type Output = T; #[inline] @@ -271,7 +268,7 @@ unsafe impl<T> const SliceIndex<[T]> for usize { /// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here /// than there are for a general `Range<usize>` (which might be `100..3`). #[rustc_const_unstable(feature = "const_index_range_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange { +unsafe impl<T> SliceIndex<[T]> for ops::IndexRange { type Output = [T]; #[inline] @@ -347,7 +344,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { type Output = [T]; #[inline] @@ -428,7 +425,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { type Output = [T]; #[inline] @@ -466,7 +463,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> { type Output = [T]; #[inline] @@ -512,7 +509,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull { +unsafe impl<T> SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -548,7 +545,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull { #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { type Output = [T]; #[inline] @@ -592,7 +589,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> { #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> { type Output = [T]; #[inline] diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 88b84bd1352..b2dd92a2379 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -685,7 +685,7 @@ where None } else { self.finished = true; - Some(mem::replace(&mut self.v, &mut [])) + Some(mem::take(&mut self.v)) } } } @@ -749,7 +749,7 @@ where match idx_opt { None => self.finish(), Some(idx) => { - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = head; Some(&mut tail[1..]) @@ -830,7 +830,7 @@ where if idx == self.v.len() { self.finished = true; } - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = tail; Some(head) @@ -876,7 +876,7 @@ where if idx == 0 { self.finished = true; } - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = head; Some(tail) diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b73e35f1e91..b1ca872b845 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -73,7 +73,7 @@ macro_rules! iterator { // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T { - if mem::size_of::<T>() == 0 { + if T::IS_ZST { zst_shrink!(self, offset); self.ptr.as_ptr() } else { diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 98c8349eb60..3a8b59d727b 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -1,7 +1,6 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch -use crate::cmp; use crate::mem; const LO_USIZE: usize = usize::repeat_u8(0x01); @@ -83,8 +82,12 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> { let mut offset = ptr.align_offset(USIZE_BYTES); if offset > 0 { - offset = cmp::min(offset, len); - if let Some(index) = memchr_naive(x, &text[..offset]) { + // FIXME(const-hack, fee1-dead): replace with min + offset = if offset < len { offset } else { len }; + // FIXME(const-hack, fee1-dead): replace with range slicing + // SAFETY: offset is within bounds + let slice = unsafe { super::from_raw_parts(text.as_ptr(), offset) }; + if let Some(index) = memchr_naive(x, slice) { return Some(index); } } @@ -110,7 +113,10 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> { // Find the byte after the point the body loop stopped. // FIXME(const-hack): Use `?` instead. - if let Some(i) = memchr_naive(x, &text[offset..]) { Some(offset + i) } else { None } + // FIXME(const-hack, fee1-dead): use range slicing + // SAFETY: offset is within bounds + let slice = unsafe { super::from_raw_parts(text.as_ptr().add(offset), text.len() - offset) }; + if let Some(i) = memchr_naive(x, slice) { Some(offset + i) } else { None } } /// Returns the last index matching the byte `x` in `text`. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f541808a618..d12809357a8 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -333,12 +333,11 @@ impl<T> [T] { /// assert_eq!(None, v.get(0..4)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get<I>(&self, index: I) -> Option<&I::Output> + pub fn get<I>(&self, index: I) -> Option<&I::Output> where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { index.get(self) } @@ -359,12 +358,11 @@ impl<T> [T] { /// assert_eq!(x, &[0, 42, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output> + pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output> where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { index.get_mut(self) } @@ -392,12 +390,11 @@ impl<T> [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output + pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. @@ -430,12 +427,11 @@ impl<T> [T] { /// assert_eq!(x, &[1, 13, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output + pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. @@ -678,9 +674,8 @@ impl<T> [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_reverse", issue = "100784")] #[inline] - pub const fn reverse(&mut self) { + pub fn reverse(&mut self) { let half_len = self.len() / 2; let Range { start, end } = self.as_mut_ptr_range(); @@ -703,7 +698,7 @@ impl<T> [T] { revswap(front_half, back_half, half_len); #[inline] - const fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) { + fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) { debug_assert!(a.len() == n); debug_assert!(b.len() == n); @@ -4404,8 +4399,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for &[T] { +impl<T> Default for &[T] { /// Creates an empty slice. fn default() -> Self { &[] @@ -4413,8 +4407,7 @@ impl<T> const Default for &[T] { } #[stable(feature = "mut_slice_default", since = "1.5.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for &mut [T] { +impl<T> Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { &mut [] diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 07fd96f9295..e6e3b55efa9 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -1456,7 +1456,6 @@ pub struct TimSortRun { /// Takes a range as denoted by start and end, that is already sorted and extends it to the right if /// necessary with sorts optimized for smaller ranges such as insertion sort. -#[cfg(not(no_global_oom_handling))] fn provide_sorted_batch<T, F>(v: &mut [T], start: usize, mut end: usize, is_less: &mut F) -> usize where F: FnMut(&T, &T) -> bool, diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 04169429949..a13107fd0de 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -206,9 +206,8 @@ impl str { /// ``` #[must_use] #[stable(feature = "is_char_boundary", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")] #[inline] - pub const fn is_char_boundary(&self, index: usize) -> bool { + pub fn is_char_boundary(&self, index: usize) -> bool { // 0 is always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. @@ -436,9 +435,8 @@ impl str { /// assert!(v.get(..42).is_none()); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> { + pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> { i.get(self) } @@ -469,9 +467,8 @@ impl str { /// assert_eq!("HEllo", v); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> { + pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> { i.get_mut(self) } @@ -502,9 +499,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked<I: ~const SliceIndex<str>>(&self, i: I) -> &I::Output { + pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -538,12 +534,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut<I: ~const SliceIndex<str>>( - &mut self, - i: I, - ) -> &mut I::Output { + pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -2582,8 +2574,7 @@ impl AsRef<[u8]> for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for &str { +impl Default for &str { /// Creates an empty str #[inline] fn default() -> Self { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 41c097b55ee..1d52335f28e 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -50,10 +50,9 @@ impl PartialOrd for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<I> const ops::Index<I> for str +impl<I> ops::Index<I> for str where - I: ~const SliceIndex<str>, + I: SliceIndex<str>, { type Output = I::Output; @@ -64,10 +63,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<I> const ops::IndexMut<I> for str +impl<I> ops::IndexMut<I> for str where - I: ~const SliceIndex<str>, + I: SliceIndex<str>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -96,7 +94,7 @@ const fn str_index_overflow_fail() -> ! { /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeFull { +unsafe impl SliceIndex<str> for ops::RangeFull { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -161,7 +159,7 @@ unsafe impl const SliceIndex<str> for ops::RangeFull { /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::Range<usize> { +unsafe impl SliceIndex<str> for ops::Range<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -271,7 +269,7 @@ unsafe impl const SliceIndex<str> for ops::Range<usize> { /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeTo<usize> { +unsafe impl SliceIndex<str> for ops::RangeTo<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -340,7 +338,7 @@ unsafe impl const SliceIndex<str> for ops::RangeTo<usize> { /// a character (as defined by `is_char_boundary`), or if `begin > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> { +unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -412,7 +410,7 @@ unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> { /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> { +unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -464,7 +462,7 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> { /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> { +unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 2f6b1c74da0..b0ab634905f 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -147,8 +147,7 @@ pub struct AtomicBool { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for AtomicBool { +impl Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. #[inline] fn default() -> Self { @@ -179,8 +178,7 @@ pub struct AtomicPtr<T> { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for AtomicPtr<T> { +impl<T> Default for AtomicPtr<T> { /// Creates a null `AtomicPtr<T>`. fn default() -> AtomicPtr<T> { AtomicPtr::new(crate::ptr::null_mut()) @@ -1916,8 +1914,7 @@ impl<T> AtomicPtr<T> { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<bool> for AtomicBool { +impl From<bool> for AtomicBool { /// Converts a `bool` into an `AtomicBool`. /// /// # Examples @@ -1935,8 +1932,7 @@ impl const From<bool> for AtomicBool { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<*mut T> for AtomicPtr<T> { +impl<T> From<*mut T> for AtomicPtr<T> { /// Converts a `*mut T` into an `AtomicPtr<T>`. #[inline] fn from(p: *mut T) -> Self { @@ -2002,8 +1998,7 @@ macro_rules! atomic_int { pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $atomic_type { + impl Default for $atomic_type { #[inline] fn default() -> Self { Self::new(Default::default()) @@ -2011,8 +2006,7 @@ macro_rules! atomic_int { } #[$stable_from] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$int_type> for $atomic_type { + impl From<$int_type> for $atomic_type { #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")] #[inline] fn from(v: $int_type) -> Self { Self::new(v) } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index af5bf441bb2..168516263f1 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -247,8 +247,7 @@ impl<T, E> Poll<Option<Result<T, E>>> { } #[stable(feature = "futures_api", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Poll<T> { +impl<T> From<T> for Poll<T> { /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`. /// /// # Example diff --git a/library/core/src/time.rs b/library/core/src/time.rs index ba1cb6efa04..b08d5782ab6 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -735,8 +735,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f64(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { match Duration::try_from_secs_f64(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -773,8 +772,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f32(secs: f32) -> Duration { + pub fn from_secs_f32(secs: f32) -> Duration { match Duration::try_from_secs_f32(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -798,8 +796,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f64(self, rhs: f64) -> Duration { + pub fn mul_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(rhs * self.as_secs_f64()) } @@ -820,8 +817,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f32(self, rhs: f32) -> Duration { + pub fn mul_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(rhs * self.as_secs_f32()) } @@ -842,8 +838,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f64(self, rhs: f64) -> Duration { + pub fn div_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(self.as_secs_f64() / rhs) } @@ -866,8 +861,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f32(self, rhs: f32) -> Duration { + pub fn div_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(self.as_secs_f32() / rhs) } @@ -1178,7 +1172,7 @@ impl fmt::Debug for Duration { emit_without_padding(f) } else { // We need to add padding. Use the `Formatter::padding` helper function. - let default_align = crate::fmt::rt::v1::Alignment::Left; + let default_align = fmt::Alignment::Left; let post_padding = f.padding(requested_w - actual_w, default_align)?; emit_without_padding(f)?; post_padding.write(f) @@ -1402,9 +1396,8 @@ impl Duration { /// assert_eq!(res, Ok(Duration::new(1, 2_929_688))); /// ``` #[stable(feature = "duration_checked_float", since = "1.66.0")] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] #[inline] - pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> { + pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> { try_from_secs!( secs = secs, mantissa_bits = 23, @@ -1479,9 +1472,8 @@ impl Duration { /// assert_eq!(res, Ok(Duration::new(1, 2_929_688))); /// ``` #[stable(feature = "duration_checked_float", since = "1.66.0")] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] #[inline] - pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> { + pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> { try_from_secs!( secs = secs, mantissa_bits = 52, diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 0620e7173bc..75d7a3f4005 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -22,8 +22,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const PartialEq),+> const PartialEq for ($($T,)+) + impl<$($T: PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -50,8 +49,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const PartialOrd + ~const PartialEq),+> const PartialOrd for ($($T,)+) + impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -81,8 +79,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const Ord),+> const Ord for ($($T,)+) + impl<$($T: Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -96,8 +93,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<$($T: ~const Default),+> const Default for ($($T,)+) { + impl<$($T: Default),+> Default for ($($T,)+) { #[inline] fn default() -> ($($T,)+) { ($({ let x: $T = Default::default(); x},)+) diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 94b0310603b..a67a842d340 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -306,9 +306,11 @@ fn atomic_compare_exchange() { ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); } +/* FIXME(#110395) #[test] fn atomic_const_from() { const _ATOMIC_U8: AtomicU8 = AtomicU8::from(1); const _ATOMIC_BOOL: AtomicBool = AtomicBool::from(true); const _ATOMIC_PTR: AtomicPtr<u32> = AtomicPtr::from(core::ptr::null_mut()); } +*/ diff --git a/library/core/tests/bool.rs b/library/core/tests/bool.rs index 4819ce911d6..47f6459915b 100644 --- a/library/core/tests/bool.rs +++ b/library/core/tests/bool.rs @@ -89,6 +89,7 @@ fn test_bool_to_option() { assert_eq!(false.then(|| 0), None); assert_eq!(true.then(|| 0), Some(0)); + /* FIXME(#110395) const fn zero() -> i32 { 0 } @@ -102,4 +103,5 @@ fn test_bool_to_option() { assert_eq!(B, Some(0)); assert_eq!(C, None); assert_eq!(D, Some(0)); + */ } diff --git a/library/core/tests/cell.rs b/library/core/tests/cell.rs index 7b77b2134cc..e084f867943 100644 --- a/library/core/tests/cell.rs +++ b/library/core/tests/cell.rs @@ -468,6 +468,7 @@ fn const_cells() { const CELL: Cell<i32> = Cell::new(3); const _: i32 = CELL.into_inner(); +/* FIXME(#110395) const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3); const _: i32 = UNSAFE_CELL.into_inner(); @@ -476,4 +477,5 @@ fn const_cells() { const CELL_FROM: Cell<i32> = Cell::from(3); const _: i32 = CELL.into_inner(); +*/ } diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs index ac0b2ca168b..85ba51c9228 100644 --- a/library/core/tests/char.rs +++ b/library/core/tests/char.rs @@ -21,6 +21,7 @@ fn test_convert() { assert!(char::try_from(0xFFFF_FFFF_u32).is_err()); } +/* FIXME(#110395) #[test] const fn test_convert_const() { assert!(u32::from('a') == 0x61); @@ -30,6 +31,7 @@ const fn test_convert_const() { assert!(char::from(b'a') == 'a'); assert!(char::from(b'\xFF') == '\u{FF}'); } +*/ #[test] fn test_from_str() { diff --git a/library/core/tests/cmp.rs b/library/core/tests/cmp.rs index 8d0e59d5a49..72fdd490da1 100644 --- a/library/core/tests/cmp.rs +++ b/library/core/tests/cmp.rs @@ -217,18 +217,19 @@ fn cmp_default() { assert_eq!(Fool(false), Fool(true)); } +/* FIXME(#110395) mod const_cmp { use super::*; struct S(i32); - impl const PartialEq for S { + impl PartialEq for S { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } - impl const PartialOrd for S { + impl PartialOrd for S { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let ret = match (self.0, other.0) { (a, b) if a > b => Ordering::Greater, @@ -248,3 +249,4 @@ mod const_cmp { const _: () = assert!(S(0) < S(1)); const _: () = assert!(S(1) > S(0)); } +*/ diff --git a/library/core/tests/convert.rs b/library/core/tests/convert.rs index f1048f4cf09..f76dd277884 100644 --- a/library/core/tests/convert.rs +++ b/library/core/tests/convert.rs @@ -1,3 +1,4 @@ +/* FIXME(#110395) #[test] fn convert() { const fn from(x: i32) -> i32 { @@ -14,3 +15,4 @@ fn convert() { const BAR: Vec<String> = into(Vec::new()); assert_eq!(BAR, Vec::<String>::new()); } +*/ diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs index 267245f05dc..033bd1ed6ed 100644 --- a/library/core/tests/hash/mod.rs +++ b/library/core/tests/hash/mod.rs @@ -9,13 +9,13 @@ struct MyHasher { hash: u64, } -impl const Default for MyHasher { +impl Default for MyHasher { fn default() -> MyHasher { MyHasher { hash: 0 } } } -impl const Hasher for MyHasher { +impl Hasher for MyHasher { fn write(&mut self, buf: &[u8]) { // FIXME(const_trait_impl): change to for loop let mut i = 0; @@ -35,13 +35,14 @@ impl const Hasher for MyHasher { #[test] fn test_writer_hasher() { - const fn hash<T: ~const Hash>(t: &T) -> u64 { + // FIXME(#110395) + /* const */ fn hash<T: Hash>(t: &T) -> u64 { let mut s = MyHasher { hash: 0 }; t.hash(&mut s); s.finish() } - const { + /* const { // FIXME(fee1-dead): assert_eq assert!(hash(&()) == 0); assert!(hash(&5_u8) == 5); @@ -52,7 +53,7 @@ fn test_writer_hasher() { let s: &str = "a"; assert!(hash(&s) == 97 + 0xFF); - }; + }; */ assert_eq!(hash(&()), 0); @@ -113,7 +114,7 @@ struct CustomHasher { output: u64, } -impl const Hasher for CustomHasher { +impl Hasher for CustomHasher { fn finish(&self) -> u64 { self.output } @@ -125,21 +126,22 @@ impl const Hasher for CustomHasher { } } -impl const Default for CustomHasher { +impl Default for CustomHasher { fn default() -> CustomHasher { CustomHasher { output: 0 } } } -impl const Hash for Custom { - fn hash<H: ~const Hasher>(&self, state: &mut H) { +impl Hash for Custom { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u64(self.hash); } } #[test] fn test_custom_state() { - const fn hash<T: ~const Hash>(t: &T) -> u64 { + // FIXME(#110395) + /* const */ fn hash<T: Hash>(t: &T) -> u64 { let mut c = CustomHasher { output: 0 }; t.hash(&mut c); c.finish() @@ -147,7 +149,7 @@ fn test_custom_state() { assert_eq!(hash(&Custom { hash: 5 }), 5); - const { assert!(hash(&Custom { hash: 6 }) == 6) }; + // const { assert!(hash(&Custom { hash: 6 }) == 6) }; } // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. diff --git a/library/core/tests/hash/sip.rs b/library/core/tests/hash/sip.rs index 3abf6efcfa9..0a67c485c98 100644 --- a/library/core/tests/hash/sip.rs +++ b/library/core/tests/hash/sip.rs @@ -23,12 +23,13 @@ fn hash<T: Hash>(x: &T) -> u64 { hash_with(SipHasher::new(), x) } +/* FIXME(#110395) #[test] const fn test_const_sip() { let val1 = 0x45; let val2 = 0xfeed; - const fn const_hash<T: ~const Hash>(x: &T) -> u64 { + const fn const_hash<T: Hash>(x: &T) -> u64 { let mut st = SipHasher::new(); x.hash(&mut st); st.finish() @@ -36,6 +37,7 @@ const fn test_const_sip() { assert!(const_hash(&(val1)) != const_hash(&(val2))); } +*/ #[test] #[allow(unused_must_use)] diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs index c7c3c479b71..e2f526d155e 100644 --- a/library/core/tests/lazy.rs +++ b/library/core/tests/lazy.rs @@ -46,11 +46,13 @@ fn unsync_once_cell_drop_empty() { drop(x); } +/* FIXME(#110395) #[test] const fn once_cell_const() { let _once_cell: OnceCell<u32> = OnceCell::new(); let _once_cell: OnceCell<u32> = OnceCell::from(32); } +*/ #[test] fn clone() { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 6cdafa411d0..84859a54c26 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -8,16 +8,13 @@ #![feature(const_assume)] #![feature(const_align_of_val_raw)] #![feature(const_black_box)] -#![feature(const_bool_to_option)] #![feature(const_caller_location)] #![feature(const_cell_into_inner)] -#![feature(const_convert)] #![feature(const_hash)] #![feature(const_heap)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] -#![feature(const_num_from_num)] #![feature(const_pointer_byte_offsets)] #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] @@ -112,6 +109,7 @@ #![feature(utf8_chunks)] #![feature(is_ascii_octdigit)] #![feature(get_many_mut)] +#![cfg_attr(not(bootstrap), feature(offset_of))] #![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)] diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index f7740a114e7..7f033816901 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -364,3 +364,193 @@ fn const_maybe_uninit() { assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 }); } + +#[test] +#[cfg(not(bootstrap))] +fn offset_of() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + struct Bar(u8, u8); + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 2); + assert_eq!(offset_of!(Foo, z.0), 4); + assert_eq!(offset_of!(Foo, z.1), 5); + + // Layout of tuples is unstable + assert!(offset_of!((u8, u16), 0) <= size_of::<(u8, u16)>() - 1); + assert!(offset_of!((u8, u16), 1) <= size_of::<(u8, u16)>() - 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_union() { + #[repr(C)] + union Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + #[derive(Copy, Clone)] + struct Bar(u8, u8); + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 0); + assert_eq!(offset_of!(Foo, z.0), 0); + assert_eq!(offset_of!(Foo, z.1), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_dst() { + #[repr(C)] + struct Alpha { + x: u8, + y: u16, + z: [u8], + } + + trait Trait {} + + #[repr(C)] + struct Beta { + x: u8, + y: u16, + z: dyn Trait, + } + + extern "C" { + type Extern; + } + + #[repr(C)] + struct Gamma { + x: u8, + y: u16, + z: Extern, + } + + assert_eq!(offset_of!(Alpha, x), 0); + assert_eq!(offset_of!(Alpha, y), 2); + + assert_eq!(offset_of!(Beta, x), 0); + assert_eq!(offset_of!(Beta, y), 2); + + assert_eq!(offset_of!(Gamma, x), 0); + assert_eq!(offset_of!(Gamma, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_packed() { + #[repr(C, packed)] + struct Foo { + x: u8, + y: u16, + } + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_projection() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + trait Projector { + type Type; + } + + impl Projector for () { + type Type = Foo; + } + + assert_eq!(offset_of!(<() as Projector>::Type, x), 0); + assert_eq!(offset_of!(<() as Projector>::Type, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_alias() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + type Bar = Foo; + + assert_eq!(offset_of!(Bar, x), 0); + assert_eq!(offset_of!(Bar, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn const_offset_of() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + const X_OFFSET: usize = offset_of!(Foo, x); + const Y_OFFSET: usize = offset_of!(Foo, y); + + assert_eq!(X_OFFSET, 0); + assert_eq!(Y_OFFSET, 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_without_const_promotion() { + #[repr(C)] + struct Foo<SuppressConstPromotion> { + x: u8, + y: u16, + _scp: SuppressConstPromotion, + } + + // Normally, offset_of is always const promoted. + // The generic parameter prevents this from happening. + // This is needed to test the codegen impl of offset_of + fn inner<SuppressConstPromotion>() { + assert_eq!(offset_of!(Foo<SuppressConstPromotion>, x), 0); + assert_eq!(offset_of!(Foo<SuppressConstPromotion>, y), 2); + } + + inner::<()>(); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_addr() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + struct Bar(u8, u8); + + let base = Foo { x: 0, y: 0, z: Bar(0, 0) }; + + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, x), ptr::addr_of!(base.x).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, y), ptr::addr_of!(base.y).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.0), ptr::addr_of!(base.z.0).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.1), ptr::addr_of!(base.z.1).addr()); +} diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index a0ca919a851..007f8442533 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -215,11 +215,13 @@ fn nonzero_const() { const ONE: Option<NonZeroU8> = NonZeroU8::new(1); assert!(ONE.is_some()); + /* FIXME(#110395) const FROM_NONZERO_U8: u8 = u8::from(NONZERO_U8); assert_eq!(FROM_NONZERO_U8, 5); const NONZERO_CONVERT: NonZeroU32 = NonZeroU32::from(NONZERO_U8); assert_eq!(NONZERO_CONVERT.get(), 5); + */ } #[test] @@ -334,3 +336,21 @@ fn test_nonzero_uint_rem() { let x: u32 = 42u32 % nz; assert_eq!(x, 2u32); } + +#[test] +fn test_signed_nonzero_neg() { + assert_eq!((-NonZeroI8::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI8::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI16::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI16::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI32::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI32::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI64::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI64::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI128::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI128::new(-1).unwrap()).get(), 1); +} diff --git a/library/core/tests/num/const_from.rs b/library/core/tests/num/const_from.rs index aca18ef39de..fa58e771879 100644 --- a/library/core/tests/num/const_from.rs +++ b/library/core/tests/num/const_from.rs @@ -1,3 +1,4 @@ +/* FIXME(#110395) #[test] fn from() { use core::convert::TryFrom; @@ -23,3 +24,4 @@ fn from() { const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16); assert_eq!(I16_FROM_U16, Ok(1i16)); } +*/ diff --git a/library/core/tests/num/ieee754.rs b/library/core/tests/num/ieee754.rs index f6e5dfc98c7..48ab75b6f17 100644 --- a/library/core/tests/num/ieee754.rs +++ b/library/core/tests/num/ieee754.rs @@ -39,7 +39,6 @@ macro_rules! assert_biteq { // ToString uses the default fmt::Display impl without special concerns, and bypasses other parts // of the formatting infrastructure, which makes it ideal for testing here. -#[allow(unused_macros)] macro_rules! roundtrip { ($f:expr => $t:ty) => { ($f).to_string().parse::<$t>().unwrap() diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index dca6321cf62..5defeb50d40 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -88,6 +88,7 @@ fn test_and() { assert_eq!(x.and(Some(2)), None); assert_eq!(x.and(None::<isize>), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.and(Some(2)); const B: Option<isize> = FOO.and(None); @@ -99,6 +100,7 @@ fn test_and() { const D: Option<isize> = BAR.and(None); assert_eq!(C, None); assert_eq!(D, None); + */ } #[test] @@ -119,6 +121,7 @@ fn test_and_then() { assert_eq!(x.and_then(plus_one), None); assert_eq!(x.and_then(none), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.and_then(plus_one); const B: Option<isize> = FOO.and_then(none); @@ -130,6 +133,7 @@ fn test_and_then() { const D: Option<isize> = BAR.and_then(none); assert_eq!(C, None); assert_eq!(D, None); + */ } #[test] @@ -142,6 +146,7 @@ fn test_or() { assert_eq!(x.or(Some(2)), Some(2)); assert_eq!(x.or(None), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.or(Some(2)); const B: Option<isize> = FOO.or(None); @@ -153,6 +158,7 @@ fn test_or() { const D: Option<isize> = BAR.or(None); assert_eq!(C, Some(2)); assert_eq!(D, None); + */ } #[test] @@ -173,6 +179,7 @@ fn test_or_else() { assert_eq!(x.or_else(two), Some(2)); assert_eq!(x.or_else(none), None); +/* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.or_else(two); const B: Option<isize> = FOO.or_else(none); @@ -184,6 +191,7 @@ fn test_or_else() { const D: Option<isize> = BAR.or_else(none); assert_eq!(C, Some(2)); assert_eq!(D, None); +*/ } #[test] @@ -215,10 +223,12 @@ fn test_unwrap_or() { let x: Option<isize> = None; assert_eq!(x.unwrap_or(2), 2); + /* FIXME(#110395) const A: isize = Some(1).unwrap_or(2); const B: isize = None.unwrap_or(2); assert_eq!(A, 1); assert_eq!(B, 2); + */ } #[test] @@ -233,10 +243,12 @@ fn test_unwrap_or_else() { let x: Option<isize> = None; assert_eq!(x.unwrap_or_else(two), 2); + /* FIXME(#110395) const A: isize = Some(1).unwrap_or_else(two); const B: isize = None.unwrap_or_else(two); assert_eq!(A, 1); assert_eq!(B, 2); + */ } #[test] @@ -439,14 +451,15 @@ fn option_const() { const OPTION: Option<usize> = Some(32); assert_eq!(OPTION, Some(32)); - const OPTION_FROM: Option<usize> = Option::from(32); - assert_eq!(OPTION_FROM, Some(32)); + // FIXME(#110395) + // const OPTION_FROM: Option<usize> = Option::from(32); + // assert_eq!(OPTION_FROM, Some(32)); const REF: Option<&usize> = OPTION.as_ref(); assert_eq!(REF, Some(&32)); - const REF_FROM: Option<&usize> = Option::from(&OPTION); - assert_eq!(REF_FROM, Some(&32)); + // const REF_FROM: Option<&usize> = Option::from(&OPTION); + // assert_eq!(REF_FROM, Some(&32)); const IS_SOME: bool = OPTION.is_some(); assert!(IS_SOME); @@ -474,7 +487,7 @@ const fn option_const_mut() { None => unreachable!(), } } - +/* FIXME(const-hack) { let as_mut: Option<&mut usize> = Option::from(&mut option); match as_mut { @@ -482,6 +495,7 @@ const fn option_const_mut() { None => unreachable!(), } } +*/ } #[test] diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index 2975c81f8fe..872611937cc 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -425,14 +425,16 @@ fn duration_const() { const SECONDS_F32: f32 = Duration::SECOND.as_secs_f32(); assert_eq!(SECONDS_F32, 1.0); - const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0); - assert_eq!(FROM_SECONDS_F32, Duration::SECOND); + // FIXME(#110395) + // const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0); + // assert_eq!(FROM_SECONDS_F32, Duration::SECOND); const SECONDS_F64: f64 = Duration::SECOND.as_secs_f64(); assert_eq!(SECONDS_F64, 1.0); - const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0); - assert_eq!(FROM_SECONDS_F64, Duration::SECOND); + // FIXME(#110395) + // const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0); + // assert_eq!(FROM_SECONDS_F64, Duration::SECOND); const MILLIS: u128 = Duration::SECOND.as_millis(); assert_eq!(MILLIS, 1_000); @@ -463,6 +465,7 @@ fn duration_const() { const CHECKED_MUL: Option<Duration> = Duration::SECOND.checked_mul(1); assert_eq!(CHECKED_MUL, Some(Duration::SECOND)); +/* FIXME(#110395) const MUL_F32: Duration = Duration::SECOND.mul_f32(1.0); assert_eq!(MUL_F32, Duration::SECOND); @@ -477,6 +480,7 @@ fn duration_const() { const DIV_F64: Duration = Duration::SECOND.div_f64(1.0); assert_eq!(DIV_F64, Duration::SECOND); +*/ const DIV_DURATION_F32: f32 = Duration::SECOND.div_duration_f32(Duration::SECOND); assert_eq!(DIV_DURATION_F32, 1.0); diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 4c1e196b5ad..54b11c543f1 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -14,6 +14,7 @@ use std::hash::Hash; use std::marker; use std::mem; use std::ops::Bound; +use std::ops::Range; use std::panic; use std::sync::atomic::AtomicUsize; use std::sync::Once; @@ -93,6 +94,7 @@ macro_rules! with_api { fn source_file($self: $S::Span) -> $S::SourceFile; fn parent($self: $S::Span) -> Option<$S::Span>; fn source($self: $S::Span) -> $S::Span; + fn byte_range($self: $S::Span) -> Range<usize>; fn start($self: $S::Span) -> LineColumn; fn end($self: $S::Span) -> LineColumn; fn before($self: $S::Span) -> $S::Span; @@ -519,3 +521,7 @@ pub struct ExpnGlobals<Span> { compound_traits!( struct ExpnGlobals<Span> { def_site, call_site, mixed_site } ); + +compound_traits!( + struct Range<T> { start, end } +); diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 9d081c8b842..c64665b6ae0 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -44,7 +44,7 @@ mod diagnostic; pub use diagnostic::{Diagnostic, Level, MultiSpan}; use std::cmp::Ordering; -use std::ops::RangeBounds; +use std::ops::{Range, RangeBounds}; use std::path::PathBuf; use std::str::FromStr; use std::{error, fmt}; @@ -488,6 +488,12 @@ impl Span { Span(self.0.source()) } + /// Returns the span's byte position range in the source file. + #[unstable(feature = "proc_macro_span", issue = "54725")] + pub fn byte_range(&self) -> Range<usize> { + self.0.byte_range() + } + /// Gets the starting line/column in the source file for this span. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn start(&self) -> LineColumn { diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 96c75f97f6e..f2fda64a1ee 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -23,11 +23,11 @@ hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate -addr2line = { version = "0.17.0", optional = true, default-features = false } +addr2line = { version = "0.19.0", optional = true, default-features = false } rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] } -miniz_oxide = { version = "0.5.0", optional = true, default-features = false } +miniz_oxide = { version = "0.6.0", optional = true, default-features = false } [dependencies.object] -version = "0.29.0" +version = "0.30.0" optional = true default-features = false features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 3afc8287ecc..c722bad2e4f 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -3168,8 +3168,7 @@ impl DefaultHasher { } #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const Default for DefaultHasher { +impl Default for DefaultHasher { /// Creates a new `DefaultHasher` using [`new`]. /// See its documentation for more. /// @@ -3181,8 +3180,7 @@ impl const Default for DefaultHasher { } #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const Hasher for DefaultHasher { +impl Hasher for DefaultHasher { // The underlying `SipHasher13` doesn't override the other // `write_*` methods, so it's ok not to forward them here. diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c550378e7d6..42a68496fc4 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -249,9 +249,9 @@ pub struct DirBuilder { pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { fn inner(path: &Path) -> io::Result<Vec<u8>> { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut bytes = Vec::with_capacity(size as usize); - io::default_read_to_end(&mut file, &mut bytes)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut bytes = Vec::with_capacity(size.unwrap_or(0)); + io::default_read_to_end(&mut file, &mut bytes, size)?; Ok(bytes) } inner(path.as_ref()) @@ -289,9 +289,9 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> { fn inner(path: &Path) -> io::Result<String> { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut string = String::with_capacity(size as usize); - io::default_read_to_string(&mut file, &mut string)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut string = String::with_capacity(size.unwrap_or(0)); + io::default_read_to_string(&mut file, &mut string, size)?; Ok(string) } inner(path.as_ref()) @@ -732,12 +732,12 @@ impl fmt::Debug for File { } /// Indicates how much extra capacity is needed to read the rest of the file. -fn buffer_capacity_required(mut file: &File) -> usize { - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let pos = file.stream_position().unwrap_or(0); +fn buffer_capacity_required(mut file: &File) -> Option<usize> { + let size = file.metadata().map(|m| m.len()).ok()?; + let pos = file.stream_position().ok()?; // Don't worry about `usize` overflow because reading will fail regardless // in that case. - size.saturating_sub(pos) as usize + Some(size.saturating_sub(pos) as usize) } #[stable(feature = "rust1", since = "1.0.0")] @@ -761,14 +761,16 @@ impl Read for File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -817,14 +819,16 @@ impl Read for &File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2511,9 +2515,10 @@ impl AsInnerMut<fs_imp::DirBuilder> for DirBuilder { /// This function will traverse symbolic links to query information about the /// destination file. In case of broken symbolic links this will return `Ok(false)`. /// -/// As opposed to the [`Path::exists`] method, this one doesn't silently ignore errors -/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission -/// denied on some of the parent directories.) +/// As opposed to the [`Path::exists`] method, this will only return `Ok(true)` or `Ok(false)` +/// if the path was _verified_ to exist or not exist. If its existence can neither be confirmed +/// nor denied, an `Err(_)` will be propagated instead. This can be the case if e.g. listing +/// permission is denied on one of the parent directories. /// /// Note that while this avoids some pitfalls of the `exists()` method, it still can not /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index e5048dcc8ac..a7428776d8f 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -9,6 +9,7 @@ use crate::io::{ self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write, }; use crate::mem; +use crate::str; // ============================================================================= // Forwarding implementations @@ -307,6 +308,17 @@ impl Read for &[u8] { *self = &self[len..]; Ok(len) } + + #[inline] + fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { + let content = str::from_utf8(self).map_err(|_| { + io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") + })?; + buf.push_str(content); + let len = self.len(); + *self = &self[len..]; + Ok(len) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -336,7 +348,7 @@ impl Write for &mut [u8] { #[inline] fn write(&mut self, data: &[u8]) -> io::Result<usize> { let amt = cmp::min(data.len(), self.len()); - let (a, b) = mem::replace(self, &mut []).split_at_mut(amt); + let (a, b) = mem::take(self).split_at_mut(amt); a.copy_from_slice(&data[..amt]); *self = b; Ok(amt) @@ -434,6 +446,33 @@ impl<A: Allocator> Read for VecDeque<u8, A> { self.drain(..n); Ok(()) } + + #[inline] + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { + // The total len is known upfront so we can reserve it in a single call. + let len = self.len(); + buf.reserve(len); + + let (front, back) = self.as_slices(); + buf.extend_from_slice(front); + buf.extend_from_slice(back); + self.clear(); + Ok(len) + } + + #[inline] + fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { + // We have to use a single contiguous slice because the `VecDequeue` might be split in the + // middle of an UTF-8 character. + let len = self.len(); + let content = self.make_contiguous(); + let string = str::from_utf8(content).map_err(|_| { + io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") + })?; + buf.push_str(string); + self.clear(); + Ok(len) + } } /// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed. @@ -446,6 +485,21 @@ impl<A: Allocator> Write for VecDeque<u8, A> { } #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let len = bufs.iter().map(|b| b.len()).sum(); + self.reserve(len); + for buf in bufs { + self.extend(&**buf); + } + Ok(len) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } + + #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.extend(buf); Ok(()) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 020c723925a..4cd7885bd4a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -253,7 +253,7 @@ mod tests; use crate::cmp; use crate::fmt; -use crate::mem::replace; +use crate::mem::take; use crate::ops::{Deref, DerefMut}; use crate::slice; use crate::str; @@ -357,9 +357,17 @@ where // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every // time is 4,500 times (!) slower than a default reservation size of 32 if the // reader has a very small amount of data to return. -pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> { +pub(crate) fn default_read_to_end<R: Read + ?Sized>( + r: &mut R, + buf: &mut Vec<u8>, + size_hint: Option<usize>, +) -> Result<usize> { let start_len = buf.len(); let start_cap = buf.capacity(); + // Optionally limit the maximum bytes read on each iteration. + // This adds an arbitrary fiddle factor to allow for more data than we expect. + let max_read_size = + size_hint.and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE)); let mut initialized = 0; // Extra initialized bytes from previous loop iteration loop { @@ -367,7 +375,12 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8> buf.reserve(32); // buf is full, need more space } - let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into(); + let mut spare = buf.spare_capacity_mut(); + if let Some(size) = max_read_size { + let len = cmp::min(spare.len(), size); + spare = &mut spare[..len] + } + let mut read_buf: BorrowedBuf<'_> = spare.into(); // SAFETY: These bytes were initialized but not filled in the previous loop unsafe { @@ -419,6 +432,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8> pub(crate) fn default_read_to_string<R: Read + ?Sized>( r: &mut R, buf: &mut String, + size_hint: Option<usize>, ) -> Result<usize> { // Note that we do *not* call `r.read_to_end()` here. We are passing // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end` @@ -429,7 +443,7 @@ pub(crate) fn default_read_to_string<R: Read + ?Sized>( // To prevent extraneously checking the UTF-8-ness of the entire buffer // we pass it to our hardcoded `default_read_to_end` implementation which // we know is guaranteed to only read data into the end of the buffer. - unsafe { append_to_string(buf, |b| default_read_to_end(r, b)) } + unsafe { append_to_string(buf, |b| default_read_to_end(r, b, size_hint)) } } pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> @@ -709,7 +723,7 @@ pub trait Read { /// [`std::fs::read`]: crate::fs::read #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { - default_read_to_end(self, buf) + default_read_to_end(self, buf, None) } /// Read all bytes until EOF in this source, appending them to `buf`. @@ -752,7 +766,7 @@ pub trait Read { /// [`std::fs::read_to_string`]: crate::fs::read_to_string #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result<usize> { - default_read_to_string(self, buf) + default_read_to_string(self, buf, None) } /// Read the exact number of bytes required to fill `buf`. @@ -1186,7 +1200,7 @@ impl<'a> IoSliceMut<'a> { } } - *bufs = &mut replace(bufs, &mut [])[remove..]; + *bufs = &mut take(bufs)[remove..]; if bufs.is_empty() { assert!(n == accumulated_len, "advancing io slices beyond their length"); } else { @@ -1329,7 +1343,7 @@ impl<'a> IoSlice<'a> { } } - *bufs = &mut replace(bufs, &mut [])[remove..]; + *bufs = &mut take(bufs)[remove..]; if bufs.is_empty() { assert!(n == accumulated_len, "advancing io slices beyond their length"); } else { diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index f4a886d889a..6d30f5e6c6c 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -314,7 +314,7 @@ fn bench_read_to_end(b: &mut test::Bencher) { b.iter(|| { let mut lr = repeat(1).take(10000000); let mut vec = Vec::with_capacity(1024); - super::default_read_to_end(&mut lr, &mut vec) + super::default_read_to_end(&mut lr, &mut vec, None) }); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 98fcc76aa98..318a46d1b63 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -289,6 +289,7 @@ #![feature(float_next_up_down)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(int_roundings)] #![feature(ip)] #![feature(ip_in_core)] #![feature(maybe_uninit_slice)] diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 8014ba992ea..e5abd02a1bc 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2844,9 +2844,11 @@ impl Path { /// This function will traverse symbolic links to query information about the /// destination file. In case of broken symbolic links this will return `Ok(false)`. /// - /// As opposed to the [`exists()`] method, this one doesn't silently ignore errors - /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission - /// denied on some of the parent directories.) + /// [`Path::exists()`] only checks whether or not a path was both found and readable. By + /// contrast, `try_exists` will return `Ok(true)` or `Ok(false)`, respectively, if the path + /// was _verified_ to exist or not exist. If its existence can neither be confirmed nor + /// denied, it will propagate an `Err(_)` instead. This can be the case if e.g. listing + /// permission is denied on one of the parent directories. /// /// Note that while this avoids some pitfalls of the `exists()` method, it still can not /// prevent time-of-check to time-of-use (TOCTOU) bugs. You should only use it in scenarios diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 8e9ea293ce4..a6bc468b092 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -1,9 +1,9 @@ use crate::cell::UnsafeCell; -use crate::fmt; use crate::mem::ManuallyDrop; use crate::ops::Deref; use crate::panic::{RefUnwindSafe, UnwindSafe}; use crate::sync::Once; +use crate::{fmt, ptr}; use super::once::ExclusiveState; @@ -69,6 +69,42 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } + /// Consumes this `LazyLock` returning the stored value. + /// + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(lazy_cell)] + /// #![feature(lazy_cell_consume)] + /// + /// use std::sync::LazyLock; + /// + /// let hello = "Hello, World!".to_string(); + /// + /// let lazy = LazyLock::new(|| hello.to_uppercase()); + /// + /// assert_eq!(&*lazy, "HELLO, WORLD!"); + /// assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string())); + /// ``` + #[unstable(feature = "lazy_cell_consume", issue = "109736")] + pub fn into_inner(mut this: Self) -> Result<T, F> { + let state = this.once.state(); + match state { + ExclusiveState::Poisoned => panic!("LazyLock instance has previously been poisoned"), + state => { + let this = ManuallyDrop::new(this); + let data = unsafe { ptr::read(&this.data) }.into_inner(); + match state { + ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })), + ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })), + ExclusiveState::Poisoned => unreachable!(), + } + } + } + } + /// Forces the evaluation of this lazy value and /// returns a reference to result. This is equivalent /// to the `Deref` impl, but is explicit. diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 8c34375ea07..36951c4f13e 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -344,8 +344,7 @@ impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {} impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {} #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for OnceLock<T> { +impl<T> Default for OnceLock<T> { /// Creates a new empty cell. /// /// # Example diff --git a/library/std/src/sys/unsupported/io.rs b/library/std/src/sys/unsupported/io.rs index 82610ffab7e..6372fca74e0 100644 --- a/library/std/src/sys/unsupported/io.rs +++ b/library/std/src/sys/unsupported/io.rs @@ -30,7 +30,7 @@ impl<'a> IoSliceMut<'a> { #[inline] pub fn advance(&mut self, n: usize) { - let slice = mem::replace(&mut self.0, &mut []); + let slice = mem::take(&mut self.0); let (_, remaining) = slice.split_at_mut(n); self.0 = remaining; } diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 77359abe429..bcc172b0fae 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -68,10 +68,13 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { c::ERROR_ALREADY_EXISTS => return AlreadyExists, c::ERROR_FILE_EXISTS => return AlreadyExists, c::ERROR_BROKEN_PIPE => return BrokenPipe, - c::ERROR_FILE_NOT_FOUND => return NotFound, - c::ERROR_PATH_NOT_FOUND => return NotFound, + c::ERROR_FILE_NOT_FOUND + | c::ERROR_PATH_NOT_FOUND + | c::ERROR_INVALID_DRIVE + | c::ERROR_BAD_NETPATH + | c::ERROR_BAD_NET_NAME => return NotFound, c::ERROR_NO_DATA => return BrokenPipe, - c::ERROR_INVALID_NAME => return InvalidFilename, + c::ERROR_INVALID_NAME | c::ERROR_BAD_PATHNAME => return InvalidFilename, c::ERROR_INVALID_PARAMETER => return InvalidInput, c::ERROR_NOT_ENOUGH_MEMORY | c::ERROR_OUTOFMEMORY => return OutOfMemory, c::ERROR_SEM_TIMEOUT diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index a158d1f718e..19d67e80a61 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -374,9 +374,9 @@ checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "3f508063cc7bb32987c71511216bd5a32be15bccb6a80b52df8b9d7f01fc3aa2" [[package]] name = "log" diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index 912d875e445..a80379e85c1 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -16,9 +16,11 @@ fn main() { let config = Config::parse(&args); #[cfg(all(any(unix, windows), not(target_os = "solaris")))] + let mut build_lock; + #[cfg(all(any(unix, windows), not(target_os = "solaris")))] + let _build_lock_guard; + #[cfg(all(any(unix, windows), not(target_os = "solaris")))] { - let mut build_lock; - let _build_lock_guard; let path = config.out.join("lock"); build_lock = fd_lock::RwLock::new(t!(std::fs::File::create(&path))); _build_lock_guard = match build_lock.try_write() { diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 040fec3615b..dd86634b47c 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -150,7 +150,7 @@ fn main() { // allow the `rustc_private` feature to link to other unstable crates // also in the sysroot. We also do this for host crates, since those // may be proc macros, in which case we might ship them. - if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() && (stage != "0" || target.is_some()) { + if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() { cmd.arg("-Z").arg("force-unstable-if-unmarked"); } diff --git a/src/bootstrap/bolt.rs b/src/bootstrap/bolt.rs index 10e6d2e7d6d..5384181ea68 100644 --- a/src/bootstrap/bolt.rs +++ b/src/bootstrap/bolt.rs @@ -40,7 +40,7 @@ pub fn optimize_with_bolt(path: &Path, profile_path: &Path, output_path: &Path) // Reorder functions within the binary .arg("-reorder-functions=hfsort+") // Split function code into hot and code regions - .arg("-split-functions=2") + .arg("-split-functions") // Split as many basic blocks as possible .arg("-split-all-cold") // Move jump tables to a separate section diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 025145244c4..680a8da6adf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -575,7 +575,7 @@ class RustBuild(object): ] patchelf_args = ["--set-rpath", ":".join(rpath_entries)] if not fname.endswith(".so"): - # Finally, set the corret .interp for binaries + # Finally, set the correct .interp for binaries with open("{}/nix-support/dynamic-linker".format(nix_deps_dir)) as dynamic_linker: patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()] @@ -722,11 +722,14 @@ class RustBuild(object): def build_bootstrap(self, color, verbose_count): """Build bootstrap""" - print("Building bootstrap") + env = os.environ.copy() + if "GITHUB_ACTIONS" in env: + print("::group::Building bootstrap") + else: + print("Building bootstrap") build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) - env = os.environ.copy() # `CARGO_BUILD_TARGET` breaks bootstrap build. # See also: <https://github.com/rust-lang/rust/issues/70208>. if "CARGO_BUILD_TARGET" in env: @@ -798,6 +801,9 @@ class RustBuild(object): # Run this from the source directory so cargo finds .cargo/config run(args, env=env, verbose=self.verbose, cwd=self.rust_root) + if "GITHUB_ACTIONS" in env: + print("::endgroup::") + def build_triple(self): """Build triple as in LLVM @@ -822,7 +828,8 @@ class RustBuild(object): if self.use_vendored_sources: vendor_dir = os.path.join(self.rust_root, 'vendor') if not os.path.exists(vendor_dir): - sync_dirs = "--sync ./src/tools/rust-analyzer/Cargo.toml " \ + sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \ + "--sync ./src/tools/rust-analyzer/Cargo.toml " \ "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \ "--sync ./src/bootstrap/Cargo.toml " print('error: vendoring required, but vendor directory does not exist.') diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 20bd71f06e9..26bd80a008f 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -97,6 +97,7 @@ class GenerateAndParseConfig(unittest.TestCase): def test_no_args(self): build = self.serialize_and_parse([]) self.assertEqual(build.get_toml("changelog-seen"), '2') + self.assertEqual(build.get_toml("profile"), 'user') self.assertIsNone(build.get_toml("llvm.download-ci-llvm")) def test_set_section(self): @@ -107,10 +108,9 @@ class GenerateAndParseConfig(unittest.TestCase): build = self.serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"]) self.assertEqual(build.get_toml("cc", section="target.x86_64-unknown-linux-gnu"), 'gcc') - # Uncomment when #108928 is fixed. - # def test_set_top_level(self): - # build = self.serialize_and_parse(["--set", "profile=compiler"]) - # self.assertEqual(build.get_toml("profile"), 'compiler') + def test_set_top_level(self): + build = self.serialize_and_parse(["--set", "profile=compiler"]) + self.assertEqual(build.get_toml("profile"), 'compiler') if __name__ == '__main__': SUITE = unittest.TestSuite() diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index e959ea06f8b..0d2d512b4b2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1008,9 +1008,24 @@ impl<'a> Builder<'a> { // Avoid deleting the rustlib/ directory we just copied // (in `impl Step for Sysroot`). if !builder.download_rustc() { + builder.verbose(&format!( + "Removing sysroot {} to avoid caching bugs", + sysroot.display() + )); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); } + + if self.compiler.stage == 0 { + // The stage 0 compiler for the build triple is always pre-built. + // Ensure that `libLLVM.so` ends up in the target libdir, so that ui-fulldeps tests can use it when run. + dist::maybe_install_llvm_target( + builder, + self.compiler.host, + &builder.sysroot(self.compiler), + ); + } + INTERNER.intern_path(sysroot) } } @@ -1384,7 +1399,7 @@ impl<'a> Builder<'a> { // Add extra cfg not defined in/by rustc // - // Note: Altrough it would seems that "-Zunstable-options" to `rustflags` is useless as + // Note: Although it would seems that "-Zunstable-options" to `rustflags` is useless as // cargo would implicitly add it, it was discover that sometimes bootstrap only use // `rustflags` without `cargo` making it required. rustflags.arg("-Zunstable-options"); @@ -1574,8 +1589,8 @@ impl<'a> Builder<'a> { // which adds to the runtime dynamic loader path when looking for // dynamic libraries. We use this by default on Unix platforms to ensure // that our nightlies behave the same on Windows, that is they work out - // of the box. This can be disabled, of course, but basically that's why - // we're gated on RUSTC_RPATH here. + // of the box. This can be disabled by setting `rpath = false` in `[rust]` + // table of `config.toml` // // Ok, so the astute might be wondering "why isn't `-C rpath` used // here?" and that is indeed a good question to ask. This codegen @@ -2030,7 +2045,7 @@ impl<'a> Builder<'a> { } #[cfg(feature = "build-metrics")] - self.metrics.enter_step(&step); + self.metrics.enter_step(&step, self); let (out, dur) = { let start = Instant::now(); @@ -2056,7 +2071,7 @@ impl<'a> Builder<'a> { } #[cfg(feature = "build-metrics")] - self.metrics.exit_step(); + self.metrics.exit_step(self); { let mut stack = self.stack.borrow_mut(); diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index c3e3fa009a6..87018574048 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -22,7 +22,7 @@ pub enum GitInfo { /// If the info should be used (`omit_git_hash` is false), this will be /// `Some`, otherwise it will be `None`. Present(Option<Info>), - /// This is not a git repostory, but the info can be fetched from the + /// This is not a git repository, but the info can be fetched from the /// `git-commit-info` file. RecordedForTarball(Info), } diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index fcaa698317d..60de46ce64c 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -105,15 +105,7 @@ impl Step for Std { cargo.arg("--lib"); } - let msg = if compiler.host == target { - format!("Checking stage{} library artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} library artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library artifacts", target); run_cargo( builder, cargo, @@ -167,18 +159,7 @@ impl Step for Std { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!( - "Checking stage{} library test/bench/example targets ({target})", - builder.top_stage - ) - } else { - format!( - "Checking stage{} library test/bench/example targets ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library test/bench/example targets", target); run_cargo( builder, cargo, @@ -252,15 +233,7 @@ impl Step for Rustc { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!("Checking stage{} compiler artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} compiler artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("compiler artifacts", target); run_cargo( builder, cargo, @@ -271,17 +244,9 @@ impl Step for Rustc { false, ); - // HACK: This avoids putting the newly built artifacts in the sysroot if we're using - // `download-rustc`, to avoid "multiple candidates for `rmeta`" errors. Technically, that's - // not quite right: people can set `download-rustc = true` to download even if there are - // changes to the compiler, and in that case ideally we would put the *new* artifacts in the - // sysroot, in case there are API changes that should be used by tools. In practice, - // though, that should be very uncommon, and people can still disable download-rustc. - if !builder.download_rustc() { - let libdir = builder.sysroot_libdir(compiler, target); - let hostdir = builder.sysroot_libdir(compiler, compiler.host); - add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target)); - } + let libdir = builder.sysroot_libdir(compiler, target); + let hostdir = builder.sysroot_libdir(compiler, compiler.host); + add_to_sysroot(&builder, &libdir, &hostdir, &librustc_stamp(builder, compiler, target)); } } @@ -325,15 +290,7 @@ impl Step for CodegenBackend { .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); rustc_cargo_env(builder, &mut cargo, target, compiler.stage); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend) - } else { - format!( - "Checking stage{} {} library ({} -> {})", - builder.top_stage, backend, &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&backend, target); run_cargo( builder, @@ -393,15 +350,7 @@ impl Step for RustAnalyzer { cargo.arg("--benches"); } - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", compiler.stage, "rust-analyzer") - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("rust-analyzer artifacts", target); run_cargo( builder, cargo, @@ -468,18 +417,7 @@ macro_rules! tool_check_step { // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 cargo.rustflag("-Zunstable-options"); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, stringify!($name).to_lowercase()) - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - builder.top_stage, - stringify!($name).to_lowercase(), - &compiler.host.triple, - target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target); run_cargo( builder, cargo, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4a4e7adcbf3..7d2a6862500 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -9,6 +9,7 @@ use std::borrow::Cow; use std::collections::HashSet; use std::env; +use std::ffi::OsStr; use std::fs; use std::io::prelude::*; use std::io::BufReader; @@ -142,23 +143,13 @@ impl Step for Std { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} stage{} library artifacts ({}) ", - crate_description(&self.crates), - compiler.stage, - compiler.host - ) - } else { - format!( - "Building{} stage{} library artifacts ({} -> {})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg( + Kind::Build, + compiler.stage, + format_args!("library artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -652,8 +643,19 @@ impl Step for Rustc { // so its artifacts can't be reused. if builder.download_rustc() && compiler.stage != 0 { // Copy the existing artifacts instead of rebuilding them. - // NOTE: this path is only taken for tools linking to rustc-dev. - builder.ensure(Sysroot { compiler }); + // NOTE: this path is only taken for tools linking to rustc-dev (including ui-fulldeps tests). + let sysroot = builder.ensure(Sysroot { compiler }); + + let ci_rustc_dir = builder.out.join(&*builder.build.build.triple).join("ci-rustc"); + for file in builder.config.rustc_dev_contents() { + let src = ci_rustc_dir.join(&file); + let dst = sysroot.join(file); + if src.is_dir() { + t!(fs::create_dir_all(dst)); + } else { + builder.copy(&src, &dst); + } + } return; } @@ -778,24 +780,13 @@ impl Step for Rustc { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} compiler artifacts (stage{} -> stage{})", - crate_description(&self.crates), - compiler.stage, - compiler.stage + 1 - ) - } else { - format!( - "Building{} compiler artifacts (stage{}:{} -> stage{}:{})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - compiler.stage + 1, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg_sysroot_tool( + Kind::Build, + compiler.stage, + format_args!("compiler artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -1102,15 +1093,7 @@ impl Step for CodegenBackend { let tmp_stamp = out_dir.join(".tmp.stamp"); - let msg = if compiler.host == target { - format!("Building stage{} codegen backend {}", compiler.stage, backend) - } else { - format!( - "Building stage{} codegen backend {} ({} -> {})", - compiler.stage, backend, compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target); let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false); if builder.config.dry_run() { return; @@ -1260,6 +1243,7 @@ impl Step for Sysroot { }; let sysroot = sysroot_dir(compiler.stage); + builder.verbose(&format!("Removing sysroot {} to avoid caching bugs", sysroot.display())); let _ = fs::remove_dir_all(&sysroot); t!(fs::create_dir_all(&sysroot)); @@ -1281,8 +1265,40 @@ impl Step for Sysroot { } // Copy the compiler into the correct sysroot. - builder.cp_r(&builder.ci_rustc_dir(builder.build.build), &sysroot); - return INTERNER.intern_path(sysroot); + // NOTE(#108767): We intentionally don't copy `rustc-dev` artifacts until they're requested with `builder.ensure(Rustc)`. + // This fixes an issue where we'd have multiple copies of libc in the sysroot with no way to tell which to load. + // There are a few quirks of bootstrap that interact to make this reliable: + // 1. The order `Step`s are run is hard-coded in `builder.rs` and not configurable. This + // avoids e.g. reordering `test::UiFulldeps` before `test::Ui` and causing the latter to + // fail because of duplicate metadata. + // 2. The sysroot is deleted and recreated between each invocation, so running `x test + // ui-fulldeps && x test ui` can't cause failures. + let mut filtered_files = Vec::new(); + // Don't trim directories or files that aren't loaded per-target; they can't cause conflicts. + let suffix = format!("lib/rustlib/{}/lib", compiler.host); + for path in builder.config.rustc_dev_contents() { + let path = Path::new(&path); + if path.parent().map_or(false, |parent| parent.ends_with(&suffix)) { + filtered_files.push(path.file_name().unwrap().to_owned()); + } + } + + let filtered_extensions = [OsStr::new("rmeta"), OsStr::new("rlib"), OsStr::new("so")]; + let ci_rustc_dir = builder.ci_rustc_dir(builder.config.build); + builder.cp_filtered(&ci_rustc_dir, &sysroot, &|path| { + if path.extension().map_or(true, |ext| !filtered_extensions.contains(&ext)) { + return true; + } + if !path.parent().map_or(true, |p| p.ends_with(&suffix)) { + return true; + } + if !filtered_files.iter().all(|f| f != path.file_name().unwrap()) { + builder.verbose_than(1, &format!("ignoring {}", path.display())); + false + } else { + true + } + }); } // Symlink the source root into the same location inside the sysroot, diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index abd28b4005d..dd1851e29a9 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -139,6 +139,10 @@ v("musl-root-mips64", "target.mips64-unknown-linux-muslabi64.musl-root", "mips64-unknown-linux-muslabi64 install directory") v("musl-root-mips64el", "target.mips64el-unknown-linux-muslabi64.musl-root", "mips64el-unknown-linux-muslabi64 install directory") +v("musl-root-riscv32gc", "target.riscv32gc-unknown-linux-musl.musl-root", + "riscv32gc-unknown-linux-musl install directory") +v("musl-root-riscv64gc", "target.riscv64gc-unknown-linux-musl.musl-root", + "riscv64gc-unknown-linux-musl install directory") v("qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs", "rootfs in qemu testing, you probably don't want to use this") v("qemu-aarch64-rootfs", "target.aarch64-unknown-linux-gnu.qemu-rootfs", @@ -417,6 +421,8 @@ def parse_example_config(known_args, config): # Avoid using quotes unless it's necessary. targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", "'{}'".format(target) if "." in target else target) + if 'profile' not in config: + set('profile', 'user', config) configure_file(sections, top_level_keys, targets, config) return section_order, sections, targets @@ -475,7 +481,7 @@ def configure_section(lines, config): def configure_top_level_key(lines, top_level_key, value): for i, line in enumerate(lines): if line.startswith('#' + top_level_key + ' = ') or line.startswith(top_level_key + ' = '): - lines[i] = "{} = {}".format(top_level_key, value) + lines[i] = "{} = {}".format(top_level_key, to_toml(value)) return raise RuntimeError("failed to find config line for {}".format(top_level_key)) @@ -521,8 +527,14 @@ def write_config_toml(writer, section_order, targets, sections): else: writer = write_uncommented(sections[section], writer) +def quit_if_file_exists(file): + if os.path.isfile(file): + err("Existing '" + file + "' detected.") if __name__ == "__main__": + # If 'config.toml' already exists, exit the script at this point + quit_if_file_exists('config.toml') + p("processing command line") # Parse all known arguments into a configuration structure that reflects the # TOML we're going to write out diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 9498b772f58..3b35ca1d15d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -996,12 +996,15 @@ impl Step for PlainSourceTarball { // If we're building from git sources, we need to vendor a complete distribution. if builder.rust_info().is_managed_git_subrepository() { // Ensure we have the submodules checked out. + builder.update_submodule(Path::new("src/tools/cargo")); builder.update_submodule(Path::new("src/tools/rust-analyzer")); // Vendor all Cargo dependencies let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("vendor") .arg("--sync") + .arg(builder.src.join("./src/tools/cargo/Cargo.toml")) + .arg("--sync") .arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml")) .arg("--sync") .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml")) @@ -1962,20 +1965,6 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir } } - // FIXME: for reasons I don't understand, the LLVM so in the `rustc` component is different than the one in `rust-dev`. - // Only the one in `rustc` works with the downloaded compiler. - if builder.download_rustc() && target == builder.build.build { - let src_libdir = builder.ci_rustc_dir(target).join("lib"); - for entry in t!(std::fs::read_dir(&src_libdir)) { - let entry = t!(entry); - if entry.file_name().to_str().unwrap().starts_with("libLLVM-") { - install_llvm_file(builder, &entry.path(), dst_libdir); - return !builder.config.dry_run(); - } - } - panic!("libLLVM.so not found in src_libdir {}!", src_libdir.display()); - } - // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely // clear why this is the case, though. llvm-config will emit the versioned diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index 36f9aaa595d..4111b7cc0d3 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/109373 +Last change is for: https://github.com/rust-lang/rust/pull/96971 diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index 24251556584..133cda639d9 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -2,7 +2,7 @@ use std::{ env, ffi::{OsStr, OsString}, fs::{self, File}, - io::{BufRead, BufReader, ErrorKind}, + io::{BufRead, BufReader, BufWriter, ErrorKind, Write}, path::{Path, PathBuf}, process::{Command, Stdio}, }; @@ -262,10 +262,20 @@ impl Config { let directory_prefix = Path::new(Path::new(uncompressed_filename).file_stem().unwrap()); // decompress the file - let data = t!(File::open(tarball)); + let data = t!(File::open(tarball), format!("file {} not found", tarball.display())); let decompressor = XzDecoder::new(BufReader::new(data)); let mut tar = tar::Archive::new(decompressor); + + // `compile::Sysroot` needs to know the contents of the `rustc-dev` tarball to avoid adding + // it to the sysroot unless it was explicitly requested. But parsing the 100 MB tarball is slow. + // Cache the entries when we extract it so we only have to read it once. + let mut recorded_entries = if dst.ends_with("ci-rustc") && pattern == "rustc-dev" { + Some(BufWriter::new(t!(File::create(dst.join(".rustc-dev-contents"))))) + } else { + None + }; + for member in t!(tar.entries()) { let mut member = t!(member); let original_path = t!(member.path()).into_owned(); @@ -283,13 +293,19 @@ impl Config { if !t!(member.unpack_in(dst)) { panic!("path traversal attack ??"); } + if let Some(record) = &mut recorded_entries { + t!(writeln!(record, "{}", short_path.to_str().unwrap())); + } let src_path = dst.join(original_path); if src_path.is_dir() && dst_path.exists() { continue; } t!(fs::rename(src_path, dst_path)); } - t!(fs::remove_dir_all(dst.join(directory_prefix))); + let dst_dir = dst.join(directory_prefix); + if dst_dir.exists() { + t!(fs::remove_dir_all(&dst_dir), format!("failed to remove {}", dst_dir.display())); + } } /// Returns whether the SHA256 checksum of `path` matches `expected`. @@ -365,6 +381,13 @@ impl Config { Some(rustfmt_path) } + pub(crate) fn rustc_dev_contents(&self) -> Vec<String> { + assert!(self.download_rustc()); + let ci_rustc_dir = self.out.join(&*self.build.triple).join("ci-rustc"); + let rustc_dev_contents_file = t!(File::open(ci_rustc_dir.join(".rustc-dev-contents"))); + t!(BufReader::new(rustc_dev_contents_file).lines().collect()) + } + pub(crate) fn download_ci_rustc(&self, commit: &str) { self.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})")); diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index b79969663ca..d8d3f300a35 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -145,10 +145,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let untracked_paths = untracked_paths_output .lines() .filter(|entry| entry.starts_with("??")) - .filter_map(|entry| { - let path = - entry.split(' ').nth(1).expect("every git status entry should list a path"); - path.ends_with(".rs").then_some(path) + .map(|entry| { + entry.split(' ').nth(1).expect("every git status entry should list a path") }); for untracked_path in untracked_paths { println!("skip untracked path {} during rustfmt invocations", untracked_path); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 42d895a3413..b62aa999246 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -12,7 +12,7 @@ use crate::util::t; use crate::dist; use crate::tarball::GeneratedTarball; -use crate::Compiler; +use crate::{Compiler, Kind}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::{Config, TargetSelection}; @@ -52,7 +52,7 @@ fn install_sh( host: Option<TargetSelection>, tarball: &GeneratedTarball, ) { - builder.info(&format!("Install {} stage{} ({:?})", package, stage, host)); + let _guard = builder.msg(Kind::Install, stage, package, host, host); let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 419bcbc63cf..238d167c4c2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -19,13 +19,14 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; +use std::fmt::Display; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; -use build_helper::ci::CiEnv; +use build_helper::ci::{gha, CiEnv}; use channel::GitInfo; use config::{DryRun, Target}; use filetime::FileTime; @@ -238,8 +239,6 @@ pub struct Build { ci_env: CiEnv, delayed_failures: RefCell<Vec<String>>, prerelease_version: Cell<Option<u32>>, - tool_artifacts: - RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>, #[cfg(feature = "build-metrics")] metrics: metrics::BuildMetrics, @@ -458,7 +457,6 @@ impl Build { ci_env: CiEnv::current(), delayed_failures: RefCell::new(Vec::new()), prerelease_version: Cell::new(None), - tool_artifacts: Default::default(), #[cfg(feature = "build-metrics")] metrics: metrics::BuildMetrics::init(), @@ -996,6 +994,85 @@ impl Build { } } + fn msg_check( + &self, + what: impl Display, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + self.msg(Kind::Check, self.config.stage, what, self.config.build, target) + } + + fn msg_build( + &self, + compiler: Compiler, + what: impl Display, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + self.msg(Kind::Build, compiler.stage, what, compiler.host, target) + } + + /// Return a `Group` guard for a [`Step`] that is built for each `--stage`. + fn msg( + &self, + action: impl Into<Kind>, + stage: u32, + what: impl Display, + host: impl Into<Option<TargetSelection>>, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing stage{stage} {what}{fmt}"); + let msg = if let Some(target) = target.into() { + let host = host.into().unwrap(); + if host == target { + msg(format_args!(" ({target})")) + } else { + msg(format_args!(" ({host} -> {target})")) + } + } else { + msg(format_args!("")) + }; + self.group(&msg) + } + + /// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`. + fn msg_unstaged( + &self, + action: impl Into<Kind>, + what: impl Display, + target: TargetSelection, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = format!("{action:?}ing {what} for {target}"); + self.group(&msg) + } + + fn msg_sysroot_tool( + &self, + action: impl Into<Kind>, + stage: u32, + what: impl Display, + host: TargetSelection, + target: TargetSelection, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing {what} {fmt}"); + let msg = if host == target { + msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1)) + } else { + msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1)) + }; + self.group(&msg) + } + + fn group(&self, msg: &str) -> Option<gha::Group> { + self.info(&msg); + match self.config.dry_run { + DryRun::SelfCheck => None, + DryRun::Disabled | DryRun::UserSelected => Some(gha::group(&msg)), + } + } + /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index a893c3a47c9..67cb8837391 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -21,7 +21,7 @@ use crate::channel; use crate::config::{Config, TargetSelection}; use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; -use crate::{CLang, GitRepo}; +use crate::{CLang, GitRepo, Kind}; use build_helper::ci::CiEnv; @@ -271,7 +271,7 @@ impl Step for Llvm { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } - builder.info(&format!("Building LLVM for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLVM", target); t!(stamp.remove()); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -813,7 +813,7 @@ impl Step for Lld { return out_dir; } - builder.info(&format!("Building LLD for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLD", target); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -911,7 +911,7 @@ impl Step for Sanitizers { return runtimes; } - builder.info(&format!("Building sanitizers for {}", self.target)); + let _guard = builder.msg_unstaged(Kind::Build, "sanitizers", self.target); t!(stamp.remove()); let _time = util::timeit(&builder); @@ -1103,7 +1103,7 @@ impl Step for CrtBeginEnd { return out_dir; } - builder.info("Building crtbegin.o and crtend.o"); + let _guard = builder.msg_unstaged(Kind::Build, "crtbegin.o and crtend.o", self.target); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); @@ -1153,7 +1153,7 @@ impl Step for Libunwind { run.builder.ensure(Libunwind { target: run.target }); } - /// Build linunwind.a + /// Build libunwind.a fn run(self, builder: &Builder<'_>) -> Self::Output { builder.update_submodule(&Path::new("src/llvm-project")); @@ -1168,7 +1168,7 @@ impl Step for Libunwind { return out_dir; } - builder.info(&format!("Building libunwind.a for {}", self.target.triple)); + let _guard = builder.msg_unstaged(Kind::Build, "libunwind.a", self.target); t!(fs::create_dir_all(&out_dir)); let mut cc_cfg = cc::Build::new(); diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index bba4d65e8c3..597aefadcfe 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -7,12 +7,16 @@ use crate::cache::INTERNER; use crate::util::output; use crate::{Build, Crate}; -#[derive(Deserialize)] +/// For more information, see the output of +/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html> +#[derive(Debug, Deserialize)] struct Output { packages: Vec<Package>, } -#[derive(Deserialize)] +/// For more information, see the output of +/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html> +#[derive(Debug, Deserialize)] struct Package { name: String, source: Option<String>, @@ -20,25 +24,18 @@ struct Package { dependencies: Vec<Dependency>, } -#[derive(Deserialize)] +/// For more information, see the output of +/// <https://doc.rust-lang.org/nightly/cargo/commands/cargo-metadata.html> +#[derive(Debug, Deserialize)] struct Dependency { name: String, source: Option<String>, } +/// Collects and stores package metadata of each workspace members into `build`, +/// by executing `cargo metadata` commands. pub fn build(build: &mut Build) { - // Run `cargo metadata` to figure out what crates we're testing. - let mut cargo = Command::new(&build.initial_cargo); - cargo - .arg("metadata") - .arg("--format-version") - .arg("1") - .arg("--no-deps") - .arg("--manifest-path") - .arg(build.src.join("Cargo.toml")); - let output = output(&mut cargo); - let output: Output = serde_json::from_str(&output).unwrap(); - for package in output.packages { + for package in workspace_members(build) { if package.source.is_none() { let name = INTERNER.intern_string(package.name); let mut path = PathBuf::from(package.manifest_path); @@ -57,3 +54,35 @@ pub fn build(build: &mut Build) { } } } + +/// Invokes `cargo metadata` to get package metadata of each workspace member. +/// +/// Note that `src/tools/cargo` is no longer a workspace member but we still +/// treat it as one here, by invoking an additional `cargo metadata` command. +fn workspace_members(build: &Build) -> impl Iterator<Item = Package> { + let cmd_metadata = |manifest_path| { + let mut cargo = Command::new(&build.initial_cargo); + cargo + .arg("metadata") + .arg("--format-version") + .arg("1") + .arg("--no-deps") + .arg("--manifest-path") + .arg(manifest_path); + cargo + }; + + // Collects `metadata.packages` from the root workspace. + let root_manifest_path = build.src.join("Cargo.toml"); + let root_output = output(&mut cmd_metadata(&root_manifest_path)); + let Output { packages, .. } = serde_json::from_str(&root_output).unwrap(); + + // Collects `metadata.packages` from src/tools/cargo separately. + let cargo_manifest_path = build.src.join("src/tools/cargo/Cargo.toml"); + let cargo_output = output(&mut cmd_metadata(&cargo_manifest_path)); + let Output { packages: cargo_packages, .. } = serde_json::from_str(&cargo_output).unwrap(); + + // We only care about the root package from `src/tool/cargo` workspace. + let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter(); + packages.into_iter().chain(cargo_package) +} diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs index 82b123ec8a5..e19d56ccd6a 100644 --- a/src/bootstrap/metrics.rs +++ b/src/bootstrap/metrics.rs @@ -4,7 +4,7 @@ //! As this module requires additional dependencies not present during local builds, it's cfg'd //! away whenever the `build.metrics` config option is not set to `true`. -use crate::builder::Step; +use crate::builder::{Builder, Step}; use crate::util::t; use crate::Build; use serde_derive::{Deserialize, Serialize}; @@ -33,7 +33,12 @@ impl BuildMetrics { BuildMetrics { state } } - pub(crate) fn enter_step<S: Step>(&self, step: &S) { + pub(crate) fn enter_step<S: Step>(&self, step: &S, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); // Consider all the stats gathered so far as the parent's. @@ -56,7 +61,12 @@ impl BuildMetrics { }); } - pub(crate) fn exit_step(&self) { + pub(crate) fn exit_step(&self, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); self.collect_stats(&mut *state); @@ -74,7 +84,12 @@ impl BuildMetrics { } } - pub(crate) fn record_test(&self, name: &str, outcome: TestOutcome) { + pub(crate) fn record_test(&self, name: &str, outcome: TestOutcome, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); state .running_steps diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index 19019ad2c08..bedf34d89e8 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -1,7 +1,7 @@ //! This module renders the JSON output of libtest into a human-readable form, trying to be as //! similar to libtest's native output as possible. //! -//! This is needed because we need to use libtest in JSON mode to extract granluar information +//! This is needed because we need to use libtest in JSON mode to extract granular information //! about the executed tests. Doing so suppresses the human-readable output, and (compared to Cargo //! and rustc) libtest doesn't include the rendered human-readable output as a JSON field. We had //! to reimplement all the rendering logic in this module because of that. @@ -124,6 +124,7 @@ impl<'a> Renderer<'a> { ignore_reason: reason.map(|s| s.to_string()), }, }, + self.builder, ); if self.builder.config.verbose_tests { diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 8a40b0f64f4..140259b0213 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -100,7 +100,7 @@ pub fn check(build: &mut Build) { Couldn't find required command: cmake You should install cmake, or set `download-ci-llvm = true` in the -`[llvm]` section section of `config.toml` to download LLVM rather +`[llvm]` section of `config.toml` to download LLVM rather than building it. " ); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index aedf1ecab13..601351ea8e3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -5,7 +5,6 @@ use std::env; use std::ffi::OsString; -use std::fmt; use std::fs; use std::iter; use std::path::{Path, PathBuf}; @@ -57,12 +56,12 @@ impl TestKind { } } -impl fmt::Display for TestKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match *self { - TestKind::Test => "Testing", - TestKind::Bench => "Benchmarking", - }) +impl Into<Kind> for TestKind { + fn into(self) -> Kind { + match self { + TestKind::Test => Kind::Test, + TestKind::Bench => Kind::Bench, + } } } @@ -1448,7 +1447,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the crate::detail_exit(1); } - let compiler = self.compiler; + let mut compiler = self.compiler; let target = self.target; let mode = self.mode; let suite = self.suite; @@ -1461,15 +1460,28 @@ note: if you're sure you want to do this, please open an issue as to why. In the return; } - if suite == "debuginfo" { - builder - .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target }); - } + // Support stage 1 ui-fulldeps. This is somewhat complicated: ui-fulldeps tests for the most + // part test the *API* of the compiler, not how it compiles a given file. As a result, we + // can run them against the stage 1 sources as long as we build them with the stage 0 + // bootstrap compiler. + // NOTE: Only stage 1 is special cased because we need the rustc_private artifacts to match the + // running compiler in stage 2 when plugins run. + let stage_id = if suite == "ui-fulldeps" && compiler.stage == 1 { + compiler = builder.compiler(compiler.stage - 1, target); + format!("stage{}-{}", compiler.stage + 1, target) + } else { + format!("stage{}-{}", compiler.stage, target) + }; if suite.ends_with("fulldeps") { builder.ensure(compile::Rustc::new(compiler, target)); } + if suite == "debuginfo" { + builder + .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target }); + } + builder.ensure(compile::Std::new(compiler, target)); // ensure that `libproc_macro` is available on the host. builder.ensure(compile::Std::new(compiler, compiler.host)); @@ -1528,7 +1540,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--src-base").arg(builder.src.join("tests").join(suite)); cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite)); cmd.arg("--sysroot-base").arg(builder.sysroot(compiler)); - cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target)); + cmd.arg("--stage-id").arg(stage_id); cmd.arg("--suite").arg(suite); cmd.arg("--mode").arg(mode); cmd.arg("--target").arg(target.rustc_target_arg()); @@ -1804,6 +1816,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--channel").arg(&builder.config.channel); + if !builder.config.omit_git_hash { + cmd.arg("--git-hash"); + } + if let Some(commit) = builder.config.download_rustc_commit() { cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}")); } @@ -1888,7 +1904,13 @@ impl BookTest { rustbook_cmd.env("RUSTC_BOOTSTRAP", "1"); rustbook_cmd.env("PATH", new_path).arg("test").arg(path); builder.add_rust_test_threads(&mut rustbook_cmd); - builder.info(&format!("Testing rustbook {}", self.path.display())); + let _guard = builder.msg( + Kind::Test, + compiler.stage, + format_args!("rustbook {}", self.path.display()), + compiler.host, + compiler.host, + ); let _time = util::timeit(&builder); let toolstate = if try_run(builder, &mut rustbook_cmd) { ToolState::TestPass @@ -2016,7 +2038,8 @@ impl Step for ErrorIndex { let mut tool = tool::ErrorIndex::command(builder); tool.arg("markdown").arg(&output); - builder.info(&format!("Testing error-index stage{}", compiler.stage)); + let _guard = + builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = util::timeit(&builder); builder.run_quiet(&mut tool); // The tests themselves need to link to std, so make sure it is @@ -2246,14 +2269,13 @@ impl Step for Crate { ); } - builder.info(&format!( - "{}{} stage{} ({} -> {})", + let _guard = builder.msg( test_kind, - crate_description(&self.crates), compiler.stage, - &compiler.host, - target - )); + crate_description(&self.crates), + compiler.host, + target, + ); let _time = util::timeit(&builder); crate::render_tests::try_run_tests(builder, &mut cargo.into()); } @@ -2369,10 +2391,8 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } - builder.info(&format!( - "{} rustdoc stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = builder.msg(test_kind, compiler.stage, "rustdoc", compiler.host, target); + let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2436,10 +2456,8 @@ impl Step for CrateRustdocJsonTypes { cargo.arg("'-Ctarget-feature=-crt-static'"); } - builder.info(&format!( - "{} rustdoc-json-types stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = + builder.msg(test_kind, compiler.stage, "rustdoc-json-types", compiler.host, target); let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2828,7 +2846,7 @@ impl Step for TestHelpers { return; } - builder.info("Building test helpers"); + let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target); t!(fs::create_dir_all(&dst)); let mut cfg = cc::Build::new(); // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d1fd2e8c42c..9418cf0a7ed 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::env; use std::fs; use std::path::PathBuf; @@ -12,6 +11,7 @@ use crate::toolstate::ToolState; use crate::util::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; +use crate::{gha, Kind}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum SourceType { @@ -33,41 +33,27 @@ struct ToolBuild { allow_features: &'static str, } -fn tooling_output( - mode: Mode, - tool: &str, - build_stage: u32, - host: &TargetSelection, - target: &TargetSelection, -) -> String { - match mode { - // depends on compiler stage, different to host compiler - Mode::ToolRustc => { - if host == target { - format!("Building tool {} (stage{} -> stage{})", tool, build_stage, build_stage + 1) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, - build_stage, - host, - build_stage + 1, - target - ) - } +impl Builder<'_> { + fn msg_tool( + &self, + mode: Mode, + tool: &str, + build_stage: u32, + host: &TargetSelection, + target: &TargetSelection, + ) -> Option<gha::Group> { + match mode { + // depends on compiler stage, different to host compiler + Mode::ToolRustc => self.msg_sysroot_tool( + Kind::Build, + build_stage, + format_args!("tool {tool}"), + *host, + *target, + ), + // doesn't depend on compiler, same as host compiler + _ => self.msg(Kind::Build, build_stage, format_args!("tool {tool}"), *host, *target), } - // doesn't depend on compiler, same as host compiler - Mode::ToolStd => { - if host == target { - format!("Building tool {} (stage{})", tool, build_stage) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, build_stage, host, build_stage, target - ) - } - } - _ => format!("Building tool {} (stage{})", tool, build_stage), } } @@ -112,143 +98,16 @@ impl Step for ToolBuild { if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } - let msg = tooling_output( + let _guard = builder.msg_tool( self.mode, self.tool, self.compiler.stage, &self.compiler.host, &self.target, ); - builder.info(&msg); - let mut duplicates = Vec::new(); - let is_expected = compile::stream_cargo(builder, cargo, vec![], &mut |msg| { - // Only care about big things like the RLS/Cargo for now - match tool { - "rls" | "cargo" | "clippy-driver" | "miri" | "rustfmt" => {} - - _ => return, - } - let (id, features, filenames) = match msg { - compile::CargoMessage::CompilerArtifact { - package_id, - features, - filenames, - target: _, - } => (package_id, features, filenames), - _ => return, - }; - let features = features.iter().map(|s| s.to_string()).collect::<Vec<_>>(); - - for path in filenames { - let val = (tool, PathBuf::from(&*path), features.clone()); - // we're only interested in deduplicating rlibs for now - if val.1.extension().and_then(|s| s.to_str()) != Some("rlib") { - continue; - } - - // Don't worry about compiles that turn out to be host - // dependencies or build scripts. To skip these we look for - // anything that goes in `.../release/deps` but *doesn't* go in - // `$target/release/deps`. This ensure that outputs in - // `$target/release` are still considered candidates for - // deduplication. - if let Some(parent) = val.1.parent() { - if parent.ends_with("release/deps") { - let maybe_target = parent - .parent() - .and_then(|p| p.parent()) - .and_then(|p| p.file_name()) - .and_then(|p| p.to_str()) - .unwrap(); - if maybe_target != &*target.triple { - continue; - } - } - } - // Record that we've built an artifact for `id`, and if one was - // already listed then we need to see if we reused the same - // artifact or produced a duplicate. - let mut artifacts = builder.tool_artifacts.borrow_mut(); - let prev_artifacts = artifacts.entry(target).or_default(); - let prev = match prev_artifacts.get(&*id) { - Some(prev) => prev, - None => { - prev_artifacts.insert(id.to_string(), val); - continue; - } - }; - if prev.1 == val.1 { - return; // same path, same artifact - } - - // If the paths are different and one of them *isn't* inside of - // `release/deps`, then it means it's probably in - // `$target/release`, or it's some final artifact like - // `libcargo.rlib`. In these situations Cargo probably just - // copied it up from `$target/release/deps/libcargo-xxxx.rlib`, - // so if the features are equal we can just skip it. - let prev_no_hash = prev.1.parent().unwrap().ends_with("release/deps"); - let val_no_hash = val.1.parent().unwrap().ends_with("release/deps"); - if prev.2 == val.2 || !prev_no_hash || !val_no_hash { - return; - } - - // ... and otherwise this looks like we duplicated some sort of - // compilation, so record it to generate an error later. - duplicates.push((id.to_string(), val, prev.clone())); - } - }); - - if is_expected && !duplicates.is_empty() { - eprintln!( - "duplicate artifacts found when compiling a tool, this \ - typically means that something was recompiled because \ - a transitive dependency has different features activated \ - than in a previous build:\n" - ); - let (same, different): (Vec<_>, Vec<_>) = - duplicates.into_iter().partition(|(_, cur, prev)| cur.2 == prev.2); - if !same.is_empty() { - eprintln!( - "the following dependencies are duplicated although they \ - have the same features enabled:" - ); - for (id, cur, prev) in same { - eprintln!(" {}", id); - // same features - eprintln!(" `{}` ({:?})\n `{}` ({:?})", cur.0, cur.1, prev.0, prev.1); - } - } - if !different.is_empty() { - eprintln!("the following dependencies have different features:"); - for (id, cur, prev) in different { - eprintln!(" {}", id); - let cur_features: HashSet<_> = cur.2.into_iter().collect(); - let prev_features: HashSet<_> = prev.2.into_iter().collect(); - eprintln!( - " `{}` additionally enabled features {:?} at {:?}", - cur.0, - &cur_features - &prev_features, - cur.1 - ); - eprintln!( - " `{}` additionally enabled features {:?} at {:?}", - prev.0, - &prev_features - &cur_features, - prev.1 - ); - } - } - eprintln!(); - eprintln!( - "to fix this you will probably want to edit the local \ - src/tools/rustc-workspace-hack/Cargo.toml crate, as \ - that will update the dependency graph to ensure that \ - these crates all share the same feature set" - ); - panic!("tools should not compile multiple copies of the same crate"); - } + let mut cargo = Command::from(cargo); + let is_expected = builder.try_run(&mut cargo); builder.save_toolstate( tool, @@ -299,7 +158,9 @@ pub fn prepare_tool_cargo( || path.ends_with("rustfmt") { cargo.env("LIBZ_SYS_STATIC", "1"); - features.push("rustc-workspace-hack/all-static".to_string()); + } + if path.ends_with("cargo") { + features.push("all-static".to_string()); } } @@ -319,6 +180,12 @@ pub fn prepare_tool_cargo( cargo.env("CFG_VERSION", builder.rust_version()); cargo.env("CFG_RELEASE_NUM", &builder.version); cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel()); + if let Some(ref ver_date) = builder.rust_info().commit_date() { + cargo.env("CFG_VER_DATE", ver_date); + } + if let Some(ref ver_hash) = builder.rust_info().sha() { + cargo.env("CFG_VER_HASH", ver_hash); + } let info = GitInfo::new(builder.config.omit_git_hash, &dir); if let Some(sha) = info.sha() { @@ -611,14 +478,13 @@ impl Step for Rustdoc { cargo.rustflag("--cfg=parallel_compiler"); } - let msg = tooling_output( + let _guard = builder.msg_tool( Mode::ToolRustc, "rustdoc", build_compiler.stage, &self.compiler.host, &target, ); - builder.info(&msg); builder.run(&mut cargo.into()); // Cargo adds a number of paths to the dylib search path on windows, which results in @@ -707,18 +573,18 @@ impl Step for Cargo { if self.target.contains("windows") { build_cred( "cargo-credential-wincred", - "src/tools/cargo/crates/credential/cargo-credential-wincred", + "src/tools/cargo/credential/cargo-credential-wincred", ); } if self.target.contains("apple-darwin") { build_cred( "cargo-credential-macos-keychain", - "src/tools/cargo/crates/credential/cargo-credential-macos-keychain", + "src/tools/cargo/credential/cargo-credential-macos-keychain", ); } build_cred( "cargo-credential-1password", - "src/tools/cargo/crates/credential/cargo-credential-1password", + "src/tools/cargo/credential/cargo-credential-1password", ); cargo_bin_path } @@ -867,6 +733,7 @@ macro_rules! tool_extended { stable = $stable:expr $(,tool_std = $tool_std:literal)? $(,allow_features = $allow_features:expr)? + $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)? ;)+) => { $( #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -909,7 +776,7 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> { - $builder.ensure(ToolBuild { + let tool = $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, tool: $tool_name, @@ -919,7 +786,27 @@ macro_rules! tool_extended { is_optional_tool: true, source_type: SourceType::InTree, allow_features: concat!($($allow_features)*), - }) + })?; + + if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 { + let bindir = $builder.sysroot($sel.compiler).join("bin"); + t!(fs::create_dir_all(&bindir)); + + #[allow(unused_variables)] + let tools_out = $builder + .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target); + + $(for add_bin in $add_bins_to_sysroot { + let bin_source = tools_out.join(exe(add_bin, $sel.target)); + let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host)); + $builder.copy(&bin_source, &bin_destination); + })? + + let tool = bindir.join(exe($tool_name, $sel.compiler.host)); + Some(tool) + } else { + Some(tool) + } } } )+ @@ -933,15 +820,15 @@ macro_rules! tool_extended { tool_extended!((self, builder), Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true; CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true; - Clippy, "src/tools/clippy", "clippy-driver", stable=true; - Miri, "src/tools/miri", "miri", stable=false; - CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"]; + Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"]; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"]; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. Rls, "src/tools/rls", "rls", stable=true, tool_std=true; RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true; - Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"]; ); impl<'a> Builder<'a> { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index ea236bee563..9f7259f883a 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -211,7 +211,7 @@ For targets: `armv7-unknown-linux-gnueabihf` (\*) These options have been selected to match the configuration of the arm toolchains shipped with Ubuntu 15.10 (+) These options have been selected to match the gcc flags we use to compile C - libraries like jemalloc. See the mk/cfg/arm(v7)-uknown-linux-gnueabi{,hf}.mk + libraries like jemalloc. See the mk/cfg/arm(v7)-unknown-linux-gnueabi{,hf}.mk file in Rust's source code. ### `aarch64-linux-gnu.config` diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch index 08d0c5b2cac..4437a870b20 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove stime() function calls stime() has been deprecated in glibc 2.31 and replaced with clock_settime(). Let's replace the stime() function calls with -clock_settime() in preperation. +clock_settime() in preparation. function old new delta rdate_main 197 224 +27 diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config index 575584ef0cf..5bfbbae206b 100644 --- a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config @@ -528,7 +528,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config index 4b1efe24aed..c28d655427e 100644 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config @@ -529,7 +529,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config index baff944cf97..50dfe7b2dd1 100644 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config @@ -529,7 +529,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config index adb2da7ddee..3566c7c8593 100644 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config @@ -528,7 +528,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile index 2089bf38716..55fefd2b725 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-illumos/Dockerfile @@ -6,12 +6,13 @@ RUN sed -i 's/^# deb-src/deb-src/' /etc/apt/sources.list COPY scripts/cross-apt-packages.sh /tmp/ RUN bash /tmp/cross-apt-packages.sh -# Required for cross-build gcc +# Required for cross-build gcc, and we install python2 to test general compatibility. RUN apt-get update && \ apt-get install -y --no-install-recommends \ libgmp-dev \ libmpfr-dev \ libmpc-dev \ + python2.7 \ && rm -rf /var/lib/apt/lists/* COPY scripts/illumos-toolchain.sh /tmp/ @@ -35,4 +36,4 @@ ENV \ ENV HOSTS=x86_64-unknown-illumos ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh index 0b06f5e3623..a5691da8cda 100755 --- a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh +++ b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh @@ -1,5 +1,5 @@ #!/bin/bash -# A quick smoke test to make sure publish_tooolstate.py works. +# A quick smoke test to make sure publish_toolstate.py works. set -euo pipefail IFS=$'\n\t' diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14-stage1/Dockerfile index 21dcf29b4a9..d45ef0a7d07 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14-stage1/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14-stage1/Dockerfile @@ -32,6 +32,10 @@ RUN sh /scripts/sccache.sh # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +# This is not the latest LLVM version, so some components required by tests may +# be missing. +ENV IS_NOT_LATEST_LLVM 1 + # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile index cfb638e8b07..1f28b939778 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-14/Dockerfile @@ -38,6 +38,10 @@ RUN sh /scripts/sccache.sh # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +# This is not the latest LLVM version, so some components required by tests may +# be missing. +ENV IS_NOT_LATEST_LLVM 1 + # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/Dockerfile index fb5037e3b97..960683b92bd 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/Dockerfile @@ -2,7 +2,6 @@ FROM ubuntu:22.10 ARG DEBIAN_FRONTEND=noninteractive -# NOTE: intentionally installs both python2 and python3 so we can test support for both. RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ gcc-multilib \ @@ -11,7 +10,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ file \ curl \ ca-certificates \ - python2.7 \ python3 \ git \ cmake \ @@ -40,6 +38,10 @@ RUN sh /scripts/sccache.sh # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +# This is not the latest LLVM version, so some components required by tests may +# be missing. +ENV IS_NOT_LATEST_LLVM 1 + # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ @@ -63,6 +65,4 @@ ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \ # work. # ../x.ps1 --stage 2 test tests/ui --pass=check \ - --host='' --target=i686-unknown-linux-gnu && \ - # Run tidy at the very end, after all the other tests. - python2.7 ../x.py --stage 2 test src/tools/tidy + --host='' --target=i686-unknown-linux-gnu diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile new file mode 100644 index 00000000000..7c75d0df590 --- /dev/null +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-16/Dockerfile @@ -0,0 +1,64 @@ +FROM ubuntu:23.04 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + gcc-multilib \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + sudo \ + gdb \ + llvm-16-tools \ + llvm-16-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + xz-utils \ + nodejs \ + mingw-w64 \ + && rm -rf /var/lib/apt/lists/* + +# Install powershell (universal package) so we can test x.ps1 on Linux +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ + dpkg -i powershell.deb && \ + rm -f powershell.deb + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# We are disabling CI LLVM since this builder is intentionally using a host +# LLVM, rather than the typical src/llvm-project LLVM. +ENV NO_DOWNLOAD_CI_LLVM 1 + +# Using llvm-link-shared due to libffi issues -- see #34486 +ENV RUST_CONFIGURE_ARGS \ + --build=x86_64-unknown-linux-gnu \ + --llvm-root=/usr/lib/llvm-16 \ + --enable-llvm-link-shared \ + --set rust.thin-lto-import-instr-limit=10 + +# NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux. +ENV SCRIPT ../x.py --stage 2 test --exclude src/tools/tidy && \ + # Run the `mir-opt` tests again but this time for a 32-bit target. + # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have + # both 32-bit and 64-bit outputs updated by the PR author, before + # the PR is approved and tested for merging. + # It will also detect tests lacking `// EMIT_MIR_FOR_EACH_BIT_WIDTH`, + # despite having different output on 32-bit vs 64-bit targets. + ../x --stage 2 test tests/mir-opt \ + --host='' --target=i686-unknown-linux-gnu && \ + # Run the UI test suite again, but in `--pass=check` mode + # + # This is intended to make sure that both `--pass=check` continues to + # work. + # + ../x.ps1 --stage 2 test tests/ui --pass=check \ + --host='' --target=i686-unknown-linux-gnu diff --git a/src/ci/docker/scripts/qemu-bare-bones-rcS b/src/ci/docker/scripts/qemu-bare-bones-rcS index 3c29bedc13c..c5d807b2d7d 100644 --- a/src/ci/docker/scripts/qemu-bare-bones-rcS +++ b/src/ci/docker/scripts/qemu-bare-bones-rcS @@ -9,7 +9,7 @@ mount -t sysfs none /sys /addentropy < /addentropy cat /dev/urandom | head -n 2048 | /addentropy -# Set up IP that qemu expects. This confgures eth0 with the public IP that QEMU +# Set up IP that qemu expects. This configures eth0 with the public IP that QEMU # will communicate to as well as the loopback 127.0.0.1 address. ifconfig eth0 10.0.2.15 ifconfig lo up diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index dbf4be4be24..8c7798aad8b 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -457,6 +457,11 @@ jobs: - name: x86_64-gnu-distcheck <<: *job-linux-8c + - name: x86_64-gnu-llvm-16 + env: + RUST_BACKTRACE: 1 + <<: *job-linux-8c + - name: x86_64-gnu-llvm-15 env: RUST_BACKTRACE: 1 diff --git a/src/ci/run.sh b/src/ci/run.sh index 3056d9fc054..966af3abc6f 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -143,7 +143,11 @@ if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ] RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-missing-tools" fi -export COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS=1 +# Unless we're using an older version of LLVM, check that all LLVM components +# used by tests are available. +if [ "$IS_NOT_LATEST_LLVM" = "" ]; then + export COMPILETEST_NEEDS_ALL_LLVM_COMPONENTS=1 +fi # Print the date from the local machine and the date from an external source to # check for clock drifts. An HTTP URL is used instead of HTTPS since on Azure diff --git a/src/doc/book b/src/doc/book -Subproject c06006157b14b3d47b5c716fc392b77f3b2e21c +Subproject 8fa6b854d515506d825390fe0d817f5ef0c8935 diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject 701d1551429da4cb609082c0ac99df569e33671 +Subproject 897fcf566f16bf87bf37199bdddec1801fd0053 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject 6337ed17fb8dcd918d78b7d97d213e923530337 +Subproject 2a5eb92197e9cf8fe91164dcbf4f9b88c0d7e73 diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8ded2ee59dd..48efa67191a 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -42,6 +42,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) + - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 62347f169a5..d7c6a884fc8 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -84,8 +84,8 @@ Note: The [`-g` flag][option-g-debug] is an alias for `-C debuginfo=2`. This flag controls whether or not the linker includes its default libraries. It takes one of the following values: -* `y`, `yes`, `on`, `true` or no value: include default libraries (the default). -* `n`, `no`, `off` or `false`: exclude default libraries. +* `y`, `yes`, `on`, `true`: include default libraries. +* `n`, `no`, `off` or `false` or no value: exclude default libraries (the default). For example, for gcc flavor linkers, this issues the `-nodefaultlibs` flag to the linker. diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index b0b2f419642..2535cd4f12c 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -117,7 +117,7 @@ $ ls formatjson5.profraw formatjson5.profraw ``` -If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing directory structure will be created. Additionally, the following special pattern strings are rewritten: +If `LLVM_PROFILE_FILE` contains a path to a nonexistent directory, the missing directory structure will be created. Additionally, the following special pattern strings are rewritten: - `%p` - The process ID. - `%h` - The hostname of the machine running the program. diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md index d8843280b84..11d7b5b5938 100644 --- a/src/doc/rustc/src/json.md +++ b/src/doc/rustc/src/json.md @@ -61,7 +61,7 @@ Diagnostics have the following format: /* The file where the span is located. Note that this path may not exist. For example, if the path points to the standard library, and the rust src is not - available in the sysroot, then it may point to a non-existent + available in the sysroot, then it may point to a nonexistent file. Beware that this may also point to the source of an external crate. */ diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c378532dbf6..75f97c1fc1e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -327,5 +327,6 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | +`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md index 09e03e4dc6f..e351ea00130 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md @@ -66,7 +66,7 @@ After completing these steps you can use rust normally in a native environment. To cross compile, you'll need to: -* Build the rust cross toochain using [rust-bootstrap-armv7-unknown-linux-uclibceabi](https://github.com/lancethepants/rust-bootstrap-armv7-unknown-linux-uclibceabi) or your own built toolchain. +* Build the rust cross toolchain using [rust-bootstrap-armv7-unknown-linux-uclibceabi](https://github.com/lancethepants/rust-bootstrap-armv7-unknown-linux-uclibceabi) or your own built toolchain. * Link your built toolchain with ```text diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index d7d31d8724c..16ccaf46b2f 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -15,6 +15,8 @@ While the integer base ABI is implied by the machine field, the floating po | f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| | sf | The base ABI uses no FPR for parameter passing. (lp64s) | +<br> + |`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | |----------------------------------|-------------|----------|----------------------------------| | lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md index e2bdf73a929..03fa284620e 100644 --- a/src/doc/rustc/src/platform-support/unknown-uefi.md +++ b/src/doc/rustc/src/platform-support/unknown-uefi.md @@ -123,7 +123,7 @@ There are 3 common ways to compile native C code for UEFI targets: targets. Be wary of any includes that are not specifically suitable for UEFI targets (especially the C standard library includes are not always compatible). Freestanding compilations are recommended to avoid - incompatibilites. + incompatibilities. ## Ecosystem diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md new file mode 100644 index 00000000000..1a6f7bb834c --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md @@ -0,0 +1,57 @@ +# `x86_64h-apple-darwin` + +**Tier: 3** + +Target for macOS on late-generation `x86_64` Apple chips, usable as the +`x86_64h` entry in universal binaries, and equivalent to LLVM's +`x86_64h-apple-macosx*` targets. + +## Target maintainers + +- Thom Chiovoloni `thom@shift.click` <https://github.com/thomcc> + +## Requirements + +This target is an `x86_64` target that only supports Apple's late-gen +(Haswell-compatible) Intel chips. It enables a set of target features available +on these chips (AVX2 and similar), and MachO binaries built with this target may +be used as the `x86_64h` entry in universal binaries ("fat" MachO binaries), and +will fail to load on machines that do not support this. + +It should support the full standard library (`std` and `alloc` either with +default or user-defined allocators). This target is probably most useful when +targetted via cross-compilation (including from `x86_64-apple-darwin`), but if +built manually, the host tools work. + +It is similar to `x86_64-apple-darwin` in nearly all respects, although the +minimum supported OS version is slightly higher (it requires 10.8 rather than +`x86_64-apple-darwin`'s 10.7). + +## Building the target + +Users on Apple targets can build this by adding it to the `target` list in +`config.toml`, or with `-Zbuild-std`. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Code built with this target can be run on the set of Intel macOS machines that +support running `x86_64h` binaries (relatively recent Intel macs). The Rust test +suite seems to work. + +## Cross-compilation toolchains and C code + +Cross-compilation to this target from Apple hosts should generally work without +much configuration, so long as XCode and the CommandLineTools are installed. +Targetting it from non-Apple hosts is difficult, but no moreso than targetting +`x86_64-apple-darwin`. + +When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM +targets should be used, or an argument like `-arch x86_64h` should be passed to +the C compiler. diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md index eb2285ef906..72157b5cd9b 100644 --- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md +++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md @@ -88,13 +88,16 @@ fn Foo() {} ``` These prefixes will be stripped when displayed in the documentation, so `[struct@Foo]` will be -rendered as `Foo`. +rendered as `Foo`. The following prefixes are available: `struct`, `enum`, `trait`, `union`, +`mod`, `module`, `const`, `constant`, `fn`, `function`, `method`, `derive`, `type`, `value`, +`macro`, `prim` or `primitive`. You can also disambiguate for functions by adding `()` after the function name, -or for macros by adding `!` after the macro name: +or for macros by adding `!` after the macro name. The macro `!` can be followed by `()`, `{}`, +or `[]`. Example: ```rust -/// This is different from [`foo!`] +/// This is different from [`foo!()`]. fn foo() {} /// This is different from [`foo()`] diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md index 21668973194..2d203f264e6 100644 --- a/src/doc/style-guide/src/principles.md +++ b/src/doc/style-guide/src/principles.md @@ -6,7 +6,7 @@ following principles (in rough priority order): * readability - scan-ability - avoiding misleading formatting - - accessibility - readable and editable by users using the the widest + - accessibility - readable and editable by users using the widest variety of hardware, including non-visual accessibility interfaces - readability of code in contexts without syntax highlighting or IDE assistance, such as rustc error messages, diffs, grep, and other diff --git a/src/doc/style-guide/src/types.md b/src/doc/style-guide/src/types.md index 25861ddabb8..ae456ef21c8 100644 --- a/src/doc/style-guide/src/types.md +++ b/src/doc/style-guide/src/types.md @@ -6,7 +6,7 @@ * `[T; expr]`, e.g., `[u32; 42]`, `[Vec<Foo>; 10 * 2 + foo()]` (space after colon, no spaces around square brackets) * `*const T`, `*mut T` (no space after `*`, space before type) * `&'a T`, `&T`, `&'a mut T`, `&mut T` (no space after `&`, single spaces separating other words) -* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keyowrds and sigils, and after commas, no trailing commas, no spaces around brackets) +* `unsafe extern "C" fn<'a, 'b, 'c>(T, U, V) -> W` or `fn()` (single spaces around keywords and sigils, and after commas, no trailing commas, no spaces around brackets) * `!` should be treated like any other type name, `Name` * `(A, B, C, D)` (spaces after commas, no spaces around parens, no trailing comma unless it is a one-tuple) * `<Baz<T> as SomeTrait>::Foo::Bar` or `Foo::Bar` or `::Foo::Bar` (no spaces around `::` or angle brackets, single spaces around `as`) diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md index 321992f7b0d..10f0fbc5062 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md @@ -202,5 +202,5 @@ fn shoot_lasers() {} #[cfg(feature = "monkeys")] // This is UNEXPECTED, because "monkeys" is not in // the values(feature) list -fn write_shakespear() {} +fn write_shakespeare() {} ``` diff --git a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md index 88f022af2ec..aea054ba911 100644 --- a/src/doc/unstable-book/src/compiler-flags/move-size-limit.md +++ b/src/doc/unstable-book/src/compiler-flags/move-size-limit.md @@ -6,5 +6,5 @@ The `-Zmove-size-limit=N` compiler flag enables `large_assignments` lints which will warn when moving objects whose size exceeds `N` bytes. Lint warns only about moves in functions that participate in code generation. -Consequently it will be ineffective for compiler invocatation that emit +Consequently it will be ineffective for compiler invocation that emit metadata only, i.e., `cargo check` like workflows. diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index 1f52ab75010..1874baa0c38 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -17,6 +17,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect - AVR - MSP430 - M68k +- LoongArch ## Register classes @@ -45,6 +46,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `reg` | `d[0-7]`, `a[0-7]` | `r` | | M68k | `reg_data` | `d[0-7]` | `d` | | M68k | `reg_addr` | `a[0-3]` | `a` | +| LoongArch | `reg` | `$r1`, `$r[4-20]`, `$r[23,30]` | `r` | +| LoongArch | `freg` | `$f[0-31]` | `f` | > **Notes**: > - NVPTX doesn't have a fixed register set, so named registers are not supported. @@ -76,6 +79,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | MSP430 | `reg` | None | `i8`, `i16` | | M68k | `reg`, `reg_addr` | None | `i16`, `i32` | | M68k | `reg_data` | None | `i8`, `i16`, `i32` | +| LoongArch64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` | +| LoongArch64 | `freg` | None | `f32`, `f64` | ## Register aliases @@ -97,6 +102,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `a5` | `bp` | | M68k | `a6` | `fp` | | M68k | `a7` | `sp`, `usp`, `ssp`, `isp` | +| LoongArch | `$r0` | `zero` | +| LoongArch | `$r2` | `tp` | +| LoongArch | `$r3` | `sp` | +| LoongArch | `$r22` | `fp` | > **Notes**: > - TI does not mandate a frame pointer for MSP430, but toolchains are allowed @@ -107,7 +116,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | Architecture | Unsupported register | Reason | | ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | -| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k) | The frame pointer cannot be used as an input or output. | +| All | `fr` (Hexagon), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `$fp` (LoongArch) | The frame pointer cannot be used as an input or output. | | All | `r19` (Hexagon) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. | | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | | MIPS | `$1` or `$at` | Reserved for assembler. | @@ -118,6 +127,10 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | +| LoongArch | `$r0` or `$zero` | This is a constant zero register which can't be modified. | +| LoongArch | `$r2` or `$tp` | This is reserved for TLS. | +| LoongArch | `$r21` | This is reserved by the ABI. | +| LoongArch | `$r31` or `$s8` | This is used internally by LLVM. | ## Template modifiers @@ -132,6 +145,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `reg` | None | `0` | None | | PowerPC | `reg_nonzero` | None | `3` | `b` | | PowerPC | `freg` | None | `0` | None | +| LoongArch | `reg` | None | `$r2` | None | +| LoongArch | `freg` | None | `$f0` | None | # Flags covered by `preserves_flags` diff --git a/src/doc/unstable-book/src/language-features/transparent-unions.md b/src/doc/unstable-book/src/language-features/transparent-unions.md index 9b39b897164..bab88b148b2 100644 --- a/src/doc/unstable-book/src/language-features/transparent-unions.md +++ b/src/doc/unstable-book/src/language-features/transparent-unions.md @@ -65,7 +65,7 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable. pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () }; ``` -Like transarent `struct`s, a transparent `union` of type `U` has the same +Like transparent `struct`s, a transparent `union` of type `U` has the same layout, size, and ABI as its single non-ZST field. If it is generic over a type `T`, and all its fields are ZSTs except for exactly one field of type `T`, then it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized). diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml index 1643fc8364b..395814e7488 100644 --- a/src/etc/installer/pkg/Distribution.xml +++ b/src/etc/installer/pkg/Distribution.xml @@ -23,7 +23,7 @@ </choices-outline> <!-- These 'selected' scripts ensure that install and uninstall can never be selected at - the same time. Exectly how they work is pretty mysterious, tied to the unspecified algorithm + the same time. Exactly how they work is pretty mysterious, tied to the unspecified algorithm the installer uses to traverse the options after one is toggled. --> <choice id="install" visible="true" diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index bca9c2ae192..36c7d82b34a 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -115,4 +115,4 @@ def synthetic_lookup(valobj, dict): if rust_type == RustType.STD_REF_CELL: return StdRefSyntheticProvider(valobj, dict, is_cell=True) - return DefaultSynthteticProvider(valobj, dict) + return DefaultSyntheticProvider(valobj, dict) diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 697ad4293c3..4f73746f817 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -69,9 +69,9 @@ def unwrap_unique_or_non_null(unique_or_nonnull): return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0) -class DefaultSynthteticProvider: +class DefaultSyntheticProvider: def __init__(self, valobj, dict): - # type: (SBValue, dict) -> DefaultSynthteticProvider + # type: (SBValue, dict) -> DefaultSyntheticProvider # logger = Logger.Logger() # logger >> "Default synthetic provider for " + str(valobj.GetName()) self.valobj = valobj diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9479b3ee036..eeee12a4310 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::{self, Region, RegionVid, TypeFoldable}; use rustc_trait_selection::traits::auto_trait::{self, AutoTraitResult}; use thin_vec::ThinVec; @@ -141,7 +141,7 @@ where let f = auto_trait::AutoTraitFinder::new(tcx); debug!("get_auto_trait_impls({:?})", ty); - let auto_traits: Vec<_> = self.cx.auto_traits.iter().copied().collect(); + let auto_traits: Vec<_> = self.cx.auto_traits.to_vec(); let mut auto_traits: Vec<Item> = auto_traits .into_iter() .filter_map(|trait_def_id| { @@ -740,10 +740,9 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionReplacer<'a, 'tcx> { } fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - (match *r { - ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(), - _ => None, - }) - .unwrap_or_else(|| r.super_fold_with(self)) + match *r { + ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r), + _ => r, + } } } diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 3a3bf6a7ab9..e4c05b57378 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -20,7 +20,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { trace!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); for trait_def_id in cx.tcx.all_traits() { - if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, trait_def_id) + if !cx.cache.effective_visibilities.is_reachable(cx.tcx, trait_def_id) || cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some() { continue; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index cc5d13808b2..3f6a5d6d901 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -528,7 +528,7 @@ pub(crate) fn build_impl( items: trait_items, polarity, kind: if utils::has_doc_flag(tcx, did, sym::fake_variadic) { - ImplKind::FakeVaradic + ImplKind::FakeVariadic } else { ImplKind::Normal }, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5fa0c120fba..c992a5388d1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -422,8 +422,8 @@ fn clean_projection<'tcx>( let bounds = cx .tcx .explicit_item_bounds(ty.skip_binder().def_id) - .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.skip_binder().substs)) + .subst_iter_copied(cx.tcx, ty.skip_binder().substs) + .map(|(pred, _)| pred) .collect::<Vec<_>>(); return clean_middle_opaque_bounds(cx, bounds); } @@ -1315,10 +1315,11 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } if let ty::TraitContainer = assoc_item.container { - let bounds = tcx.explicit_item_bounds(assoc_item.def_id); + let bounds = + tcx.explicit_item_bounds(assoc_item.def_id).subst_identity_iter_copied(); let predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; let predicates = - tcx.arena.alloc_from_iter(bounds.into_iter().chain(predicates).copied()); + tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); let mut generics = clean_ty_generics( cx, tcx.generics_of(assoc_item.def_id), @@ -1845,8 +1846,8 @@ pub(crate) fn clean_middle_ty<'tcx>( let bounds = cx .tcx .explicit_item_bounds(def_id) - .iter() - .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs)) + .subst_iter_copied(cx.tcx, substs) + .map(|(bound, _)| bound) .collect::<Vec<_>>(); clean_middle_opaque_bounds(cx, bounds) } @@ -2356,7 +2357,7 @@ fn clean_impl<'tcx>( items, polarity: tcx.impl_polarity(def_id), kind: if utils::has_doc_flag(tcx, def_id.to_def_id(), sym::fake_variadic) { - ImplKind::FakeVaradic + ImplKind::FakeVariadic } else { ImplKind::Normal }, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 6d2ce9e2833..74f330b7621 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -20,7 +20,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyId, Mutability}; use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety; -use rustc_index::vec::IndexVec; +use rustc_index::IndexVec; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, TyCtxt, Visibility}; use rustc_resolve::rustdoc::{add_doc_fragment, attrs_to_doc_fragments, inner_docs, DocFragment}; @@ -156,7 +156,7 @@ impl ExternalCrate { } /// Attempts to find where an external crate is located, given that we're - /// rendering in to the specified source destination. + /// rendering into the specified source destination. pub(crate) fn location( &self, extern_url: Option<&str>, @@ -751,7 +751,7 @@ pub(crate) enum ItemKind { PrimitiveItem(PrimitiveType), /// A required associated constant in a trait declaration. TyAssocConstItem(Type), - /// An associated associated constant in a trait impl or a provided one in a trait declaration. + /// An associated constant in a trait impl or a provided one in a trait declaration. AssocConstItem(Type, ConstantKind), /// A required associated type in a trait declaration. /// @@ -2305,7 +2305,7 @@ impl Impl { pub(crate) enum ImplKind { Normal, Auto, - FakeVaradic, + FakeVariadic, Blanket(Box<Type>), } @@ -2319,7 +2319,7 @@ impl ImplKind { } pub(crate) fn is_fake_variadic(&self) -> bool { - matches!(self, ImplKind::FakeVaradic) + matches!(self, ImplKind::FakeVariadic) } pub(crate) fn as_blanket_ty(&self) -> Option<&Type> { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index cca50df0db2..b802fd065fe 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -243,9 +243,9 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs: _ }) => { let s = if let Some(def) = def.as_local() { - print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did)) + print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def)) } else { - inline::print_inlined_const(cx.tcx, def.did) + inline::print_inlined_const(cx.tcx, def) }; s diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 1be4f364ead..b579e7f5ae9 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -491,7 +491,7 @@ impl Options { // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset // // The original key values we have are the same as the DOM storage API keys and the - // command line options, so contain `-`. Our Javascript needs to be able to look + // command line options, so contain `-`. Our JavaScript needs to be able to look // these values up both in `dataset` and in the storage API, so it needs to be able // to convert the names back and forth. Despite doing this kebab-case to // StudlyCaps transformation automatically, the JS DOM API does not provide a diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b392ba05836..46834a1d7f4 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -258,8 +258,6 @@ pub(crate) fn create_config( override_queries: Some(|_sess, providers, _external_providers| { // Most lints will require typechecking, so just don't run them. providers.lint_mod = |_, _| {}; - // Prevent `rustc_hir_analysis::check_crate` from calling `typeck` on all bodies. - providers.typeck_item_bodies = |_, _| {}; // hack so that `used_trait_imports` won't try to call typeck providers.used_trait_imports = |_, _| { static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index c0329182032..841abfab666 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -300,14 +300,13 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { ParentStackItem::Impl { for_, .. } => for_.def_id(&self.cache), ParentStackItem::Type(item_id) => item_id.as_def_id(), }; - let path = match did.and_then(|did| self.cache.paths.get(&did)) { + let path = did + .and_then(|did| self.cache.paths.get(&did)) // The current stack not necessarily has correlation // for where the type was defined. On the other // hand, `paths` always has the right // information if present. - Some((fqp, _)) => Some(&fqp[..fqp.len() - 1]), - None => None, - }; + .map(|(fqp, _)| &fqp[..fqp.len() - 1]); ((did, path), true) } } diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index b61dd571458..946c85a205f 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -514,7 +514,7 @@ struct Classifier<'src> { impl<'src> Classifier<'src> { /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code - /// file span which will be used later on by the `span_correspondance_map`. + /// file span which will be used later on by the `span_correspondence_map`. fn new(src: &str, file_span: Span, decoration_info: Option<DecorationInfo>) -> Classifier<'_> { let tokens = PeekIter::new(TokenIter { src, cursor: Cursor::new(src) }); let decorations = decoration_info.map(Decorations::new); @@ -649,7 +649,7 @@ impl<'src> Classifier<'src> { /// /// `before` is the position of the given token in the `source` string and is used as "lo" byte /// in case we want to try to generate a link for this token using the - /// `span_correspondance_map`. + /// `span_correspondence_map`. fn advance( &mut self, token: TokenKind, @@ -895,7 +895,7 @@ fn exit_span(out: &mut impl Write, closing_tag: &str) { /// flexible. /// /// Note that if `context` is not `None` and that the given `klass` contains a `Span`, the function -/// will then try to find this `span` in the `span_correspondance_map`. If found, it'll then +/// will then try to find this `span` in the `span_correspondence_map`. If found, it'll then /// generate a link for this element (which corresponds to where its definition is located). fn string<T: Display>( out: &mut impl Write, @@ -916,7 +916,7 @@ fn string<T: Display>( /// * If `klass` is `Some` but `klass.get_span()` is `None`, it writes the text wrapped in a /// `<span>` with the provided `klass`. /// * If `klass` is `Some` and has a [`rustc_span::Span`], it then tries to generate a link (`<a>` -/// element) by retrieving the link information from the `span_correspondance_map` that was filled +/// element) by retrieving the link information from the `span_correspondence_map` that was filled /// in `span_map.rs::collect_spans_and_sources`. If it cannot retrieve the information, then it's /// the same as the second point (`klass` is `Some` but doesn't have a [`rustc_span::Span`]). fn string_without_closing_tag<T: Display>( @@ -963,7 +963,7 @@ fn string_without_closing_tag<T: Display>( if let Some(href_context) = href_context { if let Some(href) = - href_context.context.shared.span_correspondance_map.get(&def_span).and_then(|href| { + href_context.context.shared.span_correspondence_map.get(&def_span).and_then(|href| { let context = href_context.context; // FIXME: later on, it'd be nice to provide two links (if possible) for all items: // one to the documentation page and one to the source definition. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 00aadb8e82a..4b0aee9c3ad 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1392,7 +1392,7 @@ static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(|| fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> { let mut map = FxHashMap::default(); - // This is the list of IDs used in Javascript. + // This is the list of IDs used in JavaScript. map.insert("help".into(), 1); map.insert("settings".into(), 1); map.insert("not-displayed".into(), 1); diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index ac5054ce1b6..a063c8c9f02 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -122,9 +122,9 @@ pub(crate) struct SharedContext<'tcx> { /// the crate. redirections: Option<RefCell<FxHashMap<String, String>>>, - /// Correspondance map used to link types used in the source code pages to allow to click on + /// Correspondence map used to link types used in the source code pages to allow to click on /// links to jump to the type's definition. - pub(crate) span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>, + pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>, /// The [`Cache`] used during rendering. pub(crate) cache: Cache, @@ -531,7 +531,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { errors: receiver, redirections: if generate_redirect_map { Some(Default::default()) } else { None }, show_type_layout, - span_correspondance_map: matches, + span_correspondence_map: matches, cache, call_locations, }; @@ -647,7 +647,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { </div>\ <noscript>\ <section>\ - You need to enable Javascript be able to update your settings.\ + You need to enable JavaScript be able to update your settings.\ </section>\ </noscript>\ <link rel=\"stylesheet\" \ @@ -709,7 +709,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { </div>\ <noscript>\ <section>\ - <p>You need to enable Javascript to use keyboard commands or search.</p>\ + <p>You need to enable JavaScript to use keyboard commands or search.</p>\ <p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\ </section>\ </noscript>", diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 463184acaa1..a5f08fdac11 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -32,6 +32,7 @@ mod context; mod print_item; mod sidebar; mod span_map; +mod type_layout; mod write_shared; pub(crate) use self::context::*; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 9a968e48b27..3e71d41ec96 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -6,16 +6,14 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::stability; -use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self, Adt, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{LayoutS, Primitive, TagEncoding, Variants}; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; +use super::type_layout::document_type_layout; use super::{ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, @@ -1933,118 +1931,6 @@ fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a }) } -fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { - fn write_size_of_layout(mut w: impl fmt::Write, layout: &LayoutS, tag_size: u64) { - if layout.abi.is_unsized() { - write!(w, "(unsized)").unwrap(); - } else { - let size = layout.size.bytes() - tag_size; - write!(w, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" }).unwrap(); - if layout.abi.is_uninhabited() { - write!( - w, - " (<a href=\"https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited\">uninhabited</a>)" - ).unwrap(); - } - } - } - - display_fn(move |mut f| { - if !cx.shared.show_type_layout { - return Ok(()); - } - - writeln!( - f, - "<h2 id=\"layout\" class=\"small-section-header\"> \ - Layout<a href=\"#layout\" class=\"anchor\">§</a></h2>" - )?; - writeln!(f, "<div class=\"docblock\">")?; - - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - match tcx.layout_of(param_env.and(ty)) { - Ok(ty_layout) => { - writeln!( - f, - "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \ - <strong>completely unstable</strong> and may even differ between compilations. \ - The only exception is types with certain <code>repr(...)</code> attributes. \ - Please see the Rust Reference’s \ - <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \ - chapter for details on type layout guarantees.</p></div>" - )?; - f.write_str("<p><strong>Size:</strong> ")?; - write_size_of_layout(&mut f, &ty_layout.layout.0, 0); - writeln!(f, "</p>")?; - if let Variants::Multiple { variants, tag, tag_encoding, .. } = - &ty_layout.layout.variants() - { - if !variants.is_empty() { - f.write_str( - "<p><strong>Size for each variant:</strong></p>\ - <ul>", - )?; - - let Adt(adt, _) = ty_layout.ty.kind() else { - span_bug!(tcx.def_span(ty_def_id), "not an adt") - }; - - let tag_size = if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int") - }; - - for (index, layout) in variants.iter_enumerated() { - let name = adt.variant(index).name; - write!(&mut f, "<li><code>{name}</code>: ")?; - write_size_of_layout(&mut f, layout, tag_size); - writeln!(&mut f, "</li>")?; - } - f.write_str("</ul>")?; - } - } - } - // This kind of layout error can occur with valid code, e.g. if you try to - // get the layout of a generic type such as `Vec<T>`. - Err(LayoutError::Unknown(_)) => { - writeln!( - f, - "<p><strong>Note:</strong> Unable to compute type layout, \ - possibly due to this type having generic parameters. \ - Layout can only be computed for concrete, fully-instantiated types.</p>" - )?; - } - // This kind of error probably can't happen with valid code, but we don't - // want to panic and prevent the docs from building, so we just let the - // user know that we couldn't compute the layout. - Err(LayoutError::SizeOverflow(_)) => { - writeln!( - f, - "<p><strong>Note:</strong> Encountered an error during type layout; \ - the type was too big.</p>" - )?; - } - Err(LayoutError::NormalizationFailure(_, _)) => { - writeln!( - f, - "<p><strong>Note:</strong> Encountered an error during type layout; \ - the type failed to be normalized.</p>" - )?; - } - } - - writeln!(f, "</div>") - }) -} - fn pluralize(count: usize) -> &'static str { if count > 1 { "s" } else { "" } } diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs new file mode 100644 index 00000000000..22aec623335 --- /dev/null +++ b/src/librustdoc/html/render/type_layout.rs @@ -0,0 +1,86 @@ +use askama::Template; + +use rustc_data_structures::captures::Captures; +use rustc_hir::def_id::DefId; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::Adt; +use rustc_span::symbol::Symbol; +use rustc_target::abi::{Primitive, TagEncoding, Variants}; + +use std::fmt; + +use crate::html::format::display_fn; +use crate::html::render::Context; + +#[derive(Template)] +#[template(path = "type_layout.html")] +struct TypeLayout<'cx> { + variants: Vec<(Symbol, TypeLayoutSize)>, + type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>, +} + +#[derive(Template)] +#[template(path = "type_layout_size.html")] +struct TypeLayoutSize { + is_unsized: bool, + is_uninhabited: bool, + size: u64, +} + +pub(crate) fn document_type_layout<'a, 'cx: 'a>( + cx: &'a Context<'cx>, + ty_def_id: DefId, +) -> impl fmt::Display + 'a + Captures<'cx> { + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); + } + + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + + let variants = + if let Ok(type_layout) = type_layout && + let Variants::Multiple { variants, tag, tag_encoding, .. } = + type_layout.layout.variants() && + !variants.is_empty() + { + let tag_size = + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") + }; + variants + .iter_enumerated() + .map(|(variant_idx, variant_layout)| { + let Adt(adt, _) = type_layout.ty.kind() else { + span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") + }; + let name = adt.variant(variant_idx).name; + let is_unsized = variant_layout.abi.is_unsized(); + let is_uninhabited = variant_layout.abi.is_uninhabited(); + let size = variant_layout.size.bytes() - tag_size; + let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; + (name, type_layout_size) + }) + .collect() + } else { + Vec::new() + }; + + let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } + }); + + Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) + }) +} diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index d13c783d2e4..99cf8e443f0 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -7,7 +7,6 @@ margin-right: 0.3em; height: 1.2rem; width: 1.2rem; - color: inherit; border: 2px solid var(--settings-input-border-color); outline: none; -webkit-appearance: none; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 6f5987e68bf..bccf675c14b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -275,8 +275,7 @@ function preLoadCss(cssUrl) { document.title = searchState.titleBeforeSearch; // We also remove the query parameter from the URL. if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); + history.replaceState(null, "", getNakedUrl() + window.location.hash); } }, getQueryStringParams: () => { @@ -376,11 +375,7 @@ function preLoadCss(cssUrl) { function handleEscape(ev) { searchState.clearInputTimeout(); - switchDisplayedElement(null); - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } + searchState.hideResults(); ev.preventDefault(); searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips @@ -535,9 +530,11 @@ function preLoadCss(cssUrl) { // ignored are included in the attribute `data-ignore-extern-crates`. const script = document .querySelector("script[data-ignore-extern-crates]"); - const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; + const ignoreExternCrates = new Set( + (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",") + ); for (const lib of libs) { - if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { + if (lib === window.currentCrate || ignoreExternCrates.has(lib)) { continue; } const structs = imp[lib]; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 929dae81c8d..3dc4f2149b8 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2412,10 +2412,6 @@ function initSearch(rawSearchIndex) { const searchAfter500ms = () => { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } searchState.hideResults(); } else { searchState.timeout = setTimeout(search, 500); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index ebbe6c1ca9a..2cba32c1b50 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global getSettingValue, getVirtualKey, updateLocalStorage, updateTheme */ +/* global getSettingValue, updateLocalStorage, updateTheme */ /* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */ /* global MAIN_ID, getVar, getSettingsButton */ @@ -32,21 +32,6 @@ } } - function handleKey(ev) { - // Don't interfere with browser shortcuts - if (ev.ctrlKey || ev.altKey || ev.metaKey) { - return; - } - switch (getVirtualKey(ev)) { - case "Enter": - case "Return": - case "Space": - ev.target.checked = !ev.target.checked; - ev.preventDefault(); - break; - } - } - function showLightAndDark() { removeClass(document.getElementById("preferred-light-theme"), "hidden"); removeClass(document.getElementById("preferred-dark-theme"), "hidden"); @@ -77,8 +62,6 @@ toggle.onchange = function() { changeSetting(this.id, this.checked); }; - toggle.onkeyup = handleKey; - toggle.onkeyrelease = handleKey; }); onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => { const settingId = elem.name; diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 9aa75517330..d999f3b36fd 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -52,12 +52,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const files = document.createElement("div"); files.className = "files"; if (elem[FILES_OFFSET]) { + const w = window.location.href.split("#")[0]; for (const file_text of elem[FILES_OFFSET]) { const file = document.createElement("a"); file.innerText = file_text; file.href = rootPath + "src/" + fullPath + file_text + ".html"; file.addEventListener("click", closeSidebarIfMobile); - const w = window.location.href.split("#")[0]; if (!hasFoundFile && w === file.href) { file.className = "selected"; dirEntry.open = true; diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html new file mode 100644 index 00000000000..58b220c7428 --- /dev/null +++ b/src/librustdoc/html/templates/type_layout.html @@ -0,0 +1,53 @@ +<h2 id="layout" class="small-section-header"> {# #} + Layout<a href="#layout" class="anchor">§</a> {# #} +</h2> {# #} +<div class="docblock"> {# #} + {% match type_layout_size %} + {% when Ok(type_layout_size) %} + <div class="warning"> {# #} + <p> {# #} + <strong>Note:</strong> Most layout information is <strong>completely {#+ #} + unstable</strong> and may even differ between compilations. {#+ #} + The only exception is types with certain <code>repr(...)</code> {#+ #} + attributes. Please see the Rust Reference’s {#+ #} + <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #} + chapter for details on type layout guarantees. {# #} + </p> {# #} + </div> {# #} + <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #} + {% if !variants.is_empty() %} + <p> {# #} + <strong>Size for each variant:</strong> {# #} + </p> {# #} + <ul> {# #} + {% for (name, layout_size) in variants %} + <li> {# #} + <code>{{ name }}</code>: {#+ #} + {{ layout_size|safe }} + </li> {# #} + {% endfor %} + </ul> {# #} + {% endif %} + {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec<T>`. #} + {% when Err(LayoutError::Unknown(_)) %} + <p> {# #} + <strong>Note:</strong> Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} + </p> {# #} + {# This kind of error probably can't happen with valid code, but we don't + want to panic and prevent the docs from building, so we just let the + user know that we couldn't compute the layout. #} + {% when Err(LayoutError::SizeOverflow(_)) %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type was too big. {# #} + </p> {# #} + {% when Err(LayoutError::NormalizationFailure(_, _)) %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type failed to be normalized. {# #} + </p> {# #} + {% endmatch %} +</div> {# #} diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html new file mode 100644 index 00000000000..9c2b39edc9f --- /dev/null +++ b/src/librustdoc/html/templates/type_layout_size.html @@ -0,0 +1,12 @@ +{% if is_unsized %} + (unsized) +{% else %} + {% if size == 1 %} + 1 byte + {% else %} + {{ size +}} bytes + {% endif %} + {% if is_uninhabited %} + {# +#} (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>) + {% endif %} +{% endif %} diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index cd6509607d5..edd046ab772 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -665,7 +665,7 @@ impl FromWithTcx<clean::Impl> for Impl { let clean::Impl { unsafety, generics, trait_, for_, items, polarity, kind } = impl_; // FIXME: use something like ImplKind in JSON? let (synthetic, blanket_impl) = match kind { - clean::ImplKind::Normal | clean::ImplKind::FakeVaradic => (false, None), + clean::ImplKind::Normal | clean::ImplKind::FakeVariadic => (false, None), clean::ImplKind::Auto => (true, None), clean::ImplKind::Blanket(ty) => (false, Some(*ty)), }; @@ -740,7 +740,7 @@ impl FromWithTcx<clean::Variant> for Variant { impl FromWithTcx<clean::Discriminant> for Discriminant { fn from_tcx(disr: clean::Discriminant, tcx: TyCtxt<'_>) -> Self { Discriminant { - // expr is only none if going through the inlineing path, which gets + // expr is only none if going through the inlining path, which gets // `rustc_middle` types, not `rustc_hir`, but because JSON never inlines // the expr is always some. expr: disr.expr(tcx).unwrap(), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a835bd2de3b..f2486abaaa7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -13,7 +13,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, Namespace, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::Mutability; -use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, ty}; use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution}; use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics}; @@ -772,11 +772,10 @@ fn trait_impls_for<'a>( module: DefId, ) -> FxHashSet<(DefId, DefId)> { let tcx = cx.tcx; - let iter = tcx.doc_link_traits_in_scope(module).iter().flat_map(|&trait_| { - trace!("considering explicit impl for trait {:?}", trait_); + let mut impls = FxHashSet::default(); - // Look at each trait implementation to see if it's an impl for `did` - tcx.find_map_relevant_impl(trait_, ty, TreatProjections::ForLookup, |impl_| { + for &trait_ in tcx.doc_link_traits_in_scope(module) { + tcx.for_each_relevant_impl(trait_, ty, |impl_| { let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); // Check if these are the same type. let impl_type = trait_ref.skip_binder().self_ty(); @@ -800,10 +799,13 @@ fn trait_impls_for<'a>( _ => false, }; - if saw_impl { Some((impl_, trait_)) } else { None } - }) - }); - iter.collect() + if saw_impl { + impls.insert((impl_, trait_)); + } + }); + } + + impls } /// Check for resolve collisions between a trait and its derive. @@ -1419,6 +1421,7 @@ impl Disambiguator { if let Some(idx) = link.find('@') { let (prefix, rest) = link.split_at(idx); let d = match prefix { + // If you update this list, please also update the relevant rustdoc book section! "struct" => Kind(DefKind::Struct), "enum" => Kind(DefKind::Enum), "trait" => Kind(DefKind::Trait), @@ -1437,6 +1440,7 @@ impl Disambiguator { Ok(Some((d, &rest[1..], &rest[1..]))) } else { let suffixes = [ + // If you update this list, please also update the relevant rustdoc book section! ("!()", DefKind::Macro(MacroKind::Bang)), ("!{}", DefKind::Macro(MacroKind::Bang)), ("![]", DefKind::Macro(MacroKind::Bang)), diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index f28c164d61d..dfa99ffcb7c 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -286,7 +286,7 @@ pub(crate) fn run( let (cx, _) = Context::init(krate, renderopts, cache, tcx).map_err(|e| e.to_string())?; // Collect CrateIds corresponding to provided target crates - // If two different versions of the crate in the dependency tree, then examples will be collcted from both. + // If two different versions of the crate in the dependency tree, then examples will be collected from both. let all_crates = tcx .crates(()) .iter() diff --git a/src/librustdoc/theme/tests.rs b/src/librustdoc/theme/tests.rs index 08a174d27d3..2a28c19c3fe 100644 --- a/src/librustdoc/theme/tests.rs +++ b/src/librustdoc/theme/tests.rs @@ -13,11 +13,11 @@ rule d // another line comment e {} -rule f/* a multine +rule f/* a multiline comment*/{} -rule g/* another multine +rule g/* another multiline comment*/h diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f54b70b417d..a6089680fae 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -10,6 +10,7 @@ use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; @@ -87,6 +88,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> { inside_public_path: bool, exact_paths: DefIdMap<Vec<Symbol>>, modules: Vec<Module<'tcx>>, + is_importable_from_parent: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -107,6 +109,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inside_public_path: true, exact_paths: Default::default(), modules: vec![om], + is_importable_from_parent: true, } } @@ -319,11 +322,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option<Symbol>, parent_id: Option<LocalDefId>, ) { - self.modules - .last_mut() - .unwrap() - .items - .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); + if self.is_importable_from_parent + // If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export` + // attribute can still be visible. + || match item.kind { + hir::ItemKind::Impl(..) => true, + hir::ItemKind::Macro(_, MacroKind::Bang) => { + self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) + } + _ => false, + } + { + self.modules + .last_mut() + .unwrap() + .items + .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); + } } fn visit_item_inner( @@ -331,7 +346,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { item: &'tcx hir::Item<'_>, renamed: Option<Symbol>, import_id: Option<LocalDefId>, - ) -> bool { + ) { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -448,7 +463,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } } - true } fn visit_foreign_item_inner( @@ -485,9 +499,23 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { } fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { - if self.visit_item_inner(i, None, None) { - walk_item(self, i); - } + self.visit_item_inner(i, None, None); + let new_value = if self.is_importable_from_parent { + matches!( + i.kind, + hir::ItemKind::Mod(..) + | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Impl(..) + | hir::ItemKind::Trait(..) + ) + } else { + // Whatever the context, if it's an impl block, the items inside it can be used so they + // should be visible. + matches!(i.kind, hir::ItemKind::Impl(..)) + }; + let prev = mem::replace(&mut self.is_importable_from_parent, new_value); + walk_item(self, i); + self.is_importable_from_parent = prev; } fn visit_mod(&mut self, _: &hir::Mod<'tcx>, _: Span, _: hir::HirId) { diff --git a/src/llvm-project b/src/llvm-project -Subproject 585a6eb3ebf7c40fd7c1b23e3ece557b3cc2aa3 +Subproject ea6fa9c2d43aaf0f11559719eda9b54d356d541 diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index 9f113c72b93..d2e9c324af8 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -38,3 +38,27 @@ impl CiEnv { } } } + +pub mod gha { + /// All github actions log messages from this call to the Drop of the return value + /// will be grouped and hidden by default in logs. Note that nesting these does + /// not really work. + pub fn group(name: impl std::fmt::Display) -> Group { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::group::{name}"); + } + Group(()) + } + + /// A guard that closes the current github actions log group on drop. + #[must_use] + pub struct Group(()); + + impl Drop for Group { + fn drop(&mut self) { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::endgroup::"); + } + } + } +} diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 84b7041fd2745ee6b3b4a150314f81aabb78e6b +Subproject 9e586fbd8b931494067144623b76c37d213b1ab diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md index 559b560dde4..d7102d2474e 100644 --- a/src/tools/clippy/CHANGELOG.md +++ b/src/tools/clippy/CHANGELOG.md @@ -6,11 +6,126 @@ document. ## Unreleased / Beta / In Rust Nightly -[7f27e2e7...master](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...master) +[149392b0...master](https://github.com/rust-lang/rust-clippy/compare/149392b0...master) + +## Rust 1.69 + +Current stable, released 2023-04-20 + +[7f27e2e7...149392b0](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...149392b0) + +### New Lints + +* [`no_mangle_with_rust_abi`] + [#10369](https://github.com/rust-lang/rust-clippy/pull/10369) +* [`significant_drop_tightening`] + [#10163](https://github.com/rust-lang/rust-clippy/pull/10163) +* [`suspicious_command_arg_space`] + [#10317](https://github.com/rust-lang/rust-clippy/pull/10317) +* [`let_underscore_untyped`] + [#10356](https://github.com/rust-lang/rust-clippy/pull/10356) +* [`question_mark_used`] + [#10342](https://github.com/rust-lang/rust-clippy/pull/10342) +* [`extra_unused_type_parameters`] + [#10028](https://github.com/rust-lang/rust-clippy/pull/10028) +* [`impl_trait_in_params`] + [10197](https://github.com/rust-lang/rust-clippy/pull/10197) +* [`transmute_int_to_non_zero`] + [#10360](https://github.com/rust-lang/rust-clippy/pull/10360) +* [`multiple_unsafe_ops_per_block`] + [#10206](https://github.com/rust-lang/rust-clippy/pull/10206) + +### Moves and Deprecations + +* Moved [`uninlined_format_args`] to `pedantic` (Now allow-by-default) + [#10265](https://github.com/rust-lang/rust-clippy/pull/10265) +* Moved [`unchecked_duration_subtraction`] to `pedantic` (Now allow-by-default) + [#10194](https://github.com/rust-lang/rust-clippy/pull/10194) + +### Enhancements + +* [`arithmetic_side_effects`]: No longer lints, if safe constant values are used. + [#10310](https://github.com/rust-lang/rust-clippy/pull/10310) +* [`needless_lifetimes`]: Now works in local macros + [#10257](https://github.com/rust-lang/rust-clippy/pull/10257) +* [`unused_io_amount`]: Now detects usages of `is_ok` and `is_err` + [#10225](https://github.com/rust-lang/rust-clippy/pull/10225) +* [`missing_docs_in_private_items`]: Added new configuration `missing-docs-in-crate-items` to lint + on items visible within the current crate. For example, `pub(crate)` items. + [#10303](https://github.com/rust-lang/rust-clippy/pull/10303) +* [`almost_swapped`]: Now detects almost swaps using `let` statements + [#10177](https://github.com/rust-lang/rust-clippy/pull/10177) +* [`wildcard_enum_match_arm`]: Now lints missing private variants, for local enums + [#10250](https://github.com/rust-lang/rust-clippy/pull/10250) + +### False Positive Fixes + +* [`explicit_auto_deref`]: Now considers projections, when determining if auto deref is applicable + [#10386](https://github.com/rust-lang/rust-clippy/pull/10386) +* [`manual_let_else`]: Now considers side effects of branches, before linting + [#10336](https://github.com/rust-lang/rust-clippy/pull/10336) +* [`uninlined_format_args`]: No longer lints for arguments with generic parameters + [#10343](https://github.com/rust-lang/rust-clippy/pull/10343) +* [`needless_lifetimes`]: No longer lints signatures in macros, if the lifetime is a metavariable + [#10380](https://github.com/rust-lang/rust-clippy/pull/10380) +* [`len_without_is_empty`]: No longer lints, if `len` as a non-default signature + [#10255](https://github.com/rust-lang/rust-clippy/pull/10255) +* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes, to reduce false + positives + [#10353](https://github.com/rust-lang/rust-clippy/pull/10353) +* [`manual_let_else`]: No longer lints `if-else` blocks if they can divergent + [#10332](https://github.com/rust-lang/rust-clippy/pull/10332) +* [`expect_used`], [`unwrap_used`], [`dbg_macro`], [`print_stdout`], [`print_stderr`]: No longer lint + in test functions, if `allow-expect-in-tests` is set + [#10391](https://github.com/rust-lang/rust-clippy/pull/10391) +* [`unnecessary_safety_comment`]: No longer lints code inside macros + [#10106](https://github.com/rust-lang/rust-clippy/pull/10106) +* [`never_loop`]: No longer lints, for statements following break statements for outer blocks. + [#10311](https://github.com/rust-lang/rust-clippy/pull/10311) + +### Suggestion Fixes/Improvements + +* [`box_default`]: The suggestion now includes the type for trait objects, when needed + [#10382](https://github.com/rust-lang/rust-clippy/pull/10382) +* [`cast_possible_truncation`]: Now suggests using `try_from` or allowing the lint + [#10038](https://github.com/rust-lang/rust-clippy/pull/10038) +* [`invalid_regex`]: Regex errors for non-literals or regular strings containing escape sequences will + now show the complete error + [#10231](https://github.com/rust-lang/rust-clippy/pull/10231) +* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works, if the base type is borrowed + [#10193](https://github.com/rust-lang/rust-clippy/pull/10193) +* [`needless_return`]: Now removes all semicolons on the same line + [#10187](https://github.com/rust-lang/rust-clippy/pull/10187) +* [`suspicious_to_owned`]: The suggestion now shows all options clearly + [#10295](https://github.com/rust-lang/rust-clippy/pull/10295) +* [`bytes_nth`]: Now suggests the correct replacement based on the context + [#10361](https://github.com/rust-lang/rust-clippy/pull/10361) +* [`bool_assert_comparison`]: The suggestion is now machine applicable + [#10218](https://github.com/rust-lang/rust-clippy/pull/10218) +* [`cast_possible_truncation`]: Corrected the lint name in the help message + [#10330](https://github.com/rust-lang/rust-clippy/pull/10330) +* [`needless_return`]: The suggestion now works on if sequences + [#10345](https://github.com/rust-lang/rust-clippy/pull/10345) +* [`needless_lifetimes`]: The suggestion is now machine applicable + [#10222](https://github.com/rust-lang/rust-clippy/pull/10222) +* [`map_entry`]: The suggestion no longer expands macros + [#10346](https://github.com/rust-lang/rust-clippy/pull/10346) + +### ICE Fixes + +* [`needless_pass_by_value`]: Fixed an ICE, caused by how late bounds were handled + [#10328](https://github.com/rust-lang/rust-clippy/pull/10328) +* [`needless_borrow`]: No longer panics on ambiguous projections + [#10403](https://github.com/rust-lang/rust-clippy/pull/10403) + +### Documentation Improvements + +* All configurations are now documented in the Clippy Book + [#10199](https://github.com/rust-lang/rust-clippy/pull/10199) ## Rust 1.68 -Current stable, released 2023-03-09 +Released 2023-03-09 [d822110d...7f27e2e7](https://github.com/rust-lang/rust-clippy/compare/d822110d...7f27e2e7) @@ -4615,6 +4730,7 @@ Released 2018-09-13 [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters [`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements +[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module [`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect [`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count [`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index c35dfcbd8c4..4db15ddb283 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -22,13 +22,12 @@ path = "src/driver.rs" [dependencies] clippy_lints = { path = "clippy_lints" } -semver = "1.0" rustc_tools_util = "0.3.0" tempfile = { version = "3.2", optional = true } termize = "0.1" [dev-dependencies] -compiletest_rs = { version = "0.9", features = ["tmp"] } +compiletest_rs = { version = "0.10", features = ["tmp"] } tester = "0.9" regex = "1.5" toml = "0.5" @@ -49,7 +48,7 @@ if_chain = "1.0" itertools = "0.10.1" quote = "1.0" serde = { version = "1.0.125", features = ["derive"] } -syn = { version = "1.0", features = ["full"] } +syn = { version = "2.0", features = ["full"] } futures = "0.3" parking_lot = "0.12" tokio = { version = "1", features = ["io-util"] } diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md index cbd73376dfa..22fbdce75e8 100644 --- a/src/tools/clippy/book/src/SUMMARY.md +++ b/src/tools/clippy/book/src/SUMMARY.md @@ -13,7 +13,9 @@ - [Development](development/README.md) - [Basics](development/basics.md) - [Adding Lints](development/adding_lints.md) + - [Lint Passes](development/lint_passes.md) - [Type Checking](development/type_checking.md) + - [Macro Expansions](development/macro_expansions.md) - [Common Tools](development/common_tools_writing_lints.md) - [Infrastructure](development/infrastructure/README.md) - [Syncing changes between Clippy and rust-lang/rust](development/infrastructure/sync.md) diff --git a/src/tools/clippy/book/src/development/README.md b/src/tools/clippy/book/src/development/README.md index 616e6d182b7..8f09f66f595 100644 --- a/src/tools/clippy/book/src/development/README.md +++ b/src/tools/clippy/book/src/development/README.md @@ -13,6 +13,24 @@ If this is your first time contributing to Clippy, you should first read the [Basics docs](basics.md). This will explain the basics on how to get the source code and how to compile and test the code. +## Additional Readings for Beginners + +If a dear reader of this documentation has never taken a class on compilers +and interpreters, it might be confusing as to why AST level deals with only +the language's syntax. And some readers might not even understand what lexing, +parsing, and AST mean. + +This documentation serves by no means as a crash course on compilers or language design. +And for details specifically related to Rust, the [Rustc Development Guide][rustc_dev_guide] +is a far better choice to peruse. + +The [Syntax and AST][ast] chapter and the [High-Level IR][hir] chapter are +great introduction to the concepts mentioned in this chapter. + +Some readers might also find the [introductory chapter][map_of_territory] of +Robert Nystrom's _Crafting Interpreters_ a helpful overview of compiled and +interpreted languages before jumping back to the Rustc guide. + ## Writing code If you have done the basic setup, it's time to start hacking. @@ -37,6 +55,10 @@ book](../lints.md). > - Triage procedure > - Bors and Homu +[ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html +[hir]: https://rustc-dev-guide.rust-lang.org/hir.html +[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/ +[map_of_territory]: https://craftinginterpreters.com/a-map-of-the-territory.html [clippy_rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md [rfc_stability]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#stability-guarantees [rfc_lint_cats]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md index 9dacaaaae5c..ccae8d37420 100644 --- a/src/tools/clippy/book/src/development/adding_lints.md +++ b/src/tools/clippy/book/src/development/adding_lints.md @@ -164,7 +164,7 @@ The process of generating the `.stderr` file is the same, and prepending the ## Rustfix tests If the lint you are working on is making use of structured suggestions, the test -file should include a `// run-rustfix` comment at the top. This will +file should include a `//@run-rustfix` comment at the top. This will additionally run [rustfix] for that test. Rustfix will apply the suggestions from the lint to the code of the test file and compare that to the contents of a `.fixed` file. diff --git a/src/tools/clippy/book/src/development/lint_passes.md b/src/tools/clippy/book/src/development/lint_passes.md new file mode 100644 index 00000000000..131f6455fde --- /dev/null +++ b/src/tools/clippy/book/src/development/lint_passes.md @@ -0,0 +1,114 @@ +# Lint passes + +Before working on the logic of a new lint, there is an important decision +that every Clippy developer must make: to use +[`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass]. + +In short, the `LateLintPass` has access to type and symbol information while the +`EarlyLintPass` doesn't. If you don't need access to type information, use the +`EarlyLintPass`. + +Let us expand on these two traits more below. + +## `EarlyLintPass` + +If you examine the documentation on [`EarlyLintPass`][early_lint_pass] closely, +you'll see that every method defined for this trait utilizes a +[`EarlyContext`][early_context]. In `EarlyContext`'s documentation, it states: + +> Context for lint checking of the AST, after expansion, before lowering to HIR. + +Voilà. `EarlyLintPass` works only on the Abstract Syntax Tree (AST) level. +And AST is generated during the [lexing and parsing][lexing_and_parsing] phase +of code compilation. Therefore, it doesn't know what a symbol means or information about types, and it should +be our trait choice for a new lint if the lint only deals with syntax-related issues. + +While linting speed has not been a concern for Clippy, +the `EarlyLintPass` is faster, and it should be your choice +if you know for sure a lint does not need type information. + +As a reminder, run the following command to generate boilerplate for lints +that use `EarlyLintPass`: + +```sh +$ cargo dev new_lint --name=<your_new_lint> --pass=early --category=<your_category_choice> +``` + +### Example for `EarlyLintPass` + +Take a look at the following code: + +```rust +let x = OurUndefinedType; +x.non_existing_method(); +``` + +From the AST perspective, both lines are "grammatically" correct. +The assignment uses a `let` and ends with a semicolon. The invocation +of a method looks fine, too. As programmers, we might raise a few +questions already, but the parser is okay with it. This is what we +mean when we say `EarlyLintPass` deals with only syntax on the AST level. + +Alternatively, think of the `foo_functions` lint we mentioned in +define new lints chapter. + +We want the `foo_functions` lint to detect functions with `foo` as their name. +Writing a lint that only checks for the name of a function means that we only +work with the AST and don't have to access the type system at all (the type system is where +`LateLintPass` comes into the picture). + +## `LateLintPass` + +In contrast to `EarlyLintPass`, `LateLintPass` contains type information. + +If you examine the documentation on [`LateLintPass`][late_lint_pass] closely, +you see that every method defined in this trait utilizes a +[`LateContext`][late_context]. + +In `LateContext`'s documentation we will find methods that +deal with type-checking, which do not exist in `EarlyContext`, such as: + +- [`maybe_typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.maybe_typeck_results) +- [`typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.typeck_results) + +### Example for `LateLintPass` + +Let us take a look with the following example: + +```rust +let x = OurUndefinedType; +x.non_existing_method(); +``` + +These two lines of code are syntactically correct code from the perspective +of the AST. We have an assignment and invoke a method on the variable that +is of a type. Grammatically, everything is in order for the parser. + +However, going down a level and looking at the type information, +the compiler will notice that both `OurUndefinedType` and `non_existing_method()` +**are undefined**. + +As Clippy developers, to access such type information, we must implement +`LateLintPass` on our lint. +When you browse through Clippy's lints, you will notice that almost every lint +is implemented in a `LateLintPass`, specifically because we often need to check +not only for syntactic issues but also type information. + +Another limitation of the `EarlyLintPass` is that the nodes are only identified +by their position in the AST. This means that you can't just get an `id` and +request a certain node. For most lints that is fine, but we have some lints +that require the inspection of other nodes, which is easier at the HIR level. +In these cases, `LateLintPass` is the better choice. + +As a reminder, run the following command to generate boilerplate for lints +that use `LateLintPass`: + +```sh +$ cargo dev new_lint --name=<your_new_lint> --pass=late --category=<your_category_choice> +``` + +[early_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.EarlyContext.html +[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html +[late_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html +[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html +[lexing_and_parsing]: https://rustc-dev-guide.rust-lang.org/overview.html#lexing-and-parsing diff --git a/src/tools/clippy/book/src/development/macro_expansions.md b/src/tools/clippy/book/src/development/macro_expansions.md new file mode 100644 index 00000000000..c5eb000272d --- /dev/null +++ b/src/tools/clippy/book/src/development/macro_expansions.md @@ -0,0 +1,158 @@ +# Dealing with macros and expansions + +Sometimes we might encounter Rust macro expansions while working with Clippy. +While macro expansions are not as dramatic and profound as the expansion +of our universe, they can certainly bring chaos to the orderly world +of code and logic. + +The general rule of thumb is that we should ignore code with macro +expansions when working with Clippy because the code can be dynamic +in ways that are difficult or impossible for us to foresee. + +## False Positives + +What exactly do we mean by _dynamic in ways that are difficult to foresee_? + +Macros are [expanded][expansion] in the `EarlyLintPass` level, +so the Abstract Syntax Tree (AST) is generated in place of macros. +This means the code which we work with in Clippy is already expanded. + +If we wrote a new lint, there is a possibility that the lint is +triggered in macro-generated code. Since this expanded macro code +is not written by the macro's user but really by the macro's author, +the user cannot and should not be responsible for fixing the issue +that triggers the lint. + +Besides, a [Span] in a macro can be changed by the macro author. +Therefore, any lint check related to lines or columns should be +avoided since they might be changed at any time and become unreliable +or incorrect information. + +Because of these unforeseeable or unstable behaviors, macro expansion +should often not be regarded as a part of the stable API. +This is also why most lints check if they are inside a macro or not +before emitting suggestions to the end user to avoid false positives. + +## How to Work with Macros + +Several functions are available for working with macros. + +### The `Span.from_expansion` method + +We could utilize a `span`'s [`from_expansion`] method, which +detects if the `span` is from a macro expansion / desugaring. +This is a very common first step in a lint: + +```rust +if expr.span.from_expansion() { + // We most likely want to ignore it. + return; +} +``` + +### `Span.ctxt` method + +The `span`'s context, given by the method [`ctxt`] and returning [SpanContext], +represents if the span is from a macro expansion and, if it is, which +macro call expanded this span. + +Sometimes, it is useful to check if the context of two spans are equal. +For instance, suppose we have the following line of code that would +expand into `1 + 0`: + +```rust +// The following code expands to `1 + 0` for both `EarlyLintPass` and `LateLintPass` +1 + mac!() +``` + +Assuming that we'd collect the `1` expression as a variable `left` and the +`0`/`mac!()` expression as a variable `right`, we can simply compare their +contexts. If the context is different, then we most likely are dealing with a +macro expansion and should just ignore it: + +```rust +if left.span.ctxt() != right.span.ctxt() { + // The code author most likely cannot modify this expression + return; +} +``` + +> **Note**: Code that is not from expansion is in the "root" context. +> So any spans whose `from_expansion` returns `false` can be assumed +> to have the same context. Because of this, using `span.from_expansion()` +> is often sufficient. + +Going a bit deeper, in a simple expression such as `a == b`, +`a` and `b` have the same context. +However, in a `macro_rules!` with `a == $b`, `$b` is expanded to +an expression that contains a different context from `a`. + +Take a look at the following macro `m`: + +```rust +macro_rules! m { + ($a:expr, $b:expr) => { + if $a.is_some() { + $b; + } + } +} + +let x: Option<u32> = Some(42); +m!(x, x.unwrap()); +``` + +If the `m!(x, x.unwrapp());` line is expanded, we would get two expanded +expressions: + +- `x.is_some()` (from the `$a.is_some()` line in the `m` macro) +- `x.unwrap()` (corresponding to `$b` in the `m` macro) + +Suppose `x.is_some()` expression's span is associated with the `x_is_some_span` variable +and `x.unwrap()` expression's span is associated with `x_unwrap_span` variable, +we could assume that these two spans do not share the same context: + +```rust +// x.is_some() is from inside the macro +// x.unwrap() is from outside the macro +assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt()); +``` + +### The `in_external_macro` function + +`rustc_middle::lint` provides a function ([`in_external_macro`]) that can +detect if the given span is from a macro defined in a foreign crate. + +Therefore, if we really want a new lint to work with macro-generated code, +this is the next line of defense to avoid macros not defined inside +the current crate since it is unfair to the user if Clippy lints code +which the user cannot change. + +For example, assume we have the following code that is being examined +by Clippy: + +```rust +#[macro_use] +extern crate a_foreign_crate_with_macros; + +// `foo` macro is defined in `a_foreign_crate_with_macros` +foo!("bar"); +``` + +Also assume that we get the corresponding variable `foo_span` for the +`foo` macro call, we could decide not to lint if `in_external_macro` +results in `true` (note that `cx` can be `EarlyContext` or `LateContext`): + +```rust +if in_external_macro(cx.sess(), foo_span) { + // We should ignore macro from a foreign crate. + return; +} +``` + +[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt +[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration +[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion +[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html +[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html +[SpanContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html diff --git a/src/tools/clippy/book/src/development/type_checking.md b/src/tools/clippy/book/src/development/type_checking.md index 5ce434b99a1..225de849566 100644 --- a/src/tools/clippy/book/src/development/type_checking.md +++ b/src/tools/clippy/book/src/development/type_checking.md @@ -51,7 +51,7 @@ impl LateLintPass<'_> for MyStructLint { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // Get type of `expr` let ty = cx.typeck_results().expr_ty(expr); - + // Check if the `Ty` of this expression is of character type if ty.is_char() { println!("Our expression is a char!"); @@ -70,18 +70,18 @@ pub fn is_char(self) -> bool { } ``` -Indeed, we just discovered `Ty`'s [`kind` method][kind], which provides us +Indeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us with [`TyKind`][TyKind] of a `Ty`. ## `TyKind` `TyKind` defines the kinds of types in Rust's type system. Peeking into [`TyKind` documentation][TyKind], we will see that it is an -enum of 27 variants, including items such as `Bool`, `Int`, `Ref`, etc. +enum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc. ### `kind` Usage -The `TyKind` of `Ty` can be returned by calling [`Ty.kind` method][kind]. +The `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind]. We often use this method to perform pattern matching in Clippy. For instance, if we want to check for a `struct`, we could examine if the @@ -107,15 +107,21 @@ impl LateLintPass<'_> for MyStructLint { We've been talking about [`ty::Ty`][middle_ty] this whole time without addressing [`hir::Ty`][hir_ty], but the latter is also important to understand. -`hir::Ty` would represent *what* an user wrote, while `ty::Ty` would understand the meaning of it (because it has more -information). +`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more +information. Example: -**Example: `fn foo(x: u32) -> u32 { x }`** +```rust +fn foo(x: u32) -> u32 { x } +``` Here the HIR sees the types without "thinking" about them, it knows that the function takes an `u32` and returns -an `u32`. But at the `ty::Ty` level the compiler understands that they're the same type, in-depth lifetimes, etc... +an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler +understands that they're the same type, in-depth lifetimes, etc... + +To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or +outside of bodies the [`TypeckResults::node_type()`][node_type] method. -you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function to convert from a `hir::Ty` to a `ty::Ty` +> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs. ## Useful Links @@ -130,6 +136,7 @@ in this chapter: [Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Adt [AdtDef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adt/struct.AdtDef.html [expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty +[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type [is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char [is_char_source]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/sty.rs.html#1831-1834 [kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md index 78e1a55cff3..a702226e861 100644 --- a/src/tools/clippy/book/src/lint_configuration.md +++ b/src/tools/clippy/book/src/lint_configuration.md @@ -55,6 +55,7 @@ Please use that command to update the file and do not edit it by hand. | [suppress-restriction-lint-in-const](#suppress-restriction-lint-in-const) | `false` | | [missing-docs-in-crate-items](#missing-docs-in-crate-items) | `false` | | [future-size-threshold](#future-size-threshold) | `16384` | +| [unnecessary-box-size](#unnecessary-box-size) | `128` | ### arithmetic-side-effects-allowed Suppress checking of the passed type names in all types of operations. @@ -561,4 +562,12 @@ The maximum byte size a `Future` can have, before it triggers the `clippy::large * [large_futures](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures) +### unnecessary-box-size +The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint + +**Default Value:** `128` (`u64`) + +* [unnecessary_box_returns](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns) + + diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs index 95222a9acdf..dd90a38f757 100644 --- a/src/tools/clippy/clippy_dev/src/update_lints.rs +++ b/src/tools/clippy/clippy_dev/src/update_lints.rs @@ -741,7 +741,7 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String { fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String { let mut seen_lints = HashSet::new(); let mut res: String = GENERATED_FILE_COMMENT.into(); - res.push_str("// run-rustfix\n\n"); + res.push_str("//@run-rustfix\n\n"); for lint in lints { if seen_lints.insert(&lint.new_name) { writeln!(res, "#![allow({})]", lint.new_name).unwrap(); diff --git a/src/tools/clippy/clippy_lints/src/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/allow_attributes.rs index 15d46e954a9..b984132acf5 100644 --- a/src/tools/clippy/clippy_lints/src/allow_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/allow_attributes.rs @@ -6,7 +6,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// Detects uses of the `#[allow]` attribute and suggests replacing it with + /// Checks for usage of the `#[allow]` attribute and suggests replacing it with /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) /// /// The expect attribute is still unstable and requires the `lint_reasons` diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index 1d9096ea64d..8c3ad24eeed 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -41,7 +41,7 @@ fn extract_bool_lit(e: &Expr<'_>) -> Option<bool> { }) = e.kind && !e.span.from_expansion() { - Some(b) + Some(*b) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs index 362f70d12d1..d74bd57fe45 100644 --- a/src/tools/clippy/clippy_lints/src/casts/mod.rs +++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs @@ -506,7 +506,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for uses of the `abs()` method that cast the result to unsigned. + /// Checks for usage of the `abs()` method that cast the result to unsigned. /// /// ### Why is this bad? /// The `unsigned_abs()` method avoids panic when called on the MIN value. @@ -625,14 +625,14 @@ declare_clippy_lint! { /// /// ### Example /// ```rust - /// let string = String::with_capacity(1); - /// let ptr = string.as_ptr() as *mut u8; + /// let mut vec = Vec::<u8>::with_capacity(1); + /// let ptr = vec.as_ptr() as *mut u8; /// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR /// ``` /// Use instead: /// ```rust - /// let mut string = String::with_capacity(1); - /// let ptr = string.as_mut_ptr(); + /// let mut vec = Vec::<u8>::with_capacity(1); + /// let ptr = vec.as_mut_ptr(); /// unsafe { ptr.write(4) }; /// ``` #[clippy::version = "1.66.0"] diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs index b2fe0386f94..7436e9ce811 100644 --- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs +++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs @@ -9,7 +9,7 @@ use rustc_span::{symbol::sym, Span}; declare_clippy_lint! { /// ### What it does - /// Checks for use of `crate` as opposed to `$crate` in a macro definition. + /// Checks for usage of `crate` as opposed to `$crate` in a macro definition. /// /// ### Why is this bad? /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs index f24dab62780..0c66d36a1d6 100644 --- a/src/tools/clippy/clippy_lints/src/declared_lints.rs +++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs @@ -215,6 +215,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO, crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO, crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO, + crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO, crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO, crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO, crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO, diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index dec357ab75c..03b5a2d6d08 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { None, &format!( "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs index 48a54f60253..ee5a875ade7 100644 --- a/src/tools/clippy/clippy_lints/src/entry.rs +++ b/src/tools/clippy/clippy_lints/src/entry.rs @@ -19,7 +19,7 @@ use rustc_span::{Span, SyntaxContext, DUMMY_SP}; declare_clippy_lint! { /// ### What it does - /// Checks for uses of `contains_key` + `insert` on `HashMap` + /// Checks for usage of `contains_key` + `insert` on `HashMap` /// or `BTreeMap`. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs index 4c69dacf381..faac6340419 100644 --- a/src/tools/clippy/clippy_lints/src/enum_variants.rs +++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs @@ -1,6 +1,6 @@ //! lint on enum variants that are prefixed or suffixed by the same characters -use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; +use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir}; use clippy_utils::source::is_present_in_source; use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start}; use rustc_hir::{EnumDef, Item, ItemKind, Variant}; @@ -135,9 +135,10 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_> && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase()) && name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric()) { - span_lint( + span_lint_hir( cx, ENUM_VARIANT_NAMES, + variant.hir_id, variant.span, "variant name starts with the enum's name", ); @@ -149,9 +150,10 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>) let item_name_chars = item_name.chars().count(); if count_match_end(item_name, name).char_count == item_name_chars { - span_lint( + span_lint_hir( cx, ENUM_VARIANT_NAMES, + variant.hir_id, variant.span, "variant name ends with the enum's name", ); diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs index e3ddbfb5981..3ddee1842a3 100644 --- a/src/tools/clippy/clippy_lints/src/format_impl.rs +++ b/src/tools/clippy/clippy_lints/src/format_impl.rs @@ -51,7 +51,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `println`, `print`, `eprintln` or `eprint` in an + /// Checks for usage of `println`, `print`, `eprintln` or `eprint` in an /// implementation of a formatting trait. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs index a866a68987d..4762b354392 100644 --- a/src/tools/clippy/clippy_lints/src/formatting.rs +++ b/src/tools/clippy/clippy_lints/src/formatting.rs @@ -10,7 +10,7 @@ use rustc_span::source_map::Span; declare_clippy_lint! { /// ### What it does - /// Checks for use of the non-existent `=*`, `=!` and `=-` + /// Checks for usage of the non-existent `=*`, `=!` and `=-` /// operators. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs index 7c5e44bb7dc..ac2d253fe83 100644 --- a/src/tools/clippy/clippy_lints/src/functions/mod.rs +++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs @@ -348,7 +348,7 @@ declare_clippy_lint! { /// // [...] /// } /// ``` - #[clippy::version = "1.68.0"] + #[clippy::version = "1.69.0"] pub IMPL_TRAIT_IN_PARAMS, restriction, "`impl Trait` is used in the function's parameters" diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index ed0bd58c770..ff838c2d56e 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -4,7 +4,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Body, FnDecl}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{self, AliasTy, Clause, EarlyBinder, PredicateKind}; +use rustc_middle::ty::{self, AliasTy, Clause, PredicateKind}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; @@ -66,8 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; - for &(p, _span) in preds { - let p = EarlyBinder(p).subst(cx.tcx, substs); + for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { if let Some(trait_pred) = p.to_opt_poly_trait_pred() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs new file mode 100644 index 00000000000..52d716feea0 --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs @@ -0,0 +1,83 @@ +use clippy_utils::{diagnostics::span_lint_and_help, is_in_cfg_test}; +use rustc_hir::{HirId, ItemId, ItemKind, Mod}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::{sym, Span}; + +declare_clippy_lint! { + /// ### What it does + /// Triggers if an item is declared after the testing module marked with `#[cfg(test)]`. + /// ### Why is this bad? + /// Having items declared after the testing module is confusing and may lead to bad test coverage. + /// ### Example + /// ```rust + /// #[cfg(test)] + /// mod tests { + /// // [...] + /// } + /// + /// fn my_function() { + /// // [...] + /// } + /// ``` + /// Use instead: + /// ```rust + /// fn my_function() { + /// // [...] + /// } + /// + /// #[cfg(test)] + /// mod tests { + /// // [...] + /// } + /// ``` + #[clippy::version = "1.70.0"] + pub ITEMS_AFTER_TEST_MODULE, + style, + "An item was found after the testing module `tests`" +} + +declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]); + +impl LateLintPass<'_> for ItemsAfterTestModule { + fn check_mod(&mut self, cx: &LateContext<'_>, _: &Mod<'_>, _: HirId) { + let mut was_test_mod_visited = false; + let mut test_mod_span: Option<Span> = None; + + let hir = cx.tcx.hir(); + let items = hir.items().collect::<Vec<ItemId>>(); + + for (i, itid) in items.iter().enumerate() { + let item = hir.item(*itid); + + if_chain! { + if was_test_mod_visited; + if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */); + if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash + == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail + if !matches!(item.kind, ItemKind::Mod(_)); + if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself + if !in_external_macro(cx.sess(), item.span); + + then { + span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined"); + }}; + + if matches!(item.kind, ItemKind::Mod(_)) { + for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) { + if_chain! { + if attr.has_name(sym::cfg); + if let Some(mitems) = attr.meta_item_list(); + if let [mitem] = &*mitems; + if mitem.has_name(sym::test); + then { + was_test_mod_visited = true; + test_mod_span = Some(item.span); + } + } + } + } + } + } +} diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 0805b4b1979..fec9c6f626c 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -168,25 +168,27 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { } if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind { + // expr.span might contains parenthesis, see issue #10529 + let actual_span = left.span.with_hi(right.span.hi()); match cmp { BinOpKind::Eq => { - check_cmp(cx, expr.span, left, right, "", 0); // len == 0 - check_cmp(cx, expr.span, right, left, "", 0); // 0 == len + check_cmp(cx, actual_span, left, right, "", 0); // len == 0 + check_cmp(cx, actual_span, right, left, "", 0); // 0 == len }, BinOpKind::Ne => { - check_cmp(cx, expr.span, left, right, "!", 0); // len != 0 - check_cmp(cx, expr.span, right, left, "!", 0); // 0 != len + check_cmp(cx, actual_span, left, right, "!", 0); // len != 0 + check_cmp(cx, actual_span, right, left, "!", 0); // 0 != len }, BinOpKind::Gt => { - check_cmp(cx, expr.span, left, right, "!", 0); // len > 0 - check_cmp(cx, expr.span, right, left, "", 1); // 1 > len + check_cmp(cx, actual_span, left, right, "!", 0); // len > 0 + check_cmp(cx, actual_span, right, left, "", 1); // 1 > len }, BinOpKind::Lt => { - check_cmp(cx, expr.span, left, right, "", 1); // len < 1 - check_cmp(cx, expr.span, right, left, "!", 0); // 0 < len + check_cmp(cx, actual_span, left, right, "", 1); // len < 1 + check_cmp(cx, actual_span, right, left, "!", 0); // 0 < len }, - BinOpKind::Ge => check_cmp(cx, expr.span, left, right, "!", 1), // len >= 1 - BinOpKind::Le => check_cmp(cx, expr.span, right, left, "!", 1), // 1 <= len + BinOpKind::Ge => check_cmp(cx, actual_span, left, right, "!", 1), // len >= 1 + BinOpKind::Le => check_cmp(cx, actual_span, right, left, "!", 1), // 1 <= len _ => (), } } diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index 51b5de27de8..637b7de920e 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type}; use clippy_utils::{is_must_use_func_call, paths}; -use rustc_hir::{Local, PatKind}; +use rustc_hir::{ExprKind, Local, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::subst::GenericArgKind; @@ -189,7 +189,18 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { if local.pat.default_binding_modes && local.ty.is_none() { // When `default_binding_modes` is true, the `let` keyword is present. - span_lint_and_help( + + // Ignore function calls that return impl traits... + if let Some(init) = local.init && + matches!(init.kind, ExprKind::Call(_, _) | ExprKind::MethodCall(_, _, _, _)) { + let expr_ty = cx.typeck_results().expr_ty(init); + if expr_ty.is_impl_trait() { + return; + } + } + + + span_lint_and_help( cx, LET_UNDERSCORE_UNTYPED, local.span, diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index b0ec14855e7..573ffe349ec 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -158,6 +158,7 @@ mod int_plus_one; mod invalid_upcast_comparisons; mod invalid_utf8_in_unchecked; mod items_after_statements; +mod items_after_test_module; mod iter_not_returning_iterator; mod large_const_arrays; mod large_enum_variant; @@ -950,15 +951,18 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv()))); store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); + let unnecessary_box_size = conf.unnecessary_box_size; store.register_late_pass(move |_| { Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new( avoid_breaking_exported_api, + unnecessary_box_size, )) }); store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk)); store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule)); store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation)); store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments)); + store.register_late_pass(|_| Box::new(items_after_test_module::ItemsAfterTestModule)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs index b0f9276475d..bba9bb445a7 100644 --- a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs +++ b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs @@ -10,7 +10,7 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Detect uses of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` + /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)` /// when `lines` has type `std::io::Lines`. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index f0a1b1dfe56..5f1fdf00be8 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -226,7 +226,8 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise, }) .fold(NeverLoopResult::Otherwise, combine_seq), - ExprKind::Yield(_, _) + ExprKind::OffsetOf(_, _) + | ExprKind::Yield(_, _) | ExprKind::Closure { .. } | ExprKind::Path(_) | ExprKind::ConstBlock(_) diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs index bc815dc4a26..4629b22d171 100644 --- a/src/tools/clippy/clippy_lints/src/manual_bits.rs +++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs @@ -13,7 +13,7 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Checks for uses of `std::mem::size_of::<T>() * 8` when + /// Checks for usage of `std::mem::size_of::<T>() * 8` when /// `T::BITS` is available. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs index 92ee79453a3..703a6b25840 100644 --- a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs +++ b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs @@ -1,5 +1,7 @@ -use clippy_utils::diagnostics::span_lint_and_help; -use clippy_utils::{expr_or_init, in_constant}; +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::source::snippet_with_context; +use clippy_utils::{expr_or_init, in_constant, std_or_core}; +use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; @@ -38,19 +40,27 @@ declare_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION] impl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) { - // Does not apply inside const because size_of_value is not cost in stable. + // Does not apply inside const because size_of_val is not cost in stable. if !in_constant(cx, expr.hir_id) && let ExprKind::Binary(ref op, left, right) = expr.kind && BinOpKind::Mul == op.node - && let Some(_receiver) = simplify(cx, left, right) + && !expr.span.from_expansion() + && let Some(receiver) = simplify(cx, left, right) { - span_lint_and_help( + let ctxt = expr.span.ctxt(); + let mut app = Applicability::MachineApplicable; + let val_name = snippet_with_context(cx, receiver.span, ctxt, "slice", &mut app).0; + let Some(sugg) = std_or_core(cx) else { return }; + + span_lint_and_sugg( cx, MANUAL_SLICE_SIZE_CALCULATION, expr.span, "manual slice size calculation", - None, - "consider using std::mem::size_of_value instead"); + "try", + format!("{sugg}::mem::size_of_val({val_name})"), + app, + ); } } } @@ -71,9 +81,9 @@ fn simplify_half<'tcx>( expr1: &'tcx Expr<'tcx>, expr2: &'tcx Expr<'tcx>, ) -> Option<&'tcx Expr<'tcx>> { - if + if !expr1.span.from_expansion() // expr1 is `[T1].len()`? - let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind + && let ExprKind::MethodCall(method_path, receiver, _, _) = expr1.kind && method_path.ident.name == sym::len && let receiver_ty = cx.typeck_results().expr_ty(receiver) && let ty::Slice(ty1) = receiver_ty.peel_refs().kind() diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs index c795c1d9a16..7d28c111624 100644 --- a/src/tools/clippy/clippy_lints/src/manual_strip.rs +++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs @@ -159,7 +159,7 @@ fn eq_pattern_length<'tcx>(cx: &LateContext<'tcx>, pattern: &Expr<'_>, expr: &'t .. }) = expr.kind { - constant_length(cx, pattern).map_or(false, |length| length == n) + constant_length(cx, pattern).map_or(false, |length| length == *n) } else { len_arg(cx, expr).map_or(false, |arg| eq_expr_value(cx, pattern, arg)) } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs index 107fad32393..33bc20dad6b 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs @@ -162,7 +162,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option<bool> { node: LitKind::Bool(b), .. }) = exp.kind { - Some(b) + Some(*b) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs index 97ecca450fa..87b63eead25 100644 --- a/src/tools/clippy/clippy_lints/src/matches/mod.rs +++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs @@ -843,7 +843,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `Err(x)?`. + /// Checks for usage of `Err(x)?`. /// /// ### Why is this bad? /// The `?` operator is designed to allow calls that @@ -878,7 +878,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `match` which could be implemented using `map` + /// Checks for usage of `match` which could be implemented using `map` /// /// ### Why is this bad? /// Using the `map` method is clearer and more concise. @@ -902,7 +902,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `match` which could be implemented using `filter` + /// Checks for usage of `match` which could be implemented using `filter` /// /// ### Why is this bad? /// Using the `filter` method is clearer and more concise. diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 04225beeb70..7945275393c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -342,6 +342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::DropTemps(_) | ExprKind::Err(_) | ExprKind::InlineAsm(_) | + ExprKind::OffsetOf(_, _) | ExprKind::Let(_) | ExprKind::Lit(_) | ExprKind::Loop(_, _, _, _) | diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 64bf55ba24c..9cafbc2e5f5 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -121,7 +121,7 @@ use rustc_span::{sym, Span}; declare_clippy_lint! { /// ### What it does - /// Checks for usages of `cloned()` on an `Iterator` or `Option` where + /// Checks for usage of `cloned()` on an `Iterator` or `Option` where /// `copied()` could be used instead. /// /// ### Why is this bad? @@ -201,7 +201,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `Iterator::flat_map()` where `filter_map()` could be + /// Checks for usage of `Iterator::flat_map()` where `filter_map()` could be /// used instead. /// /// ### Why is this bad? @@ -441,7 +441,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `_.unwrap_or_else(Default::default)` on `Option` and + /// Checks for usage of `_.unwrap_or_else(Default::default)` on `Option` and /// `Result` values. /// /// ### Why is this bad? @@ -1194,7 +1194,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `.iter().nth()` (and the related + /// Checks for usage of `.iter().nth()` (and the related /// `.iter_mut().nth()`) on standard library types with *O*(1) element access. /// /// ### Why is this bad? @@ -1221,7 +1221,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `.skip(x).next()` on iterators. + /// Checks for usage of `.skip(x).next()` on iterators. /// /// ### Why is this bad? /// `.nth(x)` is cleaner @@ -1246,7 +1246,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `.drain(..)` on `Vec` and `VecDeque` for iteration. + /// Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration. /// /// ### Why is this bad? /// `.into_iter()` is simpler with better performance. @@ -1271,7 +1271,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for using `x.get(x.len() - 1)` instead of + /// Checks for usage of `x.get(x.len() - 1)` instead of /// `x.last()`. /// /// ### Why is this bad? @@ -1304,7 +1304,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `.get().unwrap()` (or + /// Checks for usage of `.get().unwrap()` (or /// `.get_mut().unwrap`) on a standard library type which implements `Index` /// /// ### Why is this bad? @@ -1475,7 +1475,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for using `fold` when a more succinct alternative exists. + /// Checks for usage of `fold` when a more succinct alternative exists. /// Specifically, this checks for `fold`s which could be replaced by `any`, `all`, /// `sum` or `product`. /// @@ -2161,7 +2161,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `str::splitn(2, _)` + /// Checks for usage of `str::splitn(2, _)` /// /// ### Why is this bad? /// `split_once` is both clearer in intent and slightly more efficient. @@ -2197,7 +2197,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same. + /// Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same. /// ### Why is this bad? /// The function `split` is simpler and there is no performance difference in these cases, considering /// that both functions return a lazy iterator. @@ -2251,7 +2251,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `.collect::<Vec<String>>().join("")` on iterators. + /// Checks for usage of `.collect::<Vec<String>>().join("")` on iterators. /// /// ### Why is this bad? /// `.collect::<String>()` is more concise and might be more performant @@ -2377,7 +2377,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `.then_some(..).unwrap_or(..)` + /// Checks for usage of `.then_some(..).unwrap_or(..)` /// /// ### Why is this bad? /// This can be written more clearly with `if .. else ..` @@ -2553,7 +2553,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for using `x.get(0)` instead of + /// Checks for usage of `x.get(0)` instead of /// `x.first()`. /// /// ### Why is this bad? @@ -2957,7 +2957,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Detects uses of `Vec::sort_by` passing in a closure + /// Checks for usage of `Vec::sort_by` passing in a closure /// which compares the two arguments, either directly or indirectly. /// /// ### Why is this bad? @@ -3013,7 +3013,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of File::read_to_end and File::read_to_string. + /// Checks for usage of File::read_to_end and File::read_to_string. /// /// ### Why is this bad? /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values. @@ -3185,7 +3185,7 @@ declare_clippy_lint! { /// ```rust /// std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap(); /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.69.0"] pub SUSPICIOUS_COMMAND_ARG_SPACE, suspicious, "single command line argument that looks like it should be multiple arguments" diff --git a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs index 4d7427b2662..eada530d670 100644 --- a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs +++ b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs @@ -1,5 +1,3 @@ -// run-rustfix - use super::OBFUSCATED_IF_ELSE; use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_with_applicability}; use rustc_errors::Applicability; diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index c6a27cdd6fa..23d23f25f14 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -48,7 +48,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec .. } = *span { - if lit { Argument::True } else { Argument::False } + if *lit { Argument::True } else { Argument::False } } else { // The function is called with a literal which is not a boolean literal. // This is theoretically possible, but not very likely. diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 5418616ded0..2abdfacd276 100644 --- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -59,7 +59,7 @@ declare_clippy_lint! { /// unsafe { char::from_u32_unchecked(int_value) } /// } /// ``` - #[clippy::version = "1.68.0"] + #[clippy::version = "1.69.0"] pub MULTIPLE_UNSAFE_OPS_PER_BLOCK, restriction, "more than one unsafe operation per `unsafe` block" diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs index dc866ab6373..99394b9e5fb 100644 --- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs +++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs @@ -1,4 +1,4 @@ -//! Checks for uses of mutex where an atomic value could be used +//! Checks for usage of mutex where an atomic value could be used //! //! This lint is **allow** by default @@ -12,7 +12,7 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Checks for usages of `Mutex<X>` where an atomic will do. + /// Checks for usage of `Mutex<X>` where an atomic will do. /// /// ### Why is this bad? /// Using a mutex just to make access to a plain bool or @@ -49,7 +49,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for usages of `Mutex<X>` where `X` is an integral + /// Checks for usage of `Mutex<X>` where `X` is an integral /// type. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 0bedab05eec..58590df1fed 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -1,4 +1,4 @@ -//! Checks for uses of const which the type is not `Freeze` (`Cell`-free). +//! Checks for usage of const which the type is not `Freeze` (`Cell`-free). //! //! This lint is **warn** by default. @@ -196,11 +196,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty< fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let substs = cx.typeck_results().node_substs(hir_id); - let result = cx.tcx.const_eval_resolve( - cx.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ); + let result = cx + .tcx + .const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None); is_value_unfrozen_raw(cx, result, ty) } diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs index 7376ab0c846..6d3865080a6 100644 --- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs +++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs @@ -76,8 +76,8 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) { if ch == '\\' { if let Some((_, '0')) = iter.next() { // collect up to two further octal digits - if let Some((mut to, '0'..='7')) = iter.next() { - if let Some((_, '0'..='7')) = iter.peek() { + if let Some((mut to, _)) = iter.next_if(|(_, ch)| matches!(ch, '0'..='7')) { + if iter.next_if(|(_, ch)| matches!(ch, '0'..='7')).is_some() { to += 1; } found.push((from, to + 1)); @@ -90,32 +90,6 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) { return; } - // construct two suggestion strings, one with \x escapes with octal meaning - // as in C, and one with \x00 for null bytes. - let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string(); - let mut suggest_2 = suggest_1.clone(); - let mut index = 0; - for (from, to) in found { - suggest_1.push_str(&contents[index..from]); - suggest_2.push_str(&contents[index..from]); - - // construct a replacement escape - // the maximum value is \077, or \x3f, so u8 is sufficient here - if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) { - write!(suggest_1, "\\x{n:02x}").unwrap(); - } - - // append the null byte as \x00 and the following digits literally - suggest_2.push_str("\\x00"); - suggest_2.push_str(&contents[from + 2..to]); - - index = to; - } - suggest_1.push_str(&contents[index..]); - suggest_1.push('"'); - suggest_2.push_str(&contents[index..]); - suggest_2.push('"'); - span_lint_and_then( cx, OCTAL_ESCAPES, @@ -129,23 +103,53 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) { "octal escapes are not supported, `\\0` is always a null {}", if is_string { "character" } else { "byte" } )); - // suggestion 1: equivalent hex escape - diag.span_suggestion( - span, - "if an octal escape was intended, use the hexadecimal representation instead", - suggest_1, - Applicability::MaybeIncorrect, - ); - // suggestion 2: unambiguous null byte - diag.span_suggestion( - span, - format!( - "if the null {} is intended, disambiguate using", - if is_string { "character" } else { "byte" } - ), - suggest_2, - Applicability::MaybeIncorrect, - ); + + // Generate suggestions if the string is not too long (~ 5 lines) + if contents.len() < 400 { + // construct two suggestion strings, one with \x escapes with octal meaning + // as in C, and one with \x00 for null bytes. + let mut suggest_1 = if is_string { "\"" } else { "b\"" }.to_string(); + let mut suggest_2 = suggest_1.clone(); + let mut index = 0; + for (from, to) in found { + suggest_1.push_str(&contents[index..from]); + suggest_2.push_str(&contents[index..from]); + + // construct a replacement escape + // the maximum value is \077, or \x3f, so u8 is sufficient here + if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) { + write!(suggest_1, "\\x{n:02x}").unwrap(); + } + + // append the null byte as \x00 and the following digits literally + suggest_2.push_str("\\x00"); + suggest_2.push_str(&contents[from + 2..to]); + + index = to; + } + suggest_1.push_str(&contents[index..]); + suggest_2.push_str(&contents[index..]); + + suggest_1.push('"'); + suggest_2.push('"'); + // suggestion 1: equivalent hex escape + diag.span_suggestion( + span, + "if an octal escape was intended, use the hexadecimal representation instead", + suggest_1, + Applicability::MaybeIncorrect, + ); + // suggestion 2: unambiguous null byte + diag.span_suggestion( + span, + format!( + "if the null {} is intended, disambiguate using", + if is_string { "character" } else { "byte" } + ), + suggest_2, + Applicability::MaybeIncorrect, + ); + } }, ); } diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index e5713735672..fafcf257094 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -1,4 +1,5 @@ use super::ARITHMETIC_SIDE_EFFECTS; +use clippy_utils::is_from_proc_macro; use clippy_utils::{ consts::{constant, constant_simple, Constant}, diagnostics::span_lint, @@ -10,7 +11,10 @@ use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; -use rustc_span::source_map::{Span, Spanned}; +use rustc_span::{ + source_map::{Span, Spanned}, + Symbol, +}; const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[ ["f32", "f32"], @@ -20,6 +24,7 @@ const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[ ["std::string::String", "&str"], ]; const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"]; +const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; #[derive(Debug)] pub struct ArithmeticSideEffects { @@ -28,6 +33,7 @@ pub struct ArithmeticSideEffects { // Used to check whether expressions are constants, such as in enum discriminants and consts const_span: Option<Span>, expr_span: Option<Span>, + integer_methods: FxHashSet<Symbol>, } impl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]); @@ -53,6 +59,7 @@ impl ArithmeticSideEffects { allowed_unary, const_span: None, expr_span: None, + integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(), } } @@ -184,6 +191,33 @@ impl ArithmeticSideEffects { } } + /// There are some integer methods like `wrapping_div` that will panic depending on the + /// provided input. + fn manage_method_call<'tcx>( + &mut self, + args: &[hir::Expr<'tcx>], + cx: &LateContext<'tcx>, + ps: &hir::PathSegment<'tcx>, + receiver: &hir::Expr<'tcx>, + ) { + let Some(arg) = args.first() else { return; }; + if constant_simple(cx, cx.typeck_results(), receiver).is_some() { + return; + } + let instance_ty = cx.typeck_results().expr_ty(receiver); + if !Self::is_integral(instance_ty) { + return; + } + if !self.integer_methods.contains(&ps.ident.name) { + return; + } + let (actual_arg, _) = peel_hir_expr_refs(arg); + match Self::literal_integer(cx, actual_arg) { + None | Some(0) => self.issue_lint(cx, arg), + Some(_) => {}, + } + } + fn manage_unary_ops<'tcx>( &mut self, cx: &LateContext<'tcx>, @@ -206,8 +240,9 @@ impl ArithmeticSideEffects { self.issue_lint(cx, expr); } - fn should_skip_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + fn should_skip_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool { is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id) + || is_from_proc_macro(cx, expr) || self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span)) } @@ -222,6 +257,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects { hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => { self.manage_bin_ops(cx, expr, op, lhs, rhs); }, + hir::ExprKind::MethodCall(ps, receiver, args, _) => { + self.manage_method_call(args, cx, ps, receiver); + }, hir::ExprKind::Unary(un_op, un_expr) => { self.manage_unary_ops(cx, expr, un_expr, *un_op); }, diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs index eba230da6c3..19599731bd6 100644 --- a/src/tools/clippy/clippy_lints/src/operators/mod.rs +++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs @@ -685,7 +685,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using + /// Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using /// a lazy and. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs index 777395f452c..77fd45b199a 100644 --- a/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs +++ b/src/tools/clippy/clippy_lints/src/operators/numeric_arithmetic.rs @@ -1,12 +1,12 @@ +use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC}; use clippy_utils::consts::constant_simple; use clippy_utils::diagnostics::span_lint; +use clippy_utils::is_from_proc_macro; use clippy_utils::is_integer_literal; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::source_map::Span; -use super::{FLOAT_ARITHMETIC, INTEGER_ARITHMETIC}; - #[derive(Default)] pub struct Context { expr_id: Option<hir::HirId>, @@ -47,6 +47,9 @@ impl Context { let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r)); if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() { + if is_from_proc_macro(cx, expr) { + return; + } match op { hir::BinOpKind::Div | hir::BinOpKind::Rem => match &r.kind { hir::ExprKind::Lit(_lit) => (), @@ -79,6 +82,9 @@ impl Context { let ty = cx.typeck_results().expr_ty(arg); if constant_simple(cx, cx.typeck_results(), expr).is_none() { if ty.is_integral() { + if is_from_proc_macro(cx, expr) { + return; + } span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected"); self.expr_id = Some(expr.hir_id); } else if ty.is_floating_point() { diff --git a/src/tools/clippy/clippy_lints/src/question_mark_used.rs b/src/tools/clippy/clippy_lints/src/question_mark_used.rs index 9b678e8d753..ff66b8a0095 100644 --- a/src/tools/clippy/clippy_lints/src/question_mark_used.rs +++ b/src/tools/clippy/clippy_lints/src/question_mark_used.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// ```ignore /// utility_macro!(expr); /// ``` - #[clippy::version = "pre 1.29.0"] + #[clippy::version = "1.69.0"] pub QUESTION_MARK_USED, restriction, "complains if the question mark operator is used" diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index 869358fb1ba..b930b2c8dd7 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -17,7 +17,7 @@ use rustc_span::{symbol::Ident, Span, DUMMY_SP}; declare_clippy_lint! { /// ### What it does /// - /// Searches for elements marked with `#[clippy::significant_drop]` that could be early + /// Searches for elements marked with `#[clippy::has_significant_drop]` that could be early /// dropped but are in fact dropped at the end of their scopes. In other words, enforces the /// "tightening" of their possible lifetimes. /// @@ -46,7 +46,7 @@ declare_clippy_lint! { /// do_heavy_computation_that_takes_time(owned_rslt); /// } /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.69.0"] pub SIGNIFICANT_DROP_TIGHTENING, nursery, "Searches for elements marked with `#[clippy::has_significant_drop]` that could be early dropped but are in fact dropped at the end of their scopes" diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 1382c1a40da..98f5b47f7a0 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { None, &format!( "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs index c1f228d5f90..c6834a8fdaa 100644 --- a/src/tools/clippy/clippy_lints/src/types/mod.rs +++ b/src/tools/clippy/clippy_lints/src/types/mod.rs @@ -22,7 +22,7 @@ use rustc_span::source_map::Span; declare_clippy_lint! { /// ### What it does - /// Checks for use of `Box<T>` where T is a collection such as Vec anywhere in the code. + /// Checks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// /// ### Why is this bad? @@ -52,7 +52,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code. + /// Checks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// /// ### Why is this bad? @@ -85,7 +85,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `Option<Option<_>>` in function signatures and type + /// Checks for usage of `Option<Option<_>>` in function signatures and type /// definitions /// /// ### Why is this bad? @@ -164,7 +164,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `&Box<T>` anywhere in the code. + /// Checks for usage of `&Box<T>` anywhere in the code. /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information. /// /// ### Why is this bad? @@ -190,7 +190,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of redundant allocations anywhere in the code. + /// Checks for usage of redundant allocations anywhere in the code. /// /// ### Why is this bad? /// Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`, diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs index 912bcda630b..af1c8d83b4f 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size}; use rustc_errors::Applicability; use rustc_hir::{def_id::LocalDefId, FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -10,6 +10,9 @@ declare_clippy_lint! { /// /// Checks for a return type containing a `Box<T>` where `T` implements `Sized` /// + /// The lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`, + /// as returning a large `T` directly may be detrimental to performance. + /// /// ### Why is this bad? /// /// It's better to just return `T` in these cases. The caller may not need @@ -36,14 +39,16 @@ declare_clippy_lint! { pub struct UnnecessaryBoxReturns { avoid_breaking_exported_api: bool, + maximum_size: u64, } impl_lint_pass!(UnnecessaryBoxReturns => [UNNECESSARY_BOX_RETURNS]); impl UnnecessaryBoxReturns { - pub fn new(avoid_breaking_exported_api: bool) -> Self { + pub fn new(avoid_breaking_exported_api: bool, maximum_size: u64) -> Self { Self { avoid_breaking_exported_api, + maximum_size, } } @@ -71,8 +76,10 @@ impl UnnecessaryBoxReturns { let boxed_ty = return_ty.boxed_ty(); - // it's sometimes useful to return Box<T> if T is unsized, so don't lint those - if boxed_ty.is_sized(cx.tcx, cx.param_env) { + // It's sometimes useful to return Box<T> if T is unsized, so don't lint those. + // Also, don't lint if we know that T is very large, in which case returning + // a Box<T> may be beneficial. + if boxed_ty.is_sized(cx.tcx, cx.param_env) && approx_ty_size(cx, boxed_ty) <= self.maximum_size { span_lint_and_then( cx, UNNECESSARY_BOX_RETURNS, diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bc4adf1596d..01927b6b5f1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -430,7 +430,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("Unary(UnOp::{op:?}, {inner})"); self.expr(inner); }, - ExprKind::Lit(ref lit) => { + ExprKind::Lit(lit) => { bind!(self, lit); kind!("Lit(ref {lit})"); self.lit(lit); @@ -558,6 +558,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("InlineAsm(_)"); out!("// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment"); }, + ExprKind::OffsetOf(container, ref fields) => { + bind!(self, container, fields); + kind!("OffsetOf({container}, {fields})"); + } ExprKind::Struct(qpath, fields, base) => { bind!(self, qpath, fields); opt_bind!(self, base); diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs index 896a01af37d..67bb499c455 100644 --- a/src/tools/clippy/clippy_lints/src/utils/conf.rs +++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs @@ -463,6 +463,10 @@ define_Conf! { /// /// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint (future_size_threshold: u64 = 16 * 1024), + /// Lint: UNNECESSARY_BOX_RETURNS. + /// + /// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint + (unnecessary_box_size: u64 = 128), } /// Search for the configuration file. diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 14ed1368e03..00842376628 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -20,7 +20,7 @@ use std::str; declare_clippy_lint! { /// ### What it does - /// Checks for usages of def paths when a diagnostic item or a `LangItem` could be used. + /// Checks for usage of def paths when a diagnostic item or a `LangItem` could be used. /// /// ### Why is this bad? /// The path for an item is subject to change and is less efficient to look up than a diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs index d7c94b909bd..f194dc5d4b2 100644 --- a/src/tools/clippy/clippy_lints/src/write.rs +++ b/src/tools/clippy/clippy_lints/src/write.rs @@ -104,7 +104,7 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for use of `Debug` formatting. The purpose of this + /// Checks for usage of `Debug` formatting. The purpose of this /// lint is to catch debugging remnants. /// /// ### Why is this bad? diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index bb8890dcaf9..99bfc4b5717 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -450,11 +450,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { let result = self .lcx .tcx - .const_eval_resolve( - self.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ) + .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None) .ok() .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?; let result = miri_to_const(self.lcx.tcx, result); diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 28c85717061..3df40942e7b 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -218,7 +218,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS | ExprKind::AddrOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) - | ExprKind::Block(Block { stmts: [], .. }, _) => (), + | ExprKind::Block(Block { stmts: [], .. }, _) + | ExprKind::OffsetOf(..) => (), // Assignment might be to a local defined earlier, so don't eagerly evaluate. // Blocks with multiple statements might be expensive, so don't eagerly evaluate. diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 3ee7147828b..d972ed82c25 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -301,6 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), + (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => { + self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) + }, _ => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) @@ -701,6 +704,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } }, + ExprKind::OffsetOf(container, fields) => { + self.hash_ty(container); + for field in fields { + self.hash_name(field.name); + } + }, ExprKind::Let(Let { pat, init, ty, .. }) => { self.hash_expr(init); if let Some(ty) = ty { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 354b6d71aa4..ecd712f32dc 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,7 +194,7 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()), + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); if ty.is_integral() || ty.is_bool() { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index a5a4a921d94..e81eadceec0 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -139,6 +139,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Field(..) | hir::ExprKind::Index(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Loop(..) @@ -197,6 +198,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::ForLoop(..) | ast::ExprKind::Index(..) | ast::ExprKind::InlineAsm(..) + | ast::ExprKind::OffsetOf(..) | ast::ExprKind::ConstBlock(..) | ast::ExprKind::Lit(..) | ast::ExprKind::IncludedBytes(..) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 9449f0b5567..cb700126c2b 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -90,7 +90,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) { + for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { match predicate.kind().skip_binder() { // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through // and check substituions to find `U`. @@ -267,7 +267,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { }, ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { - for (predicate, _) in cx.tcx.explicit_item_bounds(*def_id) { + for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) = predicate.kind().skip_binder() { if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) { return true; @@ -743,7 +743,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx - .bound_explicit_item_bounds(ty.def_id) + .explicit_item_bounds(ty.def_id) .subst_iter_copied(cx.tcx, ty.substs) { match pred.kind().skip_binder() { @@ -975,7 +975,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 { } match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) { (Ok(size), _) => size, - (Err(_), ty::Tuple(list)) => list.as_substs().types().map(|t| approx_ty_size(cx, t)).sum(), + (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(), (Err(_), ty::Array(t, n)) => { n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t) }, diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 1dc19bac984..5dcd71cef12 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -662,6 +662,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Path(_) | ExprKind::Continue(_) | ExprKind::InlineAsm(_) + | ExprKind::OffsetOf(..) | ExprKind::Err(_) => (), } ControlFlow::Continue(()) diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml index 5c9f76dbbc6..bd26f4fc913 100644 --- a/src/tools/clippy/declare_clippy_lint/Cargo.toml +++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml @@ -10,7 +10,7 @@ proc-macro = true [dependencies] itertools = "0.10.1" quote = "1.0.21" -syn = "1.0.100" +syn = "2.0" [features] deny-warnings = [] diff --git a/src/tools/clippy/declare_clippy_lint/src/lib.rs b/src/tools/clippy/declare_clippy_lint/src/lib.rs index 26210556d65..5232e4ab7d7 100644 --- a/src/tools/clippy/declare_clippy_lint/src/lib.rs +++ b/src/tools/clippy/declare_clippy_lint/src/lib.rs @@ -6,16 +6,16 @@ use proc_macro::TokenStream; use quote::{format_ident, quote}; use syn::parse::{Parse, ParseStream}; -use syn::{parse_macro_input, Attribute, Error, Ident, Lit, LitStr, Meta, Result, Token}; +use syn::{parse_macro_input, Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta, Result, Token}; fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) -> Option<LitStr> { - if let Meta::NameValue(name_value) = attr.parse_meta().ok()? { + if let Meta::NameValue(name_value) = &attr.meta { let path_idents = name_value.path.segments.iter().map(|segment| &segment.ident); if itertools::equal(path_idents, path) - && let Lit::Str(lit) = name_value.lit + && let Expr::Lit(ExprLit { lit: Lit::Str(s), .. }) = &name_value.value { - return Some(lit); + return Some(s.clone()); } } diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 718bc41fb99..205905d5091 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -160,6 +160,9 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. config.opts.unstable_opts.mir_opt_level = Some(0); + + // Disable flattening and inlining of format_args!(), so the HIR matches with the AST. + config.opts.unstable_opts.flatten_format_args = false; } } diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index 57890ff3173..35d75cc51c2 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -126,6 +126,7 @@ fn base_config(test_dir: &str) -> compiletest::Config { let mut config = compiletest::Config { edition: Some("2021".into()), mode: TestMode::Ui, + strict_headers: true, ..Default::default() }; @@ -424,7 +425,7 @@ fn check_rustfix_coverage() { .binary_search_by_key(&filename, Path::new) .is_ok(), "`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \ - Please either add `// run-rustfix` at the top of the file or add the file to \ + Please either add `//@run-rustfix` at the top of the file or add the file to \ `RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.", ); } diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs index 27841e18aa9..1a69bb24101 100644 --- a/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=cargo_common_metadata +//@compile-flags: --crate-name=cargo_common_metadata #![warn(clippy::cargo_common_metadata)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/feature_name/fail/src/main.rs b/src/tools/clippy/tests/ui-cargo/feature_name/fail/src/main.rs index 64f01a98c90..4dd9582aff8 100644 --- a/src/tools/clippy/tests/ui-cargo/feature_name/fail/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/feature_name/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=feature_name +//@compile-flags: --crate-name=feature_name #![warn(clippy::redundant_feature_names)] #![warn(clippy::negative_feature_names)] diff --git a/src/tools/clippy/tests/ui-cargo/feature_name/pass/src/main.rs b/src/tools/clippy/tests/ui-cargo/feature_name/pass/src/main.rs index 64f01a98c90..4dd9582aff8 100644 --- a/src/tools/clippy/tests/ui-cargo/feature_name/pass/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/feature_name/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=feature_name +//@compile-flags: --crate-name=feature_name #![warn(clippy::redundant_feature_names)] #![warn(clippy::negative_feature_names)] diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs index ba4c8c873dd..c70d92e359e 100644 --- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --remap-path-prefix {{src-base}}=/remapped +//@compile-flags: --remap-path-prefix {{src-base}}=/remapped #![warn(clippy::self_named_module_files)] diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs index 1b2d3ec9459..ece260b743d 100644 --- a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs index 1b2d3ec9459..ece260b743d 100644 --- a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs index 1b2d3ec9459..ece260b743d 100644 --- a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=multiple_crate_versions +//@compile-flags: --crate-name=multiple_crate_versions #![warn(clippy::multiple_crate_versions)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs index 581babfeacb..bb3a39d0720 100644 --- a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=wildcard_dependencies +//@compile-flags: --crate-name=wildcard_dependencies #![warn(clippy::wildcard_dependencies)] fn main() {} diff --git a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs index 581babfeacb..bb3a39d0720 100644 --- a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs +++ b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/pass/src/main.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=wildcard_dependencies +//@compile-flags: --crate-name=wildcard_dependencies #![warn(clippy::wildcard_dependencies)] fn main() {} diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed index 9f299d7dec7..72c04bf80b6 100644 --- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed +++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs index 2b113f555e4..76f7c3ce94d 100644 --- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs +++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs index 837811bdf1e..acb98d7ba98 100644 --- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs +++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs @@ -1,9 +1,9 @@ -// rustc-env:RUST_BACKTRACE=0 -// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo" -// normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs" -// normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints" -// normalize-stderr-test: "'rustc'" -> "'<unnamed>'" -// normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" +//@rustc-env:RUST_BACKTRACE=0 +//@normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo" +//@normalize-stderr-test: "produce_ice.rs:\d*:\d*" -> "produce_ice.rs" +//@normalize-stderr-test: "', .*clippy_lints" -> "', clippy_lints" +//@normalize-stderr-test: "'rustc'" -> "'<unnamed>'" +//@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> "" #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed index eaea218e128..a1a10c0798e 100644 --- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed +++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs index 7efebb8fae4..32dbfe5dcac 100644 --- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs +++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed index 08634063a57..ac0752774f3 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs index f8af77e6d39..56f778621a4 100644 --- a/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs +++ b/src/tools/clippy/tests/ui-internal/invalid_msrv_attr_impl.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed index bb82faf0c90..d8a08bc9997 100644 --- a/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed +++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs index 187d468b392..f7af0e9d8be 100644 --- a/src/tools/clippy/tests/ui-internal/outer_expn_data.rs +++ b/src/tools/clippy/tests/ui-internal/outer_expn_data.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::internal)] #![allow(clippy::missing_clippy_version_attribute)] diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed index e474f370a5d..fce24412f84 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:paths.rs +//@run-rustfix +//@aux-build:paths.rs #![deny(clippy::internal)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs index f17fed6c653..b10bc9e46e2 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs +++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:paths.rs +//@run-rustfix +//@aux-build:paths.rs #![deny(clippy::internal)] #![feature(rustc_private)] diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed index 6033d06e4f6..b802de1cbc6 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed +++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs index 1bb5d55f0b6..c1bead5bdc9 100644 --- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs +++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(rustc_private)] #![deny(clippy::internal)] #![allow( diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed index aa8b45b5fe7..23e7bc16d23 100644 --- a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed +++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::uninlined_format_args)] fn main() { diff --git a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs index ad2e4863ee8..d66b2b8ff6a 100644 --- a/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs +++ b/src/tools/clippy/tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::uninlined_format_args)] fn main() { diff --git a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs index 5d9ce18f631..21e4fce26e4 100644 --- a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs +++ b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::dbg_macro)] fn foo(n: u32) -> u32 { diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs index 2bb5376076e..ba919b48788 100644 --- a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs +++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.rs @@ -1,4 +1,4 @@ -// aux-build:macros.rs +//@aux-build:macros.rs #![allow(unused)] diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs index 89f142a150d..9e267c89300 100644 --- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs +++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::expect_used)] fn expect_option() { diff --git a/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs index 667c51cb4a3..095e0d15448 100644 --- a/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs +++ b/src/tools/clippy/tests/ui-toml/mut_key/mut_key.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name mut_key +//@compile-flags: --crate-name mut_key #![warn(clippy::mutable_key_type)] diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs index 6452189a461..f5761c6afeb 100644 --- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs +++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed index 01d135764df..e4747bedddb 100644 --- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed +++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed @@ -1,5 +1,5 @@ -// aux-build:proc_macro_derive.rs -// run-rustfix +//@aux-build:proc_macro_derive.rs +//@run-rustfix #![warn(clippy::nonstandard_macro_braces)] diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs index 72883e8270c..54edded99f4 100644 --- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs +++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs @@ -1,5 +1,5 @@ -// aux-build:proc_macro_derive.rs -// run-rustfix +//@aux-build:proc_macro_derive.rs +//@run-rustfix #![warn(clippy::nonstandard_macro_braces)] diff --git a/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs index 5aefb6a6b4d..3a8b30cca36 100644 --- a/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs +++ b/src/tools/clippy/tests/ui-toml/print_macro/print_macro.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::print_stdout)] #![warn(clippy::print_stderr)] diff --git a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs index 2f3160c8338..8e1a1710a6c 100644 --- a/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs +++ b/src/tools/clippy/tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name conf_disallowed_methods +//@compile-flags: --crate-name conf_disallowed_methods #![warn(clippy::disallowed_methods)] diff --git a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs index fb0e226f3aa..179b1266169 100644 --- a/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs +++ b/src/tools/clippy/tests/ui-toml/toml_trivially_copy/test.rs @@ -1,5 +1,5 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" #![deny(clippy::trivially_copy_pass_by_ref)] diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs index f328e4d9d04..569fd2c3553 100644 --- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs +++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs @@ -1 +1,3 @@ +//@error-pattern: unknown field `foobar`, expected one of + fn main() {} diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 8447c31722d..36b372b36f4 100644 --- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -46,6 +46,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie too-many-lines-threshold trivial-copy-size-limit type-complexity-threshold + unnecessary-box-size unreadable-literal-lint-fractions upper-case-acronyms-aggressive vec-box-size-threshold diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs index 6525ea5bfc3..5d3e800cadd 100644 --- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs +++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![allow(unused_mut, clippy::get_first, clippy::from_iter_instead_of_collect)] #![warn(clippy::unwrap_used)] diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed index b8dd0619e6d..f0936b2608e 100644 --- a/src/tools/clippy/tests/ui/allow_attributes.fixed +++ b/src/tools/clippy/tests/ui/allow_attributes.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::allow_attributes)] #![feature(lint_reasons)] diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs index 295f560906a..2fb9e86126e 100644 --- a/src/tools/clippy/tests/ui/allow_attributes.rs +++ b/src/tools/clippy/tests/ui/allow_attributes.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::allow_attributes)] #![feature(lint_reasons)] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.fixed b/src/tools/clippy/tests/ui/almost_complete_range.fixed index a4bf7fe18d5..5cd0dcce6f7 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.fixed +++ b/src/tools/clippy/tests/ui/almost_complete_range.fixed @@ -1,6 +1,6 @@ -// run-rustfix -// edition:2018 -// aux-build:proc_macros.rs +//@run-rustfix +//@edition:2018 +//@aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] diff --git a/src/tools/clippy/tests/ui/almost_complete_range.rs b/src/tools/clippy/tests/ui/almost_complete_range.rs index 8237c3a1361..db0bfc8afc3 100644 --- a/src/tools/clippy/tests/ui/almost_complete_range.rs +++ b/src/tools/clippy/tests/ui/almost_complete_range.rs @@ -1,6 +1,6 @@ -// run-rustfix -// edition:2018 -// aux-build:proc_macros.rs +//@run-rustfix +//@edition:2018 +//@aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs index 3c06676d722..ab408bdf261 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs @@ -1,3 +1,5 @@ +//@aux-build:proc_macro_derive.rs + #![allow( clippy::assign_op_pattern, clippy::erasing_op, @@ -11,6 +13,8 @@ #![feature(const_mut_refs, inline_const, saturating_int_impl)] #![warn(clippy::arithmetic_side_effects)] +extern crate proc_macro_derive; + use core::num::{Saturating, Wrapping}; const ONE: i32 = 1; @@ -19,6 +23,9 @@ const ZERO: i32 = 0; #[derive(Clone, Copy)] pub struct Custom; +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + macro_rules! impl_arith { ( $( $_trait:ident, $lhs:ty, $rhs:ty, $method:ident; )* ) => { $( @@ -269,6 +276,17 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri _n = &1 * _n; _n = 23 + 85; + // Method + _n.saturating_div(1); + _n.wrapping_div(1); + _n.wrapping_rem(1); + _n.wrapping_rem_euclid(1); + + _n.saturating_div(1); + _n.checked_div(1); + _n.checked_rem(1); + _n.checked_rem_euclid(1); + // Unary _n = -2147483647; _n = -i32::MAX; @@ -376,6 +394,17 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom = Custom << _custom; _custom = &Custom << _custom; + // Method + _n.saturating_div(0); + _n.wrapping_div(0); + _n.wrapping_rem(0); + _n.wrapping_rem_euclid(0); + + _n.saturating_div(_n); + _n.wrapping_div(_n); + _n.wrapping_rem(_n); + _n.wrapping_rem_euclid(_n); + // Unary _n = -_n; _n = -&_n; diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr index 2c8ee2884e7..e9a626643ff 100644 --- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr +++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr @@ -1,5 +1,5 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:286:5 + --> $DIR/arithmetic_side_effects.rs:304:5 | LL | _n += 1; | ^^^^^^^ @@ -7,652 +7,700 @@ LL | _n += 1; = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:287:5 + --> $DIR/arithmetic_side_effects.rs:305:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:288:5 + --> $DIR/arithmetic_side_effects.rs:306:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:289:5 + --> $DIR/arithmetic_side_effects.rs:307:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:290:5 + --> $DIR/arithmetic_side_effects.rs:308:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:291:5 + --> $DIR/arithmetic_side_effects.rs:309:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:292:5 + --> $DIR/arithmetic_side_effects.rs:310:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:293:5 + --> $DIR/arithmetic_side_effects.rs:311:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:294:5 + --> $DIR/arithmetic_side_effects.rs:312:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:295:5 + --> $DIR/arithmetic_side_effects.rs:313:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:296:5 + --> $DIR/arithmetic_side_effects.rs:314:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:297:5 + --> $DIR/arithmetic_side_effects.rs:315:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:298:5 + --> $DIR/arithmetic_side_effects.rs:316:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:299:5 + --> $DIR/arithmetic_side_effects.rs:317:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:300:5 + --> $DIR/arithmetic_side_effects.rs:318:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:301:5 + --> $DIR/arithmetic_side_effects.rs:319:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:302:5 + --> $DIR/arithmetic_side_effects.rs:320:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:303:5 + --> $DIR/arithmetic_side_effects.rs:321:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:304:5 + --> $DIR/arithmetic_side_effects.rs:322:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:305:5 + --> $DIR/arithmetic_side_effects.rs:323:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:306:5 + --> $DIR/arithmetic_side_effects.rs:324:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:307:5 + --> $DIR/arithmetic_side_effects.rs:325:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:308:5 + --> $DIR/arithmetic_side_effects.rs:326:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:309:5 + --> $DIR/arithmetic_side_effects.rs:327:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:310:5 + --> $DIR/arithmetic_side_effects.rs:328:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:311:5 + --> $DIR/arithmetic_side_effects.rs:329:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:312:5 + --> $DIR/arithmetic_side_effects.rs:330:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:313:5 + --> $DIR/arithmetic_side_effects.rs:331:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:314:5 + --> $DIR/arithmetic_side_effects.rs:332:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:315:5 + --> $DIR/arithmetic_side_effects.rs:333:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:316:5 + --> $DIR/arithmetic_side_effects.rs:334:5 | LL | _custom >>= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:317:5 + --> $DIR/arithmetic_side_effects.rs:335:5 | LL | _custom >>= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:318:5 + --> $DIR/arithmetic_side_effects.rs:336:5 | LL | _custom <<= Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:319:5 + --> $DIR/arithmetic_side_effects.rs:337:5 | LL | _custom <<= &Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:320:5 + --> $DIR/arithmetic_side_effects.rs:338:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:321:5 + --> $DIR/arithmetic_side_effects.rs:339:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:322:5 + --> $DIR/arithmetic_side_effects.rs:340:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:323:5 + --> $DIR/arithmetic_side_effects.rs:341:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:324:5 + --> $DIR/arithmetic_side_effects.rs:342:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:325:5 + --> $DIR/arithmetic_side_effects.rs:343:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:326:5 + --> $DIR/arithmetic_side_effects.rs:344:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:327:5 + --> $DIR/arithmetic_side_effects.rs:345:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:328:5 + --> $DIR/arithmetic_side_effects.rs:346:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:329:5 + --> $DIR/arithmetic_side_effects.rs:347:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:330:5 + --> $DIR/arithmetic_side_effects.rs:348:5 | LL | _custom >>= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:331:5 + --> $DIR/arithmetic_side_effects.rs:349:5 | LL | _custom >>= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:332:5 + --> $DIR/arithmetic_side_effects.rs:350:5 | LL | _custom <<= -Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:333:5 + --> $DIR/arithmetic_side_effects.rs:351:5 | LL | _custom <<= &-Custom; | ^^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:336:10 + --> $DIR/arithmetic_side_effects.rs:354:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:337:10 + --> $DIR/arithmetic_side_effects.rs:355:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:338:10 + --> $DIR/arithmetic_side_effects.rs:356:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:339:10 + --> $DIR/arithmetic_side_effects.rs:357:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:340:10 + --> $DIR/arithmetic_side_effects.rs:358:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:341:10 + --> $DIR/arithmetic_side_effects.rs:359:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:342:10 + --> $DIR/arithmetic_side_effects.rs:360:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:343:10 + --> $DIR/arithmetic_side_effects.rs:361:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:344:10 + --> $DIR/arithmetic_side_effects.rs:362:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:345:10 + --> $DIR/arithmetic_side_effects.rs:363:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:346:10 + --> $DIR/arithmetic_side_effects.rs:364:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:347:10 + --> $DIR/arithmetic_side_effects.rs:365:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:348:10 + --> $DIR/arithmetic_side_effects.rs:366:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:349:10 + --> $DIR/arithmetic_side_effects.rs:367:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:350:10 + --> $DIR/arithmetic_side_effects.rs:368:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:351:10 + --> $DIR/arithmetic_side_effects.rs:369:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:352:10 + --> $DIR/arithmetic_side_effects.rs:370:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:353:10 + --> $DIR/arithmetic_side_effects.rs:371:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:354:10 + --> $DIR/arithmetic_side_effects.rs:372:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:355:15 + --> $DIR/arithmetic_side_effects.rs:373:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:356:15 + --> $DIR/arithmetic_side_effects.rs:374:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:357:15 + --> $DIR/arithmetic_side_effects.rs:375:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:358:15 + --> $DIR/arithmetic_side_effects.rs:376:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:359:15 + --> $DIR/arithmetic_side_effects.rs:377:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:360:15 + --> $DIR/arithmetic_side_effects.rs:378:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:361:15 + --> $DIR/arithmetic_side_effects.rs:379:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:362:15 + --> $DIR/arithmetic_side_effects.rs:380:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:363:15 + --> $DIR/arithmetic_side_effects.rs:381:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:364:15 + --> $DIR/arithmetic_side_effects.rs:382:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:365:15 + --> $DIR/arithmetic_side_effects.rs:383:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:366:15 + --> $DIR/arithmetic_side_effects.rs:384:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:367:15 + --> $DIR/arithmetic_side_effects.rs:385:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:368:15 + --> $DIR/arithmetic_side_effects.rs:386:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:369:15 + --> $DIR/arithmetic_side_effects.rs:387:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:370:15 + --> $DIR/arithmetic_side_effects.rs:388:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:371:15 + --> $DIR/arithmetic_side_effects.rs:389:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:372:15 + --> $DIR/arithmetic_side_effects.rs:390:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:373:15 + --> $DIR/arithmetic_side_effects.rs:391:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:374:15 + --> $DIR/arithmetic_side_effects.rs:392:15 | LL | _custom = _custom >> _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:375:15 + --> $DIR/arithmetic_side_effects.rs:393:15 | LL | _custom = _custom >> &_custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:376:15 + --> $DIR/arithmetic_side_effects.rs:394:15 | LL | _custom = Custom << _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:377:15 + --> $DIR/arithmetic_side_effects.rs:395:15 | LL | _custom = &Custom << _custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:380:10 + --> $DIR/arithmetic_side_effects.rs:398:23 + | +LL | _n.saturating_div(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:399:21 + | +LL | _n.wrapping_div(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:400:21 + | +LL | _n.wrapping_rem(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:401:28 + | +LL | _n.wrapping_rem_euclid(0); + | ^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:403:23 + | +LL | _n.saturating_div(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:404:21 + | +LL | _n.wrapping_div(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:405:21 + | +LL | _n.wrapping_rem(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:406:28 + | +LL | _n.wrapping_rem_euclid(_n); + | ^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:409:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:381:10 + --> $DIR/arithmetic_side_effects.rs:410:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:382:15 + --> $DIR/arithmetic_side_effects.rs:411:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:383:15 + --> $DIR/arithmetic_side_effects.rs:412:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:392:5 + --> $DIR/arithmetic_side_effects.rs:421:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:393:5 + --> $DIR/arithmetic_side_effects.rs:422:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:394:5 + --> $DIR/arithmetic_side_effects.rs:423:5 | LL | 1 % i / 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:395:5 + --> $DIR/arithmetic_side_effects.rs:424:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:396:5 + --> $DIR/arithmetic_side_effects.rs:425:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:407:5 + --> $DIR/arithmetic_side_effects.rs:436:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:408:5 + --> $DIR/arithmetic_side_effects.rs:437:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:409:5 + --> $DIR/arithmetic_side_effects.rs:438:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:411:5 + --> $DIR/arithmetic_side_effects.rs:440:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:413:5 + --> $DIR/arithmetic_side_effects.rs:442:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:414:5 + --> $DIR/arithmetic_side_effects.rs:443:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:416:5 + --> $DIR/arithmetic_side_effects.rs:445:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:418:5 + --> $DIR/arithmetic_side_effects.rs:447:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:419:5 + --> $DIR/arithmetic_side_effects.rs:448:5 | LL | i %= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:429:5 + --> $DIR/arithmetic_side_effects.rs:458:5 | LL | 10 / a | ^^^^^^ -error: aborting due to 109 previous errors +error: aborting due to 117 previous errors diff --git a/src/tools/clippy/tests/ui/as_conversions.rs b/src/tools/clippy/tests/ui/as_conversions.rs index c50d4088b5e..890bf0b0a7e 100644 --- a/src/tools/clippy/tests/ui/as_conversions.rs +++ b/src/tools/clippy/tests/ui/as_conversions.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::as_conversions)] #![allow(clippy::borrow_as_ptr)] diff --git a/src/tools/clippy/tests/ui/as_underscore.fixed b/src/tools/clippy/tests/ui/as_underscore.fixed index 948f6d8e6b1..69af84a0eae 100644 --- a/src/tools/clippy/tests/ui/as_underscore.fixed +++ b/src/tools/clippy/tests/ui/as_underscore.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::as_underscore)] diff --git a/src/tools/clippy/tests/ui/as_underscore.rs b/src/tools/clippy/tests/ui/as_underscore.rs index 97785ed08a8..a8cfb81d9a3 100644 --- a/src/tools/clippy/tests/ui/as_underscore.rs +++ b/src/tools/clippy/tests/ui/as_underscore.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::as_underscore)] diff --git a/src/tools/clippy/tests/ui/asm_syntax.rs b/src/tools/clippy/tests/ui/asm_syntax.rs index 0220bf3331f..c93995f939a 100644 --- a/src/tools/clippy/tests/ui/asm_syntax.rs +++ b/src/tools/clippy/tests/ui/asm_syntax.rs @@ -1,5 +1,5 @@ -// only-x86_64 -// ignore-aarch64 +//@only-x86_64 +//@ignore-aarch64 #[warn(clippy::inline_asm_x86_intel_syntax)] mod warn_intel { diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed index 2bb755290c5..ea8b895664c 100644 --- a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed +++ b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::assertions_on_result_states)] use std::result::Result; diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.rs b/src/tools/clippy/tests/ui/assertions_on_result_states.rs index d8a9bd2f1c4..6fc20f85988 100644 --- a/src/tools/clippy/tests/ui/assertions_on_result_states.rs +++ b/src/tools/clippy/tests/ui/assertions_on_result_states.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::assertions_on_result_states)] use std::result::Result; diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed index da034b51cfd..b50682ea00c 100644 --- a/src/tools/clippy/tests/ui/assign_ops.fixed +++ b/src/tools/clippy/tests/ui/assign_ops.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use core::num::Wrapping; diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs index 337bb02c8a6..780d2d040f1 100644 --- a/src/tools/clippy/tests/ui/assign_ops.rs +++ b/src/tools/clippy/tests/ui/assign_ops.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use core::num::Wrapping; diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed index 579a63ea477..8d9b023893f 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.fixed +++ b/src/tools/clippy/tests/ui/async_yields_async.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs index 5aec2fb50f6..bed79062f01 100644 --- a/src/tools/clippy/tests/ui/async_yields_async.rs +++ b/src/tools/clippy/tests/ui/async_yields_async.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] diff --git a/src/tools/clippy/tests/ui/author/blocks.rs b/src/tools/clippy/tests/ui/author/blocks.rs index a7335c01baa..164f7d0d9d6 100644 --- a/src/tools/clippy/tests/ui/author/blocks.rs +++ b/src/tools/clippy/tests/ui/author/blocks.rs @@ -1,4 +1,4 @@ -// edition:2018 +//@edition:2018 #![allow(redundant_semicolons, clippy::no_effect)] #![feature(stmt_expr_attributes)] diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs index 4914f14b58f..92c47b41a38 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] #![feature(repr128, proc_macro_hygiene, proc_macro_quote, box_patterns)] @@ -28,7 +28,7 @@ pub fn dummy(_args: TokenStream, input: TokenStream) -> TokenStream { pub fn fake_async_trait(_args: TokenStream, input: TokenStream) -> TokenStream { let mut item = parse_macro_input!(input as ItemTrait); for inner in &mut item.items { - if let TraitItem::Method(method) = inner { + if let TraitItem::Fn(method) = inner { let sig = &method.sig; let block = &mut method.default; if let Some(block) = block { @@ -70,7 +70,7 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea // Look for methods having arbitrary self type taken by &mut ref for inner in &mut item.items { - if let ImplItem::Method(method) = inner { + if let ImplItem::Fn(method) = inner { if let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig) { if let box Type::Reference(reference) = &mut pat_type.ty { // Target only unnamed lifetimes diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs index a89a06308d0..5a924ca1830 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] #![feature(repr128, proc_macro_quote)] @@ -9,7 +9,7 @@ extern crate proc_macro; -use proc_macro::{quote, TokenStream}; +use proc_macro::{quote, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; #[proc_macro_derive(DeriveSomething)] pub fn derive(_: TokenStream) -> TokenStream { @@ -86,3 +86,74 @@ pub fn extra_lifetime(_input: TokenStream) -> TokenStream { } ) } + +#[allow(unused)] +#[proc_macro_derive(ArithmeticDerive)] +pub fn arithmetic_derive(_: TokenStream) -> TokenStream { + <TokenStream as FromIterator<TokenTree>>::from_iter( + [ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + <TokenStream as FromIterator<TokenTree>>::from_iter( + [ + Ident::new("let", Span::call_site()).into(), + Ident::new("mut", Span::call_site()).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(9).into(), + Punct::new('/', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Punct::new('-', Spacing::Alone).into(), + Ident::new("_n", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ] + .into_iter(), + ), + ) + .into(), + ] + .into_iter(), + ) +} + +#[allow(unused)] +#[proc_macro_derive(ShadowDerive)] +pub fn shadow_derive(_: TokenStream) -> TokenStream { + <TokenStream as FromIterator<TokenTree>>::from_iter( + [ + Ident::new("fn", Span::call_site()).into(), + Ident::new("_foo", Span::call_site()).into(), + Group::new(Delimiter::Parenthesis, TokenStream::new()).into(), + Group::new( + Delimiter::Brace, + <TokenStream as FromIterator<TokenTree>>::from_iter( + [ + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Literal::i32_unsuffixed(2).into(), + Punct::new(';', Spacing::Alone).into(), + Ident::new("let", Span::call_site()).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new('=', Spacing::Alone).into(), + Ident::new("_x", Span::call_site()).into(), + Punct::new(';', Spacing::Alone).into(), + ] + .into_iter(), + ), + ) + .into(), + ] + .into_iter(), + ) +} diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs index a2ef0fe827c..f13b76e44b0 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs index 3c40f77469b..c2326678d0d 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs index 3d5beab1eff..94f075ed09c 100644 --- a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs +++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic #![crate_type = "proc-macro"] #![feature(let_chains)] diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map.fixed index d94e2ac6072..ea2dc2e2293 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map.fixed +++ b/src/tools/clippy/tests/ui/bind_instead_of_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map.rs b/src/tools/clippy/tests/ui/bind_instead_of_map.rs index 86f31f58284..1db58dae538 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map.rs +++ b/src/tools/clippy/tests/ui/bind_instead_of_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed index e1589843226..63c7aafcddb 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::blocks_in_if_conditions)] diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs index 49944403f6d..69b982fa8a2 100644 --- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs +++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::bind_instead_of_map)] #![allow(clippy::blocks_in_if_conditions)] diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs index 554745368bc..e1ff25c54cf 100644 --- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs +++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.rs @@ -1,4 +1,4 @@ -// compile-flags: -W clippy::restriction +//@compile-flags: -W clippy::restriction #![warn(clippy::blanket_clippy_restriction_lints)] diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed index e6e40a9948c..a9f18782e58 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed +++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::blocks_in_if_conditions)] #![allow(unused, clippy::let_and_return)] #![warn(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs index 69387ff5782..0a70317c4d4 100644 --- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs +++ b/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::blocks_in_if_conditions)] #![allow(unused, clippy::let_and_return)] #![warn(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.fixed b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed index b8dd92906c8..53f63444aef 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.fixed +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::assertions_on_constants)] #![warn(clippy::bool_assert_comparison)] diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.rs b/src/tools/clippy/tests/ui/bool_assert_comparison.rs index 0a8ad34fda5..151d93a9233 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.rs +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::assertions_on_constants)] #![warn(clippy::bool_assert_comparison)] diff --git a/src/tools/clippy/tests/ui/bool_comparison.fixed b/src/tools/clippy/tests/ui/bool_comparison.fixed index 5a012ff4d27..670eef6a21d 100644 --- a/src/tools/clippy/tests/ui/bool_comparison.fixed +++ b/src/tools/clippy/tests/ui/bool_comparison.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bool_comparison)] diff --git a/src/tools/clippy/tests/ui/bool_comparison.rs b/src/tools/clippy/tests/ui/bool_comparison.rs index c534bc25c20..72851be635d 100644 --- a/src/tools/clippy/tests/ui/bool_comparison.rs +++ b/src/tools/clippy/tests/ui/bool_comparison.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bool_comparison)] diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed index 37d3e3286a4..9831c3373d4 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs index ebdf86fd185..5e3047bb32c 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.rs +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(let_chains)] #![warn(clippy::bool_to_int_with_if)] diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed index ff5c6a8c377..3f440ce0045 100644 --- a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed +++ b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] fn main() { diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.rs b/src/tools/clippy/tests/ui/borrow_as_ptr.rs index 0f62ec6ee58..c1ca9180eef 100644 --- a/src/tools/clippy/tests/ui/borrow_as_ptr.rs +++ b/src/tools/clippy/tests/ui/borrow_as_ptr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] fn main() { diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed index eaba3b1c20c..10f2727c793 100644 --- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed +++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs index d83f9d1f875..311e9341aac 100644 --- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs +++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::borrow_as_ptr)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed index bf4691c5bc9..165e4bc8272 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed +++ b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.rs b/src/tools/clippy/tests/ui/borrow_deref_ref.rs index 28c005fdbef..66c8d69bef9 100644 --- a/src/tools/clippy/tests/ui/borrow_deref_ref.rs +++ b/src/tools/clippy/tests/ui/borrow_deref_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.rs index 5027db44561..29b08ab3643 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.rs +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.rs @@ -1,4 +1,4 @@ -// aux-build:helper.rs +//@aux-build:helper.rs #![warn(clippy::borrow_interior_mutable_const)] #![allow(clippy::declare_interior_mutable_const)] diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed index 59c0baf8718..6afce208769 100644 --- a/src/tools/clippy/tests/ui/box_default.fixed +++ b/src/tools/clippy/tests/ui/box_default.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::box_default)] #[derive(Default)] diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs index f7d832193a3..09365618e63 100644 --- a/src/tools/clippy/tests/ui/box_default.rs +++ b/src/tools/clippy/tests/ui/box_default.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::box_default)] #[derive(Default)] diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.fixed b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed index 860642363b5..fb3d521badd 100644 --- a/src/tools/clippy/tests/ui/bytes_count_to_len.fixed +++ b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bytes_count_to_len)] use std::fs::File; use std::io::Read; diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.rs b/src/tools/clippy/tests/ui/bytes_count_to_len.rs index 162730c2842..8e256b8f0b8 100644 --- a/src/tools/clippy/tests/ui/bytes_count_to_len.rs +++ b/src/tools/clippy/tests/ui/bytes_count_to_len.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::bytes_count_to_len)] use std::fs::File; use std::io::Read; diff --git a/src/tools/clippy/tests/ui/bytes_nth.fixed b/src/tools/clippy/tests/ui/bytes_nth.fixed index a35c679afb7..d3e0f676b29 100644 --- a/src/tools/clippy/tests/ui/bytes_nth.fixed +++ b/src/tools/clippy/tests/ui/bytes_nth.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_operation)] #![warn(clippy::bytes_nth)] diff --git a/src/tools/clippy/tests/ui/bytes_nth.rs b/src/tools/clippy/tests/ui/bytes_nth.rs index 1ecffea5303..b7d813fe296 100644 --- a/src/tools/clippy/tests/ui/bytes_nth.rs +++ b/src/tools/clippy/tests/ui/bytes_nth.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_operation)] #![warn(clippy::bytes_nth)] diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed index 5fbaa64db39..d5af22aefe5 100644 --- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed +++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::case_sensitive_file_extension_comparisons)] use std::string::String; diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs index 3c0d4821f9f..f5f0a0022a4 100644 --- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::case_sensitive_file_extension_comparisons)] use std::string::String; diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed index 8676b562b4f..ef0a93b01d1 100644 --- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed +++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_abs_to_unsigned)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs index 5775af874f8..96ced670a05 100644 --- a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs +++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_abs_to_unsigned)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed index 13b3cf838c9..c321cc64437 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_bool.fixed +++ b/src/tools/clippy/tests/ui/cast_lossless_bool.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.rs b/src/tools/clippy/tests/ui/cast_lossless_bool.rs index 3eed2135562..632a718920d 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_bool.rs +++ b/src/tools/clippy/tests/ui/cast_lossless_bool.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.fixed b/src/tools/clippy/tests/ui/cast_lossless_float.fixed index 32a9c1c4ae1..e72a0096acc 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_float.fixed +++ b/src/tools/clippy/tests/ui/cast_lossless_float.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.rs b/src/tools/clippy/tests/ui/cast_lossless_float.rs index 6f5ddcfe09c..dbcbaa9b815 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_float.rs +++ b/src/tools/clippy/tests/ui/cast_lossless_float.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed index 925cbf25368..7dab02084fc 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed +++ b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.rs b/src/tools/clippy/tests/ui/cast_lossless_integer.rs index c82bd9108d2..c24f73960b0 100644 --- a/src/tools/clippy/tests/ui/cast_lossless_integer.rs +++ b/src/tools/clippy/tests/ui/cast_lossless_integer.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed index b70c1912951..9b6fee270ee 100644 --- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed +++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_slice_from_raw_parts)] #[allow(unused_imports, unused_unsafe)] diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs index c1b316765c9..c0bb8137990 100644 --- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs +++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cast_slice_from_raw_parts)] #[allow(unused_imports, unused_unsafe)] diff --git a/src/tools/clippy/tests/ui/cast_size.rs b/src/tools/clippy/tests/ui/cast_size.rs index 595109be46b..cd2184aea38 100644 --- a/src/tools/clippy/tests/ui/cast_size.rs +++ b/src/tools/clippy/tests/ui/cast_size.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #[warn( clippy::cast_precision_loss, clippy::cast_possible_truncation, diff --git a/src/tools/clippy/tests/ui/cast_size_32bit.rs b/src/tools/clippy/tests/ui/cast_size_32bit.rs index 99aac6deca3..7ca20d3ca4a 100644 --- a/src/tools/clippy/tests/ui/cast_size_32bit.rs +++ b/src/tools/clippy/tests/ui/cast_size_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #[warn( clippy::cast_precision_loss, clippy::cast_possible_truncation, diff --git a/src/tools/clippy/tests/ui/cast_size_32bit.stderr b/src/tools/clippy/tests/ui/cast_size_32bit.stderr index 8990c3ba739..fb51783a487 100644 --- a/src/tools/clippy/tests/ui/cast_size_32bit.stderr +++ b/src/tools/clippy/tests/ui/cast_size_32bit.stderr @@ -4,7 +4,12 @@ error: casting `isize` to `i8` may truncate the value LL | 1isize as i8; | ^^^^^^^^^^^^ | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... = note: `-D clippy::cast-possible-truncation` implied by `-D warnings` +help: ... or use `try_from` and handle the error accordingly + | +LL | i8::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `f64` causes a loss of precision on targets with 64-bit wide pointers (`isize` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide) --> $DIR/cast_size_32bit.rs:15:5 @@ -37,24 +42,48 @@ error: casting `isize` to `i32` may truncate the value on targets with 64-bit wi | LL | 1isize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:20:5 | LL | 1isize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1isize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:21:5 | LL | 1usize as u32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | u32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:22:5 | LL | 1usize as i32; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | i32::try_from(1usize); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:22:5 @@ -69,18 +98,36 @@ error: casting `i64` to `isize` may truncate the value on targets with 32-bit wi | LL | 1i64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:25:5 | LL | 1i64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1i64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:26:5 | LL | 1u64 as isize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | isize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers --> $DIR/cast_size_32bit.rs:26:5 @@ -93,6 +140,12 @@ error: casting `u64` to `usize` may truncate the value on targets with 32-bit wi | LL | 1u64 as usize; | ^^^^^^^^^^^^^ + | + = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ... +help: ... or use `try_from` and handle the error accordingly + | +LL | usize::try_from(1u64); + | ~~~~~~~~~~~~~~~~~~~~~ error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers --> $DIR/cast_size_32bit.rs:28:5 diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed index b970b1209b6..13aadb7d330 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)] diff --git a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs index 0a8e6a89d8a..769c5d22b9d 100644 --- a/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs +++ b/src/tools/clippy/tests/ui/cfg_attr_rustfmt.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)] diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed index 3dc3cb4e757..ce2f149dc05 100644 --- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed +++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::char_lit_as_u8)] diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs index d379a023494..ffad12fc6f9 100644 --- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs +++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::char_lit_as_u8)] diff --git a/src/tools/clippy/tests/ui/checked_conversions.fixed b/src/tools/clippy/tests/ui/checked_conversions.fixed index e279ba3147b..188e6d97595 100644 --- a/src/tools/clippy/tests/ui/checked_conversions.fixed +++ b/src/tools/clippy/tests/ui/checked_conversions.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::cast_lossless, diff --git a/src/tools/clippy/tests/ui/checked_conversions.rs b/src/tools/clippy/tests/ui/checked_conversions.rs index 9d7a40995c3..70f0f0975ac 100644 --- a/src/tools/clippy/tests/ui/checked_conversions.rs +++ b/src/tools/clippy/tests/ui/checked_conversions.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::cast_lossless, diff --git a/src/tools/clippy/tests/ui/clear_with_drain.fixed b/src/tools/clippy/tests/ui/clear_with_drain.fixed index 2d9545eeed1..b68c7d867ec 100644 --- a/src/tools/clippy/tests/ui/clear_with_drain.fixed +++ b/src/tools/clippy/tests/ui/clear_with_drain.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::clear_with_drain)] diff --git a/src/tools/clippy/tests/ui/clear_with_drain.rs b/src/tools/clippy/tests/ui/clear_with_drain.rs index 4d60ee46e18..0f6562ecad5 100644 --- a/src/tools/clippy/tests/ui/clear_with_drain.rs +++ b/src/tools/clippy/tests/ui/clear_with_drain.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::clear_with_drain)] diff --git a/src/tools/clippy/tests/ui/clone_on_copy.fixed b/src/tools/clippy/tests/ui/clone_on_copy.fixed index 72b12227098..a720711585b 100644 --- a/src/tools/clippy/tests/ui/clone_on_copy.fixed +++ b/src/tools/clippy/tests/ui/clone_on_copy.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, diff --git a/src/tools/clippy/tests/ui/clone_on_copy.rs b/src/tools/clippy/tests/ui/clone_on_copy.rs index 03e210ebad9..2c5fac8faf5 100644 --- a/src/tools/clippy/tests/ui/clone_on_copy.rs +++ b/src/tools/clippy/tests/ui/clone_on_copy.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, diff --git a/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed index ecbfc1feedf..b6e09ab3190 100644 --- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed +++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs b/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs index 163dc3dddce..fa9e1a99613 100644 --- a/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs +++ b/src/tools/clippy/tests/ui/cloned_instead_of_copied.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::cloned_instead_of_copied)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed index abd059c2308..3bf3deb9b91 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed +++ b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 // Define the types in each module to avoid trait impls leaking between modules. diff --git a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs index 020ef5f840b..10107dc8f86 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs +++ b/src/tools/clippy/tests/ui/cmp_owned/asymmetric_partial_eq.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::redundant_clone, clippy::derive_partial_eq_without_eq)] // See #5700 // Define the types in each module to avoid trait impls leaking between modules. diff --git a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed index 44e41bdd114..b1133f2a59f 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed +++ b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::fmt::{self, Display}; diff --git a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs index 662673abb62..091a9aa65c0 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs +++ b/src/tools/clippy/tests/ui/cmp_owned/comparison_flip.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::fmt::{self, Display}; diff --git a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed index b28c4378e33..76f90ab2a9d 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed +++ b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::cmp_owned)] #[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)] diff --git a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs index c1089010fe1..f3f663670eb 100644 --- a/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs +++ b/src/tools/clippy/tests/ui/cmp_owned/with_suggestion.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::cmp_owned)] #[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)] diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed index d6a5a785067..8302cec45e7 100644 --- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed +++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] #[rustfmt::skip] diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs index 4399fc8b2bd..5913dcf41ca 100644 --- a/src/tools/clippy/tests/ui/collapsible_else_if.rs +++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] #[rustfmt::skip] diff --git a/src/tools/clippy/tests/ui/collapsible_if.fixed b/src/tools/clippy/tests/ui/collapsible_if.fixed index 6bb7682bae9..d2aba2ac59b 100644 --- a/src/tools/clippy/tests/ui/collapsible_if.fixed +++ b/src/tools/clippy/tests/ui/collapsible_if.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] #[rustfmt::skip] diff --git a/src/tools/clippy/tests/ui/collapsible_if.rs b/src/tools/clippy/tests/ui/collapsible_if.rs index e216a9ee54c..e0bef7f9c97 100644 --- a/src/tools/clippy/tests/ui/collapsible_if.rs +++ b/src/tools/clippy/tests/ui/collapsible_if.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::assertions_on_constants, clippy::equatable_if_let)] #[rustfmt::skip] diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed index 9792ae9ed6b..ba6c1769a9a 100644 --- a/src/tools/clippy/tests/ui/collapsible_str_replace.fixed +++ b/src/tools/clippy/tests/ui/collapsible_str_replace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::collapsible_str_replace)] diff --git a/src/tools/clippy/tests/ui/collapsible_str_replace.rs b/src/tools/clippy/tests/ui/collapsible_str_replace.rs index baee185b79e..f5871be65be 100644 --- a/src/tools/clippy/tests/ui/collapsible_str_replace.rs +++ b/src/tools/clippy/tests/ui/collapsible_str_replace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::collapsible_str_replace)] diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.rs b/src/tools/clippy/tests/ui/collection_is_never_read.rs index 01259a983ab..2c1a42a72c1 100644 --- a/src/tools/clippy/tests/ui/collection_is_never_read.rs +++ b/src/tools/clippy/tests/ui/collection_is_never_read.rs @@ -169,22 +169,35 @@ fn function_argument() { foo(&x); } -fn string() { - // Do lint (write without read) - let mut s = String::new(); - s.push_str("Hello, World!"); - - // Do not lint (read without write) - let mut s = String::from("Hello, World!"); - let _ = s.len(); - - // Do not lint (write and read) - let mut s = String::from("Hello, World!"); - s.push_str("foo, bar"); - let _ = s.len(); - - // Do lint the first line, but not the second - let mut s = String::from("Hello, World!"); - let t = String::from("foo, bar"); - s = t; +fn supported_types() { + let mut x = std::collections::BTreeMap::new(); // WARNING + x.insert(true, 1); + + let mut x = std::collections::BTreeSet::new(); // WARNING + x.insert(1); + + let mut x = std::collections::BinaryHeap::new(); // WARNING + x.push(1); + + let mut x = std::collections::HashMap::new(); // WARNING + x.insert(1, 2); + + let mut x = std::collections::HashSet::new(); // WARNING + x.insert(1); + + let mut x = std::collections::LinkedList::new(); // WARNING + x.push_front(1); + + let mut x = Some(true); // WARNING + x.insert(false); + + let mut x = String::from("hello"); // WARNING + x.push('!'); + + let mut x = Vec::new(); // WARNING + x.clear(); + x.push(1); + + let mut x = std::collections::VecDeque::new(); // WARNING + x.push_front(1); } diff --git a/src/tools/clippy/tests/ui/collection_is_never_read.stderr b/src/tools/clippy/tests/ui/collection_is_never_read.stderr index cf51a53686f..982cb445534 100644 --- a/src/tools/clippy/tests/ui/collection_is_never_read.stderr +++ b/src/tools/clippy/tests/ui/collection_is_never_read.stderr @@ -61,16 +61,64 @@ LL | let x = vec![1, 2, 3]; // WARNING | ^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> $DIR/collection_is_never_read.rs:174:5 + --> $DIR/collection_is_never_read.rs:173:5 | -LL | let mut s = String::new(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let mut x = std::collections::BTreeMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:176:5 + | +LL | let mut x = std::collections::BTreeSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:179:5 + | +LL | let mut x = std::collections::BinaryHeap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:182:5 + | +LL | let mut x = std::collections::HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:185:5 + | +LL | let mut x = std::collections::HashSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:188:5 + | +LL | let mut x = std::collections::LinkedList::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:191:5 + | +LL | let mut x = Some(true); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:194:5 + | +LL | let mut x = String::from("hello"); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:197:5 + | +LL | let mut x = Vec::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^ error: collection is never read - --> $DIR/collection_is_never_read.rs:187:5 + --> $DIR/collection_is_never_read.rs:201:5 | -LL | let mut s = String::from("Hello, World!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let mut x = std::collections::VecDeque::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 20 previous errors diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.fixed b/src/tools/clippy/tests/ui/comparison_to_empty.fixed index 261024caca7..dd2615ab25c 100644 --- a/src/tools/clippy/tests/ui/comparison_to_empty.fixed +++ b/src/tools/clippy/tests/ui/comparison_to_empty.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::comparison_to_empty)] diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.rs b/src/tools/clippy/tests/ui/comparison_to_empty.rs index 98ddd974951..5462784c6ac 100644 --- a/src/tools/clippy/tests/ui/comparison_to_empty.rs +++ b/src/tools/clippy/tests/ui/comparison_to_empty.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::comparison_to_empty)] diff --git a/src/tools/clippy/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/src/tools/clippy/tests/ui/crashes/auxiliary/proc_macro_crash.rs index 5ff2af7cd82..66419656a32 100644 --- a/src/tools/clippy/tests/ui/crashes/auxiliary/proc_macro_crash.rs +++ b/src/tools/clippy/tests/ui/crashes/auxiliary/proc_macro_crash.rs @@ -1,5 +1,5 @@ -// compile-flags: --emit=link -// no-prefer-dynamic +//@compile-flags: --emit=link +//@no-prefer-dynamic // ^ compiletest by default builds all aux files as dylibs, but we don't want that for proc-macro // crates. If we don't set this, compiletest will override the `crate_type` attribute below and // compile this as dylib. Removing this then causes the test to fail because a `dylib` crate can't diff --git a/src/tools/clippy/tests/ui/crashes/ice-10148.rs b/src/tools/clippy/tests/ui/crashes/ice-10148.rs index 1ab3570c907..c7f0224820e 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-10148.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-10148.rs @@ -1,4 +1,4 @@ -// aux-build:../../auxiliary/proc_macros.rs +//@aux-build:../../auxiliary/proc_macros.rs extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/crashes/ice-3741.rs b/src/tools/clippy/tests/ui/crashes/ice-3741.rs index 1253ddcfaeb..3106a2e7216 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-3741.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-3741.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_crash.rs +//@aux-build:proc_macro_crash.rs #![warn(clippy::suspicious_else_formatting)] diff --git a/src/tools/clippy/tests/ui/crashes/ice-4968.rs b/src/tools/clippy/tests/ui/crashes/ice-4968.rs index e0510d942c2..ac724ac93e3 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-4968.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-4968.rs @@ -1,4 +1,4 @@ -// check-pass +//@check-pass // Test for https://github.com/rust-lang/rust-clippy/issues/4968 diff --git a/src/tools/clippy/tests/ui/crashes/ice-5207.rs b/src/tools/clippy/tests/ui/crashes/ice-5207.rs index f463f78a99a..893c15f5d73 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-5207.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-5207.rs @@ -1,5 +1,8 @@ -// Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 +// compile-flags: --cap-lints=warn +// ^ for https://github.com/rust-lang/rust-clippy/issues/10645 +// Regression test for https://github.com/rust-lang/rust-clippy/issues/5207 +#![warn(clippy::future_not_send)] pub async fn bar<'a, T: 'a>(_: T) {} fn main() {} diff --git a/src/tools/clippy/tests/ui/crashes/ice-5207.stderr b/src/tools/clippy/tests/ui/crashes/ice-5207.stderr new file mode 100644 index 00000000000..59146c23e0d --- /dev/null +++ b/src/tools/clippy/tests/ui/crashes/ice-5207.stderr @@ -0,0 +1,16 @@ +error: future cannot be sent between threads safely + --> $DIR/ice-5207.rs:6:35 + | +LL | pub async fn bar<'a, T: 'a>(_: T) {} + | ^ future returned by `bar` is not `Send` + | +note: captured value is not `Send` + --> $DIR/ice-5207.rs:6:29 + | +LL | pub async fn bar<'a, T: 'a>(_: T) {} + | ^ has type `T` which is not `Send` + = note: `T` doesn't implement `std::marker::Send` + = note: `-D clippy::future-not-send` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/crashes/ice-7272.rs b/src/tools/clippy/tests/ui/crashes/ice-7272.rs index 57ab6ca14f8..e949038c8d0 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7272.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-7272.rs @@ -1,4 +1,4 @@ -// aux-build:ice-7272-aux.rs +//@aux-build:ice-7272-aux.rs #![allow(clippy::no_effect)] diff --git a/src/tools/clippy/tests/ui/crashes/ice-7410.rs b/src/tools/clippy/tests/ui/crashes/ice-7410.rs index 85fa4210321..ffe20ab1c31 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7410.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-7410.rs @@ -1,6 +1,6 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos -// ignore-windows +//@compile-flags: -Clink-arg=-nostartfiles +//@ignore-macos +//@ignore-windows #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/crashes/ice-8681.rs b/src/tools/clippy/tests/ui/crashes/ice-8681.rs index ee14f011f63..607b9caa324 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-8681.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-8681.rs @@ -1,4 +1,4 @@ -// aux-build: ice-8681-aux.rs +//@aux-build: ice-8681-aux.rs #![warn(clippy::undocumented_unsafe_blocks)] diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed index 9fc594be311..12a7b9470b3 100644 --- a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed +++ b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::crate_in_macro_def)] mod hygienic { diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.rs b/src/tools/clippy/tests/ui/crate_in_macro_def.rs index ac456108e4a..a1a9eabf639 100644 --- a/src/tools/clippy/tests/ui/crate_in_macro_def.rs +++ b/src/tools/clippy/tests/ui/crate_in_macro_def.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::crate_in_macro_def)] mod hygienic { diff --git a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs index 1b3bcece6f1..d6cd594d7c9 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs +++ b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs @@ -1,4 +1,4 @@ -// ignore-macos +//@ignore-macos #![feature(rustc_attrs)] diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs index e1c9fe30a9d..a382135bb69 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs +++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs @@ -1,5 +1,5 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos +//@compile-flags: -Clink-arg=-nostartfiles +//@ignore-macos #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/create_dir.fixed b/src/tools/clippy/tests/ui/create_dir.fixed index 8ed53a56ac0..5de3e9fea0b 100644 --- a/src/tools/clippy/tests/ui/create_dir.fixed +++ b/src/tools/clippy/tests/ui/create_dir.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::create_dir)] diff --git a/src/tools/clippy/tests/ui/create_dir.rs b/src/tools/clippy/tests/ui/create_dir.rs index 19c8fc24ba2..d375bfb4a68 100644 --- a/src/tools/clippy/tests/ui/create_dir.rs +++ b/src/tools/clippy/tests/ui/create_dir.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::create_dir)] diff --git a/src/tools/clippy/tests/ui/dbg_macro.rs b/src/tools/clippy/tests/ui/dbg_macro.rs index 25294e8c766..8701e3cd29f 100644 --- a/src/tools/clippy/tests/ui/dbg_macro.rs +++ b/src/tools/clippy/tests/ui/dbg_macro.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::dbg_macro)] fn foo(n: u32) -> u32 { diff --git a/src/tools/clippy/tests/ui/decimal_literal_representation.fixed b/src/tools/clippy/tests/ui/decimal_literal_representation.fixed index de391465125..a6eb8c21457 100644 --- a/src/tools/clippy/tests/ui/decimal_literal_representation.fixed +++ b/src/tools/clippy/tests/ui/decimal_literal_representation.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::decimal_literal_representation)] #[allow(unused_variables)] diff --git a/src/tools/clippy/tests/ui/decimal_literal_representation.rs b/src/tools/clippy/tests/ui/decimal_literal_representation.rs index 55d07698e7e..7c666d6d7a6 100644 --- a/src/tools/clippy/tests/ui/decimal_literal_representation.rs +++ b/src/tools/clippy/tests/ui/decimal_literal_representation.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::decimal_literal_representation)] #[allow(unused_variables)] diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs index 1af77d1a25b..f7819068ac5 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.rs +++ b/src/tools/clippy/tests/ui/def_id_nocore.rs @@ -1,4 +1,4 @@ -// ignore-macos +//@ignore-macos #![feature(no_core, lang_items, start)] #![no_core] diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed index f1abfdcd6ce..f44d34576f6 100644 --- a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed +++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::default_instead_of_iter_empty)] #![allow(dead_code)] use std::collections::HashMap; diff --git a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs index 2630519c46d..1c649df253c 100644 --- a/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs +++ b/src/tools/clippy/tests/ui/default_instead_of_iter_empty.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::default_instead_of_iter_empty)] #![allow(dead_code)] use std::collections::HashMap; diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed index 42c15d6a70b..9520efe6329 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs index 7da7ea254e9..cacbdb4a95b 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed index b7485b73dcd..fbabb8bcf8e 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs index 7307d31354e..7bfc390e4bf 100644 --- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs +++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] diff --git a/src/tools/clippy/tests/ui/default_trait_access.fixed b/src/tools/clippy/tests/ui/default_trait_access.fixed index 7842ef3ec40..bf5dca97641 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.fixed +++ b/src/tools/clippy/tests/ui/default_trait_access.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/default_trait_access.rs b/src/tools/clippy/tests/ui/default_trait_access.rs index cbb3e59c970..5e8e9ce85b1 100644 --- a/src/tools/clippy/tests/ui/default_trait_access.rs +++ b/src/tools/clippy/tests/ui/default_trait_access.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/deref_addrof.fixed b/src/tools/clippy/tests/ui/deref_addrof.fixed index ca5c03304c7..b27d3bc1002 100644 --- a/src/tools/clippy/tests/ui/deref_addrof.fixed +++ b/src/tools/clippy/tests/ui/deref_addrof.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] diff --git a/src/tools/clippy/tests/ui/deref_addrof.rs b/src/tools/clippy/tests/ui/deref_addrof.rs index 3db5fafe944..825090c7c12 100644 --- a/src/tools/clippy/tests/ui/deref_addrof.rs +++ b/src/tools/clippy/tests/ui/deref_addrof.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] diff --git a/src/tools/clippy/tests/ui/deref_addrof_macro.rs b/src/tools/clippy/tests/ui/deref_addrof_macro.rs index 57c0be3f51e..c7e60f36506 100644 --- a/src/tools/clippy/tests/ui/deref_addrof_macro.rs +++ b/src/tools/clippy/tests/ui/deref_addrof_macro.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::deref_addrof)] diff --git a/src/tools/clippy/tests/ui/deref_by_slicing.fixed b/src/tools/clippy/tests/ui/deref_by_slicing.fixed index 257393e56ff..f91a425c65d 100644 --- a/src/tools/clippy/tests/ui/deref_by_slicing.fixed +++ b/src/tools/clippy/tests/ui/deref_by_slicing.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::deref_by_slicing)] #![allow(clippy::borrow_deref_ref)] diff --git a/src/tools/clippy/tests/ui/deref_by_slicing.rs b/src/tools/clippy/tests/ui/deref_by_slicing.rs index e288046f927..1bfdd0a981b 100644 --- a/src/tools/clippy/tests/ui/deref_by_slicing.rs +++ b/src/tools/clippy/tests/ui/deref_by_slicing.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::deref_by_slicing)] #![allow(clippy::borrow_deref_ref)] diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed index 89ec33a0d8f..aa0efb85c29 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.fixed +++ b/src/tools/clippy/tests/ui/derivable_impls.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs index def6e41162f..8dc999ad586 100644 --- a/src/tools/clippy/tests/ui/derivable_impls.rs +++ b/src/tools/clippy/tests/ui/derivable_impls.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed index bbbe467590f..a1f29430c30 100644 --- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed +++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs index 88d6fbd1af7..ff4d888559b 100644 --- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs +++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::derive_partial_eq_without_eq)] diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed index ecb0bf3644e..d3aa2816cb6 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix //! This file tests for the `DOC_MARKDOWN` lint. #![allow(dead_code, incomplete_features)] diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs index 11c48dd103d..d1e7d8017d7 100644 --- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs +++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix //! This file tests for the `DOC_MARKDOWN` lint. #![allow(dead_code, incomplete_features)] diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs index 30674ce3708..0c8eac5ccff 100644 --- a/src/tools/clippy/tests/ui/doc_unsafe.rs +++ b/src/tools/clippy/tests/ui/doc_unsafe.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/double_comparison.fixed b/src/tools/clippy/tests/ui/double_comparison.fixed index bb6cdaa667d..c80ff671a5d 100644 --- a/src/tools/clippy/tests/ui/double_comparison.fixed +++ b/src/tools/clippy/tests/ui/double_comparison.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { let x = 1; diff --git a/src/tools/clippy/tests/ui/double_comparison.rs b/src/tools/clippy/tests/ui/double_comparison.rs index 9a2a9068a28..bc78694aa68 100644 --- a/src/tools/clippy/tests/ui/double_comparison.rs +++ b/src/tools/clippy/tests/ui/double_comparison.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { let x = 1; diff --git a/src/tools/clippy/tests/ui/duration_subsec.fixed b/src/tools/clippy/tests/ui/duration_subsec.fixed index d92b8998e88..bfd30f0042d 100644 --- a/src/tools/clippy/tests/ui/duration_subsec.fixed +++ b/src/tools/clippy/tests/ui/duration_subsec.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::needless_borrow)] #![warn(clippy::duration_subsec)] diff --git a/src/tools/clippy/tests/ui/duration_subsec.rs b/src/tools/clippy/tests/ui/duration_subsec.rs index 08da804996d..860233f084f 100644 --- a/src/tools/clippy/tests/ui/duration_subsec.rs +++ b/src/tools/clippy/tests/ui/duration_subsec.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::needless_borrow)] #![warn(clippy::duration_subsec)] diff --git a/src/tools/clippy/tests/ui/empty_drop.fixed b/src/tools/clippy/tests/ui/empty_drop.fixed index 2e1b768461a..fd0a9a7081e 100644 --- a/src/tools/clippy/tests/ui/empty_drop.fixed +++ b/src/tools/clippy/tests/ui/empty_drop.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_drop)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/empty_drop.rs b/src/tools/clippy/tests/ui/empty_drop.rs index 75232b0334d..6c15cb93302 100644 --- a/src/tools/clippy/tests/ui/empty_drop.rs +++ b/src/tools/clippy/tests/ui/empty_drop.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_drop)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs index 697412c0027..269e66ea0a8 100644 --- a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs +++ b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_attr.rs +//@aux-build:proc_macro_attr.rs #![warn(clippy::empty_line_after_outer_attr)] #![allow(clippy::assertions_on_constants)] #![feature(custom_inner_attributes)] diff --git a/src/tools/clippy/tests/ui/empty_loop.rs b/src/tools/clippy/tests/ui/empty_loop.rs index 6a8e6b550c1..54e8fb4907c 100644 --- a/src/tools/clippy/tests/ui/empty_loop.rs +++ b/src/tools/clippy/tests/ui/empty_loop.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::empty_loop)] diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs index e742b396fcd..d564b2d24f5 100644 --- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs +++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs @@ -1,5 +1,5 @@ -// compile-flags: -Clink-arg=-nostartfiles -// ignore-macos +//@compile-flags: -Clink-arg=-nostartfiles +//@ignore-macos #![warn(clippy::empty_loop)] #![feature(lang_items, start, libc)] diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed index 80f07603b8d..6fab3020839 100644 --- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed +++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_structs_with_brackets)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs index 1d1ed4c7690..0caa3c49cd6 100644 --- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs +++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::empty_structs_with_brackets)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/entry.fixed b/src/tools/clippy/tests/ui/entry.fixed index dbe09e0ff3c..7e82390605c 100644 --- a/src/tools/clippy/tests/ui/entry.fixed +++ b/src/tools/clippy/tests/ui/entry.fixed @@ -1,5 +1,5 @@ -// needs-asm-support -// run-rustfix +//@needs-asm-support +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/src/tools/clippy/tests/ui/entry.rs b/src/tools/clippy/tests/ui/entry.rs index 30fed34fc5d..742c9322535 100644 --- a/src/tools/clippy/tests/ui/entry.rs +++ b/src/tools/clippy/tests/ui/entry.rs @@ -1,5 +1,5 @@ -// needs-asm-support -// run-rustfix +//@needs-asm-support +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/src/tools/clippy/tests/ui/entry_btree.fixed b/src/tools/clippy/tests/ui/entry_btree.fixed index 94979104556..3baaacffd20 100644 --- a/src/tools/clippy/tests/ui/entry_btree.fixed +++ b/src/tools/clippy/tests/ui/entry_btree.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_entry)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/entry_btree.rs b/src/tools/clippy/tests/ui/entry_btree.rs index 080c1d959e8..770e8e91da2 100644 --- a/src/tools/clippy/tests/ui/entry_btree.rs +++ b/src/tools/clippy/tests/ui/entry_btree.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_entry)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/entry_with_else.fixed b/src/tools/clippy/tests/ui/entry_with_else.fixed index 2332fa6313f..71fe04fd648 100644 --- a/src/tools/clippy/tests/ui/entry_with_else.fixed +++ b/src/tools/clippy/tests/ui/entry_with_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/src/tools/clippy/tests/ui/entry_with_else.rs b/src/tools/clippy/tests/ui/entry_with_else.rs index 2ff0c038efe..80f74649a60 100644 --- a/src/tools/clippy/tests/ui/entry_with_else.rs +++ b/src/tools/clippy/tests/ui/entry_with_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)] #![warn(clippy::map_entry)] diff --git a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs index 7d6842f5b54..f17556ea907 100644 --- a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs +++ b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs @@ -1,4 +1,4 @@ -// ignore-x86 +//@ignore-x86 #![warn(clippy::enum_clike_unportable_variant)] #![allow(unused, non_upper_case_globals)] diff --git a/src/tools/clippy/tests/ui/enum_glob_use.fixed b/src/tools/clippy/tests/ui/enum_glob_use.fixed index a98216758bb..419370ffb1d 100644 --- a/src/tools/clippy/tests/ui/enum_glob_use.fixed +++ b/src/tools/clippy/tests/ui/enum_glob_use.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::enum_glob_use)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/enum_glob_use.rs b/src/tools/clippy/tests/ui/enum_glob_use.rs index 5d929c9731d..645ed98325c 100644 --- a/src/tools/clippy/tests/ui/enum_glob_use.rs +++ b/src/tools/clippy/tests/ui/enum_glob_use.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::enum_glob_use)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/enum_variants.rs b/src/tools/clippy/tests/ui/enum_variants.rs index efed12ee2ef..531652a0e00 100644 --- a/src/tools/clippy/tests/ui/enum_variants.rs +++ b/src/tools/clippy/tests/ui/enum_variants.rs @@ -179,4 +179,14 @@ mod issue9018 { } } +mod allow_attributes_on_variants { + enum Enum { + #[allow(clippy::enum_variant_names)] + EnumStartsWith, + #[allow(clippy::enum_variant_names)] + EndsWithEnum, + Foo, + } +} + fn main() {} diff --git a/src/tools/clippy/tests/ui/eq_op.rs b/src/tools/clippy/tests/ui/eq_op.rs index e7379550265..cdd33ebe582 100644 --- a/src/tools/clippy/tests/ui/eq_op.rs +++ b/src/tools/clippy/tests/ui/eq_op.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::eq_op)] #![allow(clippy::double_parens, clippy::identity_op, clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/equatable_if_let.fixed b/src/tools/clippy/tests/ui/equatable_if_let.fixed index 007702ab550..53e62760bef 100644 --- a/src/tools/clippy/tests/ui/equatable_if_let.fixed +++ b/src/tools/clippy/tests/ui/equatable_if_let.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] diff --git a/src/tools/clippy/tests/ui/equatable_if_let.rs b/src/tools/clippy/tests/ui/equatable_if_let.rs index 3bda7977645..55918a5bb11 100644 --- a/src/tools/clippy/tests/ui/equatable_if_let.rs +++ b/src/tools/clippy/tests/ui/equatable_if_let.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] diff --git a/src/tools/clippy/tests/ui/err_expect.fixed b/src/tools/clippy/tests/ui/err_expect.fixed index b63cbd8a8e6..6ade6f54689 100644 --- a/src/tools/clippy/tests/ui/err_expect.fixed +++ b/src/tools/clippy/tests/ui/err_expect.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/err_expect.rs b/src/tools/clippy/tests/ui/err_expect.rs index c081a745fb4..a93fb59493f 100644 --- a/src/tools/clippy/tests/ui/err_expect.rs +++ b/src/tools/clippy/tests/ui/err_expect.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed index dc129591eac..b1baf462c0f 100644 --- a/src/tools/clippy/tests/ui/eta.fixed +++ b/src/tools/clippy/tests/ui/eta.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs index 025fd6a0b7a..e113c3d6cd6 100644 --- a/src/tools/clippy/tests/ui/eta.rs +++ b/src/tools/clippy/tests/ui/eta.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/excessive_precision.fixed b/src/tools/clippy/tests/ui/excessive_precision.fixed index b74bda182be..0a07957386c 100644 --- a/src/tools/clippy/tests/ui/excessive_precision.fixed +++ b/src/tools/clippy/tests/ui/excessive_precision.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::excessive_precision)] #![allow(dead_code, unused_variables, clippy::print_literal)] diff --git a/src/tools/clippy/tests/ui/excessive_precision.rs b/src/tools/clippy/tests/ui/excessive_precision.rs index 6e84a71f24c..62a832caa67 100644 --- a/src/tools/clippy/tests/ui/excessive_precision.rs +++ b/src/tools/clippy/tests/ui/excessive_precision.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::excessive_precision)] #![allow(dead_code, unused_variables, clippy::print_literal)] diff --git a/src/tools/clippy/tests/ui/exhaustive_items.fixed b/src/tools/clippy/tests/ui/exhaustive_items.fixed index c209f5b4b72..6c7b1cab6f2 100644 --- a/src/tools/clippy/tests/ui/exhaustive_items.fixed +++ b/src/tools/clippy/tests/ui/exhaustive_items.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/exhaustive_items.rs b/src/tools/clippy/tests/ui/exhaustive_items.rs index 6f59dbf2da5..d205bac2d2a 100644 --- a/src/tools/clippy/tests/ui/exhaustive_items.rs +++ b/src/tools/clippy/tests/ui/exhaustive_items.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/expect_fun_call.fixed b/src/tools/clippy/tests/ui/expect_fun_call.fixed index 15172ae345c..8e97054fb6b 100644 --- a/src/tools/clippy/tests/ui/expect_fun_call.fixed +++ b/src/tools/clippy/tests/ui/expect_fun_call.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::expect_fun_call)] #![allow(clippy::to_string_in_format_args, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/expect_fun_call.rs b/src/tools/clippy/tests/ui/expect_fun_call.rs index 0f448d00417..31e6bcc7ff6 100644 --- a/src/tools/clippy/tests/ui/expect_fun_call.rs +++ b/src/tools/clippy/tests/ui/expect_fun_call.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::expect_fun_call)] #![allow(clippy::to_string_in_format_args, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed index 5d40c850424..71a5ed96d5c 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs index 79e03f4d76c..9d0cafa150f 100644 --- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs +++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(closure_lifetime_binder)] #![warn(clippy::explicit_auto_deref)] diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed index 6d32bbece1e..77e9f5fc1fd 100644 --- a/src/tools/clippy/tests/ui/explicit_deref_methods.fixed +++ b/src/tools/clippy/tests/ui/explicit_deref_methods.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_deref_methods)] #![allow(unused_variables)] #![allow( diff --git a/src/tools/clippy/tests/ui/explicit_deref_methods.rs b/src/tools/clippy/tests/ui/explicit_deref_methods.rs index 779909e4238..0c2cc7c2c3a 100644 --- a/src/tools/clippy/tests/ui/explicit_deref_methods.rs +++ b/src/tools/clippy/tests/ui/explicit_deref_methods.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_deref_methods)] #![allow(unused_variables)] #![allow( diff --git a/src/tools/clippy/tests/ui/explicit_write.fixed b/src/tools/clippy/tests/ui/explicit_write.fixed index 862c3fea9ee..213485bc221 100644 --- a/src/tools/clippy/tests/ui/explicit_write.fixed +++ b/src/tools/clippy/tests/ui/explicit_write.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_write)] #![allow(unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/explicit_write.rs b/src/tools/clippy/tests/ui/explicit_write.rs index 41d7c225573..64acd7108bf 100644 --- a/src/tools/clippy/tests/ui/explicit_write.rs +++ b/src/tools/clippy/tests/ui/explicit_write.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::explicit_write)] #![allow(unused_imports)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/extend_with_drain.fixed b/src/tools/clippy/tests/ui/extend_with_drain.fixed index 71ebad24c16..594f2f6d413 100644 --- a/src/tools/clippy/tests/ui/extend_with_drain.fixed +++ b/src/tools/clippy/tests/ui/extend_with_drain.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::extend_with_drain)] #![allow(clippy::iter_with_drain)] use std::collections::BinaryHeap; diff --git a/src/tools/clippy/tests/ui/extend_with_drain.rs b/src/tools/clippy/tests/ui/extend_with_drain.rs index e9f011abb0e..3e2ad02052d 100644 --- a/src/tools/clippy/tests/ui/extend_with_drain.rs +++ b/src/tools/clippy/tests/ui/extend_with_drain.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::extend_with_drain)] #![allow(clippy::iter_with_drain)] use std::collections::BinaryHeap; diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs index d6631e01290..cdfaf8d3afe 100644 --- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs +++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_derive.rs +//@aux-build:proc_macro_derive.rs #![allow( unused, diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed index 19e71862558..adcd1f6d407 100644 --- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_lifetimes)] #![warn(clippy::extra_unused_type_parameters)] diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs index e53bb587e89..c4c5227ac91 100644 --- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs +++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::needless_lifetimes)] #![warn(clippy::extra_unused_type_parameters)] diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs index 0e208b3ed0e..2045b1eebcd 100644 --- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs +++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs @@ -1,5 +1,5 @@ -// aux-build:proc_macro_derive.rs -// aux-build:proc_macros.rs +//@aux-build:proc_macro_derive.rs +//@aux-build:proc_macros.rs #![warn(clippy::field_reassign_with_default)] diff --git a/src/tools/clippy/tests/ui/filter_map_identity.fixed b/src/tools/clippy/tests/ui/filter_map_identity.fixed index a5860aa49b3..44665b451ad 100644 --- a/src/tools/clippy/tests/ui/filter_map_identity.fixed +++ b/src/tools/clippy/tests/ui/filter_map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::filter_map_identity)] diff --git a/src/tools/clippy/tests/ui/filter_map_identity.rs b/src/tools/clippy/tests/ui/filter_map_identity.rs index 7e998b9cdf7..9832acb013f 100644 --- a/src/tools/clippy/tests/ui/filter_map_identity.rs +++ b/src/tools/clippy/tests/ui/filter_map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::filter_map_identity)] diff --git a/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed b/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed index 462d46169fc..efb37f8b1b7 100644 --- a/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed +++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/filter_map_next_fixable.rs b/src/tools/clippy/tests/ui/filter_map_next_fixable.rs index 2ea00cf7307..b10e20d359e 100644 --- a/src/tools/clippy/tests/ui/filter_map_next_fixable.rs +++ b/src/tools/clippy/tests/ui/filter_map_next_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/flat_map_identity.fixed b/src/tools/clippy/tests/ui/flat_map_identity.fixed index 1f4b880ef5b..97091d6f1a5 100644 --- a/src/tools/clippy/tests/ui/flat_map_identity.fixed +++ b/src/tools/clippy/tests/ui/flat_map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::flat_map_identity)] diff --git a/src/tools/clippy/tests/ui/flat_map_identity.rs b/src/tools/clippy/tests/ui/flat_map_identity.rs index de14a06d4e6..5607683a5d0 100644 --- a/src/tools/clippy/tests/ui/flat_map_identity.rs +++ b/src/tools/clippy/tests/ui/flat_map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports, clippy::needless_return)] #![warn(clippy::flat_map_identity)] diff --git a/src/tools/clippy/tests/ui/flat_map_option.fixed b/src/tools/clippy/tests/ui/flat_map_option.fixed index 6a34f008995..eeab864c42f 100644 --- a/src/tools/clippy/tests/ui/flat_map_option.fixed +++ b/src/tools/clippy/tests/ui/flat_map_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::flat_map_option)] #![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] diff --git a/src/tools/clippy/tests/ui/flat_map_option.rs b/src/tools/clippy/tests/ui/flat_map_option.rs index 2479abddbf0..ebc389f7f02 100644 --- a/src/tools/clippy/tests/ui/flat_map_option.rs +++ b/src/tools/clippy/tests/ui/flat_map_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::flat_map_option)] #![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)] diff --git a/src/tools/clippy/tests/ui/floating_point_abs.fixed b/src/tools/clippy/tests/ui/floating_point_abs.fixed index ca747fefc64..0cc572822e7 100644 --- a/src/tools/clippy/tests/ui/floating_point_abs.fixed +++ b/src/tools/clippy/tests/ui/floating_point_abs.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_abs.rs b/src/tools/clippy/tests/ui/floating_point_abs.rs index e4b60657497..6c732d398f0 100644 --- a/src/tools/clippy/tests/ui/floating_point_abs.rs +++ b/src/tools/clippy/tests/ui/floating_point_abs.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_exp.fixed b/src/tools/clippy/tests/ui/floating_point_exp.fixed index b9e3d89c2b2..1a33b8153ec 100644 --- a/src/tools/clippy/tests/ui/floating_point_exp.fixed +++ b/src/tools/clippy/tests/ui/floating_point_exp.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_exp.rs b/src/tools/clippy/tests/ui/floating_point_exp.rs index ef008dd9be0..4f4a5ec81ac 100644 --- a/src/tools/clippy/tests/ui/floating_point_exp.rs +++ b/src/tools/clippy/tests/ui/floating_point_exp.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_hypot.fixed b/src/tools/clippy/tests/ui/floating_point_hypot.fixed index bbe411b3f48..431cb270978 100644 --- a/src/tools/clippy/tests/ui/floating_point_hypot.fixed +++ b/src/tools/clippy/tests/ui/floating_point_hypot.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] fn main() { diff --git a/src/tools/clippy/tests/ui/floating_point_hypot.rs b/src/tools/clippy/tests/ui/floating_point_hypot.rs index 586fd170ea1..e5506ed391c 100644 --- a/src/tools/clippy/tests/ui/floating_point_hypot.rs +++ b/src/tools/clippy/tests/ui/floating_point_hypot.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::imprecise_flops)] fn main() { diff --git a/src/tools/clippy/tests/ui/floating_point_log.fixed b/src/tools/clippy/tests/ui/floating_point_log.fixed index ee540646160..6582c0a0f6c 100644 --- a/src/tools/clippy/tests/ui/floating_point_log.fixed +++ b/src/tools/clippy/tests/ui/floating_point_log.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_log.rs b/src/tools/clippy/tests/ui/floating_point_log.rs index 0590670a50b..854d269fff5 100644 --- a/src/tools/clippy/tests/ui/floating_point_log.rs +++ b/src/tools/clippy/tests/ui/floating_point_log.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)] #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.fixed b/src/tools/clippy/tests/ui/floating_point_logbase.fixed index 7347bf72cbe..0783ecee1ee 100644 --- a/src/tools/clippy/tests/ui/floating_point_logbase.fixed +++ b/src/tools/clippy/tests/ui/floating_point_logbase.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_logbase.rs b/src/tools/clippy/tests/ui/floating_point_logbase.rs index ba5b8d40692..80fcfab6825 100644 --- a/src/tools/clippy/tests/ui/floating_point_logbase.rs +++ b/src/tools/clippy/tests/ui/floating_point_logbase.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed index d3e536ba350..8848981a11d 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs index 5d4a9e35cfc..b0edf5cb210 100644 --- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs +++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_powf.fixed b/src/tools/clippy/tests/ui/floating_point_powf.fixed index f7f93de2957..1e660b140c5 100644 --- a/src/tools/clippy/tests/ui/floating_point_powf.fixed +++ b/src/tools/clippy/tests/ui/floating_point_powf.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_powf.rs b/src/tools/clippy/tests/ui/floating_point_powf.rs index 499fc0e15e4..71c2f529205 100644 --- a/src/tools/clippy/tests/ui/floating_point_powf.rs +++ b/src/tools/clippy/tests/ui/floating_point_powf.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops, clippy::imprecise_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_powi.fixed b/src/tools/clippy/tests/ui/floating_point_powi.fixed index 8ffd4cc5137..41d5288d6e0 100644 --- a/src/tools/clippy/tests/ui/floating_point_powi.fixed +++ b/src/tools/clippy/tests/ui/floating_point_powi.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_powi.rs b/src/tools/clippy/tests/ui/floating_point_powi.rs index 9ae3455a134..7951aab31be 100644 --- a/src/tools/clippy/tests/ui/floating_point_powi.rs +++ b/src/tools/clippy/tests/ui/floating_point_powi.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suboptimal_flops)] #![allow(clippy::unnecessary_cast)] diff --git a/src/tools/clippy/tests/ui/floating_point_rad.fixed b/src/tools/clippy/tests/ui/floating_point_rad.fixed index 27674b8a455..af236452712 100644 --- a/src/tools/clippy/tests/ui/floating_point_rad.fixed +++ b/src/tools/clippy/tests/ui/floating_point_rad.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/floating_point_rad.rs b/src/tools/clippy/tests/ui/floating_point_rad.rs index f1ea73df398..d7612c56a3e 100644 --- a/src/tools/clippy/tests/ui/floating_point_rad.rs +++ b/src/tools/clippy/tests/ui/floating_point_rad.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(const_fn_floating_point_arithmetic)] #![warn(clippy::suboptimal_flops)] diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs index a456c085c87..4f6af870889 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs b/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs index 04ee985c086..62ce97f098d 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)] diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr index 08dd611d675..671347d2bcd 100644 --- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr +++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_32bit.stderr @@ -12,19 +12,19 @@ error: casting function pointer `foo` to `i16`, which truncates the value LL | let _ = foo as i16; | ^^^^^^^^^^ help: try: `foo as usize` -error: casting function pointer `foo` to `i32` +error: casting function pointer `foo` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:12:13 | LL | let _ = foo as i32; | ^^^^^^^^^^ help: try: `foo as usize` - | - = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings` error: casting function pointer `foo` to `i64` --> $DIR/fn_to_numeric_cast_32bit.rs:13:13 | LL | let _ = foo as i64; | ^^^^^^^^^^ help: try: `foo as usize` + | + = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings` error: casting function pointer `foo` to `i128` --> $DIR/fn_to_numeric_cast_32bit.rs:14:13 @@ -50,7 +50,7 @@ error: casting function pointer `foo` to `u16`, which truncates the value LL | let _ = foo as u16; | ^^^^^^^^^^ help: try: `foo as usize` -error: casting function pointer `foo` to `u32` +error: casting function pointer `foo` to `u32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:19:13 | LL | let _ = foo as u32; @@ -80,7 +80,7 @@ error: casting function pointer `abc` to `i16`, which truncates the value LL | let _ = abc as i16; | ^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `abc` to `i32` +error: casting function pointer `abc` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:36:13 | LL | let _ = abc as i32; @@ -116,7 +116,7 @@ error: casting function pointer `abc` to `u16`, which truncates the value LL | let _ = abc as u16; | ^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `abc` to `u32` +error: casting function pointer `abc` to `u32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:43:13 | LL | let _ = abc as u32; @@ -134,7 +134,7 @@ error: casting function pointer `abc` to `u128` LL | let _ = abc as u128; | ^^^^^^^^^^^ help: try: `abc as usize` -error: casting function pointer `f` to `i32` +error: casting function pointer `f` to `i32`, which truncates the value --> $DIR/fn_to_numeric_cast_32bit.rs:52:5 | LL | f as i32 diff --git a/src/tools/clippy/tests/ui/for_loop_fixable.fixed b/src/tools/clippy/tests/ui/for_loop_fixable.fixed index e9dd38fe40e..f578c98da15 100644 --- a/src/tools/clippy/tests/ui/for_loop_fixable.fixed +++ b/src/tools/clippy/tests/ui/for_loop_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/for_loop_fixable.rs b/src/tools/clippy/tests/ui/for_loop_fixable.rs index 534fb4dd4ef..42bc6de0c7d 100644 --- a/src/tools/clippy/tests/ui/for_loop_fixable.rs +++ b/src/tools/clippy/tests/ui/for_loop_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/format.fixed b/src/tools/clippy/tests/ui/format.fixed index beedf2c1db2..9288956f513 100644 --- a/src/tools/clippy/tests/ui/format.fixed +++ b/src/tools/clippy/tests/ui/format.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, diff --git a/src/tools/clippy/tests/ui/format.rs b/src/tools/clippy/tests/ui/format.rs index e805f181889..b2b817e0f4c 100644 --- a/src/tools/clippy/tests/ui/format.rs +++ b/src/tools/clippy/tests/ui/format.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed index 825e122be5a..ea383686135 100644 --- a/src/tools/clippy/tests/ui/format_args.fixed +++ b/src/tools/clippy/tests/ui/format_args.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::to_string_in_format_args)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs index a41e53389e5..bfb32449246 100644 --- a/src/tools/clippy/tests/ui/format_args.rs +++ b/src/tools/clippy/tests/ui/format_args.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::to_string_in_format_args)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed index 48f8093311c..915ff4fb079 100644 --- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed +++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::from_iter_instead_of_collect)] #![allow(unused_imports, unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs index ebe0ad278be..e926f8c529d 100644 --- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs +++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::from_iter_instead_of_collect)] #![allow(unused_imports, unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed index 72d635c2ccd..fc6d937060d 100644 --- a/src/tools/clippy/tests/ui/from_over_into.fixed +++ b/src/tools/clippy/tests/ui/from_over_into.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs index 965f4d5d785..fe1ebee35f1 100644 --- a/src/tools/clippy/tests/ui/from_over_into.rs +++ b/src/tools/clippy/tests/ui/from_over_into.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(type_alias_impl_trait)] #![warn(clippy::from_over_into)] diff --git a/src/tools/clippy/tests/ui/get_first.fixed b/src/tools/clippy/tests/ui/get_first.fixed index def58afa4fb..ef132b79611 100644 --- a/src/tools/clippy/tests/ui/get_first.fixed +++ b/src/tools/clippy/tests/ui/get_first.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_first)] use std::collections::BTreeMap; use std::collections::HashMap; diff --git a/src/tools/clippy/tests/ui/get_first.rs b/src/tools/clippy/tests/ui/get_first.rs index 85a381854cd..4d872235614 100644 --- a/src/tools/clippy/tests/ui/get_first.rs +++ b/src/tools/clippy/tests/ui/get_first.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_first)] use std::collections::BTreeMap; use std::collections::HashMap; diff --git a/src/tools/clippy/tests/ui/get_last_with_len.fixed b/src/tools/clippy/tests/ui/get_last_with_len.fixed index 1e90b37687a..a58dfda7988 100644 --- a/src/tools/clippy/tests/ui/get_last_with_len.fixed +++ b/src/tools/clippy/tests/ui/get_last_with_len.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_last_with_len)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/get_last_with_len.rs b/src/tools/clippy/tests/ui/get_last_with_len.rs index d63a731bd52..d626656c78f 100644 --- a/src/tools/clippy/tests/ui/get_last_with_len.rs +++ b/src/tools/clippy/tests/ui/get_last_with_len.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::get_last_with_len)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/get_unwrap.fixed b/src/tools/clippy/tests/ui/get_unwrap.fixed index 5827fc7d76e..4950c47ddeb 100644 --- a/src/tools/clippy/tests/ui/get_unwrap.fixed +++ b/src/tools/clippy/tests/ui/get_unwrap.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_mut, clippy::from_iter_instead_of_collect, clippy::get_first)] #![warn(clippy::unwrap_used)] diff --git a/src/tools/clippy/tests/ui/get_unwrap.rs b/src/tools/clippy/tests/ui/get_unwrap.rs index a2a323c14fb..6b1e8edb7bd 100644 --- a/src/tools/clippy/tests/ui/get_unwrap.rs +++ b/src/tools/clippy/tests/ui/get_unwrap.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_mut, clippy::from_iter_instead_of_collect, clippy::get_first)] #![warn(clippy::unwrap_used)] diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed index cac69ef42c4..beb16000eca 100644 --- a/src/tools/clippy/tests/ui/identity_op.fixed +++ b/src/tools/clippy/tests/ui/identity_op.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::identity_op)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs index 33201aad4f6..072e00c00f0 100644 --- a/src/tools/clippy/tests/ui/identity_op.rs +++ b/src/tools/clippy/tests/ui/identity_op.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::identity_op)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/implicit_clone.fixed b/src/tools/clippy/tests/ui/implicit_clone.fixed index 8ccc3da7b47..e62db8b40be 100644 --- a/src/tools/clippy/tests/ui/implicit_clone.fixed +++ b/src/tools/clippy/tests/ui/implicit_clone.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::implicit_clone)] #![allow(clippy::clone_on_copy, clippy::redundant_clone)] use std::borrow::Borrow; diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs index 59333312607..88352b06af3 100644 --- a/src/tools/clippy/tests/ui/implicit_clone.rs +++ b/src/tools/clippy/tests/ui/implicit_clone.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::implicit_clone)] #![allow(clippy::clone_on_copy, clippy::redundant_clone)] use std::borrow::Borrow; diff --git a/src/tools/clippy/tests/ui/implicit_hasher.rs b/src/tools/clippy/tests/ui/implicit_hasher.rs index 35d08a07bc3..ca7c1221372 100644 --- a/src/tools/clippy/tests/ui/implicit_hasher.rs +++ b/src/tools/clippy/tests/ui/implicit_hasher.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![deny(clippy::implicit_hasher)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/implicit_return.fixed b/src/tools/clippy/tests/ui/implicit_return.fixed index 5e55b8b6739..64813eafda6 100644 --- a/src/tools/clippy/tests/ui/implicit_return.fixed +++ b/src/tools/clippy/tests/ui/implicit_return.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/src/tools/clippy/tests/ui/implicit_return.rs b/src/tools/clippy/tests/ui/implicit_return.rs index 76f0a980352..39d47b110db 100644 --- a/src/tools/clippy/tests/ui/implicit_return.rs +++ b/src/tools/clippy/tests/ui/implicit_return.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::implicit_return)] #![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)] diff --git a/src/tools/clippy/tests/ui/implicit_saturating_add.fixed b/src/tools/clippy/tests/ui/implicit_saturating_add.fixed index 7d363d59a6f..7fc510d6b41 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_add.fixed +++ b/src/tools/clippy/tests/ui/implicit_saturating_add.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::implicit_saturating_add)] diff --git a/src/tools/clippy/tests/ui/implicit_saturating_add.rs b/src/tools/clippy/tests/ui/implicit_saturating_add.rs index 31a5916277f..3dcd91f42fe 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_add.rs +++ b/src/tools/clippy/tests/ui/implicit_saturating_add.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::implicit_saturating_add)] diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed index 93df81b1a7f..1a11db0982f 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed +++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)] #![warn(clippy::implicit_saturating_sub)] diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs index 8340bc8264d..9369df67430 100644 --- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs +++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)] #![warn(clippy::implicit_saturating_sub)] diff --git a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed index dd683e7f746..06919809ee9 100644 --- a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed +++ b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::inconsistent_digit_grouping)] #[deny(clippy::unreadable_literal)] #[allow(unused_variables, clippy::excessive_precision)] diff --git a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs index d5d27c853c2..04d9125f2bf 100644 --- a/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs +++ b/src/tools/clippy/tests/ui/inconsistent_digit_grouping.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[warn(clippy::inconsistent_digit_grouping)] #[deny(clippy::unreadable_literal)] #[allow(unused_variables, clippy::excessive_precision)] diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed index 5aaa00f8517..620d45e6828 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs index 2b2dd7f59a4..10ffadcb2ba 100644 --- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.fixed b/src/tools/clippy/tests/ui/inefficient_to_string.fixed index c972b9419ef..557f7fb7358 100644 --- a/src/tools/clippy/tests/ui/inefficient_to_string.fixed +++ b/src/tools/clippy/tests/ui/inefficient_to_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::inefficient_to_string)] use std::borrow::Cow; diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.rs b/src/tools/clippy/tests/ui/inefficient_to_string.rs index acdc55aa0d6..6503001e345 100644 --- a/src/tools/clippy/tests/ui/inefficient_to_string.rs +++ b/src/tools/clippy/tests/ui/inefficient_to_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::inefficient_to_string)] use std::borrow::Cow; diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed index 61985e56b76..e396ae94aaa 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs index f2768245bbc..3fce7bbb6c7 100644 --- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs +++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(exhaustive_patterns, never_type)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow(clippy::let_and_return)] diff --git a/src/tools/clippy/tests/ui/inline_fn_without_body.fixed b/src/tools/clippy/tests/ui/inline_fn_without_body.fixed index fe21a71a42c..9c5819558fe 100644 --- a/src/tools/clippy/tests/ui/inline_fn_without_body.fixed +++ b/src/tools/clippy/tests/ui/inline_fn_without_body.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::inline_fn_without_body)] #![allow(clippy::inline_always)] diff --git a/src/tools/clippy/tests/ui/inline_fn_without_body.rs b/src/tools/clippy/tests/ui/inline_fn_without_body.rs index 50746989466..43ffaf8122b 100644 --- a/src/tools/clippy/tests/ui/inline_fn_without_body.rs +++ b/src/tools/clippy/tests/ui/inline_fn_without_body.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::inline_fn_without_body)] #![allow(clippy::inline_always)] diff --git a/src/tools/clippy/tests/ui/int_plus_one.fixed b/src/tools/clippy/tests/ui/int_plus_one.fixed index 642830f24f5..5a36ec462d4 100644 --- a/src/tools/clippy/tests/ui/int_plus_one.fixed +++ b/src/tools/clippy/tests/ui/int_plus_one.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::no_effect, clippy::unnecessary_operation)] #[warn(clippy::int_plus_one)] diff --git a/src/tools/clippy/tests/ui/int_plus_one.rs b/src/tools/clippy/tests/ui/int_plus_one.rs index 0755a0c79d2..bffa4afd6b0 100644 --- a/src/tools/clippy/tests/ui/int_plus_one.rs +++ b/src/tools/clippy/tests/ui/int_plus_one.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::no_effect, clippy::unnecessary_operation)] #[warn(clippy::int_plus_one)] diff --git a/src/tools/clippy/tests/ui/integer_arithmetic.rs b/src/tools/clippy/tests/ui/integer_arithmetic.rs index 8dfdee662b9..ab9b6094c2c 100644 --- a/src/tools/clippy/tests/ui/integer_arithmetic.rs +++ b/src/tools/clippy/tests/ui/integer_arithmetic.rs @@ -1,6 +1,13 @@ +//@aux-build:proc_macro_derive.rs + #![warn(clippy::integer_arithmetic, clippy::float_arithmetic)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::op_ref)] +extern crate proc_macro_derive; + +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + #[rustfmt::skip] fn main() { let mut i = 1i32; diff --git a/src/tools/clippy/tests/ui/integer_arithmetic.stderr b/src/tools/clippy/tests/ui/integer_arithmetic.stderr index 9a795b1f291..add3b6b90fa 100644 --- a/src/tools/clippy/tests/ui/integer_arithmetic.stderr +++ b/src/tools/clippy/tests/ui/integer_arithmetic.stderr @@ -1,5 +1,5 @@ error: this operation will panic at runtime - --> $DIR/integer_arithmetic.rs:30:5 + --> $DIR/integer_arithmetic.rs:37:5 | LL | i /= 0; | ^^^^^^ attempt to divide `_` by zero @@ -7,13 +7,13 @@ LL | i /= 0; = note: `#[deny(unconditional_panic)]` on by default error: this operation will panic at runtime - --> $DIR/integer_arithmetic.rs:35:5 + --> $DIR/integer_arithmetic.rs:42:5 | LL | i %= 0; | ^^^^^^ attempt to calculate the remainder of `_` with a divisor of zero error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:9:5 + --> $DIR/integer_arithmetic.rs:16:5 | LL | 1 + i; | ^^^^^ @@ -21,146 +21,146 @@ LL | 1 + i; = note: `-D clippy::integer-arithmetic` implied by `-D warnings` error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:10:5 + --> $DIR/integer_arithmetic.rs:17:5 | LL | i * 2; | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:11:5 + --> $DIR/integer_arithmetic.rs:18:5 | LL | / 1 % LL | | i / 2; // no error, this is part of the expression in the preceding line | |_____^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:13:5 + --> $DIR/integer_arithmetic.rs:20:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:14:5 + --> $DIR/integer_arithmetic.rs:21:5 | LL | -i; | ^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:15:5 + --> $DIR/integer_arithmetic.rs:22:5 | LL | i >> 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:16:5 + --> $DIR/integer_arithmetic.rs:23:5 | LL | i << 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:26:5 + --> $DIR/integer_arithmetic.rs:33:5 | LL | i += 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:27:5 + --> $DIR/integer_arithmetic.rs:34:5 | LL | i -= 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:28:5 + --> $DIR/integer_arithmetic.rs:35:5 | LL | i *= 2; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:31:11 + --> $DIR/integer_arithmetic.rs:38:11 | LL | i /= -1; | ^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:32:5 + --> $DIR/integer_arithmetic.rs:39:5 | LL | i /= var1; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:33:5 + --> $DIR/integer_arithmetic.rs:40:5 | LL | i /= var2; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:36:11 + --> $DIR/integer_arithmetic.rs:43:11 | LL | i %= -1; | ^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:37:5 + --> $DIR/integer_arithmetic.rs:44:5 | LL | i %= var1; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:38:5 + --> $DIR/integer_arithmetic.rs:45:5 | LL | i %= var2; | ^^^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:39:5 + --> $DIR/integer_arithmetic.rs:46:5 | LL | i <<= 3; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:40:5 + --> $DIR/integer_arithmetic.rs:47:5 | LL | i >>= 2; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:82:5 + --> $DIR/integer_arithmetic.rs:89:5 | LL | 3 + &1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:83:5 + --> $DIR/integer_arithmetic.rs:90:5 | LL | &3 + 1; | ^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:84:5 + --> $DIR/integer_arithmetic.rs:91:5 | LL | &3 + &1; | ^^^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:89:5 + --> $DIR/integer_arithmetic.rs:96:5 | LL | a + x | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:93:5 + --> $DIR/integer_arithmetic.rs:100:5 | LL | x + y | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:97:5 + --> $DIR/integer_arithmetic.rs:104:5 | LL | x + y | ^^^^^ error: integer arithmetic detected - --> $DIR/integer_arithmetic.rs:101:5 + --> $DIR/integer_arithmetic.rs:108:5 | LL | (&x + &y) | ^^^^^^^^^ diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.fixed b/src/tools/clippy/tests/ui/into_iter_on_ref.fixed index b77f17944d8..9f550acb157 100644 --- a/src/tools/clippy/tests/ui/into_iter_on_ref.fixed +++ b/src/tools/clippy/tests/ui/into_iter_on_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::useless_vec, clippy::needless_borrow)] #![warn(clippy::into_iter_on_ref)] diff --git a/src/tools/clippy/tests/ui/into_iter_on_ref.rs b/src/tools/clippy/tests/ui/into_iter_on_ref.rs index 3854bb05af8..3381ae04dce 100644 --- a/src/tools/clippy/tests/ui/into_iter_on_ref.rs +++ b/src/tools/clippy/tests/ui/into_iter_on_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::useless_vec, clippy::needless_borrow)] #![warn(clippy::into_iter_on_ref)] diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed index 4f5322ebf20..9264fb7e9e7 100644 --- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed +++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { unsafe { diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs index ae51c52d8af..80c942d7757 100644 --- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs +++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { unsafe { diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed index c0ba647d707..bc43303a680 100644 --- a/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed +++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::is_digit_ascii_radix)] diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs index 68e3f3243d9..93cba5c8e4e 100644 --- a/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs +++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::is_digit_ascii_radix)] diff --git a/src/tools/clippy/tests/ui/issue_2356.fixed b/src/tools/clippy/tests/ui/issue_2356.fixed index a73ee0fb2e5..a69f5ebdc08 100644 --- a/src/tools/clippy/tests/ui/issue_2356.fixed +++ b/src/tools/clippy/tests/ui/issue_2356.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/issue_2356.rs b/src/tools/clippy/tests/ui/issue_2356.rs index 9dd9069609b..50e1bce1f8c 100644 --- a/src/tools/clippy/tests/ui/issue_2356.rs +++ b/src/tools/clippy/tests/ui/issue_2356.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::while_let_on_iterator)] #![allow(unused_mut)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/items_after_test_module.rs b/src/tools/clippy/tests/ui/items_after_test_module.rs new file mode 100644 index 00000000000..5136b2557ec --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module.rs @@ -0,0 +1,23 @@ +//@compile-flags: --test +#![allow(unused)] +#![warn(clippy::items_after_test_module)] + +fn main() {} + +fn should_not_lint() {} + +#[allow(dead_code)] +#[allow(unused)] // Some attributes to check that span replacement is good enough +#[allow(clippy::allow_attributes)] +#[cfg(test)] +mod tests { + #[test] + fn hi() {} +} + +fn should_lint() {} + +const SHOULD_ALSO_LINT: usize = 1; +macro_rules! should_not_lint { + () => {}; +} diff --git a/src/tools/clippy/tests/ui/items_after_test_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module.stderr new file mode 100644 index 00000000000..8f1616dabc1 --- /dev/null +++ b/src/tools/clippy/tests/ui/items_after_test_module.stderr @@ -0,0 +1,17 @@ +error: items were found after the testing module + --> $DIR/items_after_test_module.rs:13:1 + | +LL | / mod tests { +LL | | #[test] +LL | | fn hi() {} +LL | | } +... | +LL | | () => {}; +LL | | } + | |_^ + | + = help: move the items to before the testing module was defined + = note: `-D clippy::items-after-test-module` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/src/tools/clippy/tests/ui/iter_cloned_collect.fixed b/src/tools/clippy/tests/ui/iter_cloned_collect.fixed index 9b862133580..88f08bb991b 100644 --- a/src/tools/clippy/tests/ui/iter_cloned_collect.fixed +++ b/src/tools/clippy/tests/ui/iter_cloned_collect.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/iter_cloned_collect.rs b/src/tools/clippy/tests/ui/iter_cloned_collect.rs index 639f50665f2..d3438b7f51a 100644 --- a/src/tools/clippy/tests/ui/iter_cloned_collect.rs +++ b/src/tools/clippy/tests/ui/iter_cloned_collect.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/iter_count.fixed b/src/tools/clippy/tests/ui/iter_count.fixed index 90a6eef7526..4367a12f820 100644 --- a/src/tools/clippy/tests/ui/iter_count.fixed +++ b/src/tools/clippy/tests/ui/iter_count.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_count)] #![allow( diff --git a/src/tools/clippy/tests/ui/iter_count.rs b/src/tools/clippy/tests/ui/iter_count.rs index 6681a480a28..8c7543cf03b 100644 --- a/src/tools/clippy/tests/ui/iter_count.rs +++ b/src/tools/clippy/tests/ui/iter_count.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_count)] #![allow( diff --git a/src/tools/clippy/tests/ui/iter_kv_map.fixed b/src/tools/clippy/tests/ui/iter_kv_map.fixed index f2a4c284cb1..64201b553fd 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.fixed +++ b/src/tools/clippy/tests/ui/iter_kv_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_kv_map)] #![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)] diff --git a/src/tools/clippy/tests/ui/iter_kv_map.rs b/src/tools/clippy/tests/ui/iter_kv_map.rs index ad6564df408..ec0231ba572 100644 --- a/src/tools/clippy/tests/ui/iter_kv_map.rs +++ b/src/tools/clippy/tests/ui/iter_kv_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_kv_map)] #![allow(unused_mut, clippy::redundant_clone, clippy::suspicious_map, clippy::map_identity)] diff --git a/src/tools/clippy/tests/ui/iter_next_slice.fixed b/src/tools/clippy/tests/ui/iter_next_slice.fixed index f612d26aaab..d862abc34e0 100644 --- a/src/tools/clippy/tests/ui/iter_next_slice.fixed +++ b/src/tools/clippy/tests/ui/iter_next_slice.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_next_slice)] fn main() { diff --git a/src/tools/clippy/tests/ui/iter_next_slice.rs b/src/tools/clippy/tests/ui/iter_next_slice.rs index 5195f1c8667..da6fc46e428 100644 --- a/src/tools/clippy/tests/ui/iter_next_slice.rs +++ b/src/tools/clippy/tests/ui/iter_next_slice.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_next_slice)] fn main() { diff --git a/src/tools/clippy/tests/ui/iter_nth.rs b/src/tools/clippy/tests/ui/iter_nth.rs index 9c21dd82ee4..e7fb97d4fbc 100644 --- a/src/tools/clippy/tests/ui/iter_nth.rs +++ b/src/tools/clippy/tests/ui/iter_nth.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::iter_nth)] diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.fixed b/src/tools/clippy/tests/ui/iter_nth_zero.fixed index f23671c26e4..587b0d1d366 100644 --- a/src/tools/clippy/tests/ui/iter_nth_zero.fixed +++ b/src/tools/clippy/tests/ui/iter_nth_zero.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_nth_zero)] use std::collections::HashSet; diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.rs b/src/tools/clippy/tests/ui/iter_nth_zero.rs index 7c968d49845..93b576ec56f 100644 --- a/src/tools/clippy/tests/ui/iter_nth_zero.rs +++ b/src/tools/clippy/tests/ui/iter_nth_zero.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_nth_zero)] use std::collections::HashSet; diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed index bd9b07aefbf..4616f0cdc45 100644 --- a/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_empty_collections)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs index e15ba94bd46..81cc7265e11 100644 --- a/src/tools/clippy/tests/ui/iter_on_empty_collections.rs +++ b/src/tools/clippy/tests/ui/iter_on_empty_collections.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_empty_collections)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.fixed b/src/tools/clippy/tests/ui/iter_on_single_items.fixed index 1fa4b03641b..80dbe454b47 100644 --- a/src/tools/clippy/tests/ui/iter_on_single_items.fixed +++ b/src/tools/clippy/tests/ui/iter_on_single_items.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_single_items)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.rs b/src/tools/clippy/tests/ui/iter_on_single_items.rs index ea96d8066c5..71c8c7a3f94 100644 --- a/src/tools/clippy/tests/ui/iter_on_single_items.rs +++ b/src/tools/clippy/tests/ui/iter_on_single_items.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_on_single_items)] #![allow(clippy::iter_next_slice, clippy::redundant_clone)] diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed index c100705d017..bf576e9cbfb 100644 --- a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed +++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)] #![allow(dead_code, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs index 2caa8802066..df42d88eff0 100644 --- a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs +++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)] #![allow(dead_code, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/iter_skip_next.fixed b/src/tools/clippy/tests/ui/iter_skip_next.fixed index d56d623b526..8f2cefc4304 100644 --- a/src/tools/clippy/tests/ui/iter_skip_next.fixed +++ b/src/tools/clippy/tests/ui/iter_skip_next.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/iter_skip_next.rs b/src/tools/clippy/tests/ui/iter_skip_next.rs index 3ec5d1b8214..71d83384f3a 100644 --- a/src/tools/clippy/tests/ui/iter_skip_next.rs +++ b/src/tools/clippy/tests/ui/iter_skip_next.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::iter_skip_next)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/iter_with_drain.fixed b/src/tools/clippy/tests/ui/iter_with_drain.fixed index 0330d554926..24a95c4d0fe 100644 --- a/src/tools/clippy/tests/ui/iter_with_drain.fixed +++ b/src/tools/clippy/tests/ui/iter_with_drain.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // will emits unused mut warnings after fixing #![allow(unused_mut)] // will emits needless collect warnings after fixing diff --git a/src/tools/clippy/tests/ui/iter_with_drain.rs b/src/tools/clippy/tests/ui/iter_with_drain.rs index 993936fb8de..a118c981ee3 100644 --- a/src/tools/clippy/tests/ui/iter_with_drain.rs +++ b/src/tools/clippy/tests/ui/iter_with_drain.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // will emits unused mut warnings after fixing #![allow(unused_mut)] // will emits needless collect warnings after fixing diff --git a/src/tools/clippy/tests/ui/large_const_arrays.fixed b/src/tools/clippy/tests/ui/large_const_arrays.fixed index c5af07c8a17..f7ce6fbe6bb 100644 --- a/src/tools/clippy/tests/ui/large_const_arrays.fixed +++ b/src/tools/clippy/tests/ui/large_const_arrays.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_const_arrays)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/large_const_arrays.rs b/src/tools/clippy/tests/ui/large_const_arrays.rs index a160b9f8ad5..002ac77ddda 100644 --- a/src/tools/clippy/tests/ui/large_const_arrays.rs +++ b/src/tools/clippy/tests/ui/large_const_arrays.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_const_arrays)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/large_digit_groups.fixed b/src/tools/clippy/tests/ui/large_digit_groups.fixed index ea18dac0683..f42fcd96d79 100644 --- a/src/tools/clippy/tests/ui/large_digit_groups.fixed +++ b/src/tools/clippy/tests/ui/large_digit_groups.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_digit_groups)] fn main() { diff --git a/src/tools/clippy/tests/ui/large_digit_groups.rs b/src/tools/clippy/tests/ui/large_digit_groups.rs index ac116d5dbda..3db9da6a3a5 100644 --- a/src/tools/clippy/tests/ui/large_digit_groups.rs +++ b/src/tools/clippy/tests/ui/large_digit_groups.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::large_digit_groups)] fn main() { diff --git a/src/tools/clippy/tests/ui/large_enum_variant.rs b/src/tools/clippy/tests/ui/large_enum_variant.rs index f09f8ae0ccc..ea8bc5b4aca 100644 --- a/src/tools/clippy/tests/ui/large_enum_variant.rs +++ b/src/tools/clippy/tests/ui/large_enum_variant.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs index 7601b5c66fa..f9e3c7192ad 100644 --- a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs +++ b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs @@ -1,5 +1,5 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" #![warn(clippy::large_types_passed_by_value)] diff --git a/src/tools/clippy/tests/ui/len_zero.fixed b/src/tools/clippy/tests/ui/len_zero.fixed index c1c0b5ae40f..2c22abd7e4b 100644 --- a/src/tools/clippy/tests/ui/len_zero.fixed +++ b/src/tools/clippy/tests/ui/len_zero.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(dead_code, unused, clippy::len_without_is_empty)] @@ -176,6 +176,10 @@ fn main() { // No error; `HasWrongIsEmpty` does not have `.is_empty()`. println!("Or this!"); } + + // issue #10529 + (!has_is_empty.is_empty()).then(|| println!("This can happen.")); + (has_is_empty.is_empty()).then(|| println!("Or this!")); } fn test_slice(b: &[u8]) { diff --git a/src/tools/clippy/tests/ui/len_zero.rs b/src/tools/clippy/tests/ui/len_zero.rs index cc2eb05b6bf..a011ff97644 100644 --- a/src/tools/clippy/tests/ui/len_zero.rs +++ b/src/tools/clippy/tests/ui/len_zero.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(dead_code, unused, clippy::len_without_is_empty)] @@ -176,6 +176,10 @@ fn main() { // No error; `HasWrongIsEmpty` does not have `.is_empty()`. println!("Or this!"); } + + // issue #10529 + (has_is_empty.len() > 0).then(|| println!("This can happen.")); + (has_is_empty.len() == 0).then(|| println!("Or this!")); } fn test_slice(b: &[u8]) { diff --git a/src/tools/clippy/tests/ui/len_zero.stderr b/src/tools/clippy/tests/ui/len_zero.stderr index b6f13780253..396cfb75fb6 100644 --- a/src/tools/clippy/tests/ui/len_zero.stderr +++ b/src/tools/clippy/tests/ui/len_zero.stderr @@ -123,10 +123,22 @@ LL | if with_is_empty.len() == 0 { | ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()` error: length comparison to zero - --> $DIR/len_zero.rs:182:8 + --> $DIR/len_zero.rs:181:6 + | +LL | (has_is_empty.len() > 0).then(|| println!("This can happen.")); + | ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()` + +error: length comparison to zero + --> $DIR/len_zero.rs:182:6 + | +LL | (has_is_empty.len() == 0).then(|| println!("Or this!")); + | ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()` + +error: length comparison to zero + --> $DIR/len_zero.rs:186:8 | LL | if b.len() != 0 {} | ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()` -error: aborting due to 21 previous errors +error: aborting due to 23 previous errors diff --git a/src/tools/clippy/tests/ui/len_zero_ranges.fixed b/src/tools/clippy/tests/ui/len_zero_ranges.fixed index 79781766242..4b1241ec86b 100644 --- a/src/tools/clippy/tests/ui/len_zero_ranges.fixed +++ b/src/tools/clippy/tests/ui/len_zero_ranges.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/len_zero_ranges.rs b/src/tools/clippy/tests/ui/len_zero_ranges.rs index a0eb51cc976..4b47132c766 100644 --- a/src/tools/clippy/tests/ui/len_zero_ranges.rs +++ b/src/tools/clippy/tests/ui/len_zero_ranges.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::len_zero)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.rs b/src/tools/clippy/tests/ui/let_underscore_untyped.rs index bcb33c5c7e3..8486137d3a6 100644 --- a/src/tools/clippy/tests/ui/let_underscore_untyped.rs +++ b/src/tools/clippy/tests/ui/let_underscore_untyped.rs @@ -28,6 +28,10 @@ fn f() -> Box<dyn Display> { Box::new(1) } +fn g() -> impl Fn() { + || {} +} + fn main() { let _ = a(); let _ = b(1); @@ -35,6 +39,7 @@ fn main() { let _ = d(&1); let _ = e(); let _ = f(); + let _ = g(); _ = a(); _ = b(1); diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr index 36c3d1214d6..47e76ea1d04 100644 --- a/src/tools/clippy/tests/ui/let_underscore_untyped.stderr +++ b/src/tools/clippy/tests/ui/let_underscore_untyped.stderr @@ -1,5 +1,5 @@ error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:32:5 + --> $DIR/let_underscore_untyped.rs:36:5 | LL | let _ = a(); | ^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = a(); = note: `-D clippy::let-underscore-untyped` implied by `-D warnings` error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:33:5 + --> $DIR/let_underscore_untyped.rs:37:5 | LL | let _ = b(1); | ^^^^^^^^^^^^^ @@ -16,15 +16,7 @@ LL | let _ = b(1); = help: consider adding a type annotation or removing the `let` keyword error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:34:5 - | -LL | let _ = c(); - | ^^^^^^^^^^^^ - | - = help: consider adding a type annotation or removing the `let` keyword - -error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:35:5 + --> $DIR/let_underscore_untyped.rs:39:5 | LL | let _ = d(&1); | ^^^^^^^^^^^^^^ @@ -32,7 +24,7 @@ LL | let _ = d(&1); = help: consider adding a type annotation or removing the `let` keyword error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:36:5 + --> $DIR/let_underscore_untyped.rs:40:5 | LL | let _ = e(); | ^^^^^^^^^^^^ @@ -40,12 +32,12 @@ LL | let _ = e(); = help: consider adding a type annotation or removing the `let` keyword error: non-binding `let` without a type annotation - --> $DIR/let_underscore_untyped.rs:37:5 + --> $DIR/let_underscore_untyped.rs:41:5 | LL | let _ = f(); | ^^^^^^^^^^^^ | = help: consider adding a type annotation or removing the `let` keyword -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed index 76ff0645f41..8ba89ec78bb 100644 --- a/src/tools/clippy/tests/ui/let_unit.fixed +++ b/src/tools/clippy/tests/ui/let_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs index 895ccfe366a..7e8764a482a 100644 --- a/src/tools/clippy/tests/ui/let_unit.rs +++ b/src/tools/clippy/tests/ui/let_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![warn(clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed index f4033cd8ed8..64114f6585d 100644 --- a/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::map_identity)] #![warn(clippy::lines_filter_map_ok)] diff --git a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs index 7e11816b2ac..5aedc686336 100644 --- a/src/tools/clippy/tests/ui/lines_filter_map_ok.rs +++ b/src/tools/clippy/tests/ui/lines_filter_map_ok.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::map_identity)] #![warn(clippy::lines_filter_map_ok)] diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.fixed b/src/tools/clippy/tests/ui/lossy_float_literal.fixed index 24e372354fc..a2088575610 100644 --- a/src/tools/clippy/tests/ui/lossy_float_literal.fixed +++ b/src/tools/clippy/tests/ui/lossy_float_literal.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::lossy_float_literal)] fn main() { diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.rs b/src/tools/clippy/tests/ui/lossy_float_literal.rs index 3dcf98fa0bd..1a75f214c85 100644 --- a/src/tools/clippy/tests/ui/lossy_float_literal.rs +++ b/src/tools/clippy/tests/ui/lossy_float_literal.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::lossy_float_literal)] fn main() { diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed index a395e4f5653..b4dabe3cae5 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.fixed +++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed @@ -1,8 +1,8 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// run-rustfix -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +//@aux-build:proc_macro_derive.rs +//@run-rustfix +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] diff --git a/src/tools/clippy/tests/ui/macro_use_imports.rs b/src/tools/clippy/tests/ui/macro_use_imports.rs index b1a28733294..925a2c61f8d 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports.rs +++ b/src/tools/clippy/tests/ui/macro_use_imports.rs @@ -1,8 +1,8 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// run-rustfix -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +//@aux-build:proc_macro_derive.rs +//@run-rustfix +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] diff --git a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs index 5aac5af26db..b9677851b92 100644 --- a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs +++ b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs @@ -1,7 +1,7 @@ -// aux-build:macro_rules.rs -// aux-build:macro_use_helper.rs -// aux-build:proc_macro_derive.rs -// ignore-32bit +//@aux-build:macro_rules.rs +//@aux-build:macro_use_helper.rs +//@aux-build:proc_macro_derive.rs +//@ignore-32bit #![feature(lint_reasons)] #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)] diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed index 8c7e919bf62..ab9b375dc03 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed index 8c7e919bf62..ab9b375dc03 100644 --- a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed +++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs index f037c5b8405..eac52d1b5de 100644 --- a/src/tools/clippy/tests/ui/manual_assert.rs +++ b/src/tools/clippy/tests/ui/manual_assert.rs @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::manual_assert)] #![allow(dead_code, unused_doc_comments)] diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed index 5cc4a43af7e..e458f0d254f 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.fixed +++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_async_fn)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs index ba504b8a823..dd5ca1c9b5b 100644 --- a/src/tools/clippy/tests/ui/manual_async_fn.rs +++ b/src/tools/clippy/tests/ui/manual_async_fn.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_async_fn)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/manual_bits.fixed b/src/tools/clippy/tests/ui/manual_bits.fixed index e7f8cd878ca..037de0262e2 100644 --- a/src/tools/clippy/tests/ui/manual_bits.fixed +++ b/src/tools/clippy/tests/ui/manual_bits.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_bits)] #![allow( diff --git a/src/tools/clippy/tests/ui/manual_bits.rs b/src/tools/clippy/tests/ui/manual_bits.rs index 7b1d1549528..b15a531ec17 100644 --- a/src/tools/clippy/tests/ui/manual_bits.rs +++ b/src/tools/clippy/tests/ui/manual_bits.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_bits)] #![allow( diff --git a/src/tools/clippy/tests/ui/manual_filter.fixed b/src/tools/clippy/tests/ui/manual_filter.fixed index ef6780dc96d..755caa664d5 100644 --- a/src/tools/clippy/tests/ui/manual_filter.fixed +++ b/src/tools/clippy/tests/ui/manual_filter.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_filter)] #![allow(unused_variables, dead_code)] diff --git a/src/tools/clippy/tests/ui/manual_filter.rs b/src/tools/clippy/tests/ui/manual_filter.rs index ea0ce83172b..faccfe9db12 100644 --- a/src/tools/clippy/tests/ui/manual_filter.rs +++ b/src/tools/clippy/tests/ui/manual_filter.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_filter)] #![allow(unused_variables, dead_code)] diff --git a/src/tools/clippy/tests/ui/manual_filter_map.fixed b/src/tools/clippy/tests/ui/manual_filter_map.fixed index 4936dc9b2e0..831323089e7 100644 --- a/src/tools/clippy/tests/ui/manual_filter_map.fixed +++ b/src/tools/clippy/tests/ui/manual_filter_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure diff --git a/src/tools/clippy/tests/ui/manual_filter_map.rs b/src/tools/clippy/tests/ui/manual_filter_map.rs index 8c67e827b4c..2692303d313 100644 --- a/src/tools/clippy/tests/ui/manual_filter_map.rs +++ b/src/tools/clippy/tests/ui/manual_filter_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_filter_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.fixed b/src/tools/clippy/tests/ui/manual_find_fixable.fixed index 2bce6e624c9..9c5eb20c81c 100644 --- a/src/tools/clippy/tests/ui/manual_find_fixable.fixed +++ b/src/tools/clippy/tests/ui/manual_find_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_find)] #![allow(unused)] #![allow(clippy::needless_return, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/manual_find_fixable.rs b/src/tools/clippy/tests/ui/manual_find_fixable.rs index f5c6de37a25..7b670320ee3 100644 --- a/src/tools/clippy/tests/ui/manual_find_fixable.rs +++ b/src/tools/clippy/tests/ui/manual_find_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_find)] #![allow(unused)] #![allow(clippy::needless_return, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/manual_find_map.fixed b/src/tools/clippy/tests/ui/manual_find_map.fixed index 54302beceff..554613a30a9 100644 --- a/src/tools/clippy/tests/ui/manual_find_map.fixed +++ b/src/tools/clippy/tests/ui/manual_find_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure diff --git a/src/tools/clippy/tests/ui/manual_find_map.rs b/src/tools/clippy/tests/ui/manual_find_map.rs index afcc1825a9a..d6245758f9d 100644 --- a/src/tools/clippy/tests/ui/manual_find_map.rs +++ b/src/tools/clippy/tests/ui/manual_find_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::manual_find_map)] #![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed index 85a91543c89..55073c3b57c 100644 --- a/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed +++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_instant_elapsed)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::unchecked_duration_subtraction)] diff --git a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs index c98cb15b916..c9029a04940 100644 --- a/src/tools/clippy/tests/ui/manual_instant_elapsed.rs +++ b/src/tools/clippy/tests/ui/manual_instant_elapsed.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_instant_elapsed)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::unchecked_duration_subtraction)] diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed index 5b2b44c2fdb..87e86658668 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, dead_code)] #![warn(clippy::manual_is_ascii_check)] diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs index c9433f33a1b..931f0f20276 100644 --- a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs +++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, dead_code)] #![warn(clippy::manual_is_ascii_check)] diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.fixed b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed index 50f46d6b355..7e7da8f20bb 100644 --- a/src/tools/clippy/tests/ui/manual_main_separator_str.fixed +++ b/src/tools/clippy/tests/ui/manual_main_separator_str.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::manual_main_separator_str)] diff --git a/src/tools/clippy/tests/ui/manual_main_separator_str.rs b/src/tools/clippy/tests/ui/manual_main_separator_str.rs index 2dbb9e66151..cf90e12efc3 100644 --- a/src/tools/clippy/tests/ui/manual_main_separator_str.rs +++ b/src/tools/clippy/tests/ui/manual_main_separator_str.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::manual_main_separator_str)] diff --git a/src/tools/clippy/tests/ui/manual_map_option.fixed b/src/tools/clippy/tests/ui/manual_map_option.fixed index e12ea7ec145..e8ff65cad6a 100644 --- a/src/tools/clippy/tests/ui/manual_map_option.fixed +++ b/src/tools/clippy/tests/ui/manual_map_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow( diff --git a/src/tools/clippy/tests/ui/manual_map_option.rs b/src/tools/clippy/tests/ui/manual_map_option.rs index 325a6db06c4..b06a96451ce 100644 --- a/src/tools/clippy/tests/ui/manual_map_option.rs +++ b/src/tools/clippy/tests/ui/manual_map_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow( diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.fixed b/src/tools/clippy/tests/ui/manual_map_option_2.fixed index ebf3f8cabd4..dc722878248 100644 --- a/src/tools/clippy/tests/ui/manual_map_option_2.fixed +++ b/src/tools/clippy/tests/ui/manual_map_option_2.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow(clippy::toplevel_ref_arg)] diff --git a/src/tools/clippy/tests/ui/manual_map_option_2.rs b/src/tools/clippy/tests/ui/manual_map_option_2.rs index 1382d9af0aa..c495ab0fa6e 100644 --- a/src/tools/clippy/tests/ui/manual_map_option_2.rs +++ b/src/tools/clippy/tests/ui/manual_map_option_2.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_map)] #![allow(clippy::toplevel_ref_arg)] diff --git a/src/tools/clippy/tests/ui/manual_ok_or.fixed b/src/tools/clippy/tests/ui/manual_ok_or.fixed index fc8511626b3..d8901dc3b03 100644 --- a/src/tools/clippy/tests/ui/manual_ok_or.fixed +++ b/src/tools/clippy/tests/ui/manual_ok_or.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_ok_or)] #![allow(clippy::or_fun_call)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/manual_ok_or.rs b/src/tools/clippy/tests/ui/manual_ok_or.rs index b5303d33f5f..7188a521357 100644 --- a/src/tools/clippy/tests/ui/manual_ok_or.rs +++ b/src/tools/clippy/tests/ui/manual_ok_or.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_ok_or)] #![allow(clippy::or_fun_call)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed index 1f6df1b0a86..f2e44e56f02 100644 --- a/src/tools/clippy/tests/ui/manual_rem_euclid.fixed +++ b/src/tools/clippy/tests/ui/manual_rem_euclid.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] diff --git a/src/tools/clippy/tests/ui/manual_rem_euclid.rs b/src/tools/clippy/tests/ui/manual_rem_euclid.rs index b275e8a38d2..b2329c33a47 100644 --- a/src/tools/clippy/tests/ui/manual_rem_euclid.rs +++ b/src/tools/clippy/tests/ui/manual_rem_euclid.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed index 8f25fea678f..d3cac666763 100644 --- a/src/tools/clippy/tests/ui/manual_retain.fixed +++ b/src/tools/clippy/tests/ui/manual_retain.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_retain)] #![allow(unused, clippy::redundant_clone)] use std::collections::BTreeMap; diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs index e6b3995a689..34f0c4d5029 100644 --- a/src/tools/clippy/tests/ui/manual_retain.rs +++ b/src/tools/clippy/tests/ui/manual_retain.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_retain)] #![allow(unused, clippy::redundant_clone)] use std::collections::BTreeMap; diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed index c4f53c446c9..7dd4521fa78 100644 --- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed +++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports)] diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs index cd83cf6e65e..463ee069289 100644 --- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs +++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_imports)] diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed b/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed new file mode 100644 index 00000000000..ac85bd8d3ac --- /dev/null +++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.fixed @@ -0,0 +1,46 @@ +//@run-rustfix +//@aux-build:proc_macros.rs +#![allow(unused)] +#![warn(clippy::manual_slice_size_calculation)] + +extern crate proc_macros; + +use core::mem::{align_of, size_of}; +use proc_macros::external; + +fn main() { + let v_i32 = Vec::<i32>::new(); + let s_i32 = v_i32.as_slice(); + + // True positives: + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32) * 5; // WARNING + + let len = s_i32.len(); + let size = size_of::<i32>(); + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + let _ = std::mem::size_of_val(s_i32); // WARNING + + let _ = std::mem::size_of_val(external!(&[1u64][..])); + + // True negatives: + let _ = size_of::<i32>() + s_i32.len(); // Ok, not a multiplication + let _ = size_of::<i32>() * s_i32.partition_point(|_| true); // Ok, not len() + let _ = size_of::<i32>() * v_i32.len(); // Ok, not a slice + let _ = align_of::<i32>() * s_i32.len(); // Ok, not size_of() + let _ = size_of::<u32>() * s_i32.len(); // Ok, different types + + let _ = external!($s_i32.len() * size_of::<i32>()); + let _ = external!($s_i32.len()) * size_of::<i32>(); + + // False negatives: + let _ = 5 * size_of::<i32>() * s_i32.len(); // Ok (MISSED OPPORTUNITY) + let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY) +} + +const fn _const(s_i32: &[i32]) { + // True negative: + let _ = s_i32.len() * size_of::<i32>(); // Ok, can't use size_of_val in const +} diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs index 5082f931f3c..1f824b12bc2 100644 --- a/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs +++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.rs @@ -1,7 +1,12 @@ +//@run-rustfix +//@aux-build:proc_macros.rs #![allow(unused)] #![warn(clippy::manual_slice_size_calculation)] +extern crate proc_macros; + use core::mem::{align_of, size_of}; +use proc_macros::external; fn main() { let v_i32 = Vec::<i32>::new(); @@ -18,6 +23,8 @@ fn main() { let _ = s_i32.len() * size; // WARNING let _ = len * size; // WARNING + let _ = external!(&[1u64][..]).len() * size_of::<u64>(); + // True negatives: let _ = size_of::<i32>() + s_i32.len(); // Ok, not a multiplication let _ = size_of::<i32>() * s_i32.partition_point(|_| true); // Ok, not len() @@ -25,6 +32,9 @@ fn main() { let _ = align_of::<i32>() * s_i32.len(); // Ok, not size_of() let _ = size_of::<u32>() * s_i32.len(); // Ok, different types + let _ = external!($s_i32.len() * size_of::<i32>()); + let _ = external!($s_i32.len()) * size_of::<i32>(); + // False negatives: let _ = 5 * size_of::<i32>() * s_i32.len(); // Ok (MISSED OPPORTUNITY) let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY) diff --git a/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr index 4a24fc60a0f..e09d8057a3b 100644 --- a/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr +++ b/src/tools/clippy/tests/ui/manual_slice_size_calculation.stderr @@ -1,51 +1,46 @@ error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:11:13 + --> $DIR/manual_slice_size_calculation.rs:16:13 | LL | let _ = s_i32.len() * size_of::<i32>(); // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` | - = help: consider using std::mem::size_of_value instead = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:12:13 + --> $DIR/manual_slice_size_calculation.rs:17:13 | LL | let _ = size_of::<i32>() * s_i32.len(); // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider using std::mem::size_of_value instead + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:13:13 + --> $DIR/manual_slice_size_calculation.rs:18:13 | LL | let _ = size_of::<i32>() * s_i32.len() * 5; // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider using std::mem::size_of_value instead + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:17:13 + --> $DIR/manual_slice_size_calculation.rs:22:13 | LL | let _ = len * size_of::<i32>(); // WARNING - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = help: consider using std::mem::size_of_value instead + | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:18:13 + --> $DIR/manual_slice_size_calculation.rs:23:13 | LL | let _ = s_i32.len() * size; // WARNING - | ^^^^^^^^^^^^^^^^^^ - | - = help: consider using std::mem::size_of_value instead + | ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` error: manual slice size calculation - --> $DIR/manual_slice_size_calculation.rs:19:13 + --> $DIR/manual_slice_size_calculation.rs:24:13 | LL | let _ = len * size; // WARNING - | ^^^^^^^^^^ + | ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)` + +error: manual slice size calculation + --> $DIR/manual_slice_size_calculation.rs:26:13 | - = help: consider using std::mem::size_of_value instead +LL | let _ = external!(&[1u64][..]).len() * size_of::<u64>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))` -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/manual_split_once.fixed b/src/tools/clippy/tests/ui/manual_split_once.fixed index 50b02019cc2..e317c597109 100644 --- a/src/tools/clippy/tests/ui/manual_split_once.fixed +++ b/src/tools/clippy/tests/ui/manual_split_once.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_split_once)] #![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)] diff --git a/src/tools/clippy/tests/ui/manual_split_once.rs b/src/tools/clippy/tests/ui/manual_split_once.rs index e1e8b71a9de..7e2dc22bc46 100644 --- a/src/tools/clippy/tests/ui/manual_split_once.rs +++ b/src/tools/clippy/tests/ui/manual_split_once.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_split_once)] #![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)] diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.fixed b/src/tools/clippy/tests/ui/manual_str_repeat.fixed index 3d56f2a0ded..9468c3df904 100644 --- a/src/tools/clippy/tests/ui/manual_str_repeat.fixed +++ b/src/tools/clippy/tests/ui/manual_str_repeat.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_str_repeat)] diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.rs b/src/tools/clippy/tests/ui/manual_str_repeat.rs index e8240a949db..baa0a10260d 100644 --- a/src/tools/clippy/tests/ui/manual_str_repeat.rs +++ b/src/tools/clippy/tests/ui/manual_str_repeat.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_str_repeat)] diff --git a/src/tools/clippy/tests/ui/manual_string_new.fixed b/src/tools/clippy/tests/ui/manual_string_new.fixed index a376411bfbc..0d1bab23304 100644 --- a/src/tools/clippy/tests/ui/manual_string_new.fixed +++ b/src/tools/clippy/tests/ui/manual_string_new.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_string_new)] diff --git a/src/tools/clippy/tests/ui/manual_string_new.rs b/src/tools/clippy/tests/ui/manual_string_new.rs index 6bfc52fb1bc..2392ebfc322 100644 --- a/src/tools/clippy/tests/ui/manual_string_new.rs +++ b/src/tools/clippy/tests/ui/manual_string_new.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_string_new)] diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed index 7d68978216c..c17634bffe3 100644 --- a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed +++ b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![allow(unused_variables, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.rs b/src/tools/clippy/tests/ui/manual_unwrap_or.rs index b937fe6f977..6d49a6949fa 100644 --- a/src/tools/clippy/tests/ui/manual_unwrap_or.rs +++ b/src/tools/clippy/tests/ui/manual_unwrap_or.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![allow(unused_variables, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/map_clone.fixed b/src/tools/clippy/tests/ui/map_clone.fixed index 0860dcf8e0d..d7474f35719 100644 --- a/src/tools/clippy/tests/ui/map_clone.fixed +++ b/src/tools/clippy/tests/ui/map_clone.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_clone)] #![allow( clippy::clone_on_copy, diff --git a/src/tools/clippy/tests/ui/map_clone.rs b/src/tools/clippy/tests/ui/map_clone.rs index b6987336834..74978ae8006 100644 --- a/src/tools/clippy/tests/ui/map_clone.rs +++ b/src/tools/clippy/tests/ui/map_clone.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_clone)] #![allow( clippy::clone_on_copy, diff --git a/src/tools/clippy/tests/ui/map_collect_result_unit.fixed b/src/tools/clippy/tests/ui/map_collect_result_unit.fixed index e66c9cc2420..b00c2cf284e 100644 --- a/src/tools/clippy/tests/ui/map_collect_result_unit.fixed +++ b/src/tools/clippy/tests/ui/map_collect_result_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_collect_result_unit)] fn main() { diff --git a/src/tools/clippy/tests/ui/map_collect_result_unit.rs b/src/tools/clippy/tests/ui/map_collect_result_unit.rs index 6f08f4c3c53..ad2198ec1fe 100644 --- a/src/tools/clippy/tests/ui/map_collect_result_unit.rs +++ b/src/tools/clippy/tests/ui/map_collect_result_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_collect_result_unit)] fn main() { diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed index 8e2f11389f8..14816de1a63 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.fixed +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::let_underscore_untyped)] diff --git a/src/tools/clippy/tests/ui/map_flatten_fixable.rs b/src/tools/clippy/tests/ui/map_flatten_fixable.rs index a783a99c4ff..f38a00a59fa 100644 --- a/src/tools/clippy/tests/ui/map_flatten_fixable.rs +++ b/src/tools/clippy/tests/ui/map_flatten_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::pedantic)] #![allow(clippy::let_underscore_untyped)] diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed index 2256e51f2d0..7fb7d8c1218 100644 --- a/src/tools/clippy/tests/ui/map_identity.fixed +++ b/src/tools/clippy/tests/ui/map_identity.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_identity)] #![allow(clippy::needless_return)] diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs index ccfdc9ea76d..7891c242628 100644 --- a/src/tools/clippy/tests/ui/map_identity.rs +++ b/src/tools/clippy/tests/ui/map_identity.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::map_identity)] #![allow(clippy::needless_return)] diff --git a/src/tools/clippy/tests/ui/map_unwrap_or.rs b/src/tools/clippy/tests/ui/map_unwrap_or.rs index 32631024ca5..cb25d8567aa 100644 --- a/src/tools/clippy/tests/ui/map_unwrap_or.rs +++ b/src/tools/clippy/tests/ui/map_unwrap_or.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_lazy_evaluations)] diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed index bd5b4f7165a..ea5b6a6691e 100644 --- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed +++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] diff --git a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs index 0b892caf20e..f8bb9d8ca6a 100644 --- a/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs +++ b/src/tools/clippy/tests/ui/map_unwrap_or_fixable.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:option_helpers.rs +//@run-rustfix +//@aux-build:option_helpers.rs #![warn(clippy::map_unwrap_or)] diff --git a/src/tools/clippy/tests/ui/match_as_ref.fixed b/src/tools/clippy/tests/ui/match_as_ref.fixed index ddfa1e741ad..8fa3f532587 100644 --- a/src/tools/clippy/tests/ui/match_as_ref.fixed +++ b/src/tools/clippy/tests/ui/match_as_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::match_as_ref)] diff --git a/src/tools/clippy/tests/ui/match_as_ref.rs b/src/tools/clippy/tests/ui/match_as_ref.rs index 025d475ae13..02a17791426 100644 --- a/src/tools/clippy/tests/ui/match_as_ref.rs +++ b/src/tools/clippy/tests/ui/match_as_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::match_as_ref)] diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed index 55cd15bd5c3..7215660da67 100644 --- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed +++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_like_matches_macro)] #![allow( diff --git a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs index 5d645e108e5..afdf1069f5e 100644 --- a/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs +++ b/src/tools/clippy/tests/ui/match_expr_like_matches_macro.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_like_matches_macro)] #![allow( diff --git a/src/tools/clippy/tests/ui/match_ref_pats.fixed b/src/tools/clippy/tests/ui/match_ref_pats.fixed index cf37fc6dc90..50c3dcc1e0a 100644 --- a/src/tools/clippy/tests/ui/match_ref_pats.fixed +++ b/src/tools/clippy/tests/ui/match_ref_pats.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_ref_pats)] #![allow(dead_code, unused_variables)] #![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_ref_pats.rs b/src/tools/clippy/tests/ui/match_ref_pats.rs index 3220b97d1b5..d29ddacc04a 100644 --- a/src/tools/clippy/tests/ui/match_ref_pats.rs +++ b/src/tools/clippy/tests/ui/match_ref_pats.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_ref_pats)] #![allow(dead_code, unused_variables)] #![allow(clippy::enum_variant_names, clippy::equatable_if_let, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_result_ok.fixed b/src/tools/clippy/tests/ui/match_result_ok.fixed index 10ae1ee5245..fe67b225fa1 100644 --- a/src/tools/clippy/tests/ui/match_result_ok.fixed +++ b/src/tools/clippy/tests/ui/match_result_ok.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_result_ok)] #![allow(dead_code)] #![allow(clippy::boxed_local, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_result_ok.rs b/src/tools/clippy/tests/ui/match_result_ok.rs index bc2c4b50e27..eac382e1f62 100644 --- a/src/tools/clippy/tests/ui/match_result_ok.rs +++ b/src/tools/clippy/tests/ui/match_result_ok.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_result_ok)] #![allow(dead_code)] #![allow(clippy::boxed_local, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_single_binding.fixed b/src/tools/clippy/tests/ui/match_single_binding.fixed index 201301cc9b7..7c29bb08e64 100644 --- a/src/tools/clippy/tests/ui/match_single_binding.fixed +++ b/src/tools/clippy/tests/ui/match_single_binding.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow( unused, diff --git a/src/tools/clippy/tests/ui/match_single_binding.rs b/src/tools/clippy/tests/ui/match_single_binding.rs index 8b047b19ce9..c068d5e17c3 100644 --- a/src/tools/clippy/tests/ui/match_single_binding.rs +++ b/src/tools/clippy/tests/ui/match_single_binding.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow( unused, diff --git a/src/tools/clippy/tests/ui/match_single_binding2.fixed b/src/tools/clippy/tests/ui/match_single_binding2.fixed index e3cf56a4293..adfb4ba91f7 100644 --- a/src/tools/clippy/tests/ui/match_single_binding2.fixed +++ b/src/tools/clippy/tests/ui/match_single_binding2.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow(unused_variables)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_single_binding2.rs b/src/tools/clippy/tests/ui/match_single_binding2.rs index 5a4bb8441ff..b5cfe3654a5 100644 --- a/src/tools/clippy/tests/ui/match_single_binding2.rs +++ b/src/tools/clippy/tests/ui/match_single_binding2.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_single_binding)] #![allow(unused_variables)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed b/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed index e436bcf495f..cd53b1f06fa 100644 --- a/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed +++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_str_case_mismatch)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.rs b/src/tools/clippy/tests/ui/match_str_case_mismatch.rs index 92e2a000ade..6885305662a 100644 --- a/src/tools/clippy/tests/ui/match_str_case_mismatch.rs +++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_str_case_mismatch)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed index 9fd3739b69c..d2e6fef0759 100644 --- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed +++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_wildcard_for_single_variants)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs index 9a5c849e6ec..cff0c896065 100644 --- a/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs +++ b/src/tools/clippy/tests/ui/match_wildcard_for_single_variants.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::match_wildcard_for_single_variants)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed index 7fd340173af..d37e97b0a06 100644 --- a/src/tools/clippy/tests/ui/mem_replace.fixed +++ b/src/tools/clippy/tests/ui/mem_replace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn( diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs index fa2903addbc..34e37f3dbbb 100644 --- a/src/tools/clippy/tests/ui/mem_replace.rs +++ b/src/tools/clippy/tests/ui/mem_replace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn( diff --git a/src/tools/clippy/tests/ui/mem_replace_macro.rs b/src/tools/clippy/tests/ui/mem_replace_macro.rs index 3932e7d00c1..132873858b7 100644 --- a/src/tools/clippy/tests/ui/mem_replace_macro.rs +++ b/src/tools/clippy/tests/ui/mem_replace_macro.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] extern crate proc_macros; diff --git a/src/tools/clippy/tests/ui/methods.rs b/src/tools/clippy/tests/ui/methods.rs index 1519e4da934..e0e2cac30a2 100644 --- a/src/tools/clippy/tests/ui/methods.rs +++ b/src/tools/clippy/tests/ui/methods.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::all, clippy::pedantic)] #![allow( diff --git a/src/tools/clippy/tests/ui/methods_fixable.fixed b/src/tools/clippy/tests/ui/methods_fixable.fixed index ee7c1b0da6d..dcbed5a4d99 100644 --- a/src/tools/clippy/tests/ui/methods_fixable.fixed +++ b/src/tools/clippy/tests/ui/methods_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::filter_next)] diff --git a/src/tools/clippy/tests/ui/methods_fixable.rs b/src/tools/clippy/tests/ui/methods_fixable.rs index 6d0f1b7bd51..3a976d23527 100644 --- a/src/tools/clippy/tests/ui/methods_fixable.rs +++ b/src/tools/clippy/tests/ui/methods_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::filter_next)] diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed index f219a570e7f..f58e9a429b6 100644 --- a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed +++ b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs index 8a8ae756a4f..e00224f5ceb 100644 --- a/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs +++ b/src/tools/clippy/tests/ui/mismatched_target_os_non_unix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed b/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed index 7d9d406d99d..330587a3c4c 100644 --- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed +++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs b/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs index c1177f1eedc..5a90019a2e4 100644 --- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs +++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::mismatched_target_os)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs index e6f88c6e622..5db73a7b8ea 100644 --- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -2,8 +2,8 @@ //! compilation error. //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. -// aux-build:helper.rs -// aux-build:../../auxiliary/proc_macros.rs +//@aux-build:helper.rs +//@aux-build:../../auxiliary/proc_macros.rs #![warn(clippy::missing_const_for_fn)] #![feature(start)] diff --git a/src/tools/clippy/tests/ui/missing_doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs index 5752048949c..bf587e774f7 100644 --- a/src/tools/clippy/tests/ui/missing_doc.rs +++ b/src/tools/clippy/tests/ui/missing_doc.rs @@ -1,5 +1,5 @@ -// needs-asm-support -// aux-build: proc_macros.rs +//@needs-asm-support +//@aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] // When denying at the crate level, be sure to not get random warnings from the diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.rs b/src/tools/clippy/tests/ui/missing_doc_impl.rs index e2d49b0907d..520ddbe16b8 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.rs +++ b/src/tools/clippy/tests/ui/missing_doc_impl.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macros.rs +//@aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/missing_spin_loop.fixed b/src/tools/clippy/tests/ui/missing_spin_loop.fixed index aa89e04d26e..a15298dc37b 100644 --- a/src/tools/clippy/tests/ui/missing_spin_loop.fixed +++ b/src/tools/clippy/tests/ui/missing_spin_loop.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![allow(clippy::bool_comparison)] #![allow(unused_braces)] diff --git a/src/tools/clippy/tests/ui/missing_spin_loop.rs b/src/tools/clippy/tests/ui/missing_spin_loop.rs index 88745e47732..be74581ecd0 100644 --- a/src/tools/clippy/tests/ui/missing_spin_loop.rs +++ b/src/tools/clippy/tests/ui/missing_spin_loop.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![allow(clippy::bool_comparison)] #![allow(unused_braces)] diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed index bb4b4795516..960e5c05fb6 100644 --- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed +++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs index a19bc72baf8..e532ca62dc5 100644 --- a/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs +++ b/src/tools/clippy/tests/ui/missing_spin_loop_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::missing_spin_loop)] #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed index 9a47d7c56ed..62cfeafdc49 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![allow( dead_code, diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs index 04261cba55a..f83b7c3dbda 100644 --- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs +++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![allow( dead_code, diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.rs b/src/tools/clippy/tests/ui/module_name_repetitions.rs index ebaa77cc283..fb2c7612343 100644 --- a/src/tools/clippy/tests/ui/module_name_repetitions.rs +++ b/src/tools/clippy/tests/ui/module_name_repetitions.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![warn(clippy::module_name_repetitions)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs index 9082f1675a8..73ef35c8c36 100644 --- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![allow(unused)] #![allow(deref_nullptr)] #![allow(clippy::unnecessary_operation)] diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed index bbbb3cf621e..0c275504d36 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.fixed +++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(never_type)] #![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)] #![warn(clippy::must_use_candidate)] diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs index 94d3c83bdb9..d1c9267732f 100644 --- a/src/tools/clippy/tests/ui/must_use_candidates.rs +++ b/src/tools/clippy/tests/ui/must_use_candidates.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(never_type)] #![allow(unused_mut, unused_tuple_struct_fields, clippy::redundant_allocation)] #![warn(clippy::must_use_candidate)] diff --git a/src/tools/clippy/tests/ui/must_use_unit.fixed b/src/tools/clippy/tests/ui/must_use_unit.fixed index b7d375ff80e..4f7cf4e56d1 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.fixed +++ b/src/tools/clippy/tests/ui/must_use_unit.fixed @@ -1,5 +1,5 @@ -//run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] diff --git a/src/tools/clippy/tests/ui/must_use_unit.rs b/src/tools/clippy/tests/ui/must_use_unit.rs index 74d6b4ca865..3a814ce1685 100644 --- a/src/tools/clippy/tests/ui/must_use_unit.rs +++ b/src/tools/clippy/tests/ui/must_use_unit.rs @@ -1,5 +1,5 @@ -//run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs index 06bb085442a..d838098de11 100644 --- a/src/tools/clippy/tests/ui/mut_mut.rs +++ b/src/tools/clippy/tests/ui/mut_mut.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::mut_mut)] #![allow(unused)] #![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)] diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed index ecad10a8290..433817a4e03 100644 --- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed +++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_mut)] #![warn(clippy::mut_mutex_lock)] diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs index f2b1d6fbfbc..567a0b59e70 100644 --- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs +++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_mut)] #![warn(clippy::mut_mutex_lock)] diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed index 9da21eb6b29..d7eb1a047ed 100644 --- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed +++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_arbitrary_self_type)] #![allow(unused_mut, clippy::needless_lifetimes)] diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs index 17aeaaf97ac..85a2a957f29 100644 --- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs +++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_arbitrary_self_type)] #![allow(unused_mut, clippy::needless_lifetimes)] diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs index 02b43cce2bd..00871f9f450 100644 --- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs +++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_attr.rs +//@aux-build:proc_macro_attr.rs #![warn(clippy::needless_arbitrary_self_type)] diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr index b2edbfe4323..c7df5936d70 100644 --- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr +++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.stderr @@ -2,7 +2,7 @@ error: the type of the `self` parameter does not need to be arbitrary --> $DIR/needless_arbitrary_self_type_unfixable.rs:42:31 | LL | fn call_with_mut_self(self: &mut Self) {} - | ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'_ mut self` + | ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&mut self` | = note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings` diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed index 5e1ea663a10..7543ab72ca2 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bitwise_bool)] diff --git a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs index f3075fba0a2..2cea701dce6 100644 --- a/src/tools/clippy/tests/ui/needless_bitwise_bool.rs +++ b/src/tools/clippy/tests/ui/needless_bitwise_bool.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bitwise_bool)] diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed index 89dc13fd5b1..f860852e7b7 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.fixed +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bool)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.rs b/src/tools/clippy/tests/ui/needless_bool/fixable.rs index c11d9472e8d..6680dab5b6d 100644 --- a/src/tools/clippy/tests/ui/needless_bool/fixable.rs +++ b/src/tools/clippy/tests/ui/needless_bool/fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_bool)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed index 4cb7f6b687f..425e6eb6200 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.fixed +++ b/src/tools/clippy/tests/ui/needless_borrow.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![allow( unused, diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs index 9a01190ed8d..3f7fa4a9d7d 100644 --- a/src/tools/clippy/tests/ui/needless_borrow.rs +++ b/src/tools/clippy/tests/ui/needless_borrow.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![allow( unused, diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed index 0c47ceb7b67..6663520da8a 100644 --- a/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed +++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_borrowed_reference)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs index f883bb0c889..6c8efd2ce18 100644 --- a/src/tools/clippy/tests/ui/needless_borrowed_ref.rs +++ b/src/tools/clippy/tests/ui/needless_borrowed_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_borrowed_reference)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_collect.fixed b/src/tools/clippy/tests/ui/needless_collect.fixed index 2659ad38488..024c22de225 100644 --- a/src/tools/clippy/tests/ui/needless_collect.fixed +++ b/src/tools/clippy/tests/ui/needless_collect.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::suspicious_map, clippy::iter_count)] diff --git a/src/tools/clippy/tests/ui/needless_collect.rs b/src/tools/clippy/tests/ui/needless_collect.rs index 535ec82982b..7ed7babec30 100644 --- a/src/tools/clippy/tests/ui/needless_collect.rs +++ b/src/tools/clippy/tests/ui/needless_collect.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::suspicious_map, clippy::iter_count)] diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed index 09e671b88e1..a04f9ec651e 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed +++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_for_each)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs index abb4045b919..4975c705081 100644 --- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs +++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_for_each)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed index 86d899bb46c..92f7b3f777a 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.fixed +++ b/src/tools/clippy/tests/ui/needless_late_init.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs index 969afb38edf..be378c42f95 100644 --- a/src/tools/clippy/tests/ui/needless_late_init.rs +++ b/src/tools/clippy/tests/ui/needless_late_init.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed index e6ead69d148..7b99042f744 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed +++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs index 06eb430506f..6fcf1efc2ee 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.rs +++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed index 7e47406798c..d8a0400a4f0 100644 --- a/src/tools/clippy/tests/ui/needless_match.fixed +++ b/src/tools/clippy/tests/ui/needless_match.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_match)] #![allow(clippy::manual_map)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs index 809c694bf40..3de9bd6d7a1 100644 --- a/src/tools/clippy/tests/ui/needless_match.rs +++ b/src/tools/clippy/tests/ui/needless_match.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_match)] #![allow(clippy::manual_map)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed index acd22c6bb43..70015fccf9e 100644 --- a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed +++ b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::needless_option_as_deref)] diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.rs b/src/tools/clippy/tests/ui/needless_option_as_deref.rs index 61eda5052a2..e2e35360cb3 100644 --- a/src/tools/clippy/tests/ui/needless_option_as_deref.rs +++ b/src/tools/clippy/tests/ui/needless_option_as_deref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::needless_option_as_deref)] diff --git a/src/tools/clippy/tests/ui/needless_option_take.fixed b/src/tools/clippy/tests/ui/needless_option_take.fixed index 29691e81666..bfc6d20d5a3 100644 --- a/src/tools/clippy/tests/ui/needless_option_take.fixed +++ b/src/tools/clippy/tests/ui/needless_option_take.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { println!("Testing non erroneous option_take_on_temporary"); diff --git a/src/tools/clippy/tests/ui/needless_option_take.rs b/src/tools/clippy/tests/ui/needless_option_take.rs index 9f4109eb463..697eeab4207 100644 --- a/src/tools/clippy/tests/ui/needless_option_take.rs +++ b/src/tools/clippy/tests/ui/needless_option_take.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix fn main() { println!("Testing non erroneous option_take_on_temporary"); diff --git a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed index f11330a8916..9b98f6ea7f7 100644 --- a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed +++ b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_parens_on_range_literals)] #![allow(clippy::almost_complete_range)] diff --git a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs index 671c0009e23..088e7b2b98f 100644 --- a/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs +++ b/src/tools/clippy/tests/ui/needless_parens_on_range_literals.rs @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_parens_on_range_literals)] #![allow(clippy::almost_complete_range)] diff --git a/src/tools/clippy/tests/ui/needless_question_mark.fixed b/src/tools/clippy/tests/ui/needless_question_mark.fixed index 7eaca571992..679b73d404a 100644 --- a/src/tools/clippy/tests/ui/needless_question_mark.fixed +++ b/src/tools/clippy/tests/ui/needless_question_mark.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_question_mark)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_question_mark.rs b/src/tools/clippy/tests/ui/needless_question_mark.rs index 960bc7b7898..a993d3ec35d 100644 --- a/src/tools/clippy/tests/ui/needless_question_mark.rs +++ b/src/tools/clippy/tests/ui/needless_question_mark.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::needless_question_mark)] #![allow( diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed index 57c08996ce2..ee4e5007dc5 100644 --- a/src/tools/clippy/tests/ui/needless_return.fixed +++ b/src/tools/clippy/tests/ui/needless_return.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(yeet_expr)] diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs index 7c1feefbe32..cd999db4f40 100644 --- a/src/tools/clippy/tests/ui/needless_return.rs +++ b/src/tools/clippy/tests/ui/needless_return.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lint_reasons)] #![feature(yeet_expr)] diff --git a/src/tools/clippy/tests/ui/needless_splitn.fixed b/src/tools/clippy/tests/ui/needless_splitn.fixed index 5496031fefa..30a038312c8 100644 --- a/src/tools/clippy/tests/ui/needless_splitn.fixed +++ b/src/tools/clippy/tests/ui/needless_splitn.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_splitn)] #![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)] diff --git a/src/tools/clippy/tests/ui/needless_splitn.rs b/src/tools/clippy/tests/ui/needless_splitn.rs index 35c2465bae1..1b0b9a5981a 100644 --- a/src/tools/clippy/tests/ui/needless_splitn.rs +++ b/src/tools/clippy/tests/ui/needless_splitn.rs @@ -1,5 +1,5 @@ -// run-rustfix -// edition:2018 +//@run-rustfix +//@edition:2018 #![warn(clippy::needless_splitn)] #![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)] diff --git a/src/tools/clippy/tests/ui/neg_multiply.fixed b/src/tools/clippy/tests/ui/neg_multiply.fixed index 58ab9e85678..e07e7c88d68 100644 --- a/src/tools/clippy/tests/ui/neg_multiply.fixed +++ b/src/tools/clippy/tests/ui/neg_multiply.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::neg_multiply)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/neg_multiply.rs b/src/tools/clippy/tests/ui/neg_multiply.rs index 581290dc72e..2887af7b421 100644 --- a/src/tools/clippy/tests/ui/neg_multiply.rs +++ b/src/tools/clippy/tests/ui/neg_multiply.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::neg_multiply)] #![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed index a9b2dcfb085..89d12752834 100644 --- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed +++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed @@ -1,5 +1,5 @@ -// ignore-windows -// run-rustfix +//@ignore-windows +//@run-rustfix #![warn(clippy::non_octal_unix_permissions)] use std::fs::{DirBuilder, File, OpenOptions, Permissions}; use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs index 7d2922f494e..1b3a322d726 100644 --- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs +++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs @@ -1,5 +1,5 @@ -// ignore-windows -// run-rustfix +//@ignore-windows +//@run-rustfix #![warn(clippy::non_octal_unix_permissions)] use std::fs::{DirBuilder, File, OpenOptions, Permissions}; use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt}; diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed index aad44089de4..05802a2c865 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed +++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::diverging_sub_expression)] #![warn(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs index b9074da8427..cd5b576fa07 100644 --- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs +++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::diverging_sub_expression)] #![warn(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/numbered_fields.fixed b/src/tools/clippy/tests/ui/numbered_fields.fixed index 68c987eb4c6..a52845e53a4 100644 --- a/src/tools/clippy/tests/ui/numbered_fields.fixed +++ b/src/tools/clippy/tests/ui/numbered_fields.fixed @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::init_numbered_fields)] #![allow(unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/numbered_fields.rs b/src/tools/clippy/tests/ui/numbered_fields.rs index 2ef4fb4de53..ca93f7dce59 100644 --- a/src/tools/clippy/tests/ui/numbered_fields.rs +++ b/src/tools/clippy/tests/ui/numbered_fields.rs @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::init_numbered_fields)] #![allow(unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed index 62d932c2c6b..9e4f97253f8 100644 --- a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed +++ b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::obfuscated_if_else)] diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.rs b/src/tools/clippy/tests/ui/obfuscated_if_else.rs index 273be9092a7..c2351d64c1c 100644 --- a/src/tools/clippy/tests/ui/obfuscated_if_else.rs +++ b/src/tools/clippy/tests/ui/obfuscated_if_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::obfuscated_if_else)] diff --git a/src/tools/clippy/tests/ui/octal_escapes.rs b/src/tools/clippy/tests/ui/octal_escapes.rs index 53145ef0fd2..61ea9660457 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.rs +++ b/src/tools/clippy/tests/ui/octal_escapes.rs @@ -17,4 +17,5 @@ fn main() { let _good3 = "\0\0"; let _good4 = "X\0\0X"; let _good5 = "锈\0锈"; + let _good6 = "\0\\01"; } diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr index 295dc1798e3..aa362e96321 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.stderr +++ b/src/tools/clippy/tests/ui/octal_escapes.stderr @@ -64,6 +64,22 @@ LL | let _bad4 = "/x001234567"; | ~~~~~~~~~~~~~ error: octal-looking escape in string literal + --> $DIR/octal_escapes.rs:9:17 + | +LL | let _bad5 = "/0/03"; + | ^^^^^^^ + | + = help: octal escapes are not supported, `/0` is always a null character +help: if an octal escape was intended, use the hexadecimal representation instead + | +LL | let _bad5 = "/0/x03"; + | ~~~~~~~~ +help: if the null character is intended, disambiguate using + | +LL | let _bad5 = "/0/x003"; + | ~~~~~~~~~ + +error: octal-looking escape in string literal --> $DIR/octal_escapes.rs:10:17 | LL | let _bad6 = "Text-/055/077-MoreText"; @@ -127,5 +143,5 @@ help: if the null character is intended, disambiguate using LL | let _bad9 = "锈/x0011锈"; | ~~~~~~~~~~~~ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.fixed b/src/tools/clippy/tests/ui/option_as_ref_deref.fixed index d124d133faa..e1c0fa3f7fd 100644 --- a/src/tools/clippy/tests/ui/option_as_ref_deref.fixed +++ b/src/tools/clippy/tests/ui/option_as_ref_deref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::redundant_clone)] #![warn(clippy::option_as_ref_deref)] diff --git a/src/tools/clippy/tests/ui/option_as_ref_deref.rs b/src/tools/clippy/tests/ui/option_as_ref_deref.rs index 86e354c6716..6f4917fd149 100644 --- a/src/tools/clippy/tests/ui/option_as_ref_deref.rs +++ b/src/tools/clippy/tests/ui/option_as_ref_deref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::redundant_clone)] #![warn(clippy::option_as_ref_deref)] diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.rs b/src/tools/clippy/tests/ui/option_env_unwrap.rs index 9a56cf40d8a..ee1fe3f1fc0 100644 --- a/src/tools/clippy/tests/ui/option_env_unwrap.rs +++ b/src/tools/clippy/tests/ui/option_env_unwrap.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::option_env_unwrap)] #![allow(clippy::map_flatten)] diff --git a/src/tools/clippy/tests/ui/option_filter_map.fixed b/src/tools/clippy/tests/ui/option_filter_map.fixed index b20f73f3110..93c250cfa73 100644 --- a/src/tools/clippy/tests/ui/option_filter_map.fixed +++ b/src/tools/clippy/tests/ui/option_filter_map.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_filter_map)] #![allow(clippy::map_flatten)] diff --git a/src/tools/clippy/tests/ui/option_filter_map.rs b/src/tools/clippy/tests/ui/option_filter_map.rs index 7abaaa0fb83..2c5f03250b9 100644 --- a/src/tools/clippy/tests/ui/option_filter_map.rs +++ b/src/tools/clippy/tests/ui/option_filter_map.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_filter_map)] #![allow(clippy::map_flatten)] diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index 0456005dce4..9aebcf47100 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, @@ -25,7 +25,7 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { let _ = string.map_or(0, |s| s.len()); let _ = num.as_ref().map_or(&0, |s| s); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); @@ -34,7 +34,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { s += 1; s }); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 23b148752cb..b40b324902a 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_if_let_else)] #![allow( unused_tuple_struct_fields, @@ -33,7 +33,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { *s += 1; s } else { - &mut 0 + &0 }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -46,7 +46,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { *s += 1; s } else { - &mut 0 + &0 }; } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index a5dbf6e1f22..f5e4affb672 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -30,13 +30,13 @@ LL | let _ = if let Some(s) = &mut num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); @@ -76,13 +76,13 @@ LL | let _ = if let Some(ref mut s) = num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); diff --git a/src/tools/clippy/tests/ui/option_map_or_none.fixed b/src/tools/clippy/tests/ui/option_map_or_none.fixed index 04bfac7735f..501757647bf 100644 --- a/src/tools/clippy/tests/ui/option_map_or_none.fixed +++ b/src/tools/clippy/tests/ui/option_map_or_none.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::bind_instead_of_map)] diff --git a/src/tools/clippy/tests/ui/option_map_or_none.rs b/src/tools/clippy/tests/ui/option_map_or_none.rs index bb84f8a48f4..4d8704e737d 100644 --- a/src/tools/clippy/tests/ui/option_map_or_none.rs +++ b/src/tools/clippy/tests/ui/option_map_or_none.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::bind_instead_of_map)] diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed index 00264dcceaa..8f64451edf3 100644 --- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed +++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs index f3363ebce54..2bf7a8e0f7d 100644 --- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs +++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::option_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed index be9a65506e1..f723a55f77f 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.fixed +++ b/src/tools/clippy/tests/ui/or_fun_call.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_fun_call)] #![allow(dead_code)] #![allow(clippy::borrow_as_ptr, clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs index 628c9704638..61ef6e27f32 100644 --- a/src/tools/clippy/tests/ui/or_fun_call.rs +++ b/src/tools/clippy/tests/ui/or_fun_call.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_fun_call)] #![allow(dead_code)] #![allow(clippy::borrow_as_ptr, clippy::uninlined_format_args, clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed index 844cc4b7a09..40badac4424 100644 --- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed +++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_then_unwrap)] #![allow(clippy::map_identity, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs index 1528ef9be96..76c9942fe6c 100644 --- a/src/tools/clippy/tests/ui/or_then_unwrap.rs +++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::or_then_unwrap)] #![allow(clippy::map_identity, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.fixed b/src/tools/clippy/tests/ui/partialeq_to_none.fixed index 4644ea8f51d..81a716bd276 100644 --- a/src/tools/clippy/tests/ui/partialeq_to_none.fixed +++ b/src/tools/clippy/tests/ui/partialeq_to_none.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::partialeq_to_none)] struct Foobar; diff --git a/src/tools/clippy/tests/ui/partialeq_to_none.rs b/src/tools/clippy/tests/ui/partialeq_to_none.rs index 61011b3a8c5..f454715fa30 100644 --- a/src/tools/clippy/tests/ui/partialeq_to_none.rs +++ b/src/tools/clippy/tests/ui/partialeq_to_none.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::partialeq_to_none)] struct Foobar; diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed b/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed index ef8856830fc..393fc6e1c69 100644 --- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed +++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::path::PathBuf; #[warn(clippy::all, clippy::path_buf_push_overwrite)] diff --git a/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs b/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs index 6e2d483f454..18de6e06412 100644 --- a/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs +++ b/src/tools/clippy/tests/ui/path_buf_push_overwrite.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix use std::path::PathBuf; #[warn(clippy::all, clippy::path_buf_push_overwrite)] diff --git a/src/tools/clippy/tests/ui/patterns.fixed b/src/tools/clippy/tests/ui/patterns.fixed index cd69014326e..a1da47d84fd 100644 --- a/src/tools/clippy/tests/ui/patterns.fixed +++ b/src/tools/clippy/tests/ui/patterns.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/patterns.rs b/src/tools/clippy/tests/ui/patterns.rs index 9128da420c0..399066b813e 100644 --- a/src/tools/clippy/tests/ui/patterns.rs +++ b/src/tools/clippy/tests/ui/patterns.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/precedence.fixed b/src/tools/clippy/tests/ui/precedence.fixed index 163bd044c17..af4d5636b61 100644 --- a/src/tools/clippy/tests/ui/precedence.fixed +++ b/src/tools/clippy/tests/ui/precedence.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::precedence)] #![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)] #![allow(clippy::identity_op)] diff --git a/src/tools/clippy/tests/ui/precedence.rs b/src/tools/clippy/tests/ui/precedence.rs index 8c849e3209b..e23ae912786 100644 --- a/src/tools/clippy/tests/ui/precedence.rs +++ b/src/tools/clippy/tests/ui/precedence.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::precedence)] #![allow(unused_must_use, clippy::no_effect, clippy::unnecessary_operation)] #![allow(clippy::identity_op)] diff --git a/src/tools/clippy/tests/ui/print_stdout_build_script.rs b/src/tools/clippy/tests/ui/print_stdout_build_script.rs index 997ebef8a69..91448cb0faf 100644 --- a/src/tools/clippy/tests/ui/print_stdout_build_script.rs +++ b/src/tools/clippy/tests/ui/print_stdout_build_script.rs @@ -1,4 +1,4 @@ -// compile-flags: --crate-name=build_script_build +//@compile-flags: --crate-name=build_script_build #![warn(clippy::print_stdout)] diff --git a/src/tools/clippy/tests/ui/print_with_newline.rs b/src/tools/clippy/tests/ui/print_with_newline.rs index b8c29d207ad..ff79ca75ffa 100644 --- a/src/tools/clippy/tests/ui/print_with_newline.rs +++ b/src/tools/clippy/tests/ui/print_with_newline.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![allow(clippy::print_literal)] #![warn(clippy::print_with_newline)] diff --git a/src/tools/clippy/tests/ui/println_empty_string.fixed b/src/tools/clippy/tests/ui/println_empty_string.fixed index 9760680927a..abf951ae22d 100644 --- a/src/tools/clippy/tests/ui/println_empty_string.fixed +++ b/src/tools/clippy/tests/ui/println_empty_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::match_single_binding)] fn main() { diff --git a/src/tools/clippy/tests/ui/println_empty_string.rs b/src/tools/clippy/tests/ui/println_empty_string.rs index 80fdb3e6e21..fd86e2543cc 100644 --- a/src/tools/clippy/tests/ui/println_empty_string.rs +++ b/src/tools/clippy/tests/ui/println_empty_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::match_single_binding)] fn main() { diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed index ee7b998a0b2..2c2567d67cd 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs index c88329ce4ec..6000e5c08ac 100644 --- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs +++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] diff --git a/src/tools/clippy/tests/ui/ptr_eq.fixed b/src/tools/clippy/tests/ui/ptr_eq.fixed index 209081e6e80..d5fa273d41f 100644 --- a/src/tools/clippy/tests/ui/ptr_eq.fixed +++ b/src/tools/clippy/tests/ui/ptr_eq.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::ptr_eq)] macro_rules! mac { diff --git a/src/tools/clippy/tests/ui/ptr_eq.rs b/src/tools/clippy/tests/ui/ptr_eq.rs index 69162870807..e033366a4aa 100644 --- a/src/tools/clippy/tests/ui/ptr_eq.rs +++ b/src/tools/clippy/tests/ui/ptr_eq.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::ptr_eq)] macro_rules! mac { diff --git a/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed b/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed index c57e2990fb9..f69bc131898 100644 --- a/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed +++ b/src/tools/clippy/tests/ui/ptr_offset_with_cast.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_cast)] fn main() { diff --git a/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs b/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs index 3de7997acdd..eae36c27729 100644 --- a/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs +++ b/src/tools/clippy/tests/ui/ptr_offset_with_cast.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::unnecessary_cast)] fn main() { diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed index 5c49d46da72..7f1660f31fa 100644 --- a/src/tools/clippy/tests/ui/question_mark.fixed +++ b/src/tools/clippy/tests/ui/question_mark.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unreachable_code)] #![allow(dead_code)] #![allow(clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs index d057df6a9b3..a90eae50ed4 100644 --- a/src/tools/clippy/tests/ui/question_mark.rs +++ b/src/tools/clippy/tests/ui/question_mark.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unreachable_code)] #![allow(dead_code)] #![allow(clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/range_contains.fixed b/src/tools/clippy/tests/ui/range_contains.fixed index 4923731fe45..0a92ee7c8dd 100644 --- a/src/tools/clippy/tests/ui/range_contains.fixed +++ b/src/tools/clippy/tests/ui/range_contains.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_range_contains)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/range_contains.rs b/src/tools/clippy/tests/ui/range_contains.rs index d623ccb5da6..7a83be60957 100644 --- a/src/tools/clippy/tests/ui/range_contains.rs +++ b/src/tools/clippy/tests/ui/range_contains.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::manual_range_contains)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed index a16a3e54d45..79c133cb5e3 100644 --- a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed +++ b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_parens)] #![allow(clippy::iter_with_drain)] diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.rs b/src/tools/clippy/tests/ui/range_plus_minus_one.rs index bd6cb4d21be..689a6b7a17c 100644 --- a/src/tools/clippy/tests/ui/range_plus_minus_one.rs +++ b/src/tools/clippy/tests/ui/range_plus_minus_one.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_parens)] #![allow(clippy::iter_with_drain)] diff --git a/src/tools/clippy/tests/ui/rc_buffer.fixed b/src/tools/clippy/tests/ui/rc_buffer.fixed index 8910c01b1fc..4cba292c1b7 100644 --- a/src/tools/clippy/tests/ui/rc_buffer.fixed +++ b/src/tools/clippy/tests/ui/rc_buffer.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/src/tools/clippy/tests/ui/rc_buffer.rs b/src/tools/clippy/tests/ui/rc_buffer.rs index 1e63a43262e..d8a9aa2786d 100644 --- a/src/tools/clippy/tests/ui/rc_buffer.rs +++ b/src/tools/clippy/tests/ui/rc_buffer.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.fixed b/src/tools/clippy/tests/ui/rc_buffer_arc.fixed index 13dd6f5fcd1..ac51ac9e467 100644 --- a/src/tools/clippy/tests/ui/rc_buffer_arc.fixed +++ b/src/tools/clippy/tests/ui/rc_buffer_arc.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/src/tools/clippy/tests/ui/rc_buffer_arc.rs b/src/tools/clippy/tests/ui/rc_buffer_arc.rs index 1a521bfeb7c..21dc27bc5fa 100644 --- a/src/tools/clippy/tests/ui/rc_buffer_arc.rs +++ b/src/tools/clippy/tests/ui/rc_buffer_arc.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::rc_buffer)] #![allow(dead_code, unused_imports)] diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed index 6db02718c70..edb7715f42c 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] #![allow(clippy::disallowed_names, unused_variables, dead_code)] diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs index c15806f30c0..c59422dd966 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![allow(clippy::boxed_local, clippy::needless_pass_by_value)] #![allow(clippy::disallowed_names, unused_variables, dead_code)] diff --git a/src/tools/clippy/tests/ui/redundant_async_block.fixed b/src/tools/clippy/tests/ui/redundant_async_block.fixed index ad96993c4a7..328958491ee 100644 --- a/src/tools/clippy/tests/ui/redundant_async_block.fixed +++ b/src/tools/clippy/tests/ui/redundant_async_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::manual_async_fn)] #![warn(clippy::redundant_async_block)] diff --git a/src/tools/clippy/tests/ui/redundant_async_block.rs b/src/tools/clippy/tests/ui/redundant_async_block.rs index 7ae23558369..cd189b31555 100644 --- a/src/tools/clippy/tests/ui/redundant_async_block.rs +++ b/src/tools/clippy/tests/ui/redundant_async_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::manual_async_fn)] #![warn(clippy::redundant_async_block)] diff --git a/src/tools/clippy/tests/ui/redundant_clone.fixed b/src/tools/clippy/tests/ui/redundant_clone.fixed index 00b42745093..8bebb5183bc 100644 --- a/src/tools/clippy/tests/ui/redundant_clone.fixed +++ b/src/tools/clippy/tests/ui/redundant_clone.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // rustfix-only-machine-applicable #![feature(lint_reasons)] #![allow(clippy::drop_non_drop, clippy::implicit_clone, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/redundant_clone.rs b/src/tools/clippy/tests/ui/redundant_clone.rs index f899127db8d..b4bd5d16b1a 100644 --- a/src/tools/clippy/tests/ui/redundant_clone.rs +++ b/src/tools/clippy/tests/ui/redundant_clone.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // rustfix-only-machine-applicable #![feature(lint_reasons)] #![allow(clippy::drop_non_drop, clippy::implicit_clone, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed index b987fd2ce6f..61aed2733fe 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs index 633a2979d5d..56b28663539 100644 --- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs +++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed index 276266a2dd8..d2a65399da6 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.fixed +++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_field_names)] #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs index f674141c138..605ffd21e2f 100644 --- a/src/tools/clippy/tests/ui/redundant_field_names.rs +++ b/src/tools/clippy/tests/ui/redundant_field_names.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::redundant_field_names)] #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed index ce3229f1759..bebdf89716f 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // Issue #5746 #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs index 29b8543cf47..8fb6ed5f7ec 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // Issue #5746 #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed index 21bae909555..a9faf12cd5a 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::redundant_pattern_matching)] #![allow(unused_must_use)] #![allow( diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs index 4dd9171677e..574671d03d1 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_ipaddr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all, clippy::redundant_pattern_matching)] #![allow(unused_must_use)] #![allow( diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed index a89845c1dd3..87100b97288 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs index d6f44403487..0b69e13f655 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed index 3645f2c4bfd..bf3e692202c 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs index 866c71b7cfa..892a21d9d29 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_poll.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed index 42348df4480..c48d1522935 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(deprecated, unused_must_use)] diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs index 5949cb2271c..26f37d169fa 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_result.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::all)] #![warn(clippy::redundant_pattern_matching)] #![allow(deprecated, unused_must_use)] diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed index 106947de68c..f65c0fdd35d 100644 --- a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed +++ b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::redundant_pub_crate)] diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.rs b/src/tools/clippy/tests/ui/redundant_pub_crate.rs index f96cfd31843..fb07fed98be 100644 --- a/src/tools/clippy/tests/ui/redundant_pub_crate.rs +++ b/src/tools/clippy/tests/ui/redundant_pub_crate.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] #![warn(clippy::redundant_pub_crate)] diff --git a/src/tools/clippy/tests/ui/redundant_slicing.fixed b/src/tools/clippy/tests/ui/redundant_slicing.fixed index 8dd8d309237..56ddca71903 100644 --- a/src/tools/clippy/tests/ui/redundant_slicing.fixed +++ b/src/tools/clippy/tests/ui/redundant_slicing.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::deref_by_slicing)] #![warn(clippy::redundant_slicing)] diff --git a/src/tools/clippy/tests/ui/redundant_slicing.rs b/src/tools/clippy/tests/ui/redundant_slicing.rs index 51c16dd8d65..d67b6665e26 100644 --- a/src/tools/clippy/tests/ui/redundant_slicing.rs +++ b/src/tools/clippy/tests/ui/redundant_slicing.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused, clippy::deref_by_slicing)] #![warn(clippy::redundant_slicing)] diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed index bca777a890c..2651735d103 100644 --- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed +++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs index afe7644816d..7286652899d 100644 --- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs +++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed index 5076f61334d..e8a00a9e7f7 100644 --- a/src/tools/clippy/tests/ui/rename.fixed +++ b/src/tools/clippy/tests/ui/rename.fixed @@ -2,7 +2,7 @@ // Use that command to update this file and do not edit by hand. // Manual edits will be overwritten. -// run-rustfix +//@run-rustfix #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs index 64bc1ca7116..c8ea70c2bcb 100644 --- a/src/tools/clippy/tests/ui/rename.rs +++ b/src/tools/clippy/tests/ui/rename.rs @@ -2,7 +2,7 @@ // Use that command to update this file and do not edit by hand. // Manual edits will be overwritten. -// run-rustfix +//@run-rustfix #![allow(clippy::almost_complete_range)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed index cb91b841d2c..0334c1e1a29 100644 --- a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed +++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[clippy::cognitive_complexity = "1"] fn main() {} diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs index b3ce2758067..d350370c244 100644 --- a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs +++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[clippy::cyclomatic_complexity = "1"] fn main() {} diff --git a/src/tools/clippy/tests/ui/repeat_once.fixed b/src/tools/clippy/tests/ui/repeat_once.fixed index dc197e50300..c517bfcc6aa 100644 --- a/src/tools/clippy/tests/ui/repeat_once.fixed +++ b/src/tools/clippy/tests/ui/repeat_once.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::repeat_once)] #[allow(unused, clippy::redundant_clone)] fn main() { diff --git a/src/tools/clippy/tests/ui/repeat_once.rs b/src/tools/clippy/tests/ui/repeat_once.rs index 0ec5127117c..9a30b47418f 100644 --- a/src/tools/clippy/tests/ui/repeat_once.rs +++ b/src/tools/clippy/tests/ui/repeat_once.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::repeat_once)] #[allow(unused, clippy::redundant_clone)] fn main() { diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed index 331531b5165..119ff25918a 100644 --- a/src/tools/clippy/tests/ui/result_map_or_into_option.fixed +++ b/src/tools/clippy/tests/ui/result_map_or_into_option.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_or_into_option)] diff --git a/src/tools/clippy/tests/ui/result_map_or_into_option.rs b/src/tools/clippy/tests/ui/result_map_or_into_option.rs index 3058480e2ad..eeeef830af0 100644 --- a/src/tools/clippy/tests/ui/result_map_or_into_option.rs +++ b/src/tools/clippy/tests/ui/result_map_or_into_option.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_or_into_option)] diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed index d8b56237e98..0583d29277b 100644 --- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed +++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs index 44f50d21109..7ad3bdd04bd 100644 --- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs +++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::result_map_unit_fn)] #![allow(unused)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed index c67edb36c67..30dfc977681 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs index 0a4fef5bfe8..1837249eae1 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed index 78401e463d5..a74569599c7 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs index f9e0f7fcd6d..42f9957dfbd 100644 --- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs +++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::reversed_empty_ranges)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs index e6198a1bc9a..aea1507cc5b 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs @@ -1,5 +1,5 @@ #![feature(adt_const_params)] -#![warn(clippy::same_functions_in_if_condition)] +#![deny(clippy::same_functions_in_if_condition)] // ifs_same_cond warning is different from `ifs_same_cond`. // clippy::if_same_then_else, clippy::comparison_chain -- all empty blocks #![allow(incomplete_features)] diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr index f352ade150e..aade3b1fa45 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr @@ -9,7 +9,11 @@ note: same as this | LL | if function() { | ^^^^^^^^^^ - = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings` +note: the lint level is defined here + --> $DIR/same_functions_in_if_condition.rs:2:9 + | +LL | #![deny(clippy::same_functions_in_if_condition)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has the same function call as a previous `if` --> $DIR/same_functions_in_if_condition.rs:42:15 diff --git a/src/tools/clippy/tests/ui/search_is_some.rs b/src/tools/clippy/tests/ui/search_is_some.rs index 72f335153c1..670599b0dcf 100644 --- a/src/tools/clippy/tests/ui/search_is_some.rs +++ b/src/tools/clippy/tests/ui/search_is_some.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::search_is_some)] #![allow(dead_code)] extern crate option_helpers; diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed index 5190c5304c7..9386618c123 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::explicit_auto_deref)] #![warn(clippy::search_is_some)] diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs index 310d87333a9..6b2537a96c2 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_none.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::explicit_auto_deref)] #![warn(clippy::search_is_some)] diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed index 385a9986aba..e9116fc59f1 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::explicit_auto_deref)] #![warn(clippy::search_is_some)] diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs index 67e190ee378..b1528399457 100644 --- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs +++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, clippy::explicit_auto_deref)] #![warn(clippy::search_is_some)] diff --git a/src/tools/clippy/tests/ui/seek_from_current.fixed b/src/tools/clippy/tests/ui/seek_from_current.fixed index 1309c91b81c..34c33baf686 100644 --- a/src/tools/clippy/tests/ui/seek_from_current.fixed +++ b/src/tools/clippy/tests/ui/seek_from_current.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::seek_from_current)] use std::fs::File; diff --git a/src/tools/clippy/tests/ui/seek_from_current.rs b/src/tools/clippy/tests/ui/seek_from_current.rs index 5d9b1424cf6..22bcff1bc40 100644 --- a/src/tools/clippy/tests/ui/seek_from_current.rs +++ b/src/tools/clippy/tests/ui/seek_from_current.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::seek_from_current)] use std::fs::File; diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed index dc24d447c60..d8a6e6985d4 100644 --- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed +++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::seek_to_start_instead_of_rewind)] diff --git a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs index 4adde2c4018..fc6a6433c2b 100644 --- a/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs +++ b/src/tools/clippy/tests/ui/seek_to_start_instead_of_rewind.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::seek_to_start_instead_of_rewind)] diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed index 42e97e1ca35..ee359f60cbd 100644 --- a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed +++ b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.rs b/src/tools/clippy/tests/ui/semicolon_inside_block.rs index f40848f702e..e8516f79b20 100644 --- a/src/tools/clippy/tests/ui/semicolon_inside_block.rs +++ b/src/tools/clippy/tests/ui/semicolon_inside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed index 091eaa7518e..034c7f8c7c1 100644 --- a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed +++ b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.rs b/src/tools/clippy/tests/ui/semicolon_outside_block.rs index 7ce46431fac..4dc956d8a4b 100644 --- a/src/tools/clippy/tests/ui/semicolon_outside_block.rs +++ b/src/tools/clippy/tests/ui/semicolon_outside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/src/tools/clippy/tests/ui/shadow.rs b/src/tools/clippy/tests/ui/shadow.rs index 1fa9fc749a9..03337ec3564 100644 --- a/src/tools/clippy/tests/ui/shadow.rs +++ b/src/tools/clippy/tests/ui/shadow.rs @@ -1,6 +1,13 @@ +//@aux-build:proc_macro_derive.rs + #![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)] #![allow(clippy::let_unit_value)] +extern crate proc_macro_derive; + +#[derive(proc_macro_derive::ShadowDerive)] +pub struct Nothing; + fn shadow_same() { let x = 1; let x = x; diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr index c3d7bc2a536..92bb937d086 100644 --- a/src/tools/clippy/tests/ui/shadow.stderr +++ b/src/tools/clippy/tests/ui/shadow.stderr @@ -1,278 +1,278 @@ error: `x` is shadowed by itself in `x` - --> $DIR/shadow.rs:6:9 + --> $DIR/shadow.rs:13:9 | LL | let x = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:5:9 + --> $DIR/shadow.rs:12:9 | LL | let x = 1; | ^ = note: `-D clippy::shadow-same` implied by `-D warnings` error: `mut x` is shadowed by itself in `&x` - --> $DIR/shadow.rs:7:13 + --> $DIR/shadow.rs:14:13 | LL | let mut x = &x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:6:9 + --> $DIR/shadow.rs:13:9 | LL | let x = x; | ^ error: `x` is shadowed by itself in `&mut x` - --> $DIR/shadow.rs:8:9 + --> $DIR/shadow.rs:15:9 | LL | let x = &mut x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:7:9 + --> $DIR/shadow.rs:14:9 | LL | let mut x = &x; | ^^^^^ error: `x` is shadowed by itself in `*x` - --> $DIR/shadow.rs:9:9 + --> $DIR/shadow.rs:16:9 | LL | let x = *x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:8:9 + --> $DIR/shadow.rs:15:9 | LL | let x = &mut x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:14:9 + --> $DIR/shadow.rs:21:9 | LL | let x = x.0; | ^ | note: previous binding is here - --> $DIR/shadow.rs:13:9 + --> $DIR/shadow.rs:20:9 | LL | let x = ([[0]], ()); | ^ = note: `-D clippy::shadow-reuse` implied by `-D warnings` error: `x` is shadowed - --> $DIR/shadow.rs:15:9 + --> $DIR/shadow.rs:22:9 | LL | let x = x[0]; | ^ | note: previous binding is here - --> $DIR/shadow.rs:14:9 + --> $DIR/shadow.rs:21:9 | LL | let x = x.0; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:16:10 + --> $DIR/shadow.rs:23:10 | LL | let [x] = x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:15:9 + --> $DIR/shadow.rs:22:9 | LL | let x = x[0]; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:17:9 + --> $DIR/shadow.rs:24:9 | LL | let x = Some(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:16:10 + --> $DIR/shadow.rs:23:10 | LL | let [x] = x; | ^ error: `x` is shadowed - --> $DIR/shadow.rs:18:9 + --> $DIR/shadow.rs:25:9 | LL | let x = foo(x); | ^ | note: previous binding is here - --> $DIR/shadow.rs:17:9 + --> $DIR/shadow.rs:24:9 | LL | let x = Some(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:19:9 + --> $DIR/shadow.rs:26:9 | LL | let x = || x; | ^ | note: previous binding is here - --> $DIR/shadow.rs:18:9 + --> $DIR/shadow.rs:25:9 | LL | let x = foo(x); | ^ error: `x` is shadowed - --> $DIR/shadow.rs:20:9 + --> $DIR/shadow.rs:27:9 | LL | let x = Some(1).map(|_| x)?; | ^ | note: previous binding is here - --> $DIR/shadow.rs:19:9 + --> $DIR/shadow.rs:26:9 | LL | let x = || x; | ^ error: `y` is shadowed - --> $DIR/shadow.rs:22:9 + --> $DIR/shadow.rs:29:9 | LL | let y = match y { | ^ | note: previous binding is here - --> $DIR/shadow.rs:21:9 + --> $DIR/shadow.rs:28:9 | LL | let y = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:31:9 + --> $DIR/shadow.rs:38:9 | LL | let x = 2; | ^ | note: previous binding is here - --> $DIR/shadow.rs:30:9 + --> $DIR/shadow.rs:37:9 | LL | let x = 1; | ^ = note: `-D clippy::shadow-unrelated` implied by `-D warnings` error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:36:13 + --> $DIR/shadow.rs:43:13 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:35:10 + --> $DIR/shadow.rs:42:10 | LL | fn f(x: u32) { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:41:14 + --> $DIR/shadow.rs:48:14 | LL | Some(x) => { | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 + --> $DIR/shadow.rs:45:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:42:17 + --> $DIR/shadow.rs:49:17 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:41:14 + --> $DIR/shadow.rs:48:14 | LL | Some(x) => { | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:46:17 + --> $DIR/shadow.rs:53:17 | LL | if let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 + --> $DIR/shadow.rs:45:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:47:20 + --> $DIR/shadow.rs:54:20 | LL | while let Some(x) = Some(1) {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 + --> $DIR/shadow.rs:45:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:48:15 + --> $DIR/shadow.rs:55:15 | LL | let _ = |[x]: [u32; 1]| { | ^ | note: previous binding is here - --> $DIR/shadow.rs:38:9 + --> $DIR/shadow.rs:45:9 | LL | let x = 1; | ^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:49:13 + --> $DIR/shadow.rs:56:13 | LL | let x = 1; | ^ | note: previous binding is here - --> $DIR/shadow.rs:48:15 + --> $DIR/shadow.rs:55:15 | LL | let _ = |[x]: [u32; 1]| { | ^ error: `y` is shadowed - --> $DIR/shadow.rs:52:17 + --> $DIR/shadow.rs:59:17 | LL | if let Some(y) = y {} | ^ | note: previous binding is here - --> $DIR/shadow.rs:51:9 + --> $DIR/shadow.rs:58:9 | LL | let y = Some(1); | ^ error: `_b` shadows a previous, unrelated binding - --> $DIR/shadow.rs:88:9 + --> $DIR/shadow.rs:95:9 | LL | let _b = _a; | ^^ | note: previous binding is here - --> $DIR/shadow.rs:87:28 + --> $DIR/shadow.rs:94:28 | LL | pub async fn foo2(_a: i32, _b: i64) { | ^^ error: `x` shadows a previous, unrelated binding - --> $DIR/shadow.rs:94:21 + --> $DIR/shadow.rs:101:21 | LL | if let Some(x) = Some(1) { x } else { 1 } | ^ | note: previous binding is here - --> $DIR/shadow.rs:93:13 + --> $DIR/shadow.rs:100:13 | LL | let x = 1; | ^ diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.fixed b/src/tools/clippy/tests/ui/short_circuit_statement.fixed index dd22ecab0b5..1737d501441 100644 --- a/src/tools/clippy/tests/ui/short_circuit_statement.fixed +++ b/src/tools/clippy/tests/ui/short_circuit_statement.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::short_circuit_statement)] #![allow(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.rs b/src/tools/clippy/tests/ui/short_circuit_statement.rs index 73a55bf1f5e..ab93aa1ca5c 100644 --- a/src/tools/clippy/tests/ui/short_circuit_statement.rs +++ b/src/tools/clippy/tests/ui/short_circuit_statement.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::short_circuit_statement)] #![allow(clippy::nonminimal_bool)] diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs index c65df9ece38..8c48b21f188 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![warn(clippy::significant_drop_in_scrutinee)] #![allow(dead_code, unused_assignments)] #![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.fixed b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed index da998c610bd..ee7f2b0631a 100644 --- a/src/tools/clippy/tests/ui/significant_drop_tightening.fixed +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::significant_drop_tightening)] diff --git a/src/tools/clippy/tests/ui/significant_drop_tightening.rs b/src/tools/clippy/tests/ui/significant_drop_tightening.rs index 83823f95f68..9c139deb95f 100644 --- a/src/tools/clippy/tests/ui/significant_drop_tightening.rs +++ b/src/tools/clippy/tests/ui/significant_drop_tightening.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::significant_drop_tightening)] diff --git a/src/tools/clippy/tests/ui/single_char_add_str.fixed b/src/tools/clippy/tests/ui/single_char_add_str.fixed index 63a6d37a9cc..cbcf1ab21c9 100644 --- a/src/tools/clippy/tests/ui/single_char_add_str.fixed +++ b/src/tools/clippy/tests/ui/single_char_add_str.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_char_add_str)] macro_rules! get_string { diff --git a/src/tools/clippy/tests/ui/single_char_add_str.rs b/src/tools/clippy/tests/ui/single_char_add_str.rs index a799ea7d885..a1f005cc833 100644 --- a/src/tools/clippy/tests/ui/single_char_add_str.rs +++ b/src/tools/clippy/tests/ui/single_char_add_str.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_char_add_str)] macro_rules! get_string { diff --git a/src/tools/clippy/tests/ui/single_char_pattern.fixed b/src/tools/clippy/tests/ui/single_char_pattern.fixed index 68e26726724..dba89872070 100644 --- a/src/tools/clippy/tests/ui/single_char_pattern.fixed +++ b/src/tools/clippy/tests/ui/single_char_pattern.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] diff --git a/src/tools/clippy/tests/ui/single_char_pattern.rs b/src/tools/clippy/tests/ui/single_char_pattern.rs index 186202d78ec..6a145a14bfd 100644 --- a/src/tools/clippy/tests/ui/single_char_pattern.rs +++ b/src/tools/clippy/tests/ui/single_char_pattern.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.fixed b/src/tools/clippy/tests/ui/single_component_path_imports.fixed index 8c96c4715d3..d4d2cbbe57a 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports.fixed +++ b/src/tools/clippy/tests/ui/single_component_path_imports.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] diff --git a/src/tools/clippy/tests/ui/single_component_path_imports.rs b/src/tools/clippy/tests/ui/single_component_path_imports.rs index 8434bf7eaf1..80d72115f43 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports.rs +++ b/src/tools/clippy/tests/ui/single_component_path_imports.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::single_component_path_imports)] #![allow(unused_imports)] diff --git a/src/tools/clippy/tests/ui/single_element_loop.fixed b/src/tools/clippy/tests/ui/single_element_loop.fixed index a0dcc0172e8..1697a0cf29b 100644 --- a/src/tools/clippy/tests/ui/single_element_loop.fixed +++ b/src/tools/clippy/tests/ui/single_element_loop.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // Tests from for_loop.rs that don't have suggestions #[warn(clippy::single_element_loop)] diff --git a/src/tools/clippy/tests/ui/single_element_loop.rs b/src/tools/clippy/tests/ui/single_element_loop.rs index bc014035c98..860424f42dd 100644 --- a/src/tools/clippy/tests/ui/single_element_loop.rs +++ b/src/tools/clippy/tests/ui/single_element_loop.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // Tests from for_loop.rs that don't have suggestions #[warn(clippy::single_element_loop)] diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs index 3c86f41f3a6..c8ac768b60f 100644 --- a/src/tools/clippy/tests/ui/single_match_else.rs +++ b/src/tools/clippy/tests/ui/single_match_else.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macros.rs +//@aux-build: proc_macros.rs #![warn(clippy::single_match_else)] #![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/skip_while_next.rs b/src/tools/clippy/tests/ui/skip_while_next.rs index a551c19d98b..62574e2c8ce 100644 --- a/src/tools/clippy/tests/ui/skip_while_next.rs +++ b/src/tools/clippy/tests/ui/skip_while_next.rs @@ -1,4 +1,4 @@ -// aux-build:option_helpers.rs +//@aux-build:option_helpers.rs #![warn(clippy::skip_while_next)] #![allow(clippy::disallowed_names)] diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.fixed b/src/tools/clippy/tests/ui/stable_sort_primitive.fixed index f5f18169df2..1370dd2df4d 100644 --- a/src/tools/clippy/tests/ui/stable_sort_primitive.fixed +++ b/src/tools/clippy/tests/ui/stable_sort_primitive.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::stable_sort_primitive)] fn main() { diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.rs b/src/tools/clippy/tests/ui/stable_sort_primitive.rs index 8149c5638e0..cd344dd1238 100644 --- a/src/tools/clippy/tests/ui/stable_sort_primitive.rs +++ b/src/tools/clippy/tests/ui/stable_sort_primitive.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::stable_sort_primitive)] fn main() { diff --git a/src/tools/clippy/tests/ui/starts_ends_with.fixed b/src/tools/clippy/tests/ui/starts_ends_with.fixed index 983fac7afe6..29d56f852ed 100644 --- a/src/tools/clippy/tests/ui/starts_ends_with.fixed +++ b/src/tools/clippy/tests/ui/starts_ends_with.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_must_use)] fn main() {} diff --git a/src/tools/clippy/tests/ui/starts_ends_with.rs b/src/tools/clippy/tests/ui/starts_ends_with.rs index e3335dd2e2e..56bbe2574d4 100644 --- a/src/tools/clippy/tests/ui/starts_ends_with.rs +++ b/src/tools/clippy/tests/ui/starts_ends_with.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_must_use)] fn main() {} diff --git a/src/tools/clippy/tests/ui/string_add.rs b/src/tools/clippy/tests/ui/string_add.rs index 20edbe31fa9..de78dfe4d69 100644 --- a/src/tools/clippy/tests/ui/string_add.rs +++ b/src/tools/clippy/tests/ui/string_add.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs extern crate proc_macros; use proc_macros::external; diff --git a/src/tools/clippy/tests/ui/string_add_assign.fixed b/src/tools/clippy/tests/ui/string_add_assign.fixed index b687f43b254..616c6daaf66 100644 --- a/src/tools/clippy/tests/ui/string_add_assign.fixed +++ b/src/tools/clippy/tests/ui/string_add_assign.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::string_add, unused)] #[warn(clippy::string_add_assign)] diff --git a/src/tools/clippy/tests/ui/string_add_assign.rs b/src/tools/clippy/tests/ui/string_add_assign.rs index e5dbde108fb..e1f8859757c 100644 --- a/src/tools/clippy/tests/ui/string_add_assign.rs +++ b/src/tools/clippy/tests/ui/string_add_assign.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[allow(clippy::string_add, unused)] #[warn(clippy::string_add_assign)] diff --git a/src/tools/clippy/tests/ui/string_extend.fixed b/src/tools/clippy/tests/ui/string_extend.fixed index d200d7310fc..65c9abff3d4 100644 --- a/src/tools/clippy/tests/ui/string_extend.fixed +++ b/src/tools/clippy/tests/ui/string_extend.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[derive(Copy, Clone)] struct HasChars; diff --git a/src/tools/clippy/tests/ui/string_extend.rs b/src/tools/clippy/tests/ui/string_extend.rs index 0dd96a3b210..5f72ffe2fda 100644 --- a/src/tools/clippy/tests/ui/string_extend.rs +++ b/src/tools/clippy/tests/ui/string_extend.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #[derive(Copy, Clone)] struct HasChars; diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed index 6e665cdd563..9b315ae2b55 100644 --- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed +++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::string_from_utf8_as_bytes)] fn main() { diff --git a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs index 670d206d367..043dd235082 100644 --- a/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs +++ b/src/tools/clippy/tests/ui/string_from_utf8_as_bytes.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::string_from_utf8_as_bytes)] fn main() { diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed index 506187fc125..058f2aa54da 100644 --- a/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed +++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] diff --git a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs index 2c339f1ddb8..b550bea001f 100644 --- a/src/tools/clippy/tests/ui/string_lit_as_bytes.rs +++ b/src/tools/clippy/tests/ui/string_lit_as_bytes.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::string_lit_as_bytes)] diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed index 947a59bcc02..ef207e28cca 100644 --- a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed +++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs index 1237f1ab03a..03ec5f79d09 100644 --- a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs +++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::strlen_on_c_strings)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed index b404df94d3c..bffda1cc412 100644 --- a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs index 46eff51e220..cdd972ee30f 100644 --- a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::suspicious_doc_comments)] diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs index 21753e5dc6a..e0153cdd8cd 100644 --- a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs +++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_suspicious_else_formatting.rs +//@aux-build:proc_macro_suspicious_else_formatting.rs #![warn(clippy::suspicious_else_formatting)] #![allow(clippy::if_same_then_else, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed index ede8a39fed7..0e37701ec48 100644 --- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed +++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suspicious_operation_groupings)] #![allow(dead_code, unused_parens, clippy::eq_op)] diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs index 26ce97bb37f..dd4f3b71c37 100644 --- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs +++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::suspicious_operation_groupings)] #![allow(dead_code, unused_parens, clippy::eq_op)] diff --git a/src/tools/clippy/tests/ui/swap.fixed b/src/tools/clippy/tests/ui/swap.fixed index 9703674d1a4..fd3569cf362 100644 --- a/src/tools/clippy/tests/ui/swap.fixed +++ b/src/tools/clippy/tests/ui/swap.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: macro_rules.rs +//@run-rustfix +//@aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( diff --git a/src/tools/clippy/tests/ui/swap.rs b/src/tools/clippy/tests/ui/swap.rs index a0228065e46..34fbce0524b 100644 --- a/src/tools/clippy/tests/ui/swap.rs +++ b/src/tools/clippy/tests/ui/swap.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: macro_rules.rs +//@run-rustfix +//@aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed b/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed index 596b6ee919b..3bede3017a1 100644 --- a/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed +++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::swap_ptr_to_ref)] diff --git a/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs b/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs index 282f571211d..726b09d3764 100644 --- a/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs +++ b/src/tools/clippy/tests/ui/swap_ptr_to_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::swap_ptr_to_ref)] diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed index 4bc4bc86c76..21020182c24 100644 --- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed +++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::tabs_in_doc_comments)] #[allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs index 9db3416e659..df704267dd2 100644 --- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs +++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::tabs_in_doc_comments)] #[allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/tests_outside_test_module.rs b/src/tools/clippy/tests/ui/tests_outside_test_module.rs index 1982b1d0107..21fdfdf9005 100644 --- a/src/tools/clippy/tests/ui/tests_outside_test_module.rs +++ b/src/tools/clippy/tests/ui/tests_outside_test_module.rs @@ -1,4 +1,4 @@ -// compile-flags: --test +//@compile-flags: --test #![allow(unused)] #![warn(clippy::tests_outside_test_module)] diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.fixed b/src/tools/clippy/tests/ui/to_digit_is_some.fixed index 3c5e9642714..dc9be66d48a 100644 --- a/src/tools/clippy/tests/ui/to_digit_is_some.fixed +++ b/src/tools/clippy/tests/ui/to_digit_is_some.fixed @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::to_digit_is_some)] diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.rs b/src/tools/clippy/tests/ui/to_digit_is_some.rs index 4f247c06cee..d2a09ac30de 100644 --- a/src/tools/clippy/tests/ui/to_digit_is_some.rs +++ b/src/tools/clippy/tests/ui/to_digit_is_some.rs @@ -1,4 +1,4 @@ -//run-rustfix +//@run-rustfix #![warn(clippy::to_digit_is_some)] diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed index 174c858a47d..ea30c1fda6f 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs index 4b81a06112f..7a3d33e5be5 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg.rs +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] #![allow(clippy::uninlined_format_args, unused)] diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs index 2047593e7e4..8aaf47b1bd0 100644 --- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs index fa9221ed02d..6ab0bce770e 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.rs +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -1,9 +1,8 @@ -// compile-flags: -Z track-diagnostics -// error-pattern: created at +//@compile-flags: -Z track-diagnostics // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. -// normalize-stderr-test ".rs:\d+:\d+" -> ".rs:LL:CC" +//@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" struct A; struct B; diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed index 4ce5d421782..eef8024b131 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs index 7f2e96a22e6..a7a1caf2880 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::trait_duplication_in_bounds)] #![allow(unused)] diff --git a/src/tools/clippy/tests/ui/transmute_32bit.rs b/src/tools/clippy/tests/ui/transmute_32bit.rs index ffe22b12f55..8e1316ca39d 100644 --- a/src/tools/clippy/tests/ui/transmute_32bit.rs +++ b/src/tools/clippy/tests/ui/transmute_32bit.rs @@ -1,4 +1,4 @@ -// ignore-64bit +//@ignore-64bit #[warn(clippy::wrong_transmute)] fn main() { diff --git a/src/tools/clippy/tests/ui/transmute_32bit.stderr b/src/tools/clippy/tests/ui/transmute_32bit.stderr index 040519564b9..75ddca60d2a 100644 --- a/src/tools/clippy/tests/ui/transmute_32bit.stderr +++ b/src/tools/clippy/tests/ui/transmute_32bit.stderr @@ -1,28 +1,39 @@ -error: transmute from a `f32` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:6:31 | LL | let _: *const usize = std::mem::transmute(6.0f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::wrong-transmute` implied by `-D warnings` + = note: source type: `f32` (32 bits) + = note: target type: `*const usize` (64 bits) -error: transmute from a `f32` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:8:29 | LL | let _: *mut usize = std::mem::transmute(6.0f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `f32` (32 bits) + = note: target type: `*mut usize` (64 bits) -error: transmute from a `char` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:10:31 | LL | let _: *const usize = std::mem::transmute('x'); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `char` (32 bits) + = note: target type: `*const usize` (64 bits) -error: transmute from a `char` to a pointer +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types --> $DIR/transmute_32bit.rs:12:29 | LL | let _: *mut usize = std::mem::transmute('x'); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `char` (32 bits) + = note: target type: `*mut usize` (64 bits) error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0512`. diff --git a/src/tools/clippy/tests/ui/transmute_64bit.rs b/src/tools/clippy/tests/ui/transmute_64bit.rs index 00dc0b2c360..ceecf9b279f 100644 --- a/src/tools/clippy/tests/ui/transmute_64bit.rs +++ b/src/tools/clippy/tests/ui/transmute_64bit.rs @@ -1,4 +1,4 @@ -// ignore-32bit +//@ignore-32bit #[warn(clippy::wrong_transmute)] fn main() { diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed index 074dae5fb28..575dadde906 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmute_ptr_to_ref)] #![allow(clippy::match_single_binding)] diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs index 2edc122cf47..4238ff80478 100644 --- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs +++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmute_ptr_to_ref)] #![allow(clippy::match_single_binding)] diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed index cc84ba25bd0..05aa86c479a 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmutes_expressible_as_ptr_casts)] // These two warnings currently cover the cases transmutes_expressible_as_ptr_casts // would otherwise be responsible for diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs index aa65ab4dd24..29fa6914cfd 100644 --- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs +++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::transmutes_expressible_as_ptr_casts)] // These two warnings currently cover the cases transmutes_expressible_as_ptr_casts // would otherwise be responsible for diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.fixed b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed index e4d352f7367..7909b319ddd 100644 --- a/src/tools/clippy/tests/ui/trim_split_whitespace.fixed +++ b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::trim_split_whitespace)] #![allow(clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.rs b/src/tools/clippy/tests/ui/trim_split_whitespace.rs index f98451a9837..0cf58979fb2 100644 --- a/src/tools/clippy/tests/ui/trim_split_whitespace.rs +++ b/src/tools/clippy/tests/ui/trim_split_whitespace.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::trim_split_whitespace)] #![allow(clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs index c0af011d33d..48615583156 100644 --- a/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs +++ b/src/tools/clippy/tests/ui/trivially_copy_pass_by_ref.rs @@ -1,5 +1,5 @@ -// normalize-stderr-test "\(\d+ byte\)" -> "(N byte)" -// normalize-stderr-test "\(limit: \d+ byte\)" -> "(limit: N byte)" +//@normalize-stderr-test: "\(\d+ byte\)" -> "(N byte)" +//@normalize-stderr-test: "\(limit: \d+ byte\)" -> "(limit: N byte)" #![deny(clippy::trivially_copy_pass_by_ref)] #![allow( clippy::disallowed_names, diff --git a/src/tools/clippy/tests/ui/try_err.fixed b/src/tools/clippy/tests/ui/try_err.fixed index dc497b1690f..dc773ad4bad 100644 --- a/src/tools/clippy/tests/ui/try_err.fixed +++ b/src/tools/clippy/tests/ui/try_err.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] diff --git a/src/tools/clippy/tests/ui/try_err.rs b/src/tools/clippy/tests/ui/try_err.rs index 86aeb75cd96..7a7433a7ec2 100644 --- a/src/tools/clippy/tests/ui/try_err.rs +++ b/src/tools/clippy/tests/ui/try_err.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] diff --git a/src/tools/clippy/tests/ui/types.fixed b/src/tools/clippy/tests/ui/types.fixed index 417da42edf1..4a2616a7a22 100644 --- a/src/tools/clippy/tests/ui/types.fixed +++ b/src/tools/clippy/tests/ui/types.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/types.rs b/src/tools/clippy/tests/ui/types.rs index b16e9e538b1..5e0917907db 100644 --- a/src/tools/clippy/tests/ui/types.rs +++ b/src/tools/clippy/tests/ui/types.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code, unused_variables)] #![warn(clippy::cast_lossless)] diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed index a0e49a8beb1..757d1592184 100644 --- a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed +++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unchecked_duration_subtraction)] use std::time::{Duration, Instant}; diff --git a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs index a14a7ea57cc..da7faab6753 100644 --- a/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs +++ b/src/tools/clippy/tests/ui/unchecked_duration_subtraction.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unchecked_duration_subtraction)] use std::time::{Duration, Instant}; diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs index c05eb447b2e..229d150851a 100644 --- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs +++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_unsafe.rs +//@aux-build:proc_macro_unsafe.rs #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] #![allow(clippy::let_unit_value, clippy::missing_safety_doc)] diff --git a/src/tools/clippy/tests/ui/unicode.fixed b/src/tools/clippy/tests/ui/unicode.fixed index 94b4723452f..910968afa7f 100644 --- a/src/tools/clippy/tests/ui/unicode.fixed +++ b/src/tools/clippy/tests/ui/unicode.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// compile-flags: --test +//@run-rustfix +//@compile-flags: --test #![allow(dead_code)] #[warn(clippy::invisible_characters)] diff --git a/src/tools/clippy/tests/ui/unicode.rs b/src/tools/clippy/tests/ui/unicode.rs index 6ad0b255b94..bc4b84d3435 100644 --- a/src/tools/clippy/tests/ui/unicode.rs +++ b/src/tools/clippy/tests/ui/unicode.rs @@ -1,5 +1,5 @@ -// run-rustfix -// compile-flags: --test +//@run-rustfix +//@compile-flags: --test #![allow(dead_code)] #[warn(clippy::invisible_characters)] diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.fixed b/src/tools/clippy/tests/ui/uninlined_format_args.fixed index 3122081a44f..e25d123dd51 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args.fixed @@ -1,5 +1,5 @@ -// aux-build:proc_macros.rs -// run-rustfix +//@aux-build:proc_macros.rs +//@run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] diff --git a/src/tools/clippy/tests/ui/uninlined_format_args.rs b/src/tools/clippy/tests/ui/uninlined_format_args.rs index b153ef256e0..6793ec24441 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args.rs +++ b/src/tools/clippy/tests/ui/uninlined_format_args.rs @@ -1,5 +1,5 @@ -// aux-build:proc_macros.rs -// run-rustfix +//@aux-build:proc_macros.rs +//@run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed index 52b5343c351..559050b3df6 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2018.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed index ee72065e28a..3a753b49caf 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed +++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.edition2021.fixed @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs b/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs index b4a0a0f496e..83fbb9afd2a 100644 --- a/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs +++ b/src/tools/clippy/tests/ui/uninlined_format_args_panic.rs @@ -1,7 +1,7 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix #![warn(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs index 674ae4f1df9..d082063c8e8 100644 --- a/src/tools/clippy/tests/ui/unit_arg.rs +++ b/src/tools/clippy/tests/ui/unit_arg.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macros.rs +//@aux-build: proc_macros.rs #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow( diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed index 5787471a32c..8c065115a74 100644 --- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed +++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow(clippy::no_effect, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs index 6a42c2ccf42..af166b56ff4 100644 --- a/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs +++ b/src/tools/clippy/tests/ui/unit_arg_empty_blocks.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow(clippy::no_effect, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed index 4249ff8a958..0c269d650c8 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::pedantic)] // Should suggest lowercase diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs index 5db345f5444..b60042923ea 100644 --- a/src/tools/clippy/tests/ui/unknown_clippy_lints.rs +++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::pedantic)] // Should suggest lowercase diff --git a/src/tools/clippy/tests/ui/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs index fe60d929759..ce7cc2e97cb 100644 --- a/src/tools/clippy/tests/ui/unnecessary_box_returns.rs +++ b/src/tools/clippy/tests/ui/unnecessary_box_returns.rs @@ -54,6 +54,16 @@ fn string() -> String { String::from("Hello, world") } +struct Huge([u8; 500]); +struct HasHuge(Box<Huge>); + +impl HasHuge { + // don't lint: The size of `Huge` is very large + fn into_huge(self) -> Box<Huge> { + self.0 + } +} + fn main() { // don't lint: this is a closure let a = || -> Box<usize> { Box::new(5) }; diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed index 2f7e2997e73..bcc231ea7bc 100644 --- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_cast)] #![allow( unused_must_use, diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs index 54dd46ba59f..282b2f1283e 100644 --- a/src/tools/clippy/tests/ui/unnecessary_cast.rs +++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_cast)] #![allow( unused_must_use, diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.fixed b/src/tools/clippy/tests/ui/unnecessary_fold.fixed index 52300a3b640..2bed14973ca 100644 --- a/src/tools/clippy/tests/ui/unnecessary_fold.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_fold.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.rs b/src/tools/clippy/tests/ui/unnecessary_fold.rs index 4028d80c0a3..a3cec8ea3d5 100644 --- a/src/tools/clippy/tests/ui/unnecessary_fold.rs +++ b/src/tools/clippy/tests/ui/unnecessary_fold.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed index e01e9f07baf..a0f8dd1a200 100644 --- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments)] #![warn(clippy::unnecessary_to_owned)] diff --git a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs index 6ef2966c8b7..98f2dfe7549 100644 --- a/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs +++ b/src/tools/clippy/tests/ui/unnecessary_iter_cloned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_assignments)] #![warn(clippy::unnecessary_to_owned)] diff --git a/src/tools/clippy/tests/ui/unnecessary_join.fixed b/src/tools/clippy/tests/ui/unnecessary_join.fixed index 34795396025..e102df62599 100644 --- a/src/tools/clippy/tests/ui/unnecessary_join.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_join.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_join)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/unnecessary_join.rs b/src/tools/clippy/tests/ui/unnecessary_join.rs index 344918cd2a2..b87c15bc126 100644 --- a/src/tools/clippy/tests/ui/unnecessary_join.rs +++ b/src/tools/clippy/tests/ui/unnecessary_join.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_join)] #![allow(clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed index 3b93800f8b7..c3728886ec9 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs index 2851c0c5190..76e50fa5b03 100644 --- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs +++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build: proc_macros.rs +//@run-rustfix +//@aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed index b046694f8c6..fbd2d34591f 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::deref_addrof, diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs index 9ed9679e938..b45298a6dc4 100644 --- a/src/tools/clippy/tests/ui/unnecessary_operation.rs +++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( clippy::deref_addrof, diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed index 40052c41039..af12fd1d63d 100644 --- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_owned_empty_strings)] diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs index 2304dff5192..a460b21af8c 100644 --- a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs +++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_owned_empty_strings)] diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed b/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed index 1185eaa1d55..7fc978d3ef7 100644 --- a/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_self_imports)] #![allow(unused_imports, dead_code)] diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.rs b/src/tools/clippy/tests/ui/unnecessary_self_imports.rs index 56bfbc09402..02424bc12b0 100644 --- a/src/tools/clippy/tests/ui/unnecessary_self_imports.rs +++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unnecessary_self_imports)] #![allow(unused_imports, dead_code)] diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed index 21e2da474a8..165cabd8298 100644 --- a/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::stable_sort_primitive)] diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs index 3365bf6e119..8a2158d5a84 100644 --- a/src/tools/clippy/tests/ui/unnecessary_sort_by.rs +++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::stable_sort_primitive)] diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed index b47129e4a36..bdf746cf2c4 100644 --- a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::unnecessary_struct_initialization)] diff --git a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs index 63b11c626e5..7271e2f957a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs +++ b/src/tools/clippy/tests/ui/unnecessary_struct_initialization.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused)] #![warn(clippy::unnecessary_struct_initialization)] diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed index 345f6d604c4..c879fdc3b6a 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::needless_borrow, clippy::ptr_arg)] #![warn(clippy::unnecessary_to_owned)] diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs index 7eb53df39e5..10588beb263 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(clippy::needless_borrow, clippy::ptr_arg)] #![warn(clippy::unnecessary_to_owned)] diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs index 431093ab369..373b18470f6 100644 --- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs +++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macros.rs +//@aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] #![warn(clippy::unnecessary_safety_doc)] diff --git a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed index 12c3461c955..16c2de760e5 100644 --- a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed +++ b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![deny(clippy::unneeded_wildcard_pattern)] diff --git a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs index 4ac01d5d23b..9d9eae1d903 100644 --- a/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs +++ b/src/tools/clippy/tests/ui/unneeded_wildcard_pattern.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(stmt_expr_attributes)] #![deny(clippy::unneeded_wildcard_pattern)] diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed index 0a8e7b34dfa..8ec35ba4eea 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs index 2c454adfe89..efdb91b2402 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs +++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed index d3539d79815..de40e936747 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs index 9cea5cdea69..87f66d26c46 100644 --- a/src/tools/clippy/tests/ui/unnested_or_patterns2.rs +++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(box_patterns)] #![warn(clippy::unnested_or_patterns)] diff --git a/src/tools/clippy/tests/ui/unreadable_literal.fixed b/src/tools/clippy/tests/ui/unreadable_literal.fixed index 13e5feb1926..f5e87648a23 100644 --- a/src/tools/clippy/tests/ui/unreadable_literal.fixed +++ b/src/tools/clippy/tests/ui/unreadable_literal.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unreadable_literal)] #![allow(unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/unreadable_literal.rs b/src/tools/clippy/tests/ui/unreadable_literal.rs index 82f04e7ced5..426bdf7d732 100644 --- a/src/tools/clippy/tests/ui/unreadable_literal.rs +++ b/src/tools/clippy/tests/ui/unreadable_literal.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unreadable_literal)] #![allow(unused_tuple_struct_fields)] diff --git a/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed b/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed index f0c2ba7ccdf..b6241612d9d 100644 --- a/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed +++ b/src/tools/clippy/tests/ui/unseparated_prefix_literals.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![warn(clippy::unseparated_literal_suffix)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs b/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs index f44880b4147..ae583f4bde3 100644 --- a/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs +++ b/src/tools/clippy/tests/ui/unseparated_prefix_literals.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![warn(clippy::unseparated_literal_suffix)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/unused_rounding.fixed b/src/tools/clippy/tests/ui/unused_rounding.fixed index f6f734c05ed..f02b55502a0 100644 --- a/src/tools/clippy/tests/ui/unused_rounding.fixed +++ b/src/tools/clippy/tests/ui/unused_rounding.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unused_rounding)] fn main() { diff --git a/src/tools/clippy/tests/ui/unused_rounding.rs b/src/tools/clippy/tests/ui/unused_rounding.rs index a0267d8144a..c7bd4906d0b 100644 --- a/src/tools/clippy/tests/ui/unused_rounding.rs +++ b/src/tools/clippy/tests/ui/unused_rounding.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unused_rounding)] fn main() { diff --git a/src/tools/clippy/tests/ui/unused_unit.fixed b/src/tools/clippy/tests/ui/unused_unit.fixed index 3dd640b86f0..7b8f7847dbf 100644 --- a/src/tools/clippy/tests/ui/unused_unit.fixed +++ b/src/tools/clippy/tests/ui/unused_unit.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/src/tools/clippy/tests/ui/unused_unit.rs b/src/tools/clippy/tests/ui/unused_unit.rs index bddecf06fb7..fdde1ecadf0 100644 --- a/src/tools/clippy/tests/ui/unused_unit.rs +++ b/src/tools/clippy/tests/ui/unused_unit.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix // The output for humans should just highlight the whole span without showing // the suggested replacement, but we also want to test that suggested diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed index 84f779569ff..59a0ca3f192 100644 --- a/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed +++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unwrap_or_else_default)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs index 1735bd5808e..97cafa336ed 100644 --- a/src/tools/clippy/tests/ui/unwrap_or_else_default.rs +++ b/src/tools/clippy/tests/ui/unwrap_or_else_default.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::unwrap_or_else_default)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed index 3ac6217312a..89ea14759b7 100644 --- a/src/tools/clippy/tests/ui/use_self.fixed +++ b/src/tools/clippy/tests/ui/use_self.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![warn(clippy::use_self)] #![allow(dead_code, unreachable_code)] diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs index 9dc5d1e3f9b..49e5bcb7ed9 100644 --- a/src/tools/clippy/tests/ui/use_self.rs +++ b/src/tools/clippy/tests/ui/use_self.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![warn(clippy::use_self)] #![allow(dead_code, unreachable_code)] diff --git a/src/tools/clippy/tests/ui/use_self_trait.fixed b/src/tools/clippy/tests/ui/use_self_trait.fixed index 4e779308d02..4623aeeb0eb 100644 --- a/src/tools/clippy/tests/ui/use_self_trait.fixed +++ b/src/tools/clippy/tests/ui/use_self_trait.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::use_self)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/use_self_trait.rs b/src/tools/clippy/tests/ui/use_self_trait.rs index 325dc73b21e..d7d76dd9623 100644 --- a/src/tools/clippy/tests/ui/use_self_trait.rs +++ b/src/tools/clippy/tests/ui/use_self_trait.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::use_self)] #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs index 8c29e15b145..c672eff1c27 100644 --- a/src/tools/clippy/tests/ui/used_underscore_binding.rs +++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs @@ -1,4 +1,4 @@ -// aux-build:proc_macro_derive.rs +//@aux-build:proc_macro_derive.rs #![feature(rustc_private)] #![warn(clippy::all)] #![warn(clippy::used_underscore_binding)] diff --git a/src/tools/clippy/tests/ui/useless_asref.fixed b/src/tools/clippy/tests/ui/useless_asref.fixed index 38e4b9201e6..490d36ae6d6 100644 --- a/src/tools/clippy/tests/ui/useless_asref.fixed +++ b/src/tools/clippy/tests/ui/useless_asref.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_asref)] #![allow(clippy::explicit_auto_deref, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/useless_asref.rs b/src/tools/clippy/tests/ui/useless_asref.rs index f1e83f9d396..f2681af924d 100644 --- a/src/tools/clippy/tests/ui/useless_asref.rs +++ b/src/tools/clippy/tests/ui/useless_asref.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_asref)] #![allow(clippy::explicit_auto_deref, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed index 871e4fb5c3a..de6660c95e6 100644 --- a/src/tools/clippy/tests/ui/useless_attribute.fixed +++ b/src/tools/clippy/tests/ui/useless_attribute.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![allow(unused)] #![warn(clippy::useless_attribute)] diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs index cb50736ba39..8de4331e8a6 100644 --- a/src/tools/clippy/tests/ui/useless_attribute.rs +++ b/src/tools/clippy/tests/ui/useless_attribute.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:proc_macro_derive.rs +//@run-rustfix +//@aux-build:proc_macro_derive.rs #![allow(unused)] #![warn(clippy::useless_attribute)] diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed index 94b206d8e58..01eb6c5b080 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.fixed +++ b/src/tools/clippy/tests/ui/useless_conversion.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_conversion)] #![allow(clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs index c7ae927941b..34b43a6299b 100644 --- a/src/tools/clippy/tests/ui/useless_conversion.rs +++ b/src/tools/clippy/tests/ui/useless_conversion.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![deny(clippy::useless_conversion)] #![allow(clippy::unnecessary_wraps)] diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed index 2518d804915..d77a4dd8e0b 100644 --- a/src/tools/clippy/tests/ui/vec.fixed +++ b/src/tools/clippy/tests/ui/vec.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_vec)] #![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs index e1492e2f3ae..dfed3a29a03 100644 --- a/src/tools/clippy/tests/ui/vec.rs +++ b/src/tools/clippy/tests/ui/vec.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::useless_vec)] #![allow(clippy::nonstandard_macro_braces, clippy::uninlined_format_args)] diff --git a/src/tools/clippy/tests/ui/vec_box_sized.fixed b/src/tools/clippy/tests/ui/vec_box_sized.fixed index a40d91fdb18..0d0f710b558 100644 --- a/src/tools/clippy/tests/ui/vec_box_sized.fixed +++ b/src/tools/clippy/tests/ui/vec_box_sized.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/vec_box_sized.rs b/src/tools/clippy/tests/ui/vec_box_sized.rs index 843bbb64e71..fd3a7543ee1 100644 --- a/src/tools/clippy/tests/ui/vec_box_sized.rs +++ b/src/tools/clippy/tests/ui/vec_box_sized.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(dead_code)] diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed index 5afa0a89f82..c2f216a8911 100644 --- a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed +++ b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::while_let_on_iterator)] #![allow(dead_code, unreachable_code, unused_mut)] #![allow( diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.rs b/src/tools/clippy/tests/ui/while_let_on_iterator.rs index 3de586c9d8f..971bd5f0c4a 100644 --- a/src/tools/clippy/tests/ui/while_let_on_iterator.rs +++ b/src/tools/clippy/tests/ui/while_let_on_iterator.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![warn(clippy::while_let_on_iterator)] #![allow(dead_code, unreachable_code, unused_mut)] #![allow( diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed index 293bf75a717..ccb40acfbe1 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.fixed @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:non-exhaustive-enum.rs +//@run-rustfix +//@aux-build:non-exhaustive-enum.rs #![deny(clippy::wildcard_enum_match_arm)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow( diff --git a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs index decd86165f3..3ce00b021a5 100644 --- a/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs +++ b/src/tools/clippy/tests/ui/wildcard_enum_match_arm.rs @@ -1,5 +1,5 @@ -// run-rustfix -// aux-build:non-exhaustive-enum.rs +//@run-rustfix +//@aux-build:non-exhaustive-enum.rs #![deny(clippy::wildcard_enum_match_arm)] #![allow(dead_code, unreachable_code, unused_variables)] #![allow( diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed index 0baec6f0b64..bd845361fa8 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed @@ -1,6 +1,6 @@ -// edition:2015 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@edition:2015 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs // the 2015 edition here is needed because edition 2018 changed the module system // (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint diff --git a/src/tools/clippy/tests/ui/wildcard_imports.rs b/src/tools/clippy/tests/ui/wildcard_imports.rs index db591d56ab4..fb51f7bdfcc 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports.rs +++ b/src/tools/clippy/tests/ui/wildcard_imports.rs @@ -1,6 +1,6 @@ -// edition:2015 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@edition:2015 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs // the 2015 edition here is needed because edition 2018 changed the module system // (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed index 6d534a10edc..3aea013fb3a 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed index 6d534a10edc..3aea013fb3a 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs index b5ed58e6813..40c2d07527d 100644 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs +++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs @@ -1,8 +1,8 @@ -// revisions: edition2018 edition2021 -//[edition2018] edition:2018 -//[edition2021] edition:2021 -// run-rustfix -// aux-build:wildcard_imports_helper.rs +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +//@run-rustfix +//@aux-build:wildcard_imports_helper.rs #![warn(clippy::wildcard_imports)] #![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)] diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.stderr deleted file mode 100644 index 92f6d31530f..00000000000 --- a/src/tools/clippy/tests/ui/wildcard_imports_2021.stderr +++ /dev/null @@ -1,132 +0,0 @@ -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:9:5 - | -LL | use crate::fn_mod::*; - | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` - | - = note: `-D clippy::wildcard-imports` implied by `-D warnings` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:10:5 - | -LL | use crate::mod_mod::*; - | ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:11:5 - | -LL | use crate::multi_fn_mod::*; - | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:12:5 - | -LL | use crate::struct_mod::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:15:5 - | -LL | use wildcard_imports_helper::inner::inner_for_self_import::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:17:5 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:87:13 - | -LL | use crate::fn_mod::*; - | ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:93:75 - | -LL | use wildcard_imports_helper::inner::inner_for_self_import::{self, *}; - | ^ help: try: `inner_extern_foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:94:13 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:105:20 - | -LL | use self::{inner::*, inner2::*}; - | ^^^^^^^^ help: try: `inner::inner_foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:105:30 - | -LL | use self::{inner::*, inner2::*}; - | ^^^^^^^^^ help: try: `inner2::inner_bar` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:112:13 - | -LL | use wildcard_imports_helper::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:141:9 - | -LL | use crate::in_fn_test::*; - | ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:150:9 - | -LL | use crate:: in_fn_test:: * ; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:151:9 - | -LL | use crate:: fn_mod:: - | _________^ -LL | | *; - | |_________^ help: try: `crate:: fn_mod::foo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:162:13 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:197:17 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::insidefoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:205:13 - | -LL | use crate::super_imports::*; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:214:17 - | -LL | use super::super::*; - | ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:223:13 - | -LL | use super::super::super_imports::*; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo` - -error: usage of wildcard import - --> $DIR/wildcard_imports_2021.rs:231:13 - | -LL | use super::*; - | ^^^^^^^^ help: try: `super::foofoo` - -error: aborting due to 21 previous errors - diff --git a/src/tools/clippy/tests/ui/write_with_newline.rs b/src/tools/clippy/tests/ui/write_with_newline.rs index b79364c8758..35bd9e7f3a0 100644 --- a/src/tools/clippy/tests/ui/write_with_newline.rs +++ b/src/tools/clippy/tests/ui/write_with_newline.rs @@ -1,5 +1,5 @@ // FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934 -// // run-rustfix +// #![allow(clippy::write_literal)] #![warn(clippy::write_with_newline)] @@ -54,7 +54,7 @@ fn main() { // Don't warn on CRLF (#4208) write!(v, "\r\n"); write!(v, "foo\r\n"); - write!(v, "\\r\n"); //~ ERROR + write!(v, "\\r\n"); write!(v, "foo\rbar\n"); // Ignore expanded format strings diff --git a/src/tools/clippy/tests/ui/write_with_newline.stderr b/src/tools/clippy/tests/ui/write_with_newline.stderr index 2baaea166d8..9035275b29d 100644 --- a/src/tools/clippy/tests/ui/write_with_newline.stderr +++ b/src/tools/clippy/tests/ui/write_with_newline.stderr @@ -106,13 +106,13 @@ LL ~ v error: using `write!()` with a format string that ends in a single newline --> $DIR/write_with_newline.rs:57:5 | -LL | write!(v, "/r/n"); //~ ERROR +LL | write!(v, "/r/n"); | ^^^^^^^^^^^^^^^^^^ | help: use `writeln!` instead | -LL - write!(v, "/r/n"); //~ ERROR -LL + writeln!(v, "/r"); //~ ERROR +LL - write!(v, "/r/n"); +LL + writeln!(v, "/r"); | error: aborting due to 9 previous errors diff --git a/src/tools/clippy/tests/ui/writeln_empty_string.fixed b/src/tools/clippy/tests/ui/writeln_empty_string.fixed index e7d94acd130..45dedd9ead6 100644 --- a/src/tools/clippy/tests/ui/writeln_empty_string.fixed +++ b/src/tools/clippy/tests/ui/writeln_empty_string.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::writeln_empty_string)] diff --git a/src/tools/clippy/tests/ui/writeln_empty_string.rs b/src/tools/clippy/tests/ui/writeln_empty_string.rs index 662c62f0211..3b9f51a15d2 100644 --- a/src/tools/clippy/tests/ui/writeln_empty_string.rs +++ b/src/tools/clippy/tests/ui/writeln_empty_string.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow(unused_must_use)] #![warn(clippy::writeln_empty_string)] diff --git a/src/tools/clippy/tests/ui/zero_ptr.fixed b/src/tools/clippy/tests/ui/zero_ptr.fixed index 489aa4121a3..bed38ecafc7 100644 --- a/src/tools/clippy/tests/ui/zero_ptr.fixed +++ b/src/tools/clippy/tests/ui/zero_ptr.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { diff --git a/src/tools/clippy/tests/ui/zero_ptr.rs b/src/tools/clippy/tests/ui/zero_ptr.rs index c3b55ef9ebd..b7b778915a8 100644 --- a/src/tools/clippy/tests/ui/zero_ptr.rs +++ b/src/tools/clippy/tests/ui/zero_ptr.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix pub fn foo(_const: *const f32, _mut: *mut i64) {} fn main() { diff --git a/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed b/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed index 8906c776977..7afd80ccaca 100644 --- a/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed +++ b/src/tools/clippy/tests/ui/zero_ptr_no_std.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/clippy/tests/ui/zero_ptr_no_std.rs b/src/tools/clippy/tests/ui/zero_ptr_no_std.rs index 379c1b18d29..05a0587d22b 100644 --- a/src/tools/clippy/tests/ui/zero_ptr_no_std.rs +++ b/src/tools/clippy/tests/ui/zero_ptr_no_std.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![feature(lang_items, start, libc)] #![no_std] diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index d2f494942cf..7166d99d792 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -303,6 +303,9 @@ pub struct Config { /// The current Rust channel pub channel: String, + /// Whether adding git commit information such as the commit hash has been enabled for building + pub git_hash: bool, + /// The default Rust edition pub edition: Option<String>, @@ -419,7 +422,9 @@ pub struct TargetCfgs { impl TargetCfgs { fn new(config: &Config) -> TargetCfgs { - let targets: HashMap<String, TargetCfg> = if config.stage_id.starts_with("stage0-") { + let targets: HashMap<String, TargetCfg> = if config.stage_id.starts_with("stage0-") + || (config.suite == "ui-fulldeps" && config.stage_id.starts_with("stage1-")) + { // #[cfg(bootstrap)] // Needed only for one cycle, remove during the bootstrap bump. Self::collect_all_slow(config) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index aaa70bf19b2..ccce62bd5b0 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -102,6 +102,9 @@ pub struct TestProps { pub dont_check_compiler_stdout: bool, // For UI tests, allows compiler to generate arbitrary output to stderr pub dont_check_compiler_stderr: bool, + // When checking the output of stdout or stderr check + // that the lines of expected output are a subset of the actual output. + pub compare_output_lines_by_subset: bool, // Don't force a --crate-type=dylib flag on the command line // // Set this for example if you have an auxiliary test file that contains @@ -209,6 +212,7 @@ mod directives { pub const KNOWN_BUG: &'static str = "known-bug"; pub const MIR_UNIT_TEST: &'static str = "unit-test"; pub const REMAP_SRC_BASE: &'static str = "remap-src-base"; + pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset"; // This isn't a real directive, just one that is probably mistyped often pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags"; } @@ -233,6 +237,7 @@ impl TestProps { check_run_results: false, dont_check_compiler_stdout: false, dont_check_compiler_stderr: false, + compare_output_lines_by_subset: false, no_prefer_dynamic: false, pretty_expanded: false, pretty_mode: "normal".to_string(), @@ -467,6 +472,11 @@ impl TestProps { s.trim().to_string() }); config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base); + config.set_name_directive( + ln, + COMPARE_OUTPUT_LINES_BY_SUBSET, + &mut self.compare_output_lines_by_subset, + ); }); } diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 35d6179abaa..81179480ed8 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -115,6 +115,11 @@ pub(super) fn handle_needs( condition: cache.x86_64_dlltool, ignore_reason: "ignored when dlltool for x86_64 is not present", }, + Need { + name: "needs-git-hash", + condition: config.git_hash, + ignore_reason: "ignored when git hashes have been omitted for building", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 9af7bd5e201..362fba11697 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -252,6 +252,16 @@ fn debugger() { } #[test] +fn git_hash() { + let mut config = config(); + config.git_hash = false; + assert!(check_ignore(&config, "// needs-git-hash")); + + config.git_hash = true; + assert!(!check_ignore(&config, "// needs-git-hash")); +} + +#[test] fn sanitizers() { let mut config = config(); diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 4a2b9de8aee..c4bef998f31 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -159,6 +159,7 @@ pub fn parse_config(args: Vec<String>) -> Config { .optflag("", "nocapture", "") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") + .optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries") .optopt("", "edition", "default Rust edition", "EDITION"); let (argv0, args_) = args.split_first().unwrap(); @@ -302,6 +303,7 @@ pub fn parse_config(args: Vec<String>) -> Config { rustfix_coverage: matches.opt_present("rustfix-coverage"), has_tidy, channel: matches.opt_str("channel").unwrap(), + git_hash: matches.opt_present("git-hash"), edition: matches.opt_str("edition"), cc: matches.opt_str("cc").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 0fa5c54ae8e..f6597c72938 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1900,6 +1900,12 @@ impl<'test> TestCx<'test> { // Use a single thread for efficiency and a deterministic error message order rustc.arg("-Zthreads=1"); + // Optionally prevent default --sysroot if specified in test compile-flags. + if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) { + // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot. + rustc.arg("--sysroot").arg(&self.config.sysroot_base); + } + // Optionally prevent default --target if specified in test compile-flags. let custom_target = self.props.compile_flags.iter().any(|x| x.starts_with("--target")); @@ -3238,17 +3244,35 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += - self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout); + errors += self.compare_output( + stdout_kind, + &normalized_stdout, + &expected_stdout, + self.props.compare_output_lines_by_subset, + ); } if !self.props.dont_check_compiler_stderr { - errors += - self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr); + errors += self.compare_output( + stderr_kind, + &normalized_stderr, + &expected_stderr, + self.props.compare_output_lines_by_subset, + ); } } TestOutput::Run => { - errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout); - errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr); + errors += self.compare_output( + stdout_kind, + &normalized_stdout, + &expected_stdout, + self.props.compare_output_lines_by_subset, + ); + errors += self.compare_output( + stderr_kind, + &normalized_stderr, + &expected_stderr, + self.props.compare_output_lines_by_subset, + ); } } errors @@ -3332,7 +3356,12 @@ impl<'test> TestCx<'test> { ) }); - errors += self.compare_output("fixed", &fixed_code, &expected_fixed); + errors += self.compare_output( + "fixed", + &fixed_code, + &expected_fixed, + self.props.compare_output_lines_by_subset, + ); } else if !expected_fixed.is_empty() { panic!( "the `// run-rustfix` directive wasn't found but a `*.fixed` \ @@ -3790,11 +3819,38 @@ impl<'test> TestCx<'test> { } } - fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize { + fn compare_output( + &self, + kind: &str, + actual: &str, + expected: &str, + compare_output_by_lines: bool, + ) -> usize { if actual == expected { return 0; } + let tmp; + let (expected, actual): (&str, &str) = if compare_output_by_lines { + let actual_lines: HashSet<_> = actual.lines().collect(); + let expected_lines: Vec<_> = expected.lines().collect(); + let mut used = expected_lines.clone(); + used.retain(|line| actual_lines.contains(line)); + // check if `expected` contains a subset of the lines of `actual` + if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) { + return 0; + } + if expected_lines.is_empty() { + // if we have no lines to check, force a full overwite + ("", actual) + } else { + tmp = (expected_lines.join("\n"), used.join("\n")); + (&tmp.0, &tmp.1) + } + } else { + (expected, actual) + }; + if !self.config.bless { if expected.is_empty() { println!("normalized {}:\n{}\n", kind, actual); diff --git a/src/tools/linkchecker/linkcheck.sh b/src/tools/linkchecker/linkcheck.sh index 9eeebf444a4..6c1e668a7f0 100755 --- a/src/tools/linkchecker/linkcheck.sh +++ b/src/tools/linkchecker/linkcheck.sh @@ -16,15 +16,13 @@ # # --all Check all books. This can help make sure you don't break links # from other books into your book. +# +# --path <book-path> +# Path to the root directory for the book. Default to the current +# working directory if omitted. set -e -if [ ! -f book.toml ] && [ ! -f src/SUMMARY.md ] -then - echo "Run command in root directory of the book." - exit 1 -fi - html_dir="$(rustc +nightly --print sysroot)/share/doc/rust/html" if [ ! -d "$html_dir" ] @@ -38,6 +36,8 @@ fi export MDBOOK_OUTPUT__HTML__INPUT_404="" book_name="" +# Default to the current directory +book_path="." # Iterative will avoid cleaning up, so you can quickly run it repeatedly. iterative=0 # If "1", test all books, else only this book. @@ -52,6 +52,10 @@ do --all) all_books=1 ;; + --path) + book_path="${2:-.}" + shift + ;; *) if [ -n "$book_name" ] then @@ -70,6 +74,12 @@ then exit 1 fi +if [ ! -f "$book_path/book.toml" ] && [ ! -f "$book_path/src/SUMMARY.md" ] +then + echo "Run command in root directory of the book or provide a path to the book" + exit 1 +fi + if [ ! -d "$html_dir/$book_name" ] then echo "book name \"$book_name\" not found in sysroot \"$html_dir\"" @@ -93,11 +103,11 @@ then fi echo "Building book \"$book_name\"..." -mdbook build +mdbook build "$book_path" cp -R "$html_dir" linkcheck rm -rf "linkcheck/$book_name" -cp -R book "linkcheck/$book_name" +cp -R "$book_path/book" "linkcheck/$book_name" if [ "$all_books" = "1" ] then diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs index 2a923a61b0a..b11fb287cf4 100644 --- a/src/tools/lint-docs/src/groups.rs +++ b/src/tools/lint-docs/src/groups.rs @@ -39,11 +39,12 @@ impl<'a> LintExtractor<'a> { fn collect_groups(&self) -> Result<LintGroups, Box<dyn Error>> { let mut result = BTreeMap::new(); let mut cmd = Command::new(self.rustc_path); + cmd.env_remove("LD_LIBRARY_PATH"); cmd.arg("-Whelp"); let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?; if !output.status.success() { return Err(format!( - "failed to collect lint info: {:?}\n--- stderr\n{}--- stdout\n{}\n", + "failed to collect lint info: failed to run {cmd:?}: {:?}\n--- stderr\n{}--- stdout\n{}\n", output.status, std::str::from_utf8(&output.stderr).unwrap(), std::str::from_utf8(&output.stdout).unwrap(), diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 034c6aa0708..fe29b9abda3 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -403,6 +403,12 @@ impl<'a> LintExtractor<'a> { fs::write(&tempfile, source) .map_err(|e| format!("failed to write {}: {}", tempfile.display(), e))?; let mut cmd = Command::new(self.rustc_path); + // NOTE: bootstrap sets `LD_LIBRARY_PATH` for building lint-docs itself. + // Unfortunately, lint-docs is a bootstrap tool while rustc is built from source, + // and sometimes the paths conflict. In particular, when using `download-rustc`, + // the LLVM versions can differ between `ci-llvm` and `ci-rustc-sysroot`. + // Unset LD_LIBRARY_PATH here so it doesn't interfere with running the compiler. + cmd.env_remove("LD_LIBRARY_PATH"); if options.contains(&"edition2015") { cmd.arg("--edition=2015"); } else { @@ -415,6 +421,9 @@ impl<'a> LintExtractor<'a> { } cmd.arg("lint_example.rs"); cmd.current_dir(tempdir.path()); + if self.verbose { + eprintln!("running: {cmd:?}"); + } let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?; let stderr = std::str::from_utf8(&output.stderr).unwrap(); let msgs = stderr diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 4c735187987..04a1d939d2e 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -301,6 +301,15 @@ environment variable. We first document the most relevant and most commonly used * `-Zmiri-disable-isolation` disables host isolation. As a consequence, the program has access to host resources such as environment variables, file systems, and randomness. +* `-Zmiri-disable-leak-backtraces` disables backtraces reports for memory leaks. By default, a + backtrace is captured for every allocation when it is created, just in case it leaks. This incurs + some memory overhead to store data that is almost never used. This flag is implied by + `-Zmiri-ignore-leaks`. +* `-Zmiri-env-forward=<var>` forwards the `var` environment variable to the interpreted program. Can + be used multiple times to forward several variables. Execution will still be deterministic if the + value of forwarded variables stays the same. Has no effect if `-Zmiri-disable-isolation` is set. +* `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some + remaining threads to exist when the main thread exits. * `-Zmiri-isolation-error=<action>` configures Miri's response to operations requiring host access while isolation is enabled. `abort`, `hide`, `warn`, and `warn-nobacktrace` are the supported actions. The default is to `abort`, @@ -308,11 +317,6 @@ environment variable. We first document the most relevant and most commonly used execution with a "permission denied" error being returned to the program. `warn` prints a full backtrace when that happens; `warn-nobacktrace` is less verbose. `hide` hides the warning entirely. -* `-Zmiri-env-forward=<var>` forwards the `var` environment variable to the interpreted program. Can - be used multiple times to forward several variables. Execution will still be deterministic if the - value of forwarded variables stays the same. Has no effect if `-Zmiri-disable-isolation` is set. -* `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some - remaining threads to exist when the main thread exits. * `-Zmiri-num-cpus` states the number of available CPUs to be reported by miri. By default, the number of available CPUs is `1`. Note that this flag does not affect how miri handles threads in any way. diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 26a7ead2407..3aa71bb7e3c 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -359,6 +359,8 @@ fn main() { isolation_enabled = Some(false); } miri_config.isolated_op = miri::IsolatedOp::Allow; + } else if arg == "-Zmiri-disable-leak-backtraces" { + miri_config.collect_leak_backtraces = false; } else if arg == "-Zmiri-disable-weak-memory-emulation" { miri_config.weak_memory_emulation = false; } else if arg == "-Zmiri-track-weak-memory-loads" { @@ -385,6 +387,7 @@ fn main() { }; } else if arg == "-Zmiri-ignore-leaks" { miri_config.ignore_leaks = true; + miri_config.collect_leak_backtraces = false; } else if arg == "-Zmiri-panic-on-unsupported" { miri_config.panic_on_unsupported = true; } else if arg == "-Zmiri-tag-raw-pointers" { diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index ed958329f95..d54adb72887 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -352,7 +352,7 @@ pub enum AllocState { TreeBorrows(Box<RefCell<tree_borrows::AllocState>>), } -impl machine::AllocExtra { +impl machine::AllocExtra<'_> { #[track_caller] pub fn borrow_tracker_sb(&self) -> &RefCell<stacked_borrows::AllocState> { match self.borrow_tracker { diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index 96463279668..1f67b91569c 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -48,7 +48,7 @@ use std::{ use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir; use rustc_span::Span; use rustc_target::abi::{Align, Size}; diff --git a/src/tools/miri/src/concurrency/init_once.rs b/src/tools/miri/src/concurrency/init_once.rs index 867683d3552..7a6b8da4082 100644 --- a/src/tools/miri/src/concurrency/init_once.rs +++ b/src/tools/miri/src/concurrency/init_once.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use std::num::NonZeroU32; -use rustc_index::vec::Idx; +use rustc_index::Idx; use super::sync::EvalContextExtPriv as _; use super::thread::MachineCallback; diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs index b9620523974..662dff62c88 100644 --- a/src/tools/miri/src/concurrency/sync.rs +++ b/src/tools/miri/src/concurrency/sync.rs @@ -5,7 +5,7 @@ use std::ops::Not; use log::trace; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use super::init_once::InitOnce; use super::vector_clock::VClock; diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs index 9173eb3c4ee..5f2bc2ec558 100644 --- a/src/tools/miri/src/concurrency/thread.rs +++ b/src/tools/miri/src/concurrency/thread.rs @@ -10,7 +10,7 @@ use log::trace; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::Mutability; use rustc_middle::ty::layout::TyAndLayout; use rustc_span::Span; @@ -272,8 +272,9 @@ impl Time { fn get_wait_time(&self, clock: &Clock) -> Duration { match self { Time::Monotonic(instant) => instant.duration_since(clock.now()), - Time::RealTime(time) => - time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)), + Time::RealTime(time) => { + time.duration_since(SystemTime::now()).unwrap_or(Duration::new(0, 0)) + } } } } @@ -603,10 +604,11 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> { // this allows us to have a deterministic scheduler. for thread in self.threads.indices() { match self.timeout_callbacks.entry(thread) { - Entry::Occupied(entry) => + Entry::Occupied(entry) => { if entry.get().call_time.get_wait_time(clock) == Duration::new(0, 0) { return Some((thread, entry.remove().callback)); - }, + } + } Entry::Vacant(_) => {} } } diff --git a/src/tools/miri/src/concurrency/vector_clock.rs b/src/tools/miri/src/concurrency/vector_clock.rs index ab4764dd1c8..b36c6be5a72 100644 --- a/src/tools/miri/src/concurrency/vector_clock.rs +++ b/src/tools/miri/src/concurrency/vector_clock.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::Idx; +use rustc_index::Idx; use rustc_span::{Span, SpanData, DUMMY_SP}; use smallvec::SmallVec; use std::{ @@ -212,14 +212,16 @@ impl PartialOrd for VClock { for (l, r) in iter { match order { Ordering::Equal => order = l.cmp(r), - Ordering::Less => + Ordering::Less => { if l > r { return None; - }, - Ordering::Greater => + } + } + Ordering::Greater => { if l < r { return None; - }, + } + } } } @@ -234,18 +236,16 @@ impl PartialOrd for VClock { Ordering::Equal => Some(order), // Right has at least 1 element > than the implicit 0, // so the only valid values are Ordering::Less or None. - Ordering::Less => - match order { - Ordering::Less | Ordering::Equal => Some(Ordering::Less), - Ordering::Greater => None, - }, + Ordering::Less => match order { + Ordering::Less | Ordering::Equal => Some(Ordering::Less), + Ordering::Greater => None, + }, // Left has at least 1 element > than the implicit 0, // so the only valid values are Ordering::Greater or None. - Ordering::Greater => - match order { - Ordering::Greater | Ordering::Equal => Some(Ordering::Greater), - Ordering::Less => None, - }, + Ordering::Greater => match order { + Ordering::Greater | Ordering::Equal => Some(Ordering::Greater), + Ordering::Less => None, + }, } } diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 3c13118122c..7a726be00da 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -105,7 +105,7 @@ pub enum NonHaltingDiagnostic { } /// Level of Miri specific diagnostics -enum DiagLevel { +pub enum DiagLevel { Error, Warning, Note, @@ -114,7 +114,7 @@ enum DiagLevel { /// Attempts to prune a stacktrace to omit the Rust runtime, and returns a bool indicating if any /// frames were pruned. If the stacktrace does not have any local frames, we conclude that it must /// be pointing to a problem in the Rust runtime itself, and do not prune it at all. -fn prune_stacktrace<'tcx>( +pub fn prune_stacktrace<'tcx>( mut stacktrace: Vec<FrameInfo<'tcx>>, machine: &MiriMachine<'_, 'tcx>, ) -> (Vec<FrameInfo<'tcx>>, bool) { @@ -338,12 +338,45 @@ pub fn report_error<'tcx, 'mir>( None } +pub fn report_leaks<'mir, 'tcx>( + ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, + leaks: Vec<(AllocId, MemoryKind<MiriMemoryKind>, Allocation<Provenance, AllocExtra<'tcx>>)>, +) { + let mut any_pruned = false; + for (id, kind, mut alloc) in leaks { + let Some(backtrace) = alloc.extra.backtrace.take() else { + continue; + }; + let (backtrace, pruned) = prune_stacktrace(backtrace, &ecx.machine); + any_pruned |= pruned; + report_msg( + DiagLevel::Error, + &format!( + "memory leaked: {id:?} ({}, size: {:?}, align: {:?}), allocated here:", + kind, + alloc.size().bytes(), + alloc.align.bytes() + ), + vec![], + vec![], + vec![], + &backtrace, + &ecx.machine, + ); + } + if any_pruned { + ecx.tcx.sess.diagnostic().note_without_error( + "some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace", + ); + } +} + /// Report an error or note (depending on the `error` argument) with the given stacktrace. /// Also emits a full stacktrace of the interpreter stack. /// We want to present a multi-line span message for some errors. Diagnostics do not support this /// directly, so we pass the lines as a `Vec<String>` and display each line after the first with an /// additional `span_label` or `note` call. -fn report_msg<'tcx>( +pub fn report_msg<'tcx>( diag_level: DiagLevel, title: &str, span_msg: Vec<String>, diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index a32b18595b5..defd37c3775 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -10,6 +10,7 @@ use std::thread; use log::info; use crate::borrow_tracker::RetagFields; +use crate::diagnostics::report_leaks; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; @@ -145,6 +146,8 @@ pub struct MiriConfig { pub num_cpus: u32, /// Requires Miri to emulate pages of a certain size pub page_size: Option<u64>, + /// Whether to collect a backtrace when each allocation is created, just in case it leaks. + pub collect_leak_backtraces: bool, } impl Default for MiriConfig { @@ -179,6 +182,7 @@ impl Default for MiriConfig { gc_interval: 10_000, num_cpus: 1, page_size: None, + collect_leak_backtraces: true, } } } @@ -457,10 +461,17 @@ pub fn eval_entry<'tcx>( } // Check for memory leaks. info!("Additonal static roots: {:?}", ecx.machine.static_roots); - let leaks = ecx.leak_report(&ecx.machine.static_roots); - if leaks != 0 { - tcx.sess.err("the evaluated program leaked memory"); - tcx.sess.note_without_error("pass `-Zmiri-ignore-leaks` to disable this check"); + let leaks = ecx.find_leaked_allocations(&ecx.machine.static_roots); + if !leaks.is_empty() { + report_leaks(&ecx, leaks); + let leak_message = "the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check"; + if ecx.machine.collect_leak_backtraces { + // If we are collecting leak backtraces, each leak is a distinct error diagnostic. + tcx.sess.note_without_error(leak_message); + } else { + // If we do not have backtraces, we just report an error without any span. + tcx.sess.err(leak_message); + }; // Ignore the provided return code - let the reported error // determine the return code. return None; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f67a718ba73..fc938080a0e 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -130,6 +130,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zalways-encode-mir", "-Zextra-const-ub-checks", "-Zmir-emit-retag", + "-Zmir-keep-place-mention", "-Zmir-opt-level=0", "-Zmir-enable-passes=-CheckAlignment", ]; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 477d8d33ebb..ecb3e13dd54 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -253,20 +253,25 @@ impl ProvenanceExtra { /// Extra per-allocation data #[derive(Debug, Clone)] -pub struct AllocExtra { +pub struct AllocExtra<'tcx> { /// Global state of the borrow tracker, if enabled. pub borrow_tracker: Option<borrow_tracker::AllocState>, - /// Data race detection via the use of a vector-clock, - /// this is only added if it is enabled. + /// Data race detection via the use of a vector-clock. + /// This is only added if it is enabled. pub data_race: Option<data_race::AllocState>, - /// Weak memory emulation via the use of store buffers, - /// this is only added if it is enabled. + /// Weak memory emulation via the use of store buffers. + /// This is only added if it is enabled. pub weak_memory: Option<weak_memory::AllocState>, + /// A backtrace to where this allocation was allocated. + /// As this is recorded for leak reports, it only exists + /// if this allocation is leakable. The backtrace is not + /// pruned yet; that should be done before printing it. + pub backtrace: Option<Vec<FrameInfo<'tcx>>>, } -impl VisitTags for AllocExtra { +impl VisitTags for AllocExtra<'_> { fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) { - let AllocExtra { borrow_tracker, data_race, weak_memory } = self; + let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self; borrow_tracker.visit_tags(visit); data_race.visit_tags(visit); @@ -467,12 +472,17 @@ pub struct MiriMachine<'mir, 'tcx> { pub(crate) gc_interval: u32, /// The number of blocks that passed since the last BorTag GC pass. pub(crate) since_gc: u32, + /// The number of CPUs to be reported by miri. pub(crate) num_cpus: u32, + /// Determines Miri's page size and associated values pub(crate) page_size: u64, pub(crate) stack_addr: u64, pub(crate) stack_size: u64, + + /// Whether to collect a backtrace when each allocation is created, just in case it leaks. + pub(crate) collect_leak_backtraces: bool, } impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { @@ -581,6 +591,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> { page_size, stack_addr, stack_size, + collect_leak_backtraces: config.collect_leak_backtraces, } } @@ -728,6 +739,7 @@ impl VisitTags for MiriMachine<'_, '_> { page_size: _, stack_addr: _, stack_size: _, + collect_leak_backtraces: _, } = self; threads.visit_tags(visit); @@ -773,7 +785,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { type ExtraFnVal = Dlsym; type FrameExtra = FrameExtra<'tcx>; - type AllocExtra = AllocExtra; + type AllocExtra = AllocExtra<'tcx>; type Provenance = Provenance; type ProvenanceExtra = ProvenanceExtra; @@ -967,9 +979,24 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ) }); let buffer_alloc = ecx.machine.weak_memory.then(weak_memory::AllocState::new_allocation); + + // If an allocation is leaked, we want to report a backtrace to indicate where it was + // allocated. We don't need to record a backtrace for allocations which are allowed to + // leak. + let backtrace = if kind.may_leak() || !ecx.machine.collect_leak_backtraces { + None + } else { + Some(ecx.generate_stacktrace()) + }; + let alloc: Allocation<Provenance, Self::AllocExtra> = alloc.adjust_from_tcx( &ecx.tcx, - AllocExtra { borrow_tracker, data_race: race_alloc, weak_memory: buffer_alloc }, + AllocExtra { + borrow_tracker, + data_race: race_alloc, + weak_memory: buffer_alloc, + backtrace, + }, |ptr| ecx.global_base_pointer(ptr), )?; Ok(Cow::Owned(alloc)) @@ -1049,7 +1076,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { fn before_memory_read( _tcx: TyCtxt<'tcx>, machine: &Self, - alloc_extra: &AllocExtra, + alloc_extra: &AllocExtra<'tcx>, (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra), range: AllocRange, ) -> InterpResult<'tcx> { @@ -1069,7 +1096,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { fn before_memory_write( _tcx: TyCtxt<'tcx>, machine: &mut Self, - alloc_extra: &mut AllocExtra, + alloc_extra: &mut AllocExtra<'tcx>, (alloc_id, prov_extra): (AllocId, Self::ProvenanceExtra), range: AllocRange, ) -> InterpResult<'tcx> { @@ -1089,7 +1116,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { fn before_memory_deallocation( _tcx: TyCtxt<'tcx>, machine: &mut Self, - alloc_extra: &mut AllocExtra, + alloc_extra: &mut AllocExtra<'tcx>, (alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra), range: AllocRange, ) -> InterpResult<'tcx> { diff --git a/src/tools/miri/src/tag_gc.rs b/src/tools/miri/src/tag_gc.rs index c1194fe2216..cefdcc2b5b8 100644 --- a/src/tools/miri/src/tag_gc.rs +++ b/src/tools/miri/src/tag_gc.rs @@ -125,7 +125,7 @@ impl VisitTags for Operand<Provenance> { } } -impl VisitTags for Allocation<Provenance, AllocExtra> { +impl VisitTags for Allocation<Provenance, AllocExtra<'_>> { fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) { for prov in self.provenance().provenances() { prov.visit_tags(visit); diff --git a/src/tools/miri/tests/fail/const-ub-checks.stderr b/src/tools/miri/tests/fail/const-ub-checks.stderr index a8b7ea242b9..596a6bb4ca8 100644 --- a/src/tools/miri/tests/fail/const-ub-checks.stderr +++ b/src/tools/miri/tests/fail/const-ub-checks.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of constant value failed LL | ptr.read(); | ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +note: erroneous constant used + --> $DIR/const-ub-checks.rs:LL:CC + | +LL | let _x = UNALIGNED_READ; + | ^^^^^^^^^^^^^^ + error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs new file mode 100644 index 00000000000..7c5f440b774 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs @@ -0,0 +1,13 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation + +fn main() { + let p = { + let b = Box::new(42); + &*b as *const i32 + }; + unsafe { + let _ = *p; //~ ERROR: dereferenced after this allocation got freed + } + panic!("this should never print"); +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr new file mode 100644 index 00000000000..7b76389c753 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed + --> $DIR/dangling_pointer_deref_underscore.rs:LL:CC + | +LL | let _ = *p; + | ^^ pointer to ALLOC was dereferenced after this allocation got freed + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/dangling_pointer_deref_underscore.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr index d41fcfd2302..9aad1fc9b02 100644 --- a/src/tools/miri/tests/fail/erroneous_const2.stderr +++ b/src/tools/miri/tests/fail/erroneous_const2.stderr @@ -4,6 +4,20 @@ error[E0080]: evaluation of constant value failed LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow +note: erroneous constant used + --> $DIR/erroneous_const2.rs:LL:CC + | +LL | println!("{}", FOO); + | ^^^ + +note: erroneous constant used + --> $DIR/erroneous_const2.rs:LL:CC + | +LL | println!("{}", FOO); + | ^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/miri/tests/fail/memleak.rs b/src/tools/miri/tests/fail/memleak.rs index d384caf81a5..cbeb163b56c 100644 --- a/src/tools/miri/tests/fail/memleak.rs +++ b/src/tools/miri/tests/fail/memleak.rs @@ -1,4 +1,4 @@ -//@error-pattern: the evaluated program leaked memory +//@error-pattern: memory leaked //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" fn main() { diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr index f8b62af3eb8..6d9b664c8f4 100644 --- a/src/tools/miri/tests/fail/memleak.stderr +++ b/src/tools/miri/tests/fail/memleak.stderr @@ -1,10 +1,23 @@ -The following memory was leaked: ALLOC (Rust heap, size: 4, align: 4) { -$stripped$ -} +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_alloc(layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::boxed::Box::<i32>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC +note: inside `main` + --> $DIR/memleak.rs:LL:CC + | +LL | std::mem::forget(Box::new(42)); + | ^^^^^^^^^^^^ -error: the evaluated program leaked memory +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: pass `-Zmiri-ignore-leaks` to disable this check +note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check error: aborting due to previous error diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.rs b/src/tools/miri/tests/fail/memleak_no_backtrace.rs new file mode 100644 index 00000000000..24d4a02df71 --- /dev/null +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.rs @@ -0,0 +1,7 @@ +//@compile-flags: -Zmiri-disable-leak-backtraces +//@error-pattern: the evaluated program leaked memory +//@normalize-stderr-test: ".*│.*" -> "$$stripped$$" + +fn main() { + std::mem::forget(Box::new(42)); +} diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr new file mode 100644 index 00000000000..f44e6ce0797 --- /dev/null +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr @@ -0,0 +1,4 @@ +error: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr b/src/tools/miri/tests/fail/memleak_rc.32bit.stderr index da222609091..0e1146cf4ad 100644 --- a/src/tools/miri/tests/fail/memleak_rc.32bit.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.32bit.stderr @@ -1,10 +1,24 @@ -The following memory was leaked: ALLOC (Rust heap, size: 16, align: 4) { -$stripped$ -} +error: memory leaked: ALLOC (Rust heap, size: 16, align: 4), allocated here: + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_alloc(layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::boxed::Box::<std::rc::RcBox<std::cell::RefCell<std::option::Option<Dummy>>>>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::rc::Rc::<std::cell::RefCell<std::option::Option<Dummy>>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC +note: inside `main` + --> $DIR/memleak_rc.rs:LL:CC + | +LL | let x = Dummy(Rc::new(RefCell::new(None))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the evaluated program leaked memory +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: pass `-Zmiri-ignore-leaks` to disable this check +note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check error: aborting due to previous error diff --git a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr b/src/tools/miri/tests/fail/memleak_rc.64bit.stderr index 8c24bbc779b..4979588f370 100644 --- a/src/tools/miri/tests/fail/memleak_rc.64bit.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.64bit.stderr @@ -1,11 +1,24 @@ -The following memory was leaked: ALLOC (Rust heap, size: 32, align: 8) { -$stripped$ -$stripped$ -} +error: memory leaked: ALLOC (Rust heap, size: 32, align: 8), allocated here: + --> RUSTLIB/alloc/src/alloc.rs:LL:CC + | +LL | unsafe { __rust_alloc(layout.size(), layout.align()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: inside `std::alloc::alloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::alloc::Global::alloc_impl` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::exchange_malloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `std::boxed::Box::<std::rc::RcBox<std::cell::RefCell<std::option::Option<Dummy>>>>::new` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::rc::Rc::<std::cell::RefCell<std::option::Option<Dummy>>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC +note: inside `main` + --> $DIR/memleak_rc.rs:LL:CC + | +LL | let x = Dummy(Rc::new(RefCell::new(None))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: the evaluated program leaked memory +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: pass `-Zmiri-ignore-leaks` to disable this check +note: the evaluated program leaked memory, pass `-Zmiri-ignore-leaks` to disable this check error: aborting due to previous error diff --git a/src/tools/miri/tests/fail/memleak_rc.rs b/src/tools/miri/tests/fail/memleak_rc.rs index 76ecd71b011..cf4671912ad 100644 --- a/src/tools/miri/tests/fail/memleak_rc.rs +++ b/src/tools/miri/tests/fail/memleak_rc.rs @@ -1,4 +1,4 @@ -//@error-pattern: the evaluated program leaked memory +//@error-pattern: memory leaked //@stderr-per-bitwidth //@normalize-stderr-test: ".*│.*" -> "$$stripped$$" diff --git a/src/tools/miri/tests/pass/track-alloc-1.rs b/src/tools/miri/tests/pass/track-alloc-1.rs deleted file mode 100644 index 427c800dc51..00000000000 --- a/src/tools/miri/tests/pass/track-alloc-1.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Ensure that tracking early allocations doesn't ICE Miri. -// Early allocations are probably part of the runtime and therefore uninteresting, but they -// shouldn't cause a crash. -//@compile-flags: -Zmiri-track-alloc-id=1 -//@normalize-stderr-test: "[48] bytes" -> "SIZE bytes" -fn main() {} diff --git a/src/tools/miri/tests/pass/track-alloc-1.stderr b/src/tools/miri/tests/pass/track-alloc-1.stderr deleted file mode 100644 index 7206edbb701..00000000000 --- a/src/tools/miri/tests/pass/track-alloc-1.stderr +++ /dev/null @@ -1,5 +0,0 @@ -note: tracking was triggered - | - = note: created extern static allocation of SIZE bytes (alignment ALIGN bytes) with id 1 - = note: (no span available) - diff --git a/src/tools/rls/Cargo.toml b/src/tools/rls/Cargo.toml index 92b50bf4cec..b84647eb332 100644 --- a/src/tools/rls/Cargo.toml +++ b/src/tools/rls/Cargo.toml @@ -7,7 +7,3 @@ license = "Apache-2.0/MIT" [dependencies] serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.83" -# A noop dependency that changes in the Rust repository, it's a bit of a hack. -# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` -# for more information. -rustc-workspace-hack = "1.0.0" diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs index d258a024729..a9cd8e705a4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs @@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder; mod symbol; pub use symbol::*; -use std::ops::Bound; +use std::ops::{Bound, Range}; use crate::tt; @@ -298,6 +298,10 @@ impl server::Span for RustAnalyzer { // FIXME handle span span } + fn byte_range(&mut self, _span: Self::Span) -> Range<usize> { + // FIXME handle span + Range { start: 0, end: 0 } + } fn start(&mut self, _span: Self::Span) -> LineColumn { // FIXME handle span LineColumn { line: 0, column: 0 } diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml deleted file mode 100644 index e088ffbbe77..00000000000 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ /dev/null @@ -1,102 +0,0 @@ -[package] -name = "rustc-workspace-hack" -version = "1.0.0" -license = 'MIT OR Apache-2.0' -description = """ -Hack for the compiler's own build system -""" -edition = "2021" - -[lib] -path = "lib.rs" - -# For documentation about what this is and why in the world these dependencies -# are appearing, see `README.md`. - -[target.'cfg(windows)'.dependencies.winapi] -version = "0.3" -features = [ - "accctrl", - "aclapi", - "basetsd", - "cfg", - "consoleapi", - "errhandlingapi", - "evntrace", - "fibersapi", - "handleapi", - "in6addr", - "inaddr", - "ioapiset", - "jobapi", - "jobapi2", - "knownfolders", - "libloaderapi", - "lmcons", - "memoryapi", - "minschannel", - "minwinbase", - "mstcpip", - "mswsock", - "namedpipeapi", - "ntdef", - "ntsecapi", - "ntstatus", - "objbase", - "processenv", - "processthreadsapi", - "profileapi", - "psapi", - "schannel", - "securitybaseapi", - "shellapi", - "shlobj", - "sspi", - "synchapi", - "sysinfoapi", - "threadpoollegacyapiset", - "timezoneapi", - "userenv", - "winbase", - "wincon", - "wincrypt", - "windef", - "winioctl", - "winnt", - "winreg", - "winsock2", - "winuser", - "ws2def", - "ws2ipdef", - "ws2tcpip", -] - -[dependencies] -bstr = { version = "0.2.17", features = ["default"] } -clap = { version = "3.1.1", features = ["derive", "clap_derive"]} -curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } -# Ensure `extra_traits` of libc, which is used transitively by Cargo. -libc = { version = "0.2", features = ["extra_traits"] } -# Ensure `js` of getrandom, which is (unfortunately) used transitively by Cargo. -getrandom = { version = "0.2", features = ["js"] } -# Ensure default features of libz-sys, which are disabled in some scenarios. -libz-sys = { version = "1.1.2" } -# Ensure default features of regex, which are disabled in some scenarios. -regex = { version = "1.5.6" } -serde_json = { version = "1.0.31", features = ["raw_value", "unbounded_depth"] } -syn = { version = "1", features = ['full', 'visit', 'visit-mut'] } # `visit-mut` required by Cargo via `gix` -url = { version = "2.0", features = ['serde'] } -# Ensure default features of rand, which are disabled in some scenarios. -rand = { version = "0.8.5" } - -# Ensure features of `hashbrown`, `smallvec`, and `once_cell`, -# which are used transitively by Cargo (via `gix`). -hashbrown = { version = "0.12.3", default-features = false, features = ["inline-more"] } -once_cell = { version = "1.16.0", default-features = false, features = ["unstable"] } -smallvec = { version = "1.10.0", features = ["write"] } - -[target.'cfg(not(windows))'.dependencies] -openssl = { version = "0.10.35", optional = true } - -[features] -all-static = ['openssl/vendored', 'curl-sys/static-curl', 'curl-sys/force-system-lib-on-osx'] diff --git a/src/tools/rustc-workspace-hack/README.md b/src/tools/rustc-workspace-hack/README.md deleted file mode 100644 index 3c61470358b..00000000000 --- a/src/tools/rustc-workspace-hack/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# `rustc-workspace-hack` - -This crate is a bit of a hack to make workspaces in rustc work a bit better. -The rationale for this existence is a bit subtle, but the general idea is that -we want commands like `./x.py build src/tools/{clippy,cargo}` to share as -many dependencies as possible. - -Each invocation is a different invocation of Cargo, however. Each time Cargo -runs a build it will re-resolve the dependency graph, notably selecting -different features sometimes for each build. - -For example, let's say there's a very deep dependency like `winapi` in each of -these builds. For Cargo, `winapi` has 33 features enabled. In Clippy, however, -`winapi` has 22 features enabled. This means that building Cargo and then the -Clippy will actually build winapi twice, which in turn will build duplicates -of everything that depends on `winapi`. This is bad! - -The goal of this crate is to solve this problem and ensure that the resolved -dependency graph for all of these tools is the same in the various subsets of -each tool, notably enabling the same features of transitive dependencies. - -All tools vendored here depend on the `rustc-workspace-hack` crate on crates.io. -When on crates.io this crate is an empty crate that is just a noop. We override -it, however, in this workspace to this crate here, which means we can control -crates in the dependency graph for each of these tools. diff --git a/src/tools/rustc-workspace-hack/lib.rs b/src/tools/rustc-workspace-hack/lib.rs deleted file mode 100644 index 44425d9c15f..00000000000 --- a/src/tools/rustc-workspace-hack/lib.rs +++ /dev/null @@ -1 +0,0 @@ -// intentionally left blank diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index 72baad606f0..692d5e3fcef 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -42,7 +42,7 @@ function parseOptions(args) { "executable_path": null, "no_sandbox": false, }; - const correspondances = { + const correspondences = { "--doc-folder": "doc_folder", "--tests-folder": "tests_folder", "--debug": "debug", @@ -73,7 +73,7 @@ function parseOptions(args) { } opts["jobs"] = parseInt(arg_value); } else if (arg !== "--file") { - opts[correspondances[arg]] = arg_value; + opts[correspondences[arg]] = arg_value; } else { opts["files"].push(arg_value); } @@ -82,9 +82,9 @@ function parseOptions(args) { process.exit(0); } else if (arg === "--no-sandbox") { console.log("`--no-sandbox` is being used. Be very careful!"); - opts[correspondances[arg]] = true; - } else if (correspondances[arg]) { - opts[correspondances[arg]] = true; + opts[correspondences[arg]] = true; + } else if (correspondences[arg]) { + opts[correspondences[arg]] = true; } else { console.log("Unknown option `" + arg + "`."); console.log("Use `--help` to see the list of options"); diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index ac96bedf2fe..824e4219136 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -399,7 +399,9 @@ pub(crate) fn format_expr( } } ast::ExprKind::Underscore => Some("_".to_owned()), - ast::ExprKind::FormatArgs(..) | ast::ExprKind::IncludedBytes(..) => { + ast::ExprKind::FormatArgs(..) + | ast::ExprKind::IncludedBytes(..) + | ast::ExprKind::OffsetOf(..) => { // These do not occur in the AST because macros aren't expanded. unreachable!() } diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index a26375ee643..ca171657407 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -499,6 +499,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Field(..) | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::InlineAsm(..) + | ast::ExprKind::OffsetOf(..) | ast::ExprKind::Let(..) | ast::ExprKind::Path(..) | ast::ExprKind::Range(..) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index a9eb6c8d03f..411cbc760e0 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[ "ISC", "Unlicense/MIT", "Unlicense OR MIT", + "0BSD", "0BSD OR MIT OR Apache-2.0", // adler license "Zlib OR Apache-2.0 OR MIT", // tinyvec "MIT OR Apache-2.0 OR Zlib", // tinyvec_macros @@ -33,30 +34,36 @@ const LICENSES: &[&str] = &[ const EXCEPTIONS: &[(&str, &str)] = &[ ("ar_archive_writer", "Apache-2.0 WITH LLVM-exception"), // rustc ("mdbook", "MPL-2.0"), // mdbook - ("openssl", "Apache-2.0"), // cargo, mdbook ("colored", "MPL-2.0"), // rustfmt ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde) - ("bytesize", "Apache-2.0"), // cargo - ("im-rc", "MPL-2.0+"), // cargo - ("sized-chunks", "MPL-2.0+"), // cargo via im-rc - ("bitmaps", "MPL-2.0+"), // cargo via im-rc - ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), // cargo via pasetors - ("subtle", "BSD-3-Clause"), // cargo via pasetors - ("dunce", "CC0-1.0 OR MIT-0"), // cargo via gix (and dev dependency) - ("imara-diff", "Apache-2.0"), // cargo via gix - ("sha1_smol", "BSD-3-Clause"), // cargo via gix - ("unicode-bom", "Apache-2.0"), // cargo via gix - ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot - ("snap", "BSD-3-Clause"), // rustc - ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) - ("self_cell", "Apache-2.0"), // rustc (fluent translations) + ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku + ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot + ("snap", "BSD-3-Clause"), // rustc + ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) + ("self_cell", "Apache-2.0"), // rustc (fluent translations) // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target - ("similar", "Apache-2.0"), // cargo (dev dependency) - ("normalize-line-endings", "Apache-2.0"), // cargo (dev dependency) ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) ]; +const EXCEPTIONS_CARGO: &[(&str, &str)] = &[ + ("bitmaps", "MPL-2.0+"), + ("bytesize", "Apache-2.0"), + ("dunce", "CC0-1.0 OR MIT-0"), + ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"), + ("im-rc", "MPL-2.0+"), + ("imara-diff", "Apache-2.0"), + ("instant", "BSD-3-Clause"), + ("normalize-line-endings", "Apache-2.0"), + ("openssl", "Apache-2.0"), + ("ryu", "Apache-2.0 OR BSL-1.0"), + ("sha1_smol", "BSD-3-Clause"), + ("similar", "Apache-2.0"), + ("sized-chunks", "MPL-2.0+"), + ("subtle", "BSD-3-Clause"), + ("unicode-bom", "Apache-2.0"), +]; + const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), ("cranelift-codegen", "Apache-2.0 WITH LLVM-exception"), @@ -156,7 +163,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "lazy_static", "libc", "libloading", - "libz-sys", "litemap", "lock_api", "log", @@ -177,7 +183,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "perf-event-open-sys", "petgraph", "pin-project-lite", - "pkg-config", "polonius-engine", "ppv-lite86", "proc-macro-hack", @@ -217,7 +222,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "stable_deref_trait", "stacker", "static_assertions", - "subtle", // dependency of cargo (via pasetors) "syn", "synstructure", "tempfile", @@ -256,7 +260,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "unicode-security", "unicode-width", "unicode-xid", - "vcpkg", "valuable", "version_check", "wasi", @@ -333,13 +336,6 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "windows_x86_64_msvc", ]; -const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[ - // This crate takes quite a long time to build, so don't allow two versions of them - // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times - // under control. - "cargo", -]; - /// Dependency checks. /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path @@ -359,8 +355,16 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { &["rustc_driver", "rustc_codegen_llvm"], bad, ); - check_crate_duplicate(&metadata, FORBIDDEN_TO_HAVE_DUPLICATES, bad); - check_rustfix(&metadata, bad); + + // Check cargo independently as it has it's own workspace. + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("src/tools/cargo/Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures); + let cargo_metadata = t!(cmd.exec()); + let runtime_ids = HashSet::new(); + check_license_exceptions(&cargo_metadata, EXCEPTIONS_CARGO, runtime_ids, bad); + check_rustfix(&metadata, &cargo_metadata, bad); // Check rustc_codegen_cranelift independently as it has it's own workspace. let mut cmd = cargo_metadata::MetadataCommand::new(); @@ -377,7 +381,6 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { &["rustc_codegen_cranelift"], bad, ); - check_crate_duplicate(&metadata, &[], bad); let mut cmd = cargo_metadata::MetadataCommand::new(); cmd.cargo_path(cargo) @@ -523,40 +526,6 @@ fn check_permitted_dependencies( } } -/// Prevents multiple versions of some expensive crates. -fn check_crate_duplicate( - metadata: &Metadata, - forbidden_to_have_duplicates: &[&str], - bad: &mut bool, -) { - for &name in forbidden_to_have_duplicates { - let matches: Vec<_> = metadata.packages.iter().filter(|pkg| pkg.name == name).collect(); - match matches.len() { - 0 => { - tidy_error!( - bad, - "crate `{}` is missing, update `check_crate_duplicate` \ - if it is no longer used", - name - ); - } - 1 => {} - _ => { - tidy_error!( - bad, - "crate `{}` is duplicated in `Cargo.lock`, \ - it is too expensive to build multiple times, \ - so make sure only one version appears across all dependencies", - name - ); - for pkg in matches { - println!(" * {}", pkg.id); - } - } - } - } -} - /// Finds a package with the given name. fn pkg_from_name<'a>(metadata: &'a Metadata, name: &'static str) -> &'a Package { let mut i = metadata.packages.iter().filter(|p| p.name == name); @@ -606,19 +575,24 @@ fn deps_of_filtered<'a>( } } -fn direct_deps_of<'a>(metadata: &'a Metadata, pkg_id: &'a PackageId) -> Vec<&'a Package> { +fn direct_deps_of<'a>( + metadata: &'a Metadata, + pkg_id: &'a PackageId, +) -> impl Iterator<Item = &'a Package> { let resolve = metadata.resolve.as_ref().unwrap(); let node = resolve.nodes.iter().find(|n| &n.id == pkg_id).unwrap(); - node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg)).collect() + node.deps.iter().map(|dep| pkg_from_id(metadata, &dep.pkg)) } -fn check_rustfix(metadata: &Metadata, bad: &mut bool) { - let cargo = pkg_from_name(metadata, "cargo"); - let compiletest = pkg_from_name(metadata, "compiletest"); - let cargo_deps = direct_deps_of(metadata, &cargo.id); - let compiletest_deps = direct_deps_of(metadata, &compiletest.id); - let cargo_rustfix = cargo_deps.iter().find(|p| p.name == "rustfix").unwrap(); - let compiletest_rustfix = compiletest_deps.iter().find(|p| p.name == "rustfix").unwrap(); +fn check_rustfix(rust_metadata: &Metadata, cargo_metadata: &Metadata, bad: &mut bool) { + let cargo = pkg_from_name(cargo_metadata, "cargo"); + let cargo_rustfix = + direct_deps_of(cargo_metadata, &cargo.id).find(|p| p.name == "rustfix").unwrap(); + + let compiletest = pkg_from_name(rust_metadata, "compiletest"); + let compiletest_rustfix = + direct_deps_of(rust_metadata, &compiletest.id).find(|p| p.name == "rustfix").unwrap(); + if cargo_rustfix.version != compiletest_rustfix.version { tidy_error!( bad, diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 29664c854c8..c19fa8e9656 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -9,8 +9,8 @@ use std::path::{Path, PathBuf}; // FIXME: The following limits should be reduced eventually. const ENTRY_LIMIT: usize = 885; -const ROOT_ENTRY_LIMIT: usize = 891; -const ISSUES_ENTRY_LIMIT: usize = 1977; +const ROOT_ENTRY_LIMIT: usize = 894; +const ISSUES_ENTRY_LIMIT: usize = 1953; fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap<PathBuf, usize> = HashMap::new(); diff --git a/tests/assembly/asm/inline-asm-avx.rs b/tests/assembly/asm/inline-asm-avx.rs new file mode 100644 index 00000000000..c2875f3e0a4 --- /dev/null +++ b/tests/assembly/asm/inline-asm-avx.rs @@ -0,0 +1,25 @@ +// assembly-output: emit-asm +// compile-flags: --crate-type=lib +// only-x86_64 +// ignore-sgx + +#![feature(portable_simd)] + +use std::simd::Simd; +use std::arch::asm; + +#[target_feature(enable = "avx")] +#[no_mangle] +// CHECK-LABEL: convert: +pub unsafe fn convert(a: *const f32) -> Simd<f32, 8> { + // CHECK: vbroadcastss (%{{[er][a-ds0-9][xpi0-9]?}}), {{%ymm[0-7]}} + let b: Simd<f32, 8>; + unsafe { + asm!( + "vbroadcastss {b}, [{a}]", + a = in(reg) a, + b = out(ymm_reg) b, + ); + } + b +} diff --git a/tests/assembly/asm/loongarch-type.rs b/tests/assembly/asm/loongarch-type.rs new file mode 100644 index 00000000000..4e296f3ade5 --- /dev/null +++ b/tests/assembly/asm/loongarch-type.rs @@ -0,0 +1,196 @@ +// min-llvm-version: 16.0 +// assembly-output: emit-asm +// compile-flags: --target loongarch64-unknown-linux-gnu +// needs-llvm-components: loongarch + +#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)] +#![crate_type = "rlib"] +#![no_core] +#![allow(asm_sub_register, non_camel_case_types)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} +#[rustc_builtin_macro] +macro_rules! concat { + () => {}; +} +#[rustc_builtin_macro] +macro_rules! stringify { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +type ptr = *const i32; + +impl Copy for i8 {} +impl Copy for i16 {} +impl Copy for i32 {} +impl Copy for i64 {} +impl Copy for f32 {} +impl Copy for f64 {} +impl Copy for ptr {} +extern "C" { + fn extern_func(); + static extern_static: u8; +} + +// Hack to avoid function merging +extern "Rust" { + fn dont_merge(s: &str); +} + +// CHECK-LABEL: sym_fn: +// CHECK: #APP +// CHECK: pcalau12i $t0, %got_pc_hi20(extern_func) +// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_func) +// CHECK: #NO_APP +#[no_mangle] +pub unsafe fn sym_fn() { + asm!("la.got $r12, {}", sym extern_func); +} + +// CHECK-LABEL: sym_static: +// CHECK: #APP +// CHECK: pcalau12i $t0, %got_pc_hi20(extern_static) +// CHECK: ld.d $t0, $t0, %got_pc_lo12(extern_static) +// CHECK: #NO_APP +#[no_mangle] +pub unsafe fn sym_static() { + asm!("la.got $r12, {}", sym extern_static); +} + +macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => { + #[no_mangle] + pub unsafe fn $func(x: $ty) -> $ty { + dont_merge(stringify!($func)); + + let y; + asm!(concat!($mov," {}, {}"), out($class) y, in($class) x); + y + } +};} + +macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => { + #[no_mangle] + pub unsafe fn $func(x: $ty) -> $ty { + dont_merge(stringify!($func)); + + let y; + asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x); + y + } +};} + +// CHECK-LABEL: reg_i8: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_i8, i8, reg, "move"); + +// CHECK-LABEL: reg_i16: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_i16, i16, reg, "move"); + +// CHECK-LABEL: reg_i32: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_i32, i32, reg, "move"); + +// CHECK-LABEL: reg_f32: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_f32, f32, reg, "move"); + +// CHECK-LABEL: reg_i64: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_i64, i64, reg, "move"); + +// CHECK-LABEL: reg_f64: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_f64, f64, reg, "move"); + +// CHECK-LABEL: reg_ptr: +// CHECK: #APP +// CHECK: move ${{[a-z0-9]+}}, ${{[a-z0-9]+}} +// CHECK: #NO_APP +check!(reg_ptr, ptr, reg, "move"); + +// CHECK-LABEL: freg_f32: +// CHECK: #APP +// CHECK: fmov.s $f{{[a-z0-9]+}}, $f{{[a-z0-9]+}} +// CHECK: #NO_APP +check!(freg_f32, f32, freg, "fmov.s"); + +// CHECK-LABEL: freg_f64: +// CHECK: #APP +// CHECK: fmov.d $f{{[a-z0-9]+}}, $f{{[a-z0-9]+}} +// CHECK: #NO_APP +check!(freg_f64, f64, freg, "fmov.d"); + +// CHECK-LABEL: r4_i8: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_i8, i8, "$r4", "move"); + +// CHECK-LABEL: r4_i16: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_i16, i16, "$r4", "move"); + +// CHECK-LABEL: r4_i32: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_i32, i32, "$r4", "move"); + +// CHECK-LABEL: r4_f32: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_f32, f32, "$r4", "move"); + +// CHECK-LABEL: r4_i64: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_i64, i64, "$r4", "move"); + +// CHECK-LABEL: r4_f64: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_f64, f64, "$r4", "move"); + +// CHECK-LABEL: r4_ptr: +// CHECK: #APP +// CHECK: move $a0, $a0 +// CHECK: #NO_APP +check_reg!(r4_ptr, ptr, "$r4", "move"); + +// CHECK-LABEL: f0_f32: +// CHECK: #APP +// CHECK: fmov.s $f{{[a-z0-9]+}}, $f{{[a-z0-9]+}} +// CHECK: #NO_APP +check_reg!(f0_f32, f32, "$f0", "fmov.s"); + +// CHECK-LABEL: f0_f64: +// CHECK: #APP +// CHECK: fmov.d $f{{[a-z0-9]+}}, $f{{[a-z0-9]+}} +// CHECK: #NO_APP +check_reg!(f0_f64, f64, "$f0", "fmov.d"); diff --git a/tests/codegen-units/item-collection/cross-crate-trait-method.rs b/tests/codegen-units/item-collection/cross-crate-trait-method.rs index dc0984c8a98..b7216a14318 100644 --- a/tests/codegen-units/item-collection/cross-crate-trait-method.rs +++ b/tests/codegen-units/item-collection/cross-crate-trait-method.rs @@ -1,4 +1,4 @@ -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/function-as-argument.rs b/tests/codegen-units/item-collection/function-as-argument.rs index ea500c3111a..d951cbfacec 100644 --- a/tests/codegen-units/item-collection/function-as-argument.rs +++ b/tests/codegen-units/item-collection/function-as-argument.rs @@ -1,5 +1,4 @@ -// -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/generic-functions.rs b/tests/codegen-units/item-collection/generic-functions.rs index 04383bb8edb..f790cd0dadd 100644 --- a/tests/codegen-units/item-collection/generic-functions.rs +++ b/tests/codegen-units/item-collection/generic-functions.rs @@ -1,4 +1,4 @@ -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/generic-impl.rs b/tests/codegen-units/item-collection/generic-impl.rs index 4260230c2c6..e19eec36b31 100644 --- a/tests/codegen-units/item-collection/generic-impl.rs +++ b/tests/codegen-units/item-collection/generic-impl.rs @@ -1,4 +1,4 @@ -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/trait-implementations.rs b/tests/codegen-units/item-collection/trait-implementations.rs index a816cb03241..ad0ed7da28e 100644 --- a/tests/codegen-units/item-collection/trait-implementations.rs +++ b/tests/codegen-units/item-collection/trait-implementations.rs @@ -1,4 +1,4 @@ -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/trait-method-as-argument.rs b/tests/codegen-units/item-collection/trait-method-as-argument.rs index 235569728a2..164ef794ca7 100644 --- a/tests/codegen-units/item-collection/trait-method-as-argument.rs +++ b/tests/codegen-units/item-collection/trait-method-as-argument.rs @@ -1,5 +1,4 @@ -// -// compile-flags:-Zprint-mono-items=eager +// compile-flags:-Zprint-mono-items=eager -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen-units/item-collection/trait-method-default-impl.rs b/tests/codegen-units/item-collection/trait-method-default-impl.rs index bfcdb6fa142..d953582cce9 100644 --- a/tests/codegen-units/item-collection/trait-method-default-impl.rs +++ b/tests/codegen-units/item-collection/trait-method-default-impl.rs @@ -1,4 +1,4 @@ -// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on +// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on -Zinline-mir=no #![deny(dead_code)] #![feature(start)] diff --git a/tests/codegen/align-fn.rs b/tests/codegen/align-fn.rs index c5886cf2808..f3cf614e185 100644 --- a/tests/codegen/align-fn.rs +++ b/tests/codegen/align-fn.rs @@ -7,3 +7,43 @@ #[no_mangle] #[repr(align(16))] pub fn fn_align() {} + +pub struct A; + +impl A { + // CHECK: align 16 + #[no_mangle] + #[repr(align(16))] + pub fn method_align(self) {} + + // CHECK: align 16 + #[no_mangle] + #[repr(align(16))] + pub fn associated_fn() {} +} + +trait T: Sized { + fn trait_fn() {} + + // CHECK: align 32 + #[repr(align(32))] + fn trait_method(self) {} +} + +impl T for A { + // CHECK: align 16 + #[no_mangle] + #[repr(align(16))] + fn trait_fn() {} + + // CHECK: align 16 + #[no_mangle] + #[repr(align(16))] + fn trait_method(self) {} +} + +impl T for () {} + +pub fn foo() { + ().trait_method(); +} diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs index 7b8ab2c79a7..3706ddf99fd 100644 --- a/tests/codegen/array-map.rs +++ b/tests/codegen/array-map.rs @@ -21,7 +21,7 @@ pub fn short_integer_map(x: [u32; 8]) -> [u32; 8] { pub fn short_integer_zip_map(x: [u32; 8], y: [u32; 8]) -> [u32; 8] { // CHECK: %[[A:.+]] = load <8 x i32> // CHECK: %[[B:.+]] = load <8 x i32> - // CHECK: sub <8 x i32> %[[A]], %[[B]] + // CHECK: sub <8 x i32> %[[B]], %[[A]] // CHECK: store <8 x i32> x.zip(y).map(|(x, y)| x - y) } diff --git a/tests/codegen/debuginfo-constant-locals.rs b/tests/codegen/debuginfo-constant-locals.rs new file mode 100644 index 00000000000..95a1b8c9d21 --- /dev/null +++ b/tests/codegen/debuginfo-constant-locals.rs @@ -0,0 +1,28 @@ +// compile-flags: -g -O + +// Check that simple constant values are preserved in debuginfo across both MIR opts and LLVM opts + +#![crate_type = "lib"] + +#[no_mangle] +pub fn check_it() { + let a = 1; + let b = 42; + + foo(a + b); +} + +#[inline(never)] +fn foo(x: i32) { + std::process::exit(x); +} + +// CHECK-LABEL: @check_it +// CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[a_metadata:[0-9]+]], metadata !DIExpression()) +// CHECK: call void @llvm.dbg.value(metadata i32 42, metadata ![[b_metadata:[0-9]+]], metadata !DIExpression()) + +// CHECK: ![[a_metadata]] = !DILocalVariable(name: "a" +// CHECK-SAME: line: 9 + +// CHECK: ![[b_metadata]] = !DILocalVariable(name: "b" +// CHECK-SAME: line: 10 diff --git a/tests/codegen/inline-hint.rs b/tests/codegen/inline-hint.rs index d3ea1915a8b..bb2a8e6a649 100644 --- a/tests/codegen/inline-hint.rs +++ b/tests/codegen/inline-hint.rs @@ -1,7 +1,7 @@ // Checks that closures, constructors, and shims except // for a drop glue receive inline hint by default. // -// compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 +// compile-flags: -Cno-prepopulate-passes -Csymbol-mangling-version=v0 -Zinline-mir=no #![crate_type = "lib"] pub fn f() { diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs new file mode 100644 index 00000000000..69e9b1d1206 --- /dev/null +++ b/tests/codegen/intrinsics/transmute-niched.rs @@ -0,0 +1,184 @@ +// revisions: OPT DBG +// [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes +// [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes +// only-64bit (so I don't need to worry about usize) +// min-llvm-version: 15.0 # this test assumes `ptr`s + +#![crate_type = "lib"] + +use std::mem::transmute; +use std::num::NonZeroU32; + +#[repr(u8)] +pub enum SmallEnum { + A = 10, + B = 11, + C = 12, +} + +// CHECK-LABEL: @check_to_enum( +#[no_mangle] +pub unsafe fn check_to_enum(x: i8) -> SmallEnum { + // OPT: %0 = icmp uge i8 %x, 10 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp ule i8 %x, 12 + // OPT: call void @llvm.assume(i1 %1) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_from_enum( +#[no_mangle] +pub unsafe fn check_from_enum(x: SmallEnum) -> i8 { + // OPT: %0 = icmp uge i8 %x, 10 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp ule i8 %x, 12 + // OPT: call void @llvm.assume(i1 %1) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_to_ordering( +#[no_mangle] +pub unsafe fn check_to_ordering(x: u8) -> std::cmp::Ordering { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_from_ordering( +#[no_mangle] +pub unsafe fn check_from_ordering(x: std::cmp::Ordering) -> u8 { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +#[repr(i32)] +pub enum Minus100ToPlus100 { + A = -100, + B = -90, + C = -80, + D = -70, + E = -60, + F = -50, + G = -40, + H = -30, + I = -20, + J = -10, + K = 0, + L = 10, + M = 20, + N = 30, + O = 40, + P = 50, + Q = 60, + R = 70, + S = 80, + T = 90, + U = 100, +} + +// CHECK-LABEL: @check_enum_from_char( +#[no_mangle] +pub unsafe fn check_enum_from_char(x: char) -> Minus100ToPlus100 { + // OPT: %0 = icmp ule i32 %x, 1114111 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp uge i32 %x, -100 + // OPT: %2 = icmp ule i32 %x, 100 + // OPT: %3 = or i1 %1, %2 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i32 %x + + transmute(x) +} + +// CHECK-LABEL: @check_enum_to_char( +#[no_mangle] +pub unsafe fn check_enum_to_char(x: Minus100ToPlus100) -> char { + // OPT: %0 = icmp uge i32 %x, -100 + // OPT: %1 = icmp ule i32 %x, 100 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i32 %x, 1114111 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i32 %x + + transmute(x) +} + +// CHECK-LABEL: @check_swap_pair( +#[no_mangle] +pub unsafe fn check_swap_pair(x: (char, NonZeroU32)) -> (NonZeroU32, char) { + // OPT: %0 = icmp ule i32 %x.0, 1114111 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp uge i32 %x.0, 1 + // OPT: call void @llvm.assume(i1 %1) + // OPT: %2 = icmp uge i32 %x.1, 1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i32 %x.1, 1114111 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: %[[P1:.+]] = insertvalue { i32, i32 } poison, i32 %x.0, 0 + // CHECK: %[[P2:.+]] = insertvalue { i32, i32 } %[[P1]], i32 %x.1, 1 + // CHECK: ret { i32, i32 } %[[P2]] + + transmute(x) +} + +// CHECK-LABEL: @check_bool_from_ordering( +#[no_mangle] +pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i8 %x, 1 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: ret i1 %[[R]] + + transmute(x) +} + +// CHECK-LABEL: @check_bool_to_ordering( +#[no_mangle] +pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering { + // CHECK: %0 = zext i1 %x to i8 + // OPT: %1 = icmp ule i8 %0, 1 + // OPT: call void @llvm.assume(i1 %1) + // OPT: %2 = icmp uge i8 %0, -1 + // OPT: %3 = icmp ule i8 %0, 1 + // OPT: %4 = or i1 %2, %3 + // OPT: call void @llvm.assume(i1 %4) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %0 + + transmute(x) +} diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 57f901c6719..664e697c2a5 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -8,10 +8,10 @@ #![feature(inline_const)] #![allow(unreachable_code)] -use std::mem::{transmute, MaybeUninit}; +use std::mem::MaybeUninit; +use std::intrinsics::{transmute, transmute_unchecked}; -// Some of the cases here are statically rejected by `mem::transmute`, so -// we need to generate custom MIR for those cases to get to codegen. +// Some of these need custom MIR to not get removed by MIR optimizations. use std::intrinsics::mir::*; enum Never {} @@ -30,59 +30,35 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_size(x: u16) -> u32 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_size(x: u32) -> u16 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_to_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK: call void @llvm.trap mir!{ @@ -95,7 +71,7 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK-LABEL: @check_from_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { // CHECK: ret i16 poison mir!{ @@ -169,8 +145,8 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 { #[no_mangle] pub unsafe fn check_byte_to_bool(x: u8) -> bool { // CHECK-NOT: alloca - // CHECK: %0 = trunc i8 %x to i1 - // CHECK: ret i1 %0 + // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: ret i1 %[[R]] transmute(x) } @@ -178,8 +154,8 @@ pub unsafe fn check_byte_to_bool(x: u8) -> bool { #[no_mangle] pub unsafe fn check_byte_from_bool(x: bool) -> u8 { // CHECK-NOT: alloca - // CHECK: %0 = zext i1 %x to i8 - // CHECK: ret i8 %0 + // CHECK: %[[R:.+]] = zext i1 %x to i8 + // CHECK: ret i8 %[[R:.+]] transmute(x) } diff --git a/tests/codegen/local-generics-in-exe-internalized.rs b/tests/codegen/local-generics-in-exe-internalized.rs index e5430fbf17a..449c5ca75fc 100644 --- a/tests/codegen/local-generics-in-exe-internalized.rs +++ b/tests/codegen/local-generics-in-exe-internalized.rs @@ -1,4 +1,4 @@ -// compile-flags: -C no-prepopulate-passes -Zshare-generics=yes +// compile-flags: -C no-prepopulate-passes -Zshare-generics=yes -Zinline-mir=no // Check that local generics are internalized if they are in the same CGU diff --git a/tests/codegen/optimize-attr-1.rs b/tests/codegen/optimize-attr-1.rs index 1d1f0a38657..d95ba853030 100644 --- a/tests/codegen/optimize-attr-1.rs +++ b/tests/codegen/optimize-attr-1.rs @@ -9,7 +9,7 @@ // CHECK-LABEL: define{{.*}}i32 @nothing // CHECK-SAME: [[NOTHING_ATTRS:#[0-9]+]] // SIZE-OPT: ret i32 4 -// SPEEC-OPT: ret i32 4 +// SPEED-OPT: ret i32 4 #[no_mangle] pub fn nothing() -> i32 { 2 + 2 diff --git a/tests/codegen/option-as-slice.rs b/tests/codegen/option-as-slice.rs index d735d558374..1edd9ba9f7d 100644 --- a/tests/codegen/option-as-slice.rs +++ b/tests/codegen/option-as-slice.rs @@ -1,5 +1,7 @@ // compile-flags: -O -Z randomize-layout=no // only-x86_64 +// ignore-llvm-version: 16.0.0 +// ^ needs https://reviews.llvm.org/D146149 in 16.0.1 #![crate_type = "lib"] #![feature(option_as_slice)] diff --git a/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs b/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs index 59092dbf637..15bd0f17421 100644 --- a/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs +++ b/tests/codegen/remap_path_prefix/auxiliary/xcrate-generic.rs @@ -3,4 +3,6 @@ #![crate_type = "lib"] -pub fn foo<T>() {} +pub fn foo<T: Default>() -> T { + T::default() +} diff --git a/tests/codegen/remap_path_prefix/xcrate-generic.rs b/tests/codegen/remap_path_prefix/xcrate-generic.rs index 7a9d2ca9b6b..399deec1fc9 100644 --- a/tests/codegen/remap_path_prefix/xcrate-generic.rs +++ b/tests/codegen/remap_path_prefix/xcrate-generic.rs @@ -7,7 +7,7 @@ extern crate xcrate_generic; pub fn foo() { - xcrate_generic::foo::<u32>(); + println!("{}", xcrate_generic::foo::<u32>()); } // Here we check that local debuginfo is mapped correctly. diff --git a/tests/codegen/thread-local.rs b/tests/codegen/thread-local.rs index aa7fab7fb17..caf0366d2c1 100644 --- a/tests/codegen/thread-local.rs +++ b/tests/codegen/thread-local.rs @@ -20,8 +20,8 @@ thread_local!(static A: Cell<u32> = const { Cell::new(1) }); // CHECK-LABEL: @get #[no_mangle] fn get() -> u32 { - // CHECK: %0 = load i32, {{.*}}[[TLS]]{{.*}} - // CHECK-NEXT: ret i32 %0 + // CHECK: [[RET_0:%.+]] = load i32, {{.*}}[[TLS]]{{.*}} + // CHECK-NEXT: ret i32 [[RET_0]] A.with(|a| a.get()) } @@ -36,8 +36,8 @@ fn set(v: u32) { // CHECK-LABEL: @get_aux #[no_mangle] fn get_aux() -> u64 { - // CHECK: %0 = load i64, {{.*}}[[TLS_AUX]] - // CHECK-NEXT: ret i64 %0 + // CHECK: [[RET_1:%.+]] = load i64, {{.*}}[[TLS_AUX]] + // CHECK-NEXT: ret i64 [[RET_1]] aux::A.with(|a| a.get()) } diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs new file mode 100644 index 00000000000..461dd550cd7 --- /dev/null +++ b/tests/codegen/transmute-optimized.rs @@ -0,0 +1,109 @@ +// compile-flags: -O -Z merge-functions=disabled +// min-llvm-version: 15.0 # this test uses `ptr`s +// ignore-debug + +#![crate_type = "lib"] + +// This tests that LLVM can optimize based on the niches in the source or +// destination types for transmutes. + +#[repr(u32)] +pub enum AlwaysZero32 { X = 0 } + +// CHECK-LABEL: i32 @issue_109958(i32 +#[no_mangle] +pub fn issue_109958(x: AlwaysZero32) -> i32 { + // CHECK: ret i32 0 + unsafe { std::mem::transmute(x) } +} + +// CHECK-LABEL: i1 @reference_is_null(ptr +#[no_mangle] +pub fn reference_is_null(x: &i32) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_null_is_null(ptr +#[no_mangle] +pub fn non_null_is_null(x: std::ptr::NonNull<i32>) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_zero_is_null( +#[no_mangle] +pub fn non_zero_is_null(x: std::num::NonZeroUsize) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_null_is_zero(ptr +#[no_mangle] +pub fn non_null_is_zero(x: std::ptr::NonNull<i32>) -> bool { + // CHECK: ret i1 false + let a: isize = unsafe { std::mem::transmute(x) }; + a == 0 +} + +// CHECK-LABEL: i1 @bool_ordering_is_ge(i1 +#[no_mangle] +pub fn bool_ordering_is_ge(x: bool) -> bool { + // CHECK: ret i1 true + let y: std::cmp::Ordering = unsafe { std::mem::transmute(x) }; + y.is_ge() +} + +// CHECK-LABEL: i1 @ordering_is_ge_then_transmute_to_bool(i8 +#[no_mangle] +pub fn ordering_is_ge_then_transmute_to_bool(x: std::cmp::Ordering) -> bool { + let r = x.is_ge(); + let _: bool = unsafe { std::mem::transmute(x) }; + r +} + +// CHECK-LABEL: i32 @normal_div(i32 +#[no_mangle] +pub fn normal_div(a: u32, b: u32) -> u32 { + // CHECK: call core::panicking::panic + a / b +} + +// CHECK-LABEL: i32 @div_transmute_nonzero(i32 +#[no_mangle] +pub fn div_transmute_nonzero(a: u32, b: std::num::NonZeroI32) -> u32 { + // CHECK-NOT: call core::panicking::panic + // CHECK: %[[R:.+]] = udiv i32 %a, %b + // CHECK-NEXT: ret i32 %[[R]] + // CHECK-NOT: call core::panicking::panic + let d: u32 = unsafe { std::mem::transmute(b) }; + a / d +} + +#[repr(i8)] +pub enum OneTwoThree { One = 1, Two = 2, Three = 3 } + +// CHECK-LABEL: i8 @ordering_transmute_onetwothree(i8 +#[no_mangle] +pub unsafe fn ordering_transmute_onetwothree(x: std::cmp::Ordering) -> OneTwoThree { + // CHECK: ret i8 1 + std::mem::transmute(x) +} + +// CHECK-LABEL: i8 @onetwothree_transmute_ordering(i8 +#[no_mangle] +pub unsafe fn onetwothree_transmute_ordering(x: OneTwoThree) -> std::cmp::Ordering { + // CHECK: ret i8 1 + std::mem::transmute(x) +} + +// CHECK-LABEL: i1 @char_is_negative(i32 +#[no_mangle] +pub fn char_is_negative(c: char) -> bool { + // CHECK: ret i1 false + let x: i32 = unsafe { std::mem::transmute(c) }; + x < 0 +} diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index af2cef472ec..a0894a505c7 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -1,4 +1,4 @@ -// compile-flags: -O -C no-prepopulate-passes +// compile-flags: -C opt-level=0 -C no-prepopulate-passes // min-llvm-version: 15.0 # this test assumes `ptr`s and thus no `pointercast`s #![crate_type = "lib"] @@ -10,7 +10,7 @@ // However, `bitcast`s and `ptrtoint`s and `inttoptr`s are still worth doing when // that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`. -// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float noundef %x) +// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x) // CHECK: %0 = bitcast float %x to i32 // CHECK-NEXT: ret i32 %0 #[no_mangle] @@ -18,7 +18,7 @@ pub fn f32_to_bits(x: f32) -> u32 { unsafe { std::mem::transmute(x) } } -// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 noundef zeroext %b) +// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b) // CHECK: %0 = zext i1 %b to i8 // CHECK-NEXT: ret i8 %0 #[no_mangle] @@ -26,7 +26,7 @@ pub fn bool_to_byte(b: bool) -> u8 { unsafe { std::mem::transmute(b) } } -// CHECK-LABEL: define{{.*}}noundef zeroext i1 @byte_to_bool(i8 noundef %byte) +// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte) // CHECK: %0 = trunc i8 %byte to i1 // CHECK-NEXT: ret i1 %0 #[no_mangle] @@ -34,14 +34,14 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) } -// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr noundef %p) +// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr %p) // CHECK: ret ptr %p #[no_mangle] pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { unsafe { std::mem::transmute(p) } } -// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr noundef %p) +// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p) // CHECK: %0 = ptrtoint ptr %p to [[USIZE]] // CHECK-NEXT: ret [[USIZE]] %0 #[no_mangle] @@ -49,7 +49,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { unsafe { std::mem::transmute(p) } } -// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] noundef %i) +// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) // CHECK: %0 = inttoptr [[USIZE]] %i to ptr // CHECK-NEXT: ret ptr %0 #[no_mangle] diff --git a/tests/debuginfo/auxiliary/macro-stepping.rs b/tests/debuginfo/auxiliary/macro-stepping.rs index 4447dd22ddb..ae50e11440b 100644 --- a/tests/debuginfo/auxiliary/macro-stepping.rs +++ b/tests/debuginfo/auxiliary/macro-stepping.rs @@ -5,6 +5,6 @@ #[macro_export] macro_rules! new_scope { () => { - let x = 1; + let x = 1; opaque(x); } } diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index e4b2b7b79bc..a7287cffd02 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -79,22 +79,28 @@ extern crate macro_stepping; // exports new_scope!() // lldb-check:[...]#inc-loc2[...] // lldb-command:next // lldb-command:frame select +// lldb-check:[...]#inc-loc1[...] +// lldb-command:next +// lldb-command:frame select +// lldb-check:[...]#inc-loc2[...] +// lldb-command:next +// lldb-command:frame select // lldb-check:[...]#inc-loc3[...] macro_rules! foo { () => { - let a = 1; - let b = 2; - let c = 3; - } + let a = 1; opaque(a); + let b = 2; opaque(b); + let c = 3; opaque(c); + }; } macro_rules! foo2 { () => { foo!(); - let x = 1; + let x = 1; opaque(x); foo!(); - } + }; } fn main() { @@ -118,4 +124,6 @@ fn main() { fn zzz() {()} +fn opaque(_: u32) {} + include!("macro-stepping.inc"); diff --git a/tests/debuginfo/pretty-std.rs b/tests/debuginfo/pretty-std.rs index 7bb2810c2b2..c7df7dc3cb3 100644 --- a/tests/debuginfo/pretty-std.rs +++ b/tests/debuginfo/pretty-std.rs @@ -130,8 +130,8 @@ // cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String] // cdb-command: dx linkedlist -// cdb-check:linkedlist : { len=0x2 } [Type: alloc::collections::linked_list::LinkedList<i32>] -// cdb-check: [<Raw View>] [Type: alloc::collections::linked_list::LinkedList<i32>] +// cdb-check:linkedlist : { len=0x2 } [Type: alloc::collections::linked_list::LinkedList<i32,alloc::alloc::Global>] +// cdb-check: [<Raw View>] [Type: alloc::collections::linked_list::LinkedList<i32,alloc::alloc::Global>] // cdb-check: [0x0] : 128 [Type: int] // cdb-check: [0x1] : 42 [Type: int] diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs index b1ec9b06830..3b8280bc4a9 100644 --- a/tests/debuginfo/unsized.rs +++ b/tests/debuginfo/unsized.rs @@ -1,4 +1,6 @@ // compile-flags:-g +// ignore-gdb-version: 13.1 - 99.0 +// ^ https://sourceware.org/bugzilla/show_bug.cgi?id=30330 // === GDB TESTS =================================================================================== diff --git a/tests/incremental/const-generics/change-const-param-gat.rs b/tests/incremental/const-generics/change-const-param-gat.rs new file mode 100644 index 00000000000..f1449d5681e --- /dev/null +++ b/tests/incremental/const-generics/change-const-param-gat.rs @@ -0,0 +1,29 @@ +// revisions: rpass1 rpass2 rpass3 +// compile-flags: -Zincremental-ignore-spans +#![feature(generic_associated_types)] + +// This test unsures that with_opt_const_param returns the +// def_id of the N param in the Foo::Assoc GAT. + +trait Foo { + type Assoc<const N: usize>; + fn foo( + &self, + ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }>; +} + +impl Foo for () { + type Assoc<const N: usize> = [(); N]; + fn foo( + &self, + ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }> { + [(); { if cfg!(rpass2) { 3 } else { 2 } }] + } +} + +fn main() { + assert_eq!( + ().foo(), + [(); { if cfg!(rpass2) { 3 } else { 2 } }] + ); +} diff --git a/tests/incremental/const-generics/change-const-param-type.rs b/tests/incremental/const-generics/change-const-param-type.rs new file mode 100644 index 00000000000..1aac1bc7d72 --- /dev/null +++ b/tests/incremental/const-generics/change-const-param-type.rs @@ -0,0 +1,68 @@ +// revisions: rpass1 rpass2 rpass3 +// compile-flags: -Zincremental-ignore-spans + +enum Foo<const N: usize> { + Variant, + Variant2(), + Variant3 {}, +} + +impl Foo<1> { + fn foo<const N: usize>(&self) -> [(); N] { [(); N] } +} + +impl Foo<2> { + fn foo<const N: u32>(self) -> usize { N as usize } +} + +struct Bar<const N: usize>; +struct Bar2<const N: usize>(); +struct Bar3<const N: usize> {} + +#[cfg(rpass1)] +struct ChangingStruct<const N: usize>; + +#[cfg(any(rpass2, rpass3))] +struct ChangingStruct<const N: u32>; + +struct S; + +impl S { + #[cfg(rpass1)] + fn changing_method<const N: usize>(self) {} + + #[cfg(any(rpass2, rpass3))] + fn changing_method<const N: u32>(self) {} +} + +// We want to verify that all goes well when the value of the const argument change. +// To avoid modifying `main`'s HIR, we use a separate constant, and use `{ FOO_ARG + 1 }` +// inside the body to keep having an `AnonConst` to compute. +const FOO_ARG: usize = if cfg!(rpass2) { 1 } else { 0 }; + +fn main() { + let foo = Foo::Variant::<{ FOO_ARG + 1 }>; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::Variant2::<{ FOO_ARG + 1 }>(); + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::Variant3::<{ FOO_ARG + 1 }> {}; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant2(); + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant3 {}; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let _ = Bar::<{ FOO_ARG + 1 }>; + let _ = Bar2::<{ FOO_ARG + 1 }>(); + let _ = Bar3::<{ FOO_ARG + 1 }> {}; + + let _ = ChangingStruct::<{ 5 }>; + let _ = S.changing_method::<{ 5 }>(); +} diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs index db367d07094..f685fe46d70 100644 --- a/tests/incremental/hashes/enum_constructors.rs +++ b/tests/incremental/hashes/enum_constructors.rs @@ -334,9 +334,9 @@ pub fn change_constructor_variant_c_like() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_variant_c_like() { let _x = Clike::C; diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs index 7aca4324233..a835b8eef8c 100644 --- a/tests/incremental/hashes/let_expressions.rs +++ b/tests/incremental/hashes/let_expressions.rs @@ -91,7 +91,7 @@ pub fn change_mutability_of_slot() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -176,7 +176,7 @@ pub fn change_mutability_of_binding_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -193,9 +193,9 @@ pub fn add_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -210,9 +210,9 @@ pub fn change_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_initializer() { let _x = 5u16; diff --git a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 19daae86589..41657b53fc1 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -7,10 +7,10 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 bb0: { - _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 // mir::Constant // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -18,4 +18,4 @@ promoted[0] in FOO: &[&i32; 1] = { } } -alloc2 (extern static: X) +alloc3 (extern static: X) diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 5b13d60052f..25ba0face6b 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -18,11 +18,11 @@ - StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 - StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 -- _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 +- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 // mir::Constant - // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 -- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } - _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 - _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -50,5 +50,5 @@ } } - -- alloc2 (extern static: X) +- alloc3 (extern static: X) diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff new file mode 100644 index 00000000000..4e2f1b39d2b --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff @@ -0,0 +1,43 @@ +- // MIR for `concrete` before ConstProp ++ // MIR for `concrete` after ConstProp + + fn concrete() -> () { + let mut _0: (); // return place in scope 0 at $DIR/offset_of.rs:+0:15: +0:15 + let _1: usize; // in scope 0 at $DIR/offset_of.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/offset_of.rs:+1:9: +1:10 + let _2: usize; // in scope 1 at $DIR/offset_of.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/offset_of.rs:+2:9: +2:10 + let _3: usize; // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + scope 3 { + debug z0 => _3; // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11 + let _4: usize; // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + scope 4 { + debug z1 => _4; // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:10 +- _1 = OffsetOf(Alpha, [0]); // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 ++ _1 = const 4_usize; // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 + StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:10 +- _2 = OffsetOf(Alpha, [1]); // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 ++ _2 = const 0_usize; // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 + StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 +- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 ++ _3 = const 2_usize; // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 + StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 +- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 ++ _4 = const 3_usize; // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 + StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/offset_of.rs:+5:1: +5:2 + return; // scope 0 at $DIR/offset_of.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff new file mode 100644 index 00000000000..5c6cb47089e --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff @@ -0,0 +1,39 @@ +- // MIR for `generic` before ConstProp ++ // MIR for `generic` after ConstProp + + fn generic() -> () { + let mut _0: (); // return place in scope 0 at $DIR/offset_of.rs:+0:17: +0:17 + let _1: usize; // in scope 0 at $DIR/offset_of.rs:+1:9: +1:11 + scope 1 { + debug gx => _1; // in scope 1 at $DIR/offset_of.rs:+1:9: +1:11 + let _2: usize; // in scope 1 at $DIR/offset_of.rs:+2:9: +2:11 + scope 2 { + debug gy => _2; // in scope 2 at $DIR/offset_of.rs:+2:9: +2:11 + let _3: usize; // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + scope 3 { + debug dx => _3; // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11 + let _4: usize; // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + scope 4 { + debug dy => _4; // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:11 + _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $DIR/offset_of.rs:+1:14: +1:37 + StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:11 + _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $DIR/offset_of.rs:+2:14: +2:37 + StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:37 + StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:37 + StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/offset_of.rs:+5:1: +5:2 + return; // scope 0 at $DIR/offset_of.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs new file mode 100644 index 00000000000..eabdf848079 --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.rs @@ -0,0 +1,49 @@ +// unit-test +// compile-flags: -O + +#![feature(offset_of)] + +use std::marker::PhantomData; +use std::mem::offset_of; + +struct Alpha { + x: u8, + y: u16, + z: Beta, +} + +struct Beta(u8, u8); + +struct Gamma<T> { + x: u8, + y: u16, + _t: T, +} + +#[repr(C)] +struct Delta<T> { + _phantom: PhantomData<T>, + x: u8, + y: u16, +} + +// EMIT_MIR offset_of.concrete.ConstProp.diff +fn concrete() { + let x = offset_of!(Alpha, x); + let y = offset_of!(Alpha, y); + let z0 = offset_of!(Alpha, z.0); + let z1 = offset_of!(Alpha, z.1); +} + +// EMIT_MIR offset_of.generic.ConstProp.diff +fn generic<T>() { + let gx = offset_of!(Gamma<T>, x); + let gy = offset_of!(Gamma<T>, y); + let dx = offset_of!(Delta<T>, x); + let dy = offset_of!(Delta<T>, y); +} + +fn main() { + concrete(); + generic::<()>(); +} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir deleted file mode 100644 index 81cfd22db6c..00000000000 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `main` after PreCodegen - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir deleted file mode 100644 index 81cfd22db6c..00000000000 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `main` after PreCodegen - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir deleted file mode 100644 index 002e914e8fa..00000000000 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `main` after SimplifyLocals-final - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir deleted file mode 100644 index 002e914e8fa..00000000000 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `main` after SimplifyLocals-final - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 - scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 - } - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 - } -} diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.diff index 18df6f9af5f..3aebfb69e0a 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.diff @@ -8,7 +8,7 @@ + let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:14:8: 14:21 + let mut _3: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:12:18: 12:25 + scope 2 { -+ debug buffer => _3; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 ++ debug buffer => const _; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 + scope 3 { + debug index => _0; // in scope 3 at $DIR/issue_106141.rs:13:9: 13:14 + } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff index 6184a0acd18..d76cd0e2bb8 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -10,50 +10,52 @@ + scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _6: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { -+ scope 3 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ scope 4 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _4; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _8: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _9: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: u16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ } -+ } -+ scope 5 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _11: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _12: u16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ scope 6 { -+ debug x => _12; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ } -+ scope 7 { -+ scope 8 { -+ debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } + } -+ } -+ } -+ scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _13: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 10 { -+ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ scope 11 { -+ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 14 { -+ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } + } + } ++ scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } + } + } -+ scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL -+ } + } + } + } @@ -67,75 +69,81 @@ - // mir::Constant - // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 - // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::<impl u16>::unchecked_shl}, val: Value(<ZST>) } -+ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = const 65535_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _8 = Gt(_4, move _9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_12); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + -+ bb3: { -+ _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ bb2: { ++ _9 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::<u16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = _4 as u16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _7 = Result::<u16, TryFromIntError>::Ok(move _10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_12); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _11 = discriminant(_7); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<u16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { -+ _6 = Option::<u16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { -+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _14 = move ((_9 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<u16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ _12 = move ((_7 as Ok).0: u16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ _6 = Option::<u16>::Some(move _12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _5 = move ((_8 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir index 726b6bbf93b..3c175ed1504 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -7,122 +7,130 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _4: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _5: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { - scope 3 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _2; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - scope 4 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _2; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _8: u16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - } - } - scope 5 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _5; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: u16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug x => _10; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - scope 8 { - debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } } - } - } - scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _4; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _11: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - scope 10 { - debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL - } - scope 11 { - scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL - scope 14 { - scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } } } + scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } } } - scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _11; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL - } } } } bb0: { - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = const 65535_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_2, move _7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _12 = discriminant(_4); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - } - - bb2: { StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb3: { - _5 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + bb2: { + _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::<u16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb4: { - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = _2 as u16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = Result::<u16, TryFromIntError>::Ok(move _8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - StorageDead(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _9 = discriminant(_5); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<u16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - _4 = Option::<u16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb7: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<u16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb8: { - _10 = move ((_5 as Ok).0: u16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _4 = Option::<u16>::Some(move _10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb9: { - _3 = move ((_4 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _0 = unchecked_shl::<u16>(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _3 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shl::<u16>(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff index 35d5b6e72f2..f3d3e6090bb 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -10,50 +10,52 @@ + scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _6: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { -+ scope 3 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ scope 4 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _4; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _8: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _9: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: i16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ } -+ } -+ scope 5 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _11: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _12: i16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ scope 6 { -+ debug x => _12; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ } -+ scope 7 { -+ scope 8 { -+ debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } + } -+ } -+ } -+ scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _13: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 10 { -+ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ scope 11 { -+ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 14 { -+ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } + } + } ++ scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } + } + } -+ scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL -+ } + } + } + } @@ -67,75 +69,81 @@ - // mir::Constant - // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 - // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::<impl i16>::unchecked_shr}, val: Value(<ZST>) } -+ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = const 32767_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _8 = Gt(_4, move _9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_12); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + -+ bb3: { -+ _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ bb2: { ++ _9 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::<i16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = _4 as i16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _7 = Result::<i16, TryFromIntError>::Ok(move _10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_12); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _11 = discriminant(_7); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<i16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { -+ _6 = Option::<i16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { -+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _14 = move ((_9 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<i16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ _12 = move ((_7 as Ok).0: i16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ _6 = Option::<i16>::Some(move _12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _5 = move ((_8 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir index b006085b54c..724b3c56723 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -7,122 +7,130 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _4: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _5: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { - scope 3 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _2; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - scope 4 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _2; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _8: i16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - } - } - scope 5 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _5; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: i16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug x => _10; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - scope 8 { - debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } } - } - } - scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _4; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _11: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - scope 10 { - debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL - } - scope 11 { - scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL - scope 14 { - scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } } } + scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } } } - scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _11; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL - } } } } bb0: { - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = const 32767_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_2, move _7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _12 = discriminant(_4); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - } - - bb2: { StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb3: { - _5 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + bb2: { + _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::<i16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb4: { - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = _2 as i16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = Result::<i16, TryFromIntError>::Ok(move _8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - StorageDead(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _9 = discriminant(_5); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<i16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - _4 = Option::<i16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb7: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<i16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb8: { - _10 = move ((_5 as Ok).0: i16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _4 = Option::<i16>::Some(move _10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb9: { - _3 = move ((_4 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _0 = unchecked_shr::<i16>(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _3 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shr::<i16>(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff index 543ddcfc44c..8a8cd896e85 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff @@ -34,7 +34,7 @@ - // + literal: Const { ty: unsafe fn(Option<T>) -> T {Option::<T>::unwrap_unchecked}, val: Value(<ZST>) } + StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + _4 = discriminant(_2); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _4) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL } bb1: { diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir index 2324f53566c..f0c9ef419bd 100644 --- a/tests/mir-opt/issue_99325.main.built.after.mir +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -2,7 +2,7 @@ | User Type Annotations | 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[22bb]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15 diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index 42b60532690..9f955b4717b 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -4,31 +4,29 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24 let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 let mut _2: std::option::Option<u32>; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 - let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue_59352.rs:15:12: 15:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let mut _4: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let _5: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => const 8_u32; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _3: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _4: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL scope 2 (inlined Option::<u32>::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug self => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _6: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _3; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _5: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } } scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue_59352.rs:15:42: 15:50 debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _8: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _7: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL scope 4 { debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL } } bb0: { - StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _5 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _4 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) } @@ -43,8 +41,8 @@ fn num_to_digit(_1: char) -> u32 { } bb2: { - _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _6 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _6) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL } bb3: { @@ -57,16 +55,15 @@ fn num_to_digit(_1: char) -> u32 { } bb5: { - _4 = &_5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _6 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + _3 = &_4; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _5 = discriminant((*_3)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 - switchInt(move _6) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { - _8 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/option.rs:LL:COL // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) } diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir deleted file mode 100644 index 4f5df133181..00000000000 --- a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir +++ /dev/null @@ -1,25 +0,0 @@ -// MIR for `f_u64` after PreCodegen - -fn f_u64() -> () { - let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16 - let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 - scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21 - debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 - let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 - scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 - } - } - - bb0: { - StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 - _2 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 - // mir::Constant - // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18 - // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) } - } - - bb1: { - StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 - return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 - } -} diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir deleted file mode 100644 index 8654e80cd7c..00000000000 --- a/tests/mir-opt/lower_intrinsics_e2e.f_unit.PreCodegen.after.mir +++ /dev/null @@ -1,22 +0,0 @@ -// MIR for `f_unit` after PreCodegen - -fn f_unit() -> () { - let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17 - scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19 - debug t => const (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 - let _1: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17 - scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 - } - } - - bb0: { - _1 = f_zst::<()>(const ()) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17 - // mir::Constant - // + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14 - // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) } - } - - bb1: { - return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 - } -} diff --git a/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index 6cd6d8b7795..be5baf6ee39 100644 --- a/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/tests/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -1,39 +1,39 @@ // MIR for `use_x` 0 nll | Free Region Mapping -| '_#0r | Global | ['_#2r, '_#1r, '_#0r, '_#4r, '_#3r] -| '_#1r | Local | ['_#1r, '_#4r] -| '_#2r | Local | ['_#2r, '_#1r, '_#4r] -| '_#3r | Local | ['_#4r, '_#3r] -| '_#4r | Local | ['_#4r] +| '?0 | Global | ['?2, '?1, '?0, '?4, '?3] +| '?1 | Local | ['?1, '?4] +| '?2 | Local | ['?2, '?1, '?4] +| '?3 | Local | ['?4, '?3] +| '?4 | Local | ['?4] | | Inferred Region Values -| '_#0r | U0 | {bb0[0..=1], '_#0r, '_#1r, '_#2r, '_#3r, '_#4r} -| '_#1r | U0 | {bb0[0..=1], '_#1r} -| '_#2r | U0 | {bb0[0..=1], '_#2r} -| '_#3r | U0 | {bb0[0..=1], '_#3r} -| '_#4r | U0 | {bb0[0..=1], '_#4r} -| '_#5r | U0 | {bb0[0..=1], '_#1r} -| '_#6r | U0 | {bb0[0..=1], '_#2r} -| '_#7r | U0 | {bb0[0..=1], '_#1r} -| '_#8r | U0 | {bb0[0..=1], '_#3r} +| '?0 | U0 | {bb0[0..=1], '?0, '?1, '?2, '?3, '?4} +| '?1 | U0 | {bb0[0..=1], '?1} +| '?2 | U0 | {bb0[0..=1], '?2} +| '?3 | U0 | {bb0[0..=1], '?3} +| '?4 | U0 | {bb0[0..=1], '?4} +| '?5 | U0 | {bb0[0..=1], '?1} +| '?6 | U0 | {bb0[0..=1], '?2} +| '?7 | U0 | {bb0[0..=1], '?1} +| '?8 | U0 | {bb0[0..=1], '?3} | | Inference Constraints -| '_#0r live at {bb0[0..=1]} -| '_#1r live at {bb0[0..=1]} -| '_#2r live at {bb0[0..=1]} -| '_#3r live at {bb0[0..=1]} -| '_#4r live at {bb0[0..=1]} -| '_#1r: '_#5r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) -| '_#1r: '_#7r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) -| '_#2r: '_#6r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) -| '_#3r: '_#8r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) -| '_#5r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) -| '_#6r: '_#2r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) -| '_#7r: '_#1r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) -| '_#8r: '_#3r due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) +| '?0 live at {bb0[0..=1]} +| '?1 live at {bb0[0..=1]} +| '?2 live at {bb0[0..=1]} +| '?3 live at {bb0[0..=1]} +| '?4 live at {bb0[0..=1]} +| '?1: '?5 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) +| '?1: '?7 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) +| '?2: '?6 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) +| '?3: '?8 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) +| '?5: '?1 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:26: 12:27) ($DIR/named_lifetimes_basic.rs:12:26: 12:27 (#0) +| '?6: '?2 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:42: 12:43) ($DIR/named_lifetimes_basic.rs:12:42: 12:43 (#0) +| '?7: '?1 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:54: 12:55) ($DIR/named_lifetimes_basic.rs:12:54: 12:55 (#0) +| '?8: '?3 due to BoringNoLocation at All($DIR/named_lifetimes_basic.rs:12:66: 12:67) ($DIR/named_lifetimes_basic.rs:12:66: 12:67 (#0) | -fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool { +fn use_x(_1: &'?5 mut i32, _2: &'?6 u32, _3: &'?7 u32, _4: &'?8 u32) -> bool { debug w => _1; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:26: +0:27 debug x => _2; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:42: +0:43 debug y => _3; // in scope 0 at $DIR/named_lifetimes_basic.rs:+0:54: +0:55 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 798e45df8ca..71bdfcc5c49 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -1,24 +1,24 @@ // MIR for `main` 0 nll | Free Region Mapping -| '_#0r | Global | ['_#0r, '_#1r] -| '_#1r | Local | ['_#1r] +| '?0 | Global | ['?0, '?1] +| '?1 | Local | ['?1] | | Inferred Region Values -| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} -| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} -| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]} -| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} -| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]} +| '?0 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '?0, '?1} +| '?1 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '?1} +| '?2 | U0 | {bb1[0..=7], bb2[0..=2]} +| '?3 | U0 | {bb1[1..=7], bb2[0..=2]} +| '?4 | U0 | {bb1[4..=7], bb2[0..=2]} | | Inference Constraints -| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#2r live at {bb1[0]} -| '_#3r live at {bb1[1..=3]} -| '_#4r live at {bb1[4..=7], bb2[0..=2]} -| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) -| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) +| '?0 live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '?1 live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '?2 live at {bb1[0]} +| '?3 live at {bb1[1..=3]} +| '?4 live at {bb1[4..=7], bb2[0..=2]} +| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 @@ -32,10 +32,10 @@ fn main() -> () { let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 scope 1 { debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 - let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + let _2: &'?3 usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 scope 2 { debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 - let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + let _6: &'?4 usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 scope 3 { debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 } @@ -55,7 +55,7 @@ fn main() -> () { } bb1: { - _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 + _2 = &'?2 _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 4767bfc76ed..9fa8609b751 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -1,24 +1,24 @@ // MIR for `main` 0 nll | Free Region Mapping -| '_#0r | Global | ['_#0r, '_#1r] -| '_#1r | Local | ['_#1r] +| '?0 | Global | ['?0, '?1] +| '?1 | Local | ['?1] | | Inferred Region Values -| '_#0r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#0r, '_#1r} -| '_#1r | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '_#1r} -| '_#2r | U0 | {bb1[0..=7], bb2[0..=2]} -| '_#3r | U0 | {bb1[1..=7], bb2[0..=2]} -| '_#4r | U0 | {bb1[4..=7], bb2[0..=2]} +| '?0 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '?0, '?1} +| '?1 | U0 | {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0], '?1} +| '?2 | U0 | {bb1[0..=7], bb2[0..=2]} +| '?3 | U0 | {bb1[1..=7], bb2[0..=2]} +| '?4 | U0 | {bb1[4..=7], bb2[0..=2]} | | Inference Constraints -| '_#0r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#1r live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} -| '_#2r live at {bb1[0]} -| '_#3r live at {bb1[1..=3]} -| '_#4r live at {bb1[4..=7], bb2[0..=2]} -| '_#2r: '_#3r due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) -| '_#3r: '_#4r due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) +| '?0 live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '?1 live at {bb0[0..=8], bb1[0..=7], bb2[0..=3], bb3[0..=3], bb4[0..=1], bb5[0..=2], bb6[0..=5], bb7[0]} +| '?2 live at {bb1[0]} +| '?3 live at {bb1[1..=3]} +| '?4 live at {bb1[4..=7], bb2[0..=2]} +| '?2: '?3 due to Assignment at Single(bb1[0]) ($DIR/region_subtyping_basic.rs:18:13: 18:18 (#0) +| '?3: '?4 due to Assignment at Single(bb1[3]) ($DIR/region_subtyping_basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 @@ -32,10 +32,10 @@ fn main() -> () { let _10: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+7:9: +7:18 scope 1 { debug v => _1; // in scope 1 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 - let _2: &'_#3r usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 + let _2: &'?3 usize; // in scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 scope 2 { debug p => _2; // in scope 2 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 - let _6: &'_#4r usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 + let _6: &'?4 usize; // in scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 scope 3 { debug q => _6; // in scope 3 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 } @@ -55,7 +55,7 @@ fn main() -> () { } bb1: { - _2 = &'_#2r _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 + _2 = &'?2 _1[_3]; // bb1[0]: scope 1 at $DIR/region_subtyping_basic.rs:+2:13: +2:18 FakeRead(ForLet(None), _2); // bb1[1]: scope 1 at $DIR/region_subtyping_basic.rs:+2:9: +2:10 StorageLive(_6); // bb1[2]: scope 2 at $DIR/region_subtyping_basic.rs:+3:9: +3:10 _6 = _2; // bb1[3]: scope 2 at $DIR/region_subtyping_basic.rs:+3:13: +3:14 diff --git a/tests/mir-opt/pre-codegen/README.md b/tests/mir-opt/pre-codegen/README.md new file mode 100644 index 00000000000..a338c18e09e --- /dev/null +++ b/tests/mir-opt/pre-codegen/README.md @@ -0,0 +1,3 @@ +The goal of this directory is to track the quality of MIR that is given to codegen in a standard `-O` condiguration. + +As such, feel free to `--bless` whatever changes you get here, so long as doing so doesn't add substantially more MIR. diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.rs b/tests/mir-opt/pre-codegen/duplicate_switch_targets.rs new file mode 100644 index 00000000000..d8af6b14dad --- /dev/null +++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.rs @@ -0,0 +1,17 @@ +// compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 +// ignore-debug: standard library debug assertions add a panic that breaks this optimization + +#![crate_type = "lib"] + +pub enum Thing { + A, + B, +} + +// EMIT_MIR duplicate_switch_targets.ub_if_b.PreCodegen.after.mir +pub unsafe fn ub_if_b(t: Thing) -> Thing { + match t { + Thing::A => t, + Thing::B => std::hint::unreachable_unchecked(), + } +} diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir new file mode 100644 index 00000000000..0e885cf94fd --- /dev/null +++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir @@ -0,0 +1,27 @@ +// MIR for `ub_if_b` after PreCodegen + +fn ub_if_b(_1: Thing) -> Thing { + debug t => _1; // in scope 0 at $DIR/duplicate_switch_targets.rs:+0:23: +0:24 + let mut _0: Thing; // return place in scope 0 at $DIR/duplicate_switch_targets.rs:+0:36: +0:41 + let mut _2: isize; // in scope 0 at $DIR/duplicate_switch_targets.rs:+2:9: +2:17 + scope 1 (inlined unreachable_unchecked) { // at $DIR/duplicate_switch_targets.rs:15:21: 15:55 + scope 2 { + scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/duplicate_switch_targets.rs:+1:11: +1:12 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/duplicate_switch_targets.rs:+1:5: +1:12 + } + + bb1: { + unreachable; // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2: { + _0 = move _1; // scope 0 at $DIR/duplicate_switch_targets.rs:+2:21: +2:22 + return; // scope 0 at $DIR/duplicate_switch_targets.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/pre-codegen/intrinsics.f_u64.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/intrinsics.f_u64.PreCodegen.after.mir new file mode 100644 index 00000000000..76e1fea2f95 --- /dev/null +++ b/tests/mir-opt/pre-codegen/intrinsics.f_u64.PreCodegen.after.mir @@ -0,0 +1,26 @@ +// MIR for `f_u64` after PreCodegen + +fn f_u64() -> () { + let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:16: +0:16 + let mut _1: u64; // in scope 0 at $DIR/intrinsics.rs:+1:5: +1:21 + scope 1 (inlined f_dispatch::<u64>) { // at $DIR/intrinsics.rs:19:5: 19:21 + debug t => const 0_u64; // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23 + let _2: (); // in scope 1 at $DIR/intrinsics.rs:27:9: 27:21 + scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/intrinsics.rs:24:8: 24:32 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21 + _1 = const 0_u64; // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21 + _2 = f_non_zst::<u64>(move _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:27:9: 27:21 + // mir::Constant + // + span: $DIR/intrinsics.rs:27:9: 27:18 + // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21 + return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/intrinsics.f_unit.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/intrinsics.f_unit.PreCodegen.after.mir new file mode 100644 index 00000000000..3d416de34df --- /dev/null +++ b/tests/mir-opt/pre-codegen/intrinsics.f_unit.PreCodegen.after.mir @@ -0,0 +1,22 @@ +// MIR for `f_unit` after PreCodegen + +fn f_unit() -> () { + let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:17: +0:17 + scope 1 (inlined f_dispatch::<()>) { // at $DIR/intrinsics.rs:13:5: 13:19 + debug t => const (); // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23 + let _1: (); // in scope 1 at $DIR/intrinsics.rs:25:9: 25:17 + scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/intrinsics.rs:24:8: 24:32 + } + } + + bb0: { + _1 = f_zst::<()>(const ()) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:25:9: 25:17 + // mir::Constant + // + span: $DIR/intrinsics.rs:25:9: 25:14 + // + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/lower_intrinsics_e2e.rs b/tests/mir-opt/pre-codegen/intrinsics.rs index 872ef59b081..ecdb656cb85 100644 --- a/tests/mir-opt/lower_intrinsics_e2e.rs +++ b/tests/mir-opt/pre-codegen/intrinsics.rs @@ -1,16 +1,20 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + // Checks that we do not have any branches in the MIR for the two tested functions. // compile-flags: -Cpanic=abort #![feature(core_intrinsics)] #![crate_type = "lib"] -// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir +// EMIT_MIR intrinsics.f_unit.PreCodegen.after.mir pub fn f_unit() { f_dispatch(()); } -// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir +// EMIT_MIR intrinsics.f_u64.PreCodegen.after.mir pub fn f_u64() { f_dispatch(0u64); } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.diff index 691aa01a564..691aa01a564 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.32bit.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.32bit.diff diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.diff index 691aa01a564..691aa01a564 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ConstProp.64bit.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ConstProp.64bit.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.mir new file mode 100644 index 00000000000..7886bf19e0c --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.32bit.mir @@ -0,0 +1,18 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.mir new file mode 100644 index 00000000000..7886bf19e0c --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.PreCodegen.after.64bit.mir @@ -0,0 +1,18 @@ +// MIR for `main` after PreCodegen + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff index 98cd020dade..98cd020dade 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.32bit.diff diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff index 98cd020dade..98cd020dade 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.ScalarReplacementOfAggregates.64bit.diff diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir new file mode 100644 index 00000000000..5bea94c7fe8 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -0,0 +1,18 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir new file mode 100644 index 00000000000..5bea94c7fe8 --- /dev/null +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -0,0 +1,18 @@ +// MIR for `main` after SimplifyLocals-final + +fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 + scope 1 { + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 + scope 2 { + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + scope 3 { + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + } + } + } + + bb0: { + return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 + } +} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.rs b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs index 5ffa153476d..bb32cd3afb1 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.rs +++ b/tests/mir-opt/pre-codegen/optimizes_into_variable.rs @@ -1,5 +1,4 @@ // ignore-wasm32 compiled with panic=abort by default -// unit-test // compile-flags: -C overflow-checks=on struct Point { diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir new file mode 100644 index 00000000000..343a4a5a6f3 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.mir @@ -0,0 +1,91 @@ +// MIR for `forward_loop` after PreCodegen + +fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { + debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:21: +0:26 + debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:33: +0:36 + debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:43: +0:44 + let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:60: +0:60 + let mut _4: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _5: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _8: &mut std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6 + let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10 + let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 + } + scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:21:14: 21:24 + debug self => _8; // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + } + scope 3 (inlined <std::ops::Range<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:21:14: 21:24 + debug self => _4; // in scope 3 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + _4 = std::ops::Range::<u32> { start: _1, end: _2 }; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + _5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb1: { + StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + _8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + _7 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) } + } + + bb2: { + _10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + _11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/range_iter.rs:22:9: 22:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) } + } + + bb3: { + unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + } + + bb4: { + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6 + drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb5: { + StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb6: { + return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2 + } + + bb7 (cleanup): { + drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2 + } + + bb9: { + _9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir new file mode 100644 index 00000000000..f45eabba252 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.inclusive_loop.PreCodegen.after.mir @@ -0,0 +1,95 @@ +// MIR for `inclusive_loop` after PreCodegen + +fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { + debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:23: +0:28 + debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:35: +0:38 + debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:45: +0:46 + let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:62: +0:62 + let mut _4: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _5: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _8: &mut std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6 + let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10 + let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10 + } + scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) { // at $DIR/range_iter.rs:28:14: 28:25 + debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + } + scope 3 (inlined RangeInclusive::<u32>::new) { // at $DIR/range_iter.rs:28:14: 28:25 + debug start => _1; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + debug end => _2; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + } + scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:28:14: 28:25 + debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + _4 = RangeInclusive::<u32> { start: _1, end: _2, exhausted: const false }; // scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL + StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + _5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:25 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb1: { + StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + _8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + _7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive<u32>) -> Option<<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::Item> {<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value(<ZST>) } + } + + bb2: { + _10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10 + StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + _11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10 + StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + _6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/range_iter.rs:29:9: 29:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) } + } + + bb3: { + unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + } + + bb4: { + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6 + drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb5: { + StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13 + StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6 + } + + bb6: { + return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2 + } + + bb7 (cleanup): { + drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2 + } + + bb9: { + _9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir new file mode 100644 index 00000000000..d013b1b9462 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.range_inclusive_iter_next.PreCodegen.after.mir @@ -0,0 +1,20 @@ +// MIR for `range_inclusive_iter_next` after PreCodegen + +fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> { + debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:34: +0:36 + let mut _0: std::option::Option<u32>; // return place in scope 0 at $DIR/range_iter.rs:+0:67: +0:78 + scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) { // at $DIR/range_iter.rs:16:8: 16:14 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb0: { + _0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_1) -> bb1; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive<u32>) -> Option<<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::Item> {<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir new file mode 100644 index 00000000000..cae46e2b0bb --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.mir @@ -0,0 +1,20 @@ +// MIR for `range_iter_next` after PreCodegen + +fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> { + debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:24: +0:26 + let mut _0: std::option::Option<u32>; // return place in scope 0 at $DIR/range_iter.rs:+0:48: +0:59 + scope 1 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:11:8: 11:14 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + } + + bb0: { + _0 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_1) -> bb1; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/range.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/range_iter.rs b/tests/mir-opt/pre-codegen/range_iter.rs new file mode 100644 index 00000000000..fe21d4dfde4 --- /dev/null +++ b/tests/mir-opt/pre-codegen/range_iter.rs @@ -0,0 +1,31 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + +#![crate_type = "lib"] + +use std::ops::{Range, RangeInclusive}; + +// EMIT_MIR range_iter.range_iter_next.PreCodegen.after.mir +pub fn range_iter_next(it: &mut Range<u32>) -> Option<u32> { + it.next() +} + +// EMIT_MIR range_iter.range_inclusive_iter_next.PreCodegen.after.mir +pub fn range_inclusive_iter_next(it: &mut RangeInclusive<u32>) -> Option<u32> { + it.next() +} + +// EMIT_MIR range_iter.forward_loop.PreCodegen.after.mir +pub fn forward_loop(start: u32, end: u32, f: impl Fn(u32)) { + for x in start..end { + f(x) + } +} + +// EMIT_MIR range_iter.inclusive_loop.PreCodegen.after.mir +pub fn inclusive_loop(start: u32, end: u32, f: impl Fn(u32)) { + for x in start..=end { + f(x) + } +} diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir new file mode 100644 index 00000000000..986ab35886f --- /dev/null +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -0,0 +1,56 @@ +// MIR for `ezmap` after PreCodegen + +fn ezmap(_1: Option<i32>) -> Option<i32> { + debug x => _1; // in scope 0 at $DIR/simple_option_map.rs:+0:14: +0:15 + let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map.rs:+0:33: +0:44 + let mut _6: i32; // in scope 0 at $DIR/simple_option_map.rs:11:25: 11:29 + scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map.rs:18:12: 18:15]>) { // at $DIR/simple_option_map.rs:18:5: 18:22 + debug slf => _1; // in scope 1 at $DIR/simple_option_map.rs:6:17: 6:20 + debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:18:12: 18:15]; // in scope 1 at $DIR/simple_option_map.rs:6:33: 6:34 + let mut _2: isize; // in scope 1 at $DIR/simple_option_map.rs:11:9: 11:16 + let _3: i32; // in scope 1 at $DIR/simple_option_map.rs:11:14: 11:15 + let mut _4: i32; // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29 + let mut _5: (i32,); // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29 + scope 2 { + debug x => _3; // in scope 2 at $DIR/simple_option_map.rs:11:14: 11:15 + scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map.rs:11:25: 11:29 + debug n => _6; // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14 + } + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22 + _2 = discriminant(_1); // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14 + switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map.rs:10:5: 10:14 + } + + bb1: { + _0 = Option::<i32>::None; // scope 1 at $DIR/simple_option_map.rs:12:17: 12:21 + goto -> bb4; // scope 1 at $DIR/simple_option_map.rs:12:17: 12:21 + } + + bb2: { + unreachable; // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14 + } + + bb3: { + _3 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map.rs:11:14: 11:15 + StorageLive(_4); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + StorageLive(_5); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + _5 = (move _3,); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + StorageLive(_6); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + _6 = move (_5.0: i32); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + _4 = Add(_6, const 1_i32); // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21 + StorageDead(_6); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29 + StorageDead(_5); // scope 2 at $DIR/simple_option_map.rs:11:28: 11:29 + _0 = Option::<i32>::Some(move _4); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30 + StorageDead(_4); // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30 + goto -> bb4; // scope 1 at $DIR/simple_option_map.rs:14:1: 14:2 + } + + bb4: { + StorageDead(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22 + return; // scope 0 at $DIR/simple_option_map.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/simple_option_map_e2e.rs b/tests/mir-opt/pre-codegen/simple_option_map.rs index 2acd2a227b8..fb3da68e4af 100644 --- a/tests/mir-opt/simple_option_map_e2e.rs +++ b/tests/mir-opt/pre-codegen/simple_option_map.rs @@ -1,3 +1,7 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + #[inline(always)] fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U> where @@ -9,7 +13,7 @@ where } } -// EMIT_MIR simple_option_map_e2e.ezmap.PreCodegen.after.mir +// EMIT_MIR simple_option_map.ezmap.PreCodegen.after.mir pub fn ezmap(x: Option<i32>) -> Option<i32> { map(x, |n| n + 1) } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir new file mode 100644 index 00000000000..f27525bf3d9 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.mir @@ -0,0 +1,103 @@ +// MIR for `forward_loop` after PreCodegen + +fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 + let mut _3: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _5: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _8: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + } + } + scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:28:20: 28:26 + debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + scope 4 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26 + debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb10, unwind: bb8]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL + // + user_ty: UserType(0) + // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + _7 = <std::slice::Iter<'_, T> as Iterator>::next(_8) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + // mir::Constant + // + span: $DIR/slice_iter.rs:28:14: 28:26 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) } + } + + bb2: { + _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + switchInt(move _9) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + } + + bb3: { + _10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/slice_iter.rs:29:9: 29:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) } + } + + bb4: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26 + } + + bb5: { + StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + drop(_2) -> bb7; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb6: { + StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb7: { + return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2 + } + + bb8 (cleanup): { + drop(_2) -> [return: bb9, unwind terminate]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb9 (cleanup): { + resume; // scope 0 at $DIR/slice_iter.rs:+0:1: +4:2 + } + + bb10: { + _3 = move _4; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:25: +1:26 + StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir new file mode 100644 index 00000000000..62dd9667d96 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.mir @@ -0,0 +1,114 @@ +// MIR for `reverse_loop` after PreCodegen + +fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { + debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33 + debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45 + let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60 + let mut _3: std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + let mut _5: std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _8: &mut std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6 + let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10 + let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13 + scope 1 { + debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + scope 2 { + debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10 + } + scope 7 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _8; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + let mut _13: &mut std::slice::Iter<'_, T>; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + } + } + scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:35:20: 35:26 + debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + } + scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32 + debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + scope 5 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + debug iter => _4; // in scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + } + } + scope 6 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32 + debug self => _3; // in scope 6 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL + } + + bb0: { + StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26 + _4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb9, unwind: bb7]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL + // + user_ty: UserType(0) + // + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) } + } + + bb1: { + StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + _8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + StorageLive(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _13 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _13) -> [return: bb10, unwind: bb7]; // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) } + } + + bb2: { + _10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10 + StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + _11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10 + StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + _6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13 + // mir::Constant + // + span: $DIR/slice_iter.rs:36:9: 36:10 + // + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) } + } + + bb3: { + unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + } + + bb4: { + StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6 + drop(_2) -> bb6; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb5: { + StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13 + StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb6: { + return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2 + } + + bb7 (cleanup): { + drop(_2) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/slice_iter.rs:+0:1: +4:2 + } + + bb9: { + _3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32 + StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + _5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32 + goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6 + } + + bb10: { + StorageDead(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL + _9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.rs b/tests/mir-opt/pre-codegen/slice_iter.rs new file mode 100644 index 00000000000..ca423ca55e6 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.rs @@ -0,0 +1,38 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + +#![crate_type = "lib"] + +// When this test was added, the MIR for `next` was 174 lines just for the basic +// blocks -- far more if you counted the scopes. The goal of having this here +// is to hopefully keep it a reasonable size, ideally eventually small enough +// that the mir inliner would actually be willing to inline it, since it's an +// important building block and usually very few *backend* instructions. + +// As such, feel free to `--bless` whatever changes you get here, so long as +// doing so doesn't add substantially more MIR. + +// EMIT_MIR slice_iter.slice_iter_next.PreCodegen.after.mir +pub fn slice_iter_next<'a, T>(it: &mut std::slice::Iter<'a, T>) -> Option<&'a T> { + it.next() +} + +// EMIT_MIR slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir +pub fn slice_iter_mut_next_back<'a, T>(it: &mut std::slice::IterMut<'a, T>) -> Option<&'a mut T> { + it.next_back() +} + +// EMIT_MIR slice_iter.forward_loop.PreCodegen.after.mir +pub fn forward_loop<'a, T>(slice: &'a [T], f: impl Fn(&T)) { + for x in slice.iter() { + f(x) + } +} + +// EMIT_MIR slice_iter.reverse_loop.PreCodegen.after.mir +pub fn reverse_loop<'a, T>(slice: &'a [T], f: impl Fn(&T)) { + for x in slice.iter().rev() { + f(x) + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir new file mode 100644 index 00000000000..a1431d473bc --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir @@ -0,0 +1,17 @@ +// MIR for `slice_iter_mut_next_back` after PreCodegen + +fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> { + debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:40: +0:42 + let mut _0: std::option::Option<&mut T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:80: +0:97 + + bb0: { + _0 = <std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:19 + // mir::Constant + // + span: $DIR/slice_iter.rs:23:8: 23:17 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::IterMut<'_, T>) -> Option<<std::slice::IterMut<'_, T> as Iterator>::Item> {<std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir new file mode 100644 index 00000000000..d2a963cad12 --- /dev/null +++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_next.PreCodegen.after.mir @@ -0,0 +1,17 @@ +// MIR for `slice_iter_next` after PreCodegen + +fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> { + debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:31: +0:33 + let mut _0: std::option::Option<&T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:68: +0:81 + + bb0: { + _0 = <std::slice::Iter<'_, T> as Iterator>::next(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:14 + // mir::Constant + // + span: $DIR/slice_iter.rs:18:8: 18:12 + // + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir index 935dbb28b0f..53971b4cffc 100644 --- a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.new.PreCodegen.after.mir @@ -1,66 +1,70 @@ // MIR for `new` after PreCodegen fn new(_1: Result<T, E>) -> Result<T, E> { - debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15 - let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46 - let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22 - let _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21 - let _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22 - let mut _6: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37 - let _7: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36 - let _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33 + debug x => _1; // in scope 0 at $DIR/try_identity.rs:+0:14: +0:15 + let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity.rs:+0:34: +0:46 + let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity.rs:+2:15: +7:10 + let mut _3: isize; // in scope 0 at $DIR/try_identity.rs:+4:17: +4:22 + let _4: T; // in scope 0 at $DIR/try_identity.rs:+4:20: +4:21 + let _5: E; // in scope 0 at $DIR/try_identity.rs:+5:21: +5:22 + let mut _6: isize; // in scope 0 at $DIR/try_identity.rs:+8:13: +8:37 + let _7: T; // in scope 0 at $DIR/try_identity.rs:+8:35: +8:36 + let _8: E; // in scope 0 at $DIR/try_identity.rs:+9:32: +9:33 scope 1 { - debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21 + debug v => _4; // in scope 1 at $DIR/try_identity.rs:+4:20: +4:21 } scope 2 { - debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22 + debug e => _5; // in scope 2 at $DIR/try_identity.rs:+5:21: +5:22 } scope 3 { - debug v => _7; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36 + debug v => _7; // in scope 3 at $DIR/try_identity.rs:+8:35: +8:36 } scope 4 { - debug e => _8; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33 + debug e => _8; // in scope 4 at $DIR/try_identity.rs:+9:32: +9:33 } bb0: { - StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 - switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 + StorageLive(_2); // scope 0 at $DIR/try_identity.rs:+2:15: +7:10 + _3 = discriminant(_1); // scope 0 at $DIR/try_identity.rs:+3:19: +3:20 + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+3:13: +3:20 } bb1: { - _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22 - _2 = ControlFlow::<E, T>::Break(move _5); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 - goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48 + _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity.rs:+5:21: +5:22 + _2 = ControlFlow::<E, T>::Break(move _5); // scope 2 at $DIR/try_identity.rs:+5:27: +5:48 + goto -> bb4; // scope 0 at $DIR/try_identity.rs:+5:47: +5:48 } bb2: { - unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 + unreachable; // scope 0 at $DIR/try_identity.rs:+3:19: +3:20 } bb3: { - _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21 - _2 = ControlFlow::<E, T>::Continue(move _4); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 - goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50 + _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity.rs:+4:20: +4:21 + _2 = ControlFlow::<E, T>::Continue(move _4); // scope 1 at $DIR/try_identity.rs:+4:26: +4:50 + goto -> bb4; // scope 0 at $DIR/try_identity.rs:+4:49: +4:50 } bb4: { - _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + _6 = discriminant(_2); // scope 0 at $DIR/try_identity.rs:+2:15: +7:10 + switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+2:9: +7:10 } bb5: { - _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33 - _0 = Result::<T, E>::Err(move _8); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51 - StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 - return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity.rs:+9:32: +9:33 + _0 = Result::<T, E>::Err(move _8); // scope 4 at $DIR/try_identity.rs:+9:45: +9:51 + StorageDead(_2); // scope 0 at $DIR/try_identity.rs:+12:1: +12:2 + goto -> bb7; // scope 0 at $DIR/try_identity.rs:+12:1: +12:2 } bb6: { - _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36 - _0 = Result::<T, E>::Ok(move _7); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6 - StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 - return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 + _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity.rs:+8:35: +8:36 + _0 = Result::<T, E>::Ok(move _7); // scope 0 at $DIR/try_identity.rs:+1:5: +11:6 + StorageDead(_2); // scope 0 at $DIR/try_identity.rs:+12:1: +12:2 + goto -> bb7; // scope 0 at $DIR/try_identity.rs:+12:1: +12:2 + } + + bb7: { + return; // scope 0 at $DIR/try_identity.rs:+12:2: +12:2 } } diff --git a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir index d88ae5ac93e..e217d19947f 100644 --- a/tests/mir-opt/try_identity_e2e.old.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir @@ -1,36 +1,40 @@ // MIR for `old` after PreCodegen fn old(_1: Result<T, E>) -> Result<T, E> { - debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15 - let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46 - let mut _2: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18 - let _3: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17 - let _4: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18 + debug x => _1; // in scope 0 at $DIR/try_identity.rs:+0:14: +0:15 + let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity.rs:+0:34: +0:46 + let mut _2: isize; // in scope 0 at $DIR/try_identity.rs:+3:13: +3:18 + let _3: T; // in scope 0 at $DIR/try_identity.rs:+3:16: +3:17 + let _4: E; // in scope 0 at $DIR/try_identity.rs:+4:17: +4:18 scope 1 { - debug v => _3; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17 + debug v => _3; // in scope 1 at $DIR/try_identity.rs:+3:16: +3:17 } scope 2 { - debug e => _4; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18 + debug e => _4; // in scope 2 at $DIR/try_identity.rs:+4:17: +4:18 } bb0: { - _2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16 - switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16 + _2 = discriminant(_1); // scope 0 at $DIR/try_identity.rs:+2:15: +2:16 + switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+2:9: +2:16 } bb1: { - _4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18 - _0 = Result::<T, E>::Err(move _4); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36 - return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2 + _4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity.rs:+4:17: +4:18 + _0 = Result::<T, E>::Err(move _4); // scope 2 at $DIR/try_identity.rs:+4:30: +4:36 + goto -> bb4; // scope 0 at $DIR/try_identity.rs:+7:1: +7:2 } bb2: { - unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16 + unreachable; // scope 0 at $DIR/try_identity.rs:+2:15: +2:16 } bb3: { - _3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17 - _0 = Result::<T, E>::Ok(move _3); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6 - return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2 + _3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity.rs:+3:16: +3:17 + _0 = Result::<T, E>::Ok(move _3); // scope 0 at $DIR/try_identity.rs:+1:5: +6:6 + goto -> bb4; // scope 0 at $DIR/try_identity.rs:+7:1: +7:2 + } + + bb4: { + return; // scope 0 at $DIR/try_identity.rs:+7:2: +7:2 } } diff --git a/tests/mir-opt/try_identity_e2e.rs b/tests/mir-opt/pre-codegen/try_identity.rs index 00cb80f5035..079ecccab28 100644 --- a/tests/mir-opt/try_identity_e2e.rs +++ b/tests/mir-opt/pre-codegen/try_identity.rs @@ -1,9 +1,13 @@ +// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 +// only-64bit +// ignore-debug + // Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings // of that syntax. use std::ops::ControlFlow; -// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir +// EMIT_MIR try_identity.new.PreCodegen.after.mir fn new<T, E>(x: Result<T, E>) -> Result<T, E> { Ok( match { @@ -18,7 +22,7 @@ fn new<T, E>(x: Result<T, E>) -> Result<T, E> { ) } -// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir +// EMIT_MIR try_identity.old.PreCodegen.after.mir fn old<T, E>(x: Result<T, E>) -> Result<T, E> { Ok( match x { diff --git a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir b/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir deleted file mode 100644 index cae89fb177a..00000000000 --- a/tests/mir-opt/simple_option_map_e2e.ezmap.PreCodegen.after.mir +++ /dev/null @@ -1,42 +0,0 @@ -// MIR for `ezmap` after PreCodegen - -fn ezmap(_1: Option<i32>) -> Option<i32> { - debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15 - let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44 - scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]>) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22 - debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20 - debug f => const ZeroSized: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34 - let mut _2: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16 - let _3: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 - let mut _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - scope 2 { - debug x => _3; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 - scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - debug n => _3; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14 - } - } - } - - bb0: { - _2 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14 - switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14 - } - - bb1: { - _0 = Option::<i32>::None; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21 - return; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21 - } - - bb2: { - unreachable; // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14 - } - - bb3: { - _3 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15 - StorageLive(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29 - _4 = Add(_3, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21 - _0 = Option::<i32>::Some(move _4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30 - StorageDead(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30 - return; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2 - } -} diff --git a/tests/mir-opt/simplify_arm.rs b/tests/mir-opt/simplify_arm.rs index c247872e2af..4c471ce0468 100644 --- a/tests/mir-opt/simplify_arm.rs +++ b/tests/mir-opt/simplify_arm.rs @@ -6,8 +6,7 @@ // EMIT_MIR simplify_arm.id_try.SimplifyArmIdentity.diff // EMIT_MIR simplify_arm.id_try.SimplifyBranchSame.diff -// This pass is broken since deaggregation changed -// ignore-test +// ignore-test This pass is broken since deaggregation changed fn id(o: Option<u8>) -> Option<u8> { match o { diff --git a/tests/mir-opt/simplify_arm_identity.rs b/tests/mir-opt/simplify_arm_identity.rs index cf6ff57aa96..e122cd50e00 100644 --- a/tests/mir-opt/simplify_arm_identity.rs +++ b/tests/mir-opt/simplify_arm_identity.rs @@ -4,8 +4,7 @@ // compile-flags: -Zmir-opt-level=3 // EMIT_MIR_FOR_EACH_BIT_WIDTH -// This pass is broken since deaggregation changed -// ignore-test +// ignore-test This pass is broken since deaggregation changed enum Src { Foo(u8), diff --git a/tests/mir-opt/storage_ranges.main.nll.0.mir b/tests/mir-opt/storage_ranges.main.nll.0.mir index 8e10e70f192..5bb1a7bf0c9 100644 --- a/tests/mir-opt/storage_ranges.main.nll.0.mir +++ b/tests/mir-opt/storage_ranges.main.nll.0.mir @@ -1,21 +1,21 @@ // MIR for `main` 0 nll | Free Region Mapping -| '_#0r | Global | ['_#0r, '_#1r] -| '_#1r | Local | ['_#1r] +| '?0 | Global | ['?0, '?1] +| '?1 | Local | ['?1] | | Inferred Region Values -| '_#0r | U0 | {bb0[0..=22], '_#0r, '_#1r} -| '_#1r | U0 | {bb0[0..=22], '_#1r} -| '_#2r | U0 | {bb0[10..=11]} -| '_#3r | U0 | {bb0[11]} +| '?0 | U0 | {bb0[0..=22], '?0, '?1} +| '?1 | U0 | {bb0[0..=22], '?1} +| '?2 | U0 | {bb0[10..=11]} +| '?3 | U0 | {bb0[11]} | | Inference Constraints -| '_#0r live at {bb0[0..=22]} -| '_#1r live at {bb0[0..=22]} -| '_#2r live at {bb0[10]} -| '_#3r live at {bb0[11]} -| '_#2r: '_#3r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) +| '?0 live at {bb0[0..=22]} +| '?1 live at {bb0[0..=22]} +| '?2 live at {bb0[10]} +| '?3 live at {bb0[11]} +| '?2: '?3 due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:+0:11: +0:11 diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 9cd504f004d..7bd7bb7c1ea 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -20,13 +20,13 @@ extern crate rustc_session; use rustc_borrowck::consumers::BodyWithBorrowckFacts; use rustc_driver::Compilation; -use rustc_hir::def_id::LocalDefId; use rustc_hir::def::DefKind; +use rustc_hir::def_id::LocalDefId; use rustc_interface::interface::Compiler; use rustc_interface::{Config, Queries}; use rustc_middle::ty::query::query_values::mir_borrowck; use rustc_middle::ty::query::{ExternProviders, Providers}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use std::cell::RefCell; use std::collections::HashMap; @@ -127,10 +127,7 @@ thread_local! { } fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> mir_borrowck<'tcx> { - let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts( - tcx, - ty::WithOptConstParam::unknown(def_id), - ); + let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts(tcx, def_id); // SAFETY: The reader casts the 'static lifetime to 'tcx before using it. let body_with_facts: BodyWithBorrowckFacts<'static> = unsafe { std::mem::transmute(body_with_facts) }; diff --git a/tests/run-make/const-prop-lint/Makefile b/tests/run-make/const-prop-lint/Makefile new file mode 100644 index 00000000000..f29f282f787 --- /dev/null +++ b/tests/run-make/const-prop-lint/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# Test that emitting an error because of arithmetic +# overflow lint does not leave .o files around +# because of interrupted codegen. + +all: + $(RUSTC) input.rs; test $$? -eq 1 + ls *.o; test $$? -ne 0 diff --git a/tests/run-make/const-prop-lint/input.rs b/tests/run-make/const-prop-lint/input.rs new file mode 100644 index 00000000000..ccbdfb8d50b --- /dev/null +++ b/tests/run-make/const-prop-lint/input.rs @@ -0,0 +1,5 @@ +#![deny(arithmetic_overflow)] + +fn main() { + let x = 255u8 + 1; +} diff --git a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt index 48983ba4358..7eb33a29a92 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt @@ -11,16 +11,16 @@ 11| 3| self.strength = new_strength; 12| 3| } ------------------ - | <generics::Firework<i32>>::set_strength: - | 10| 1| fn set_strength(&mut self, new_strength: T) { - | 11| 1| self.strength = new_strength; - | 12| 1| } - ------------------ | <generics::Firework<f64>>::set_strength: | 10| 2| fn set_strength(&mut self, new_strength: T) { | 11| 2| self.strength = new_strength; | 12| 2| } ------------------ + | <generics::Firework<i32>>::set_strength: + | 10| 1| fn set_strength(&mut self, new_strength: T) { + | 11| 1| self.strength = new_strength; + | 12| 1| } + ------------------ 13| |} 14| | 15| |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display { diff --git a/tests/run-make/coverage/uses_crate.rs b/tests/run-make/coverage/uses_crate.rs index 20cb05fe5b0..1ee8037a1e7 100644 --- a/tests/run-make/coverage/uses_crate.rs +++ b/tests/run-make/coverage/uses_crate.rs @@ -1,3 +1,6 @@ +// FIXME #110395 +// ignore-llvm-cov-show-diffs + #![allow(unused_assignments, unused_variables)] // compile-flags: -C opt-level=3 # validates coverage now works with optimizations extern crate used_crate; diff --git a/tests/run-make/coverage/uses_inline_crate.rs b/tests/run-make/coverage/uses_inline_crate.rs index a7fe8532be3..f7aff3c3f8a 100644 --- a/tests/run-make/coverage/uses_inline_crate.rs +++ b/tests/run-make/coverage/uses_inline_crate.rs @@ -1,3 +1,6 @@ +// FIXME #110395 +// ignore-llvm-cov-show-diffs + #![allow(unused_assignments, unused_variables)] // compile-flags: -C opt-level=3 # validates coverage now works with optimizations diff --git a/tests/run-make/issue-107094/Makefile b/tests/run-make/issue-107094/Makefile new file mode 100644 index 00000000000..d614e3e1055 --- /dev/null +++ b/tests/run-make/issue-107094/Makefile @@ -0,0 +1,7 @@ +# needs-git-hash + +include ../tools.mk + +all: + $(BARE_RUSTC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}" + $(BARE_RUSTDOC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}" diff --git a/tests/run-make/pointer-auth-link-with-c/Makefile b/tests/run-make/pointer-auth-link-with-c/Makefile index 7acea03802c..dffbd303582 100644 --- a/tests/run-make/pointer-auth-link-with-c/Makefile +++ b/tests/run-make/pointer-auth-link-with-c/Makefile @@ -5,10 +5,10 @@ include ../tools.mk all: $(COMPILE_OBJ) $(TMPDIR)/test.o test.c $(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o - $(RUSTC) -Z branch-protection=bti,pac-ret,leaf test.rs + $(RUSTC) --target $(TARGET) -Z branch-protection=bti,pac-ret,leaf test.rs $(call RUN,test) $(COMPILE_OBJ) $(TMPDIR)/test.o test.c -mbranch-protection=bti+pac-ret+leaf $(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o - $(RUSTC) -Z branch-protection=bti,pac-ret,leaf test.rs + $(RUSTC) --target $(TARGET) -Z branch-protection=bti,pac-ret,leaf test.rs $(call RUN,test) diff --git a/tests/run-make/translation/Makefile b/tests/run-make/translation/Makefile index 0acf64e5da7..07e0547cfa0 100644 --- a/tests/run-make/translation/Makefile +++ b/tests/run-make/translation/Makefile @@ -46,6 +46,8 @@ sysroot: test.rs working.ftl rm -f $(FAKEROOT)/lib/rustlib/src mkdir $(FAKEROOT)/lib/rustlib/src ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src + # When download-rustc is enabled, `$(SYSROOT)` will have a share directory. Delete the link to it. + rm -f $(FAKEROOT)/share mkdir -p $(FAKEROOT)/share/locale/zh-CN/ ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | $(CGREP) "this is a test message" diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 733be9bebba..a44ff9d3e4a 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -256,6 +256,15 @@ set-local-storage: {"rustdoc-disable-shortcuts": "false"} click: ".setting-line:last-child .setting-check span" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +// We now check that focusing a toggle and pressing Space is like clicking on it. +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "false"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} + // Make sure that "Disable keyboard shortcuts" actually took effect. press-key: "Escape" press-key: "?" diff --git a/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs b/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs new file mode 100644 index 00000000000..4fa26204be9 --- /dev/null +++ b/tests/rustdoc-json/reexport/auxiliary/enum_with_discriminant.rs @@ -0,0 +1,6 @@ +//! Should not be inlined + +/// Should not be inlined +pub enum O { + L = -1, +} diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs new file mode 100644 index 00000000000..40b681d7dbb --- /dev/null +++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs @@ -0,0 +1,10 @@ +// Regression Test for https://github.com/rust-lang/rust/issues/110138 +// aux-build: enum_with_discriminant.rs + +#[doc(inline)] +pub extern crate enum_with_discriminant; + +// @!has '$.index[*][?(@.docs == "Should not be inlined")]' +// @is '$.index[*][?(@.name == "enum_with_discriminant")].kind' '"extern_crate"' +// @set enum_with_discriminant = '$.index[*][?(@.name == "enum_with_discriminant")].id' +// @is '$.index[*][?(@.name == "doc_inline_external_crate")].inner.items[*]' $enum_with_discriminant diff --git a/tests/rustdoc-json/reexport/extern_crate_glob.rs b/tests/rustdoc-json/reexport/extern_crate_glob.rs new file mode 100644 index 00000000000..8efb94fd3f1 --- /dev/null +++ b/tests/rustdoc-json/reexport/extern_crate_glob.rs @@ -0,0 +1,10 @@ +// aux-build: enum_with_discriminant.rs + +extern crate enum_with_discriminant; + +#[doc(inline)] +pub use enum_with_discriminant::*; + +// @!has '$.index[*][?(@.docs == "Should not be inlined")]' +// @set use = '$.index[*][?(@.inner.name == "enum_with_discriminant")].id' +// @is '$.index[*][?(@.name == "extern_crate_glob")].inner.items[*]' $use diff --git a/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs new file mode 100644 index 00000000000..e49fe079813 --- /dev/null +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-2.rs @@ -0,0 +1,9 @@ +// check-pass + +pub fn f() -> impl Sized { + pub enum E { + V(E), + } + + unimplemented!() +} diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs index 939da186fbc..939da186fbc 100644 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait-return.rs +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.rs diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.stderr index aff7402bc91..aff7402bc91 100644 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait-return.stderr +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type-impl-trait-return.stderr diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs index ac517257498..096130d7768 100644 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs +++ b/tests/rustdoc-ui/error-in-impl-trait/infinite-recursive-type.rs @@ -1,6 +1,9 @@ +// check-pass + fn f() -> impl Sized { - enum E { //~ ERROR + enum E { V(E), } + unimplemented!() } diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr b/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr deleted file mode 100644 index a61577bd14a..00000000000 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0072]: recursive type `f::E` has infinite size - --> $DIR/infinite-recursive-type-impl-trait.rs:2:5 - | -LL | enum E { - | ^^^^^^ -LL | V(E), - | - recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -LL | V(Box<E>), - | ++++ + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0072`. diff --git a/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs b/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs deleted file mode 100644 index 6c48f5aa01f..00000000000 --- a/tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-enum.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub enum O { - L = -1, -} diff --git a/tests/rustdoc-ui/intra-doc/inline-external-enum.rs b/tests/rustdoc-ui/intra-doc/inline-external-enum.rs deleted file mode 100644 index 363dd7f64c2..00000000000 --- a/tests/rustdoc-ui/intra-doc/inline-external-enum.rs +++ /dev/null @@ -1,8 +0,0 @@ -// check-pass -// aux-build: inner-crate-enum.rs -// compile-flags:-Z unstable-options --output-format json - -#[doc(inline)] -pub extern crate inner_crate_enum; - -fn main() {} diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs new file mode 100644 index 00000000000..ef9c56f7592 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs @@ -0,0 +1,6 @@ +// this test used to ICE +#![deny(rustdoc::broken_intra_doc_links)] +//! [Clone ()]. //~ ERROR unresolved +//! [Clone !]. //~ ERROR incompatible +//! [`Clone ()`]. //~ ERROR unresolved +//! [`Clone !`]. //~ ERROR incompatible diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr new file mode 100644 index 00000000000..8669b0c2086 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr @@ -0,0 +1,54 @@ +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:3:6 + | +LL | //! [Clone ()]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace + | +note: the lint level is defined here + --> $DIR/issue-110495-suffix-with-space.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the trait, prefix with `trait@` + | +LL - //! [Clone ()]. +LL + //! [trait@Clone ]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:4:6 + | +LL | //! [Clone !]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL - //! [Clone !]. +LL + //! [derive@Clone ]. + | + +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:5:7 + | +LL | //! [`Clone ()`]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace + | +help: to link to the trait, prefix with `trait@` + | +LL - //! [`Clone ()`]. +LL + //! [`trait@Clone (`]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:6:7 + | +LL | //! [`Clone !`]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL | //! [`derive@Clone !`]. + | +++++++ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs index d368db909fa..6006354eba4 100644 --- a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs +++ b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs @@ -29,7 +29,7 @@ pub trait Stage { // // @has - '//*[@id="associatedconstant.ARRAY1"]' \ // 'const ARRAY1: [u8; { _ }]' - const ARRAY1: [u8; Struct::new(/* ... */) + Self::ABSTRACT * 1_000]; + const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]; // @has - '//*[@id="associatedconstant.VERBOSE"]' \ // 'const VERBOSE: [u16; { _ }]' @@ -73,10 +73,14 @@ pub struct Struct { private: () } impl Struct { const fn new() -> Self { Self { private: () } } + const fn do_something(self, x: usize) -> usize { + x + } } - +/* FIXME(const-trait): readd this impl const std::ops::Add<usize> for Struct { type Output = usize; fn add(self, _: usize) -> usize { 0 } } +*/ diff --git a/tests/rustdoc/issue-110422-inner-private.rs b/tests/rustdoc/issue-110422-inner-private.rs new file mode 100644 index 00000000000..ee8ed5cc6e1 --- /dev/null +++ b/tests/rustdoc/issue-110422-inner-private.rs @@ -0,0 +1,64 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/110422>. +// This test ensures that inner items (except for implementations and macros) +// don't appear in documentation. + +// compile-flags: --document-private-items + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// Checking there is no "trait" entry. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 4 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Macros' + +// @has - '//a[@href="fn.foo.html"]' 'foo' +fn foo() { + fn bar() {} + + // @has - '//a[@class="macro"]' 'visible_macro' + // @!has - '//a[@class="macro"]' 'non_visible_macro' + // @has 'foo/macro.visible_macro.html' + // @!has 'foo/macro.non_visible_macro.html' + #[macro_export] + macro_rules! visible_macro { + () => {} + } + + macro_rules! non_visible_macro { + () => {} + } +} + +// @has 'foo/index.html' +// @has - '//a[@href="struct.Bar.html"]' 'Bar' +struct Bar; + +const BAR: i32 = { + // @!has - '//a[@href="fn.yo.html"]' 'yo' + // @!has 'foo/fn.yo.html' + fn yo() {} + + // @!has 'foo/index.html' '//a[@href="trait.Foo.html"]' 'Foo' + // @!has 'foo/trait.Foo.html' + trait Foo { + fn babar() {} + } + impl Foo for Bar {} + + // @has 'foo/struct.Bar.html' + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub(crate) fn foo()' + // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 + // We now check that the `Foo` trait is not documented nor visible on `Bar` page. + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Implementations' + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Auto Trait Implementations' + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Blanket Implementations' + // @!has - '//*[@href="trait.Foo.html#method.babar"]/*[@class="code-header"]' 'fn babar()' + impl Bar { + fn foo() {} + } + + 1 +}; diff --git a/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs new file mode 100644 index 00000000000..d8953eaf597 --- /dev/null +++ b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs @@ -0,0 +1,24 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/46506>. +// This test ensures that if public re-exported is re-exported, it won't be inlined. + +#![crate_name = "foo"] + +// @has 'foo/associations/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy' +// @has 'foo/associations/trait.GroupedBy.html' +pub mod associations { + mod belongs_to { + pub trait GroupedBy {} + } + pub use self::belongs_to::GroupedBy; +} + +// @has 'foo/prelude/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' +// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;' +pub mod prelude { + pub use associations::GroupedBy; +} diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs new file mode 100644 index 00000000000..1429b5e4741 --- /dev/null +++ b/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs @@ -0,0 +1,39 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/60522>. +// This test ensures that the `banana` and `peach` modules don't appear twice +// and that the visible modules are not the re-exported ones. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Modules' +// @count - '//*[@id="main-content"]/*[@class="item-table"]//*[@class="mod"]' 2 +// @has - '//*[@id="main-content"]//*[@class="mod"]' 'banana' +// @has - '//*[@id="main-content"]//*[@href="banana/index.html"]' 'banana' +// @has - '//*[@id="main-content"]//*[@class="mod"]' 'peach' +// @has - '//*[@id="main-content"]//*[@href="peach/index.html"]' 'peach' + +pub use crate::my_crate::*; + +mod my_crate { + pub mod banana { + pub struct Yellow; + } + pub mod peach { + pub struct Pink; + } +} + +// @has 'foo/banana/index.html' +// @count - '//*[@id="main-content"]//*[@class="struct"]' 1 +// @has - '//*[@id="main-content"]//*[@class="struct"]' 'Brown' +pub mod banana { + pub struct Brown; +} + +// @has 'foo/peach/index.html' +// @count - '//*[@id="main-content"]//*[@class="struct"]' 1 +// @has - '//*[@id="main-content"]//*[@class="struct"]' 'Pungent' +pub mod peach { + pub struct Pungent; +} diff --git a/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs b/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs new file mode 100644 index 00000000000..95ddd4c7471 --- /dev/null +++ b/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs @@ -0,0 +1,31 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/94183>. +// This test ensures that a publicly re-exported private trait will +// appear in the blanket impl list. + +#![crate_name = "foo"] + +// @has 'foo/struct.S.html' + +mod actual_sub { + pub trait Actual {} + pub trait Another {} + + // `Another` is publicly re-exported so it should appear in the blanket impl list. + // @has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Another for T' + impl<T> Another for T {} + + trait Foo {} + + // `Foo` is not publicly re-exported nor reachable so it shouldn't appear in the + // blanket impl list. + // @!has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Foo for T' + impl<T> Foo for T {} +} + +pub use actual_sub::{Actual, Another}; + +// `Actual` is publicly re-exported so it should appear in the blanket impl list. +// @has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Actual for T' +impl<T> Actual for T {} + +pub struct S; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index 1120302ac7e..5d742dc391a 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -13,57 +13,57 @@ use std::marker::Destruct; pub struct S<T>(T); // @!has foo/trait.Tr.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Clone' +// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' // @!has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Clone' +// @has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Fn' #[const_trait] pub trait Tr<T> { // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const' - // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - fn a<A: ~const Clone + ~const Destruct>() + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + fn a<A: ~const Fn() + ~const Destruct>() where - Option<A>: ~const Clone + ~const Destruct, + Option<A>: ~const Fn() + ~const Destruct, { } } // @has - '//section[@id="impl-Tr%3CT%3E-for-T"]' '' // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]' '~const' -// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Clone' +// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const' -// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' -impl<T: ~const Clone + ~const Destruct> const Tr<T> for T +// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' +impl<T: ~const Fn() + ~const Destruct> const Tr<T> for T where - Option<T>: ~const Clone + ~const Destruct, + Option<T>: ~const Fn() + ~const Destruct, { - fn a<A: ~const Clone + ~const Destruct>() + fn a<A: ~const Fn() + ~const Destruct>() where - Option<A>: ~const Clone + ~const Destruct, + Option<A>: ~const Fn() + ~const Destruct, { } } // @!has foo/fn.foo.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Clone' +// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' // @!has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Clone' -pub const fn foo<F: ~const Clone + ~const Destruct>() +// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Fn' +pub const fn foo<F: ~const Fn() + ~const Destruct>() where - Option<F>: ~const Clone + ~const Destruct, + Option<F>: ~const Fn() + ~const Destruct, { F::a() } impl<T> S<T> { // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const' - // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - pub const fn foo<B, C: ~const Clone + ~const Destruct>() + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + pub const fn foo<B, C: ~const Fn() + ~const Destruct>() where - B: ~const Clone + ~const Destruct, + B: ~const Fn() + ~const Destruct, { B::a() } diff --git a/tests/ui-fulldeps/compiler-calls.rs b/tests/ui-fulldeps/compiler-calls.rs index a9520b59277..b6d3b7b040d 100644 --- a/tests/ui-fulldeps/compiler-calls.rs +++ b/tests/ui-fulldeps/compiler-calls.rs @@ -2,7 +2,6 @@ // Test that the Callbacks interface to the compiler works. // ignore-cross-compile -// ignore-stage1 // ignore-remote #![feature(rustc_private)] diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 6ba13387b04..1dd6d211b3f 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -3,8 +3,8 @@ #![feature(rustc_private)] #![crate_type = "lib"] -extern crate rustc_macros; -use rustc_macros::fluent_messages; +extern crate rustc_fluent_macro; +use rustc_fluent_macro::fluent_messages; /// Copy of the relevant `DiagnosticMessage` variant constructed by `fluent_messages` as it /// expects `crate::DiagnosticMessage` to exist. diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.rs b/tests/ui-fulldeps/hash-stable-is-unstable.rs index 11fe688f391..37d7472ec60 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.rs +++ b/tests/ui-fulldeps/hash-stable-is-unstable.rs @@ -1,4 +1,3 @@ -// ignore-stage1 // compile-flags: -Zdeduplicate-diagnostics=yes extern crate rustc_data_structures; //~^ use of unstable library feature 'rustc_private' diff --git a/tests/ui-fulldeps/hash-stable-is-unstable.stderr b/tests/ui-fulldeps/hash-stable-is-unstable.stderr index d25657691ed..1a8994d722e 100644 --- a/tests/ui-fulldeps/hash-stable-is-unstable.stderr +++ b/tests/ui-fulldeps/hash-stable-is-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:3:1 + --> $DIR/hash-stable-is-unstable.rs:2:1 | LL | extern crate rustc_data_structures; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | extern crate rustc_data_structures; = help: add `#![feature(rustc_private)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:5:1 + --> $DIR/hash-stable-is-unstable.rs:4:1 | LL | extern crate rustc_macros; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | extern crate rustc_macros; = help: add `#![feature(rustc_private)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:7:1 + --> $DIR/hash-stable-is-unstable.rs:6:1 | LL | extern crate rustc_query_system; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | extern crate rustc_query_system; = help: add `#![feature(rustc_private)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:10:5 + --> $DIR/hash-stable-is-unstable.rs:9:5 | LL | use rustc_macros::HashStable; | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | use rustc_macros::HashStable; = help: add `#![feature(rustc_private)]` to the crate attributes to enable error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/hash-stable-is-unstable.rs:13:10 + --> $DIR/hash-stable-is-unstable.rs:12:10 | LL | #[derive(HashStable)] | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 3aa65d53d4e..994fc26ba02 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -7,15 +7,17 @@ #![deny(rustc::diagnostic_outside_of_impl)] extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; use rustc_errors::{ - AddToDiagnostic, IntoDiagnostic, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, Handler, DiagnosticMessage, SubdiagnosticMessage, + AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, Handler, + IntoDiagnostic, SubdiagnosticMessage, }; -use rustc_macros::{fluent_messages, Diagnostic, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; fluent_messages! { "./diagnostics.ftl" } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 6f797ebc2dd..6e670c01852 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,5 +1,5 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:41:17 + --> $DIR/diagnostics.rs:43:17 | LL | handler.struct_err("untranslatable diagnostic") | ^^^^^^^^^^ @@ -11,13 +11,13 @@ LL | #![deny(rustc::untranslatable_diagnostic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:61:14 + --> $DIR/diagnostics.rs:63:14 | LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:78:25 + --> $DIR/diagnostics.rs:80:25 | LL | let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:81:25 + --> $DIR/diagnostics.rs:83:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:81:25 + --> $DIR/diagnostics.rs:83:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/pathless-extern-unstable.rs b/tests/ui-fulldeps/pathless-extern-unstable.rs index 524b0c2f73a..7fba8343bc0 100644 --- a/tests/ui-fulldeps/pathless-extern-unstable.rs +++ b/tests/ui-fulldeps/pathless-extern-unstable.rs @@ -1,4 +1,3 @@ -// ignore-stage1 // edition:2018 // compile-flags:--extern rustc_middle diff --git a/tests/ui-fulldeps/pathless-extern-unstable.stderr b/tests/ui-fulldeps/pathless-extern-unstable.stderr index dcc3cddd32c..174cd3c2804 100644 --- a/tests/ui-fulldeps/pathless-extern-unstable.stderr +++ b/tests/ui-fulldeps/pathless-extern-unstable.stderr @@ -1,5 +1,5 @@ error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead? - --> $DIR/pathless-extern-unstable.rs:7:9 + --> $DIR/pathless-extern-unstable.rs:6:9 | LL | pub use rustc_middle; | ^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/auxiliary/empty-plugin.rs b/tests/ui-fulldeps/plugin/auxiliary/empty-plugin.rs index c24cdc97aa5..c24cdc97aa5 100644 --- a/tests/ui-fulldeps/auxiliary/empty-plugin.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/empty-plugin.rs diff --git a/tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs index 3f6caecaa5a..3f6caecaa5a 100644 --- a/tests/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/issue-40001-plugin.rs diff --git a/tests/ui-fulldeps/auxiliary/lint-for-crate.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs index 6304c07d2c7..6304c07d2c7 100644 --- a/tests/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-for-crate.rs diff --git a/tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs index 4a41e7fbb72..4a41e7fbb72 100644 --- a/tests/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs diff --git a/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs index 30956deb799..30956deb799 100644 --- a/tests/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs diff --git a/tests/ui-fulldeps/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs index c2c024865e8..c2c024865e8 100644 --- a/tests/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs diff --git a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs b/tests/ui-fulldeps/plugin/auxiliary/lto-syntax-extension-lib.rs index 954a1e554da..954a1e554da 100644 --- a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-lib.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lto-syntax-extension-lib.rs diff --git a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs b/tests/ui-fulldeps/plugin/auxiliary/lto-syntax-extension-plugin.rs index 9b075c1a5b9..9b075c1a5b9 100644 --- a/tests/ui-fulldeps/auxiliary/lto-syntax-extension-plugin.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/lto-syntax-extension-plugin.rs diff --git a/tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs b/tests/ui-fulldeps/plugin/auxiliary/multiple-plugins-1.rs index fd6e9e20f03..fd6e9e20f03 100644 --- a/tests/ui-fulldeps/auxiliary/multiple-plugins-1.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/multiple-plugins-1.rs diff --git a/tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs b/tests/ui-fulldeps/plugin/auxiliary/multiple-plugins-2.rs index fd6e9e20f03..fd6e9e20f03 100644 --- a/tests/ui-fulldeps/auxiliary/multiple-plugins-2.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/multiple-plugins-2.rs diff --git a/tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs b/tests/ui-fulldeps/plugin/auxiliary/outlive-expansion-phase.rs index e83dfe80463..e83dfe80463 100644 --- a/tests/ui-fulldeps/auxiliary/outlive-expansion-phase.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/outlive-expansion-phase.rs diff --git a/tests/ui-fulldeps/auxiliary/rlib-crate-test.rs b/tests/ui-fulldeps/plugin/auxiliary/rlib-crate-test.rs index 3ba73538ecf..3ba73538ecf 100644 --- a/tests/ui-fulldeps/auxiliary/rlib-crate-test.rs +++ b/tests/ui-fulldeps/plugin/auxiliary/rlib-crate-test.rs diff --git a/tests/ui-fulldeps/feature-gate-plugin.rs b/tests/ui-fulldeps/plugin/feature-gate-plugin.rs index 85eaf533643..85eaf533643 100644 --- a/tests/ui-fulldeps/feature-gate-plugin.rs +++ b/tests/ui-fulldeps/plugin/feature-gate-plugin.rs diff --git a/tests/ui-fulldeps/feature-gate-plugin.stderr b/tests/ui-fulldeps/plugin/feature-gate-plugin.stderr index 5e40561c7f5..5e40561c7f5 100644 --- a/tests/ui-fulldeps/feature-gate-plugin.stderr +++ b/tests/ui-fulldeps/plugin/feature-gate-plugin.stderr diff --git a/tests/ui-fulldeps/gated-plugin.rs b/tests/ui-fulldeps/plugin/gated-plugin.rs index 85eaf533643..85eaf533643 100644 --- a/tests/ui-fulldeps/gated-plugin.rs +++ b/tests/ui-fulldeps/plugin/gated-plugin.rs diff --git a/tests/ui-fulldeps/gated-plugin.stderr b/tests/ui-fulldeps/plugin/gated-plugin.stderr index f48f1eab60b..f48f1eab60b 100644 --- a/tests/ui-fulldeps/gated-plugin.stderr +++ b/tests/ui-fulldeps/plugin/gated-plugin.stderr diff --git a/tests/ui-fulldeps/issue-15778-fail.rs b/tests/ui-fulldeps/plugin/issue-15778-fail.rs index beecaadf955..beecaadf955 100644 --- a/tests/ui-fulldeps/issue-15778-fail.rs +++ b/tests/ui-fulldeps/plugin/issue-15778-fail.rs diff --git a/tests/ui-fulldeps/issue-15778-fail.stderr b/tests/ui-fulldeps/plugin/issue-15778-fail.stderr index a37893e1203..a37893e1203 100644 --- a/tests/ui-fulldeps/issue-15778-fail.stderr +++ b/tests/ui-fulldeps/plugin/issue-15778-fail.stderr diff --git a/tests/ui-fulldeps/issue-40001.rs b/tests/ui-fulldeps/plugin/issue-40001.rs index e14338fdbbf..e14338fdbbf 100644 --- a/tests/ui-fulldeps/issue-40001.rs +++ b/tests/ui-fulldeps/plugin/issue-40001.rs diff --git a/tests/ui-fulldeps/issue-40001.stderr b/tests/ui-fulldeps/plugin/issue-40001.stderr index 73ec0692464..73ec0692464 100644 --- a/tests/ui-fulldeps/issue-40001.stderr +++ b/tests/ui-fulldeps/plugin/issue-40001.stderr diff --git a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs b/tests/ui-fulldeps/plugin/lint-group-plugin-deny-cmdline.rs index 9f8a879608c..9f8a879608c 100644 --- a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.rs +++ b/tests/ui-fulldeps/plugin/lint-group-plugin-deny-cmdline.rs diff --git a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr b/tests/ui-fulldeps/plugin/lint-group-plugin-deny-cmdline.stderr index 20486d596d9..20486d596d9 100644 --- a/tests/ui-fulldeps/lint-group-plugin-deny-cmdline.stderr +++ b/tests/ui-fulldeps/plugin/lint-group-plugin-deny-cmdline.stderr diff --git a/tests/ui-fulldeps/lint-group-plugin.rs b/tests/ui-fulldeps/plugin/lint-group-plugin.rs index 7b74be7a954..7b74be7a954 100644 --- a/tests/ui-fulldeps/lint-group-plugin.rs +++ b/tests/ui-fulldeps/plugin/lint-group-plugin.rs diff --git a/tests/ui-fulldeps/lint-group-plugin.stderr b/tests/ui-fulldeps/plugin/lint-group-plugin.stderr index 6f429dad017..6f429dad017 100644 --- a/tests/ui-fulldeps/lint-group-plugin.stderr +++ b/tests/ui-fulldeps/plugin/lint-group-plugin.stderr diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-allow.rs b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-allow.rs index 1cc16e2fd1c..1cc16e2fd1c 100644 --- a/tests/ui-fulldeps/lint-plugin-cmdline-allow.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-allow.rs diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-allow.stderr index f06703a2784..f06703a2784 100644 --- a/tests/ui-fulldeps/lint-plugin-cmdline-allow.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-allow.stderr diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-load.rs b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-load.rs index 0bd95dfbd14..0bd95dfbd14 100644 --- a/tests/ui-fulldeps/lint-plugin-cmdline-load.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-load.rs diff --git a/tests/ui-fulldeps/lint-plugin-cmdline-load.stderr b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-load.stderr index 82679c9e10a..82679c9e10a 100644 --- a/tests/ui-fulldeps/lint-plugin-cmdline-load.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-cmdline-load.stderr diff --git a/tests/ui-fulldeps/lint-plugin-deny-attr.rs b/tests/ui-fulldeps/plugin/lint-plugin-deny-attr.rs index 04230a8e883..04230a8e883 100644 --- a/tests/ui-fulldeps/lint-plugin-deny-attr.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-deny-attr.rs diff --git a/tests/ui-fulldeps/lint-plugin-deny-attr.stderr b/tests/ui-fulldeps/plugin/lint-plugin-deny-attr.stderr index 5e8891bf1f1..5e8891bf1f1 100644 --- a/tests/ui-fulldeps/lint-plugin-deny-attr.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-deny-attr.stderr diff --git a/tests/ui-fulldeps/lint-plugin-deny-cmdline.rs b/tests/ui-fulldeps/plugin/lint-plugin-deny-cmdline.rs index c460cfd5f94..c460cfd5f94 100644 --- a/tests/ui-fulldeps/lint-plugin-deny-cmdline.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-deny-cmdline.rs diff --git a/tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr b/tests/ui-fulldeps/plugin/lint-plugin-deny-cmdline.stderr index d5d6b535214..d5d6b535214 100644 --- a/tests/ui-fulldeps/lint-plugin-deny-cmdline.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-deny-cmdline.stderr diff --git a/tests/ui-fulldeps/lint-plugin-forbid-attrs.rs b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.rs index cf31b3ec158..cf31b3ec158 100644 --- a/tests/ui-fulldeps/lint-plugin-forbid-attrs.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.rs diff --git a/tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr index ae34b25cc2f..ae34b25cc2f 100644 --- a/tests/ui-fulldeps/lint-plugin-forbid-attrs.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-attrs.stderr diff --git a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.rs index b9d1aa85a69..b9d1aa85a69 100644 --- a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.rs diff --git a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr index 491c4d20646..491c4d20646 100644 --- a/tests/ui-fulldeps/lint-plugin-forbid-cmdline.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin-forbid-cmdline.stderr diff --git a/tests/ui-fulldeps/lint-plugin.rs b/tests/ui-fulldeps/plugin/lint-plugin.rs index 66057eea6bc..66057eea6bc 100644 --- a/tests/ui-fulldeps/lint-plugin.rs +++ b/tests/ui-fulldeps/plugin/lint-plugin.rs diff --git a/tests/ui-fulldeps/lint-plugin.stderr b/tests/ui-fulldeps/plugin/lint-plugin.stderr index dd5d3d72ecf..dd5d3d72ecf 100644 --- a/tests/ui-fulldeps/lint-plugin.stderr +++ b/tests/ui-fulldeps/plugin/lint-plugin.stderr diff --git a/tests/ui-fulldeps/lint-tool-cmdline-allow.rs b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.rs index 83a8b3e1a7e..83a8b3e1a7e 100644 --- a/tests/ui-fulldeps/lint-tool-cmdline-allow.rs +++ b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.rs diff --git a/tests/ui-fulldeps/lint-tool-cmdline-allow.stderr b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr index b060e3a3e38..b060e3a3e38 100644 --- a/tests/ui-fulldeps/lint-tool-cmdline-allow.stderr +++ b/tests/ui-fulldeps/plugin/lint-tool-cmdline-allow.stderr diff --git a/tests/ui-fulldeps/lint-tool-test.rs b/tests/ui-fulldeps/plugin/lint-tool-test.rs index f92bcd213b8..f92bcd213b8 100644 --- a/tests/ui-fulldeps/lint-tool-test.rs +++ b/tests/ui-fulldeps/plugin/lint-tool-test.rs diff --git a/tests/ui-fulldeps/lint-tool-test.stderr b/tests/ui-fulldeps/plugin/lint-tool-test.stderr index 027cf8f80cf..027cf8f80cf 100644 --- a/tests/ui-fulldeps/lint-tool-test.stderr +++ b/tests/ui-fulldeps/plugin/lint-tool-test.stderr diff --git a/tests/ui-fulldeps/lto-syntax-extension.rs b/tests/ui-fulldeps/plugin/lto-syntax-extension.rs index 5964e70f195..5964e70f195 100644 --- a/tests/ui-fulldeps/lto-syntax-extension.rs +++ b/tests/ui-fulldeps/plugin/lto-syntax-extension.rs diff --git a/tests/ui-fulldeps/lto-syntax-extension.stderr b/tests/ui-fulldeps/plugin/lto-syntax-extension.stderr index 555493f3230..555493f3230 100644 --- a/tests/ui-fulldeps/lto-syntax-extension.stderr +++ b/tests/ui-fulldeps/plugin/lto-syntax-extension.stderr diff --git a/tests/ui-fulldeps/macro-crate-rlib.rs b/tests/ui-fulldeps/plugin/macro-crate-rlib.rs index 1fd514c6173..38bd340539b 100644 --- a/tests/ui-fulldeps/macro-crate-rlib.rs +++ b/tests/ui-fulldeps/plugin/macro-crate-rlib.rs @@ -1,4 +1,5 @@ // aux-build:rlib-crate-test.rs +// ignore-stage1 // ignore-cross-compile gives a different error message #![feature(plugin)] diff --git a/tests/ui-fulldeps/macro-crate-rlib.stderr b/tests/ui-fulldeps/plugin/macro-crate-rlib.stderr index 9c2b992b765..0651cee56f7 100644 --- a/tests/ui-fulldeps/macro-crate-rlib.stderr +++ b/tests/ui-fulldeps/plugin/macro-crate-rlib.stderr @@ -1,5 +1,5 @@ error[E0457]: plugin `rlib_crate_test` only found in rlib format, but must be available in dylib format - --> $DIR/macro-crate-rlib.rs:5:11 + --> $DIR/macro-crate-rlib.rs:6:11 | LL | #![plugin(rlib_crate_test)] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui-fulldeps/multiple-plugins.rs b/tests/ui-fulldeps/plugin/multiple-plugins.rs index 9af3ebd570c..9af3ebd570c 100644 --- a/tests/ui-fulldeps/multiple-plugins.rs +++ b/tests/ui-fulldeps/plugin/multiple-plugins.rs diff --git a/tests/ui-fulldeps/multiple-plugins.stderr b/tests/ui-fulldeps/plugin/multiple-plugins.stderr index 878ffabfc7f..878ffabfc7f 100644 --- a/tests/ui-fulldeps/multiple-plugins.stderr +++ b/tests/ui-fulldeps/plugin/multiple-plugins.stderr diff --git a/tests/ui-fulldeps/outlive-expansion-phase.rs b/tests/ui-fulldeps/plugin/outlive-expansion-phase.rs index fb22888d98a..fb22888d98a 100644 --- a/tests/ui-fulldeps/outlive-expansion-phase.rs +++ b/tests/ui-fulldeps/plugin/outlive-expansion-phase.rs diff --git a/tests/ui-fulldeps/outlive-expansion-phase.stderr b/tests/ui-fulldeps/plugin/outlive-expansion-phase.stderr index e40a08ae73b..e40a08ae73b 100644 --- a/tests/ui-fulldeps/outlive-expansion-phase.stderr +++ b/tests/ui-fulldeps/plugin/outlive-expansion-phase.stderr diff --git a/tests/ui-fulldeps/plugin-args.rs b/tests/ui-fulldeps/plugin/plugin-args.rs index 488f2b775bf..488f2b775bf 100644 --- a/tests/ui-fulldeps/plugin-args.rs +++ b/tests/ui-fulldeps/plugin/plugin-args.rs diff --git a/tests/ui-fulldeps/plugin-args.stderr b/tests/ui-fulldeps/plugin/plugin-args.stderr index 177f33005c8..177f33005c8 100644 --- a/tests/ui-fulldeps/plugin-args.stderr +++ b/tests/ui-fulldeps/plugin/plugin-args.stderr diff --git a/tests/ui-fulldeps/plugin-as-extern-crate.rs b/tests/ui-fulldeps/plugin/plugin-as-extern-crate.rs index 4d26e08d81e..4d26e08d81e 100644 --- a/tests/ui-fulldeps/plugin-as-extern-crate.rs +++ b/tests/ui-fulldeps/plugin/plugin-as-extern-crate.rs diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 6cc7bab3726..80ab03ab24c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -6,6 +6,7 @@ // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Diagnostic is strictly internal to the compiler // the test is just ignored on stable and beta: +// ignore-stage1 // ignore-beta // ignore-stable @@ -16,8 +17,10 @@ extern crate rustc_span; use rustc_span::symbol::Ident; use rustc_span::Span; +extern crate rustc_fluent_macro; extern crate rustc_macros; -use rustc_macros::{fluent_messages, Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; extern crate rustc_middle; use rustc_middle::ty::Ty; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index a2f3bb5277b..5e1bea4e38c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,11 +1,11 @@ error: unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:41:1 + --> $DIR/diagnostic-derive.rs:44:1 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:44:5 + --> $DIR/diagnostic-derive.rs:47:5 | LL | Foo, | ^^^ @@ -13,7 +13,7 @@ LL | Foo, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:46:5 + --> $DIR/diagnostic-derive.rs:49:5 | LL | Bar, | ^^^ @@ -21,19 +21,19 @@ LL | Bar, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: expected parentheses: #[diag(...)] - --> $DIR/diagnostic-derive.rs:52:8 + --> $DIR/diagnostic-derive.rs:55:8 | LL | #[diag = "E0123"] | ^ error: `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:57:1 + --> $DIR/diagnostic-derive.rs:60:1 | LL | #[nonsense(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:57:1 + --> $DIR/diagnostic-derive.rs:60:1 | LL | / #[nonsense(no_crate_example, code = "E0123")] LL | | @@ -45,7 +45,7 @@ LL | | struct InvalidStructAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:64:1 + --> $DIR/diagnostic-derive.rs:67:1 | LL | / #[diag("E0123")] LL | | @@ -55,13 +55,13 @@ LL | | struct InvalidLitNestedAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:74:16 + --> $DIR/diagnostic-derive.rs:77:16 | LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:74:1 + --> $DIR/diagnostic-derive.rs:77:1 | LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")] LL | | @@ -72,7 +72,7 @@ LL | | struct InvalidNestedStructAttr1 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:80:8 + --> $DIR/diagnostic-derive.rs:83:8 | LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^ @@ -80,7 +80,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:80:1 + --> $DIR/diagnostic-derive.rs:83:1 | LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")] LL | | @@ -91,7 +91,7 @@ LL | | struct InvalidNestedStructAttr2 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:86:8 + --> $DIR/diagnostic-derive.rs:89:8 | LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^ @@ -99,7 +99,7 @@ LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:86:1 + --> $DIR/diagnostic-derive.rs:89:1 | LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")] LL | | @@ -110,7 +110,7 @@ LL | | struct InvalidNestedStructAttr3 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:92:42 + --> $DIR/diagnostic-derive.rs:95:42 | LL | #[diag(no_crate_example, code = "E0123", slug = "foo")] | ^^^^ @@ -118,55 +118,55 @@ LL | #[diag(no_crate_example, code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:99:5 + --> $DIR/diagnostic-derive.rs:102:5 | LL | #[suggestion = "bar"] | ^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:106:8 + --> $DIR/diagnostic-derive.rs:109:8 | LL | #[diag(no_crate_example, code = "E0456")] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:105:8 + --> $DIR/diagnostic-derive.rs:108:8 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:106:26 + --> $DIR/diagnostic-derive.rs:109:26 | LL | #[diag(no_crate_example, code = "E0456")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:105:26 + --> $DIR/diagnostic-derive.rs:108:26 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:112:42 + --> $DIR/diagnostic-derive.rs:115:42 | LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:112:26 + --> $DIR/diagnostic-derive.rs:115:26 | LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] | ^^^^ error: diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:117:43 + --> $DIR/diagnostic-derive.rs:120:43 | LL | #[diag(no_crate_example, no_crate::example, code = "E0456")] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:122:1 + --> $DIR/diagnostic-derive.rs:125:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | struct KindNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:125:1 + --> $DIR/diagnostic-derive.rs:128:1 | LL | / #[diag(code = "E0456")] LL | | @@ -184,31 +184,31 @@ LL | | struct SlugNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:136:5 + --> $DIR/diagnostic-derive.rs:139:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:144:5 + --> $DIR/diagnostic-derive.rs:147:5 | LL | #[nonsense] | ^^^^^^^^^^^ error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:161:5 + --> $DIR/diagnostic-derive.rs:164:5 | LL | #[label(no_crate_label)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:169:46 + --> $DIR/diagnostic-derive.rs:172:46 | LL | #[suggestion(no_crate_suggestion, code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:174:10 + --> $DIR/diagnostic-derive.rs:177:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ expected `'}'` in format string @@ -217,7 +217,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:184:10 + --> $DIR/diagnostic-derive.rs:187:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ unmatched `}` in format string @@ -226,19 +226,19 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:204:5 + --> $DIR/diagnostic-derive.rs:207:5 | LL | #[label(no_crate_label)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:223:5 + --> $DIR/diagnostic-derive.rs:226:5 | LL | #[suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:231:18 + --> $DIR/diagnostic-derive.rs:234:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^ @@ -246,13 +246,13 @@ LL | #[suggestion(nonsense = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:231:5 + --> $DIR/diagnostic-derive.rs:234:5 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:240:18 + --> $DIR/diagnostic-derive.rs:243:18 | LL | #[suggestion(msg = "bar")] | ^^^ @@ -260,13 +260,13 @@ LL | #[suggestion(msg = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:240:5 + --> $DIR/diagnostic-derive.rs:243:5 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:263:5 + --> $DIR/diagnostic-derive.rs:266:5 | LL | / #[suggestion(no_crate_suggestion, code = "This is suggested code")] LL | | @@ -276,79 +276,79 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: specified multiple times - --> $DIR/diagnostic-derive.rs:279:24 + --> $DIR/diagnostic-derive.rs:282:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:279:18 + --> $DIR/diagnostic-derive.rs:282:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:287:33 + --> $DIR/diagnostic-derive.rs:290:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:287:18 + --> $DIR/diagnostic-derive.rs:290:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:294:5 + --> $DIR/diagnostic-derive.rs:297:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:445:5 + --> $DIR/diagnostic-derive.rs:448:5 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:447:24 + --> $DIR/diagnostic-derive.rs:450:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:453:69 + --> $DIR/diagnostic-derive.rs:456:69 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] | ^^^^^^^^ error: the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive.rs:520:5 + --> $DIR/diagnostic-derive.rs:523:5 | LL | #[help(no_crate_help)] | ^^^^^^^^^^^^^^^^^^^^^^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive.rs:529:32 + --> $DIR/diagnostic-derive.rs:532:32 | LL | #[label(no_crate_label, foo)] | ^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:537:29 + --> $DIR/diagnostic-derive.rs:540:29 | LL | #[label(no_crate_label, foo = "...")] | ^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:545:29 + --> $DIR/diagnostic-derive.rs:548:29 | LL | #[label(no_crate_label, foo("..."))] | ^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:557:5 + --> $DIR/diagnostic-derive.rs:560:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -356,13 +356,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:577:1 + --> $DIR/diagnostic-derive.rs:580:1 | LL | #[error(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:577:1 + --> $DIR/diagnostic-derive.rs:580:1 | LL | / #[error(no_crate_example, code = "E0123")] LL | | @@ -374,13 +374,13 @@ LL | | struct ErrorAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:584:1 + --> $DIR/diagnostic-derive.rs:587:1 | LL | #[warn_(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:584:1 + --> $DIR/diagnostic-derive.rs:587:1 | LL | / #[warn_(no_crate_example, code = "E0123")] LL | | @@ -392,13 +392,13 @@ LL | | struct WarnAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:591:1 + --> $DIR/diagnostic-derive.rs:594:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:591:1 + --> $DIR/diagnostic-derive.rs:594:1 | LL | / #[lint(no_crate_example, code = "E0123")] LL | | @@ -410,19 +410,19 @@ LL | | struct LintAttributeOnSessionDiag {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:598:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:598:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:598:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | / #[lint(no_crate_example, code = "E0123")] LL | | @@ -435,19 +435,19 @@ LL | | struct LintAttributeOnLintDiag {} = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:608:53 + --> $DIR/diagnostic-derive.rs:611:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:608:39 + --> $DIR/diagnostic-derive.rs:611:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:617:24 + --> $DIR/diagnostic-derive.rs:620:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -455,7 +455,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:625:17 + --> $DIR/diagnostic-derive.rs:628:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -463,13 +463,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:632:5 + --> $DIR/diagnostic-derive.rs:635:5 | LL | #[suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:639:1 + --> $DIR/diagnostic-derive.rs:642:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -477,7 +477,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:646:5 + --> $DIR/diagnostic-derive.rs:649:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -485,13 +485,13 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/diagnostic-derive.rs:642:24 + --> $DIR/diagnostic-derive.rs:645:24 | LL | #[multipart_suggestion()] | ^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:654:1 + --> $DIR/diagnostic-derive.rs:657:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -499,7 +499,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:663:1 + --> $DIR/diagnostic-derive.rs:666:1 | LL | #[label] | ^^^^^^^^ @@ -507,31 +507,31 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:697:7 + --> $DIR/diagnostic-derive.rs:700:7 | LL | #[subdiagnostic(bad)] | ^^^^^^^^^^^^^^^^^^ error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:705:5 + --> $DIR/diagnostic-derive.rs:708:5 | LL | #[subdiagnostic = "bad"] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:713:7 + --> $DIR/diagnostic-derive.rs:716:7 | LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:721:7 + --> $DIR/diagnostic-derive.rs:724:7 | LL | #[subdiagnostic("bad")] | ^^^^^^^^^^^^^^^^^^^^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:729:5 + --> $DIR/diagnostic-derive.rs:732:5 | LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -539,31 +539,31 @@ LL | #[subdiagnostic(eager)] = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:787:23 + --> $DIR/diagnostic-derive.rs:790:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:795:23 + --> $DIR/diagnostic-derive.rs:798:23 | LL | #[suggestion(code(foo))] | ^^^ error: unexpected token - --> $DIR/diagnostic-derive.rs:795:23 + --> $DIR/diagnostic-derive.rs:798:23 | LL | #[suggestion(code(foo))] | ^^^ error: expected string literal - --> $DIR/diagnostic-derive.rs:804:25 + --> $DIR/diagnostic-derive.rs:807:25 | LL | #[suggestion(code = 3)] | ^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:819:5 + --> $DIR/diagnostic-derive.rs:822:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -573,67 +573,67 @@ LL | #[suggestion(no_crate_suggestion, code = "")] = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:57:3 + --> $DIR/diagnostic-derive.rs:60:3 | LL | #[nonsense(no_crate_example, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:144:7 + --> $DIR/diagnostic-derive.rs:147:7 | LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:577:3 + --> $DIR/diagnostic-derive.rs:580:3 | LL | #[error(no_crate_example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:584:3 + --> $DIR/diagnostic-derive.rs:587:3 | LL | #[warn_(no_crate_example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:591:3 + --> $DIR/diagnostic-derive.rs:594:3 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:598:3 + --> $DIR/diagnostic-derive.rs:601:3 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:639:3 + --> $DIR/diagnostic-derive.rs:642:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:642:3 + --> $DIR/diagnostic-derive.rs:645:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:646:7 + --> $DIR/diagnostic-derive.rs:649:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` - --> $DIR/diagnostic-derive.rs:69:8 + --> $DIR/diagnostic-derive.rs:72:8 | LL | #[diag(nonsense, code = "E0123")] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:801:10 + --> $DIR/diagnostic-derive.rs:804:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -641,7 +641,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:338:10 + --> $DIR/diagnostic-derive.rs:341:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 1d928ca93f9..1bfbb60015d 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -4,6 +4,7 @@ // The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, // changing the output of this test. Since Subdiagnostic is strictly internal to the compiler // the test is just ignored on stable and beta: +// ignore-stage1 // ignore-beta // ignore-stable @@ -11,12 +12,14 @@ #![crate_type = "lib"] extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::{fluent_messages, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::Subdiagnostic; use rustc_span::Span; fluent_messages! { "./example.ftl" } diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 4211b91f04a..fca4f506890 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,5 +1,5 @@ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:49:1 + --> $DIR/subdiagnostic-derive.rs:52:1 | LL | / #[label(no_crate_example)] LL | | @@ -9,133 +9,133 @@ LL | | } | |_^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:56:1 + --> $DIR/subdiagnostic-derive.rs:59:1 | LL | #[label] | ^^^^^^^^ error: `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:65:1 + --> $DIR/subdiagnostic-derive.rs:68:1 | LL | #[foo] | ^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:75:1 + --> $DIR/subdiagnostic-derive.rs:78:1 | LL | #[label = "..."] | ^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:84:9 + --> $DIR/subdiagnostic-derive.rs:87:9 | LL | #[label(bug = "...")] | ^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:84:1 + --> $DIR/subdiagnostic-derive.rs:87:1 | LL | #[label(bug = "...")] | ^^^^^^^^^^^^^^^^^^^^^ error: unexpected literal in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:94:9 + --> $DIR/subdiagnostic-derive.rs:97:9 | LL | #[label("...")] | ^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:103:9 + --> $DIR/subdiagnostic-derive.rs:106:9 | LL | #[label(slug = 4)] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:103:1 + --> $DIR/subdiagnostic-derive.rs:106:1 | LL | #[label(slug = 4)] | ^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:113:9 + --> $DIR/subdiagnostic-derive.rs:116:9 | LL | #[label(slug("..."))] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:113:1 + --> $DIR/subdiagnostic-derive.rs:116:1 | LL | #[label(slug("..."))] | ^^^^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:133:9 + --> $DIR/subdiagnostic-derive.rs:136:9 | LL | #[label()] | ^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:142:27 + --> $DIR/subdiagnostic-derive.rs:145:27 | LL | #[label(no_crate_example, code = "...")] | ^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:151:27 + --> $DIR/subdiagnostic-derive.rs:154:27 | LL | #[label(no_crate_example, applicability = "machine-applicable")] | ^^^^^^^^^^^^^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:160:1 + --> $DIR/subdiagnostic-derive.rs:163:1 | LL | #[foo] | ^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:174:5 + --> $DIR/subdiagnostic-derive.rs:177:5 | LL | #[bar] | ^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:186:5 + --> $DIR/subdiagnostic-derive.rs:189:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:198:5 + --> $DIR/subdiagnostic-derive.rs:201:5 | LL | #[bar = 4] | ^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:210:5 + --> $DIR/subdiagnostic-derive.rs:213:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:222:13 + --> $DIR/subdiagnostic-derive.rs:225:13 | LL | #[label(code = "...")] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:222:5 + --> $DIR/subdiagnostic-derive.rs:225:5 | LL | #[label(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:251:5 + --> $DIR/subdiagnostic-derive.rs:254:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:248:1 + --> $DIR/subdiagnostic-derive.rs:251:1 | LL | / #[label(no_crate_example)] LL | | @@ -147,13 +147,13 @@ LL | | } | |_^ error: `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:261:5 + --> $DIR/subdiagnostic-derive.rs:264:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:271:5 + --> $DIR/subdiagnostic-derive.rs:274:5 | LL | #[bar] | ^^^^^^ @@ -161,13 +161,13 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:282:5 + --> $DIR/subdiagnostic-derive.rs:285:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:293:5 + --> $DIR/subdiagnostic-derive.rs:296:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | #[bar("...")] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive.rs:309:1 + --> $DIR/subdiagnostic-derive.rs:312:1 | LL | / union AC { LL | | @@ -185,73 +185,73 @@ LL | | } | |_^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:324:44 + --> $DIR/subdiagnostic-derive.rs:327:44 | LL | #[label(no_crate_example, no_crate::example)] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:337:5 + --> $DIR/subdiagnostic-derive.rs:340:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:334:5 + --> $DIR/subdiagnostic-derive.rs:337:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:343:8 + --> $DIR/subdiagnostic-derive.rs:346:8 | LL | struct AG { | ^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:380:46 + --> $DIR/subdiagnostic-derive.rs:383:46 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:380:32 + --> $DIR/subdiagnostic-derive.rs:383:32 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:398:5 + --> $DIR/subdiagnostic-derive.rs:401:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:395:5 + --> $DIR/subdiagnostic-derive.rs:398:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:408:5 + --> $DIR/subdiagnostic-derive.rs:411:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:421:1 + --> $DIR/subdiagnostic-derive.rs:424:1 | LL | #[suggestion(no_crate_example)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:431:62 + --> $DIR/subdiagnostic-derive.rs:434:62 | LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] | ^^^^^ error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:449:1 + --> $DIR/subdiagnostic-derive.rs:452:1 | LL | / #[suggestion(no_crate_example, code = "...")] LL | | @@ -261,25 +261,25 @@ LL | | } | |_^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:463:1 + --> $DIR/subdiagnostic-derive.rs:466:1 | LL | #[label] | ^^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:483:39 + --> $DIR/subdiagnostic-derive.rs:486:39 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:502:43 + --> $DIR/subdiagnostic-derive.rs:505:43 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:525:5 + --> $DIR/subdiagnostic-derive.rs:528:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:528:5 + --> $DIR/subdiagnostic-derive.rs:531:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:522:1 + --> $DIR/subdiagnostic-derive.rs:525:1 | LL | / #[suggestion(no_crate_example, code = "...")] LL | | @@ -307,7 +307,7 @@ LL | | } | |_^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:537:42 + --> $DIR/subdiagnostic-derive.rs:540:42 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^^^^ @@ -315,7 +315,7 @@ LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "mac = help: only `style` and `applicability` are valid nested attributes error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:537:1 + --> $DIR/subdiagnostic-derive.rs:540:1 | LL | / #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] LL | | @@ -326,19 +326,19 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:547:5 + --> $DIR/subdiagnostic-derive.rs:550:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:555:23 + --> $DIR/subdiagnostic-derive.rs:558:23 | LL | #[suggestion_part()] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:564:5 + --> $DIR/subdiagnostic-derive.rs:567:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:561:1 + --> $DIR/subdiagnostic-derive.rs:564:1 | LL | / #[multipart_suggestion(no_crate_example)] LL | | @@ -358,121 +358,121 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:572:5 + --> $DIR/subdiagnostic-derive.rs:575:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:578:23 + --> $DIR/subdiagnostic-derive.rs:581:23 | LL | #[suggestion_part(foo = "bar")] | ^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:582:5 + --> $DIR/subdiagnostic-derive.rs:585:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:585:5 + --> $DIR/subdiagnostic-derive.rs:588:5 | LL | #[suggestion_part()] | ^^^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:575:23 + --> $DIR/subdiagnostic-derive.rs:578:23 | LL | #[suggestion_part()] | ^ error: expected `,` - --> $DIR/subdiagnostic-derive.rs:578:27 + --> $DIR/subdiagnostic-derive.rs:581:27 | LL | #[suggestion_part(foo = "bar")] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:593:37 + --> $DIR/subdiagnostic-derive.rs:596:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:593:23 + --> $DIR/subdiagnostic-derive.rs:596:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:622:5 + --> $DIR/subdiagnostic-derive.rs:625:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:670:34 + --> $DIR/subdiagnostic-derive.rs:673:34 | LL | #[suggestion_part(code("foo"))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:670:28 + --> $DIR/subdiagnostic-derive.rs:673:28 | LL | #[suggestion_part(code("foo"))] | ^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:680:41 + --> $DIR/subdiagnostic-derive.rs:683:41 | LL | #[suggestion_part(code("foo", "bar"))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:680:28 + --> $DIR/subdiagnostic-derive.rs:683:28 | LL | #[suggestion_part(code("foo", "bar"))] | ^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:690:30 + --> $DIR/subdiagnostic-derive.rs:693:30 | LL | #[suggestion_part(code(3))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:690:28 + --> $DIR/subdiagnostic-derive.rs:693:28 | LL | #[suggestion_part(code(3))] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:700:29 + --> $DIR/subdiagnostic-derive.rs:703:29 | LL | #[suggestion_part(code())] | ^ error: expected string literal - --> $DIR/subdiagnostic-derive.rs:712:30 + --> $DIR/subdiagnostic-derive.rs:715:30 | LL | #[suggestion_part(code = 3)] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:754:1 + --> $DIR/subdiagnostic-derive.rs:757:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:754:1 + --> $DIR/subdiagnostic-derive.rs:757:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:766:1 | LL | #[suggestion_hidden(no_crate_example, code = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -480,7 +480,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:771:1 + --> $DIR/subdiagnostic-derive.rs:774:1 | LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -488,7 +488,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:779:51 + --> $DIR/subdiagnostic-derive.rs:782:51 | LL | #[suggestion(no_crate_example, code = "", style = "foo")] | ^^^^^ @@ -496,31 +496,31 @@ LL | #[suggestion(no_crate_example, code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:787:49 + --> $DIR/subdiagnostic-derive.rs:790:49 | LL | #[suggestion(no_crate_example, code = "", style = 42)] | ^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:795:48 + --> $DIR/subdiagnostic-derive.rs:798:48 | LL | #[suggestion(no_crate_example, code = "", style)] | ^ error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:803:48 + --> $DIR/subdiagnostic-derive.rs:806:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: expected `,` - --> $DIR/subdiagnostic-derive.rs:803:48 + --> $DIR/subdiagnostic-derive.rs:806:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:815:5 + --> $DIR/subdiagnostic-derive.rs:818:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -529,7 +529,7 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:812:1 + --> $DIR/subdiagnostic-derive.rs:815:1 | LL | / #[suggestion(no_crate_example, code = "")] LL | | @@ -541,67 +541,67 @@ LL | | } | |_^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:65:3 + --> $DIR/subdiagnostic-derive.rs:68:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:160:3 + --> $DIR/subdiagnostic-derive.rs:163:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:174:7 + --> $DIR/subdiagnostic-derive.rs:177:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:186:7 + --> $DIR/subdiagnostic-derive.rs:189:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:198:7 + --> $DIR/subdiagnostic-derive.rs:201:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:210:7 + --> $DIR/subdiagnostic-derive.rs:213:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:271:7 + --> $DIR/subdiagnostic-derive.rs:274:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:282:7 + --> $DIR/subdiagnostic-derive.rs:285:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:293:7 + --> $DIR/subdiagnostic-derive.rs:296:7 | LL | #[bar("...")] | ^^^ error[E0425]: cannot find value `slug` in module `crate::fluent_generated` - --> $DIR/subdiagnostic-derive.rs:123:9 + --> $DIR/subdiagnostic-derive.rs:126:9 | LL | #[label(slug)] | ^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_29` in this scope - --> $DIR/subdiagnostic-derive.rs:706:10 + --> $DIR/subdiagnostic-derive.rs:709:10 | LL | #[derive(Subdiagnostic)] | ^^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index dfde8c97ec2..95f27efa771 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -33,7 +33,6 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { // Find items in the local crate. let items = stable_mir::all_local_items(); - assert!(get_item(tcx, &items, (DefKind::Fn, "foo_bar")).is_some()); assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); // Find the `std` crate. @@ -52,6 +51,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { stable_mir::mir::Terminator::Return => {} other => panic!("{other:?}"), } + + let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); + let body = foo_bar.body(); + assert_eq!(body.blocks.len(), 4); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Call { .. } => {} + other => panic!("{other:?}"), + } } // Use internal API to find a function in a crate. diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs new file mode 100644 index 00000000000..b1a0f39962b --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -0,0 +1,16 @@ +#![feature(associated_const_equality)] + +// Issue 110549 + +pub trait TraitWAssocConst { + const A: usize; +} + +fn foo<T: TraitWAssocConst<A = 32>>() {} + +fn bar<T: TraitWAssocConst>() { + foo::<T>(); + //~^ ERROR type mismatch resolving `<T as TraitWAssocConst>::A == 32` +} + +fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr new file mode 100644 index 00000000000..8175e510a09 --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 32` + --> $DIR/projection-unspecified-but-bounded.rs:12:11 + | +LL | foo::<T>(); + | ^ expected `32`, found `<T as TraitWAssocConst>::A` + | + = note: expected constant `32` + found constant `<T as TraitWAssocConst>::A` +note: required by a bound in `foo` + --> $DIR/projection-unspecified-but-bounded.rs:9:28 + | +LL | fn foo<T: TraitWAssocConst<A = 32>>() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr index 7b0d1c50516..1648cfb266b 100644 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr +++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr @@ -2,5 +2,5 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: #0 [typeck] type-checking `weird` -#1 [typeck_item_bodies] type-checking all item bodies +#1 [used_trait_imports] finding used_trait_imports `weird` end of query stack diff --git a/tests/ui/issues/issue-27901.rs b/tests/ui/associated-types/issue-27901.rs index ffd90b68983..ffd90b68983 100644 --- a/tests/ui/issues/issue-27901.rs +++ b/tests/ui/associated-types/issue-27901.rs diff --git a/tests/ui/associated-types/substs-ppaux.verbose.stderr b/tests/ui/associated-types/substs-ppaux.verbose.stderr index e4f6ba573ca..ad67899e6da 100644 --- a/tests/ui/associated-types/substs-ppaux.verbose.stderr +++ b/tests/ui/associated-types/substs-ppaux.verbose.stderr @@ -77,7 +77,7 @@ LL | <str as Foo<u8>>::bar; | ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `str` -note: required for `str` to implement `Foo<'_#0r, '_#1r, u8>` +note: required for `str` to implement `Foo<'?0, '?1, u8>` --> $DIR/substs-ppaux.rs:11:17 | LL | impl<'a,'b,T,S> Foo<'a, 'b, S> for T {} diff --git a/tests/ui/async-await/feature-self-return-type.stderr b/tests/ui/async-await/feature-self-return-type.stderr index 8924683684f..747c54b6694 100644 --- a/tests/ui/async-await/feature-self-return-type.stderr +++ b/tests/ui/async-await/feature-self-return-type.stderr @@ -4,6 +4,7 @@ error[E0597]: `bar` does not live long enough LL | let x = { | - borrow later stored here LL | let bar = 22; + | --- binding `bar` declared here LL | Foo::new(&bar).await | ^^^^ borrowed value does not live long enough LL | diff --git a/tests/ui/async-await/issue-61949-self-return-type.stderr b/tests/ui/async-await/issue-61949-self-return-type.stderr index 638b197bc02..ac85ed2887a 100644 --- a/tests/ui/async-await/issue-61949-self-return-type.stderr +++ b/tests/ui/async-await/issue-61949-self-return-type.stderr @@ -13,6 +13,7 @@ error[E0597]: `bar` does not live long enough LL | let x = { | - borrow later stored here LL | let bar = 22; + | --- binding `bar` declared here LL | Foo::new(&bar).await | ^^^^ borrowed value does not live long enough LL | diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr index 28174825d8b..6bdb9ded482 100644 --- a/tests/ui/async-await/issue-74047.stderr +++ b/tests/ui/async-await/issue-74047.stderr @@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from` LL | impl TryFrom<OtherStream> for MyStream {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation | - = help: implement the missing item: `type Error = Type;` - = help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }` + = help: implement the missing item: `type Error = /* Type */;` + = help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/attributes/invalid-repr.rs b/tests/ui/attributes/invalid-repr.rs new file mode 100644 index 00000000000..10a487c127e --- /dev/null +++ b/tests/ui/attributes/invalid-repr.rs @@ -0,0 +1,5 @@ +#[repr(align(16))] +//~^ ERROR attribute should be applied to a struct, enum, function, associated function, or union +pub type Foo = i32; + +fn main() {} diff --git a/tests/ui/attributes/invalid-repr.stderr b/tests/ui/attributes/invalid-repr.stderr new file mode 100644 index 00000000000..98a6a24b3c4 --- /dev/null +++ b/tests/ui/attributes/invalid-repr.stderr @@ -0,0 +1,12 @@ +error[E0517]: attribute should be applied to a struct, enum, function, associated function, or union + --> $DIR/invalid-repr.rs:1:8 + | +LL | #[repr(align(16))] + | ^^^^^^^^^ +LL | +LL | pub type Foo = i32; + | ------------------- not a struct, enum, function, associated function, or union + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr index 0ca14c3f3bc..047175626e3 100644 --- a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr +++ b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr @@ -1,19 +1,3 @@ -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 - | -LL | ref foo @ [.., ref mut bar] => (), - | ^^^^^^^ ----------- value is mutably borrowed by `bar` here - | | - | value is borrowed by `foo` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 - | -LL | ref foo @ Some(box ref mut s) => (), - | ^^^^^^^ --------- value is mutably borrowed by `s` here - | | - | value is borrowed by `foo` here - error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:18:5 | @@ -43,6 +27,14 @@ LL | &x; LL | drop(r); | - mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 + | +LL | ref foo @ [.., ref mut bar] => (), + | ^^^^^^^ ----------- value is mutably borrowed by `bar` here + | | + | value is borrowed by `foo` here + error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:50:5 | @@ -120,6 +112,14 @@ LL | &mut x; LL | drop(r); | - immutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 + | +LL | ref foo @ Some(box ref mut s) => (), + | ^^^^^^^ --------- value is mutably borrowed by `s` here + | | + | value is borrowed by `foo` here + error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:134:5 | diff --git a/tests/ui/borrowck/borrowck-block-unint.rs b/tests/ui/borrowck/borrowck-block-uninit.rs index 8d13b25a357..8d13b25a357 100644 --- a/tests/ui/borrowck/borrowck-block-unint.rs +++ b/tests/ui/borrowck/borrowck-block-uninit.rs diff --git a/tests/ui/borrowck/borrowck-block-unint.stderr b/tests/ui/borrowck/borrowck-block-uninit.stderr index f47921a9752..1a5969586f2 100644 --- a/tests/ui/borrowck/borrowck-block-unint.stderr +++ b/tests/ui/borrowck/borrowck-block-uninit.stderr @@ -1,5 +1,5 @@ error[E0381]: used binding `x` isn't initialized - --> $DIR/borrowck-block-unint.rs:4:11 + --> $DIR/borrowck-block-uninit.rs:4:11 | LL | let x: isize; | - binding declared here but left uninitialized diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed new file mode 100644 index 00000000000..4a8831dab95 --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed @@ -0,0 +1,39 @@ +// run-rustfix +#![allow(unused)] +struct S; + +impl S { + fn call(&mut self, f: impl FnOnce((), &mut Self)) { + // change state or something ... + f((), self); + // change state or something ... + } + + fn get(&self) {} + fn set(&mut self) {} +} + +fn main() { + let mut v = S; + + v.call(|(), this: &mut S| this.get()); + //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable + v.call(|(), this: &mut S| this.set()); + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + v.call(|(), this: &mut S| { + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + _ = this; + this.set(); + this.get(); + S::get(&this); + + use std::ops::Add; + let v = 0u32; + _ = v + v; + _ = v.add(3); + }); +} diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs new file mode 100644 index 00000000000..fcd855f862d --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs @@ -0,0 +1,39 @@ +// run-rustfix +#![allow(unused)] +struct S; + +impl S { + fn call(&mut self, f: impl FnOnce((), &mut Self)) { + // change state or something ... + f((), self); + // change state or something ... + } + + fn get(&self) {} + fn set(&mut self) {} +} + +fn main() { + let mut v = S; + + v.call(|(), this: &mut S| v.get()); + //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable + v.call(|(), this: &mut S| v.set()); + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + v.call(|(), this: &mut S| { + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + _ = v; + v.set(); + v.get(); + S::get(&v); + + use std::ops::Add; + let v = 0u32; + _ = v + v; + _ = v.add(3); + }); +} diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr new file mode 100644 index 00000000000..25974e0d008 --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr @@ -0,0 +1,85 @@ +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/issue-109271-pass-self-into-closure.rs:19:5 + | +LL | v.call(|(), this: &mut S| v.get()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | | help: try using the closure argument: `this` + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:21:5 + | +LL | v.call(|(), this: &mut S| v.set()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | | help: try using the closure argument: `this` + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:21:12 + | +LL | v.call(|(), this: &mut S| v.set()); + | -------^^^^^^^^^^^^^^^^^^--------- + | | | | | + | | | | second borrow occurs due to use of `v` in closure + | | | second mutable borrow occurs here + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:25:5 + | +LL | v.call(|(), this: &mut S| { + | ^ ---- ------------------ first mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - first borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______^ second mutable borrow occurs here + | +help: try using the closure argument + | +LL ~ _ = this; +LL ~ this.set(); +LL ~ this.get(); +LL ~ S::get(&this); + | + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:25:12 + | +LL | v.call(|(), this: &mut S| { + | - ---- ^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - second borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______- first mutable borrow occurs here + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/issues/issue-47646.rs b/tests/ui/borrowck/issue-47646.rs index ace6cdce841..ace6cdce841 100644 --- a/tests/ui/issues/issue-47646.rs +++ b/tests/ui/borrowck/issue-47646.rs diff --git a/tests/ui/issues/issue-47646.stderr b/tests/ui/borrowck/issue-47646.stderr index 84cf9237a56..84cf9237a56 100644 --- a/tests/ui/issues/issue-47646.stderr +++ b/tests/ui/borrowck/issue-47646.stderr diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs index 37b5c5d9d7a..835cd20798f 100644 --- a/tests/ui/borrowck/let_underscore_temporary.rs +++ b/tests/ui/borrowck/let_underscore_temporary.rs @@ -1,4 +1,4 @@ -// check-pass +// check-fail fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { let _ = if let Some(s) = *string { s.len() } else { 0 }; @@ -8,6 +8,7 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -21,6 +22,33 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; +} + +fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) { + let _: _ = if let Some(s) = *string { s.len() } else { 0 }; + let _: _ = if let Some(s) = &num { s } else { &0 }; + let _: _ = if let Some(s) = &mut num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; + let _: _ = if let Some(ref s) = num { s } else { &0 }; + let _: _ = if let Some(mut s) = num { + s += 1; + s + } else { + 0 + }; + let _: _ = if let Some(ref mut s) = num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed }; } diff --git a/tests/ui/borrowck/let_underscore_temporary.stderr b/tests/ui/borrowck/let_underscore_temporary.stderr new file mode 100644 index 00000000000..74f3598c4d0 --- /dev/null +++ b/tests/ui/borrowck/let_underscore_temporary.stderr @@ -0,0 +1,79 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:10:14 + | +LL | let _ = if let Some(s) = &mut num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:24:14 + | +LL | let _ = if let Some(ref mut s) = num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:36:14 + | +LL | let _: _ = if let Some(s) = &mut num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:50:14 + | +LL | let _: _ = if let Some(ref mut s) = num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/borrowck/move-error-snippets-ext.rs b/tests/ui/borrowck/move-error-snippets-ext.rs index c77f6c8276e..27041d55d8f 100644 --- a/tests/ui/borrowck/move-error-snippets-ext.rs +++ b/tests/ui/borrowck/move-error-snippets-ext.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) macro_rules! aaa { ($c:ident) => {{ diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr index 36606fd49f2..7e64e67f24c 100644 --- a/tests/ui/chalkify/bugs/async.stderr +++ b/tests/ui/chalkify/bugs/async.stderr @@ -18,7 +18,7 @@ LL | async fn foo(x: u32) -> u32 { #3 [mir_built] building MIR for `foo` #4 [unsafety_check_result] unsafety-checking `foo` #5 [mir_const] preparing `foo` for borrow checking -#6 [mir_promoted] processing MIR for `foo` +#6 [mir_promoted] promoting constants in MIR for `foo` #7 [mir_borrowck] borrow-checking `foo` #8 [type_of] computing type of `foo::{opaque#0}` #9 [check_mod_item_types] checking item types in top-level module diff --git a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index ad061d93cb2..8a32f0d99e7 100644 --- a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -1,17 +1,3 @@ -error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/pattern-matching-should-fail.rs:67:23 - | -LL | let c1 = || match x { }; - | ^ - | - = note: the matched value is of type `u8` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let c1 = || match x { -LL + _ => todo!(), -LL ~ }; - | - error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:8:23 | @@ -69,6 +55,20 @@ LL | let t: !; LL | match t { }; | ^ `t` used here but it isn't initialized +error[E0004]: non-exhaustive patterns: type `u8` is non-empty + --> $DIR/pattern-matching-should-fail.rs:67:23 + | +LL | let c1 = || match x { }; + | ^ + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ let c1 = || match x { +LL + _ => todo!(), +LL ~ }; + | + error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:67:23 | diff --git a/tests/ui/closures/binder/nested-closures-regions.stderr b/tests/ui/closures/binder/nested-closures-regions.stderr index b385e0ed6e0..381aadb1564 100644 --- a/tests/ui/closures/binder/nested-closures-regions.stderr +++ b/tests/ui/closures/binder/nested-closures-regions.stderr @@ -9,11 +9,11 @@ LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; extern "rust-call" fn((&(),)), (), ] - = note: late-bound region is '_#4r - = note: late-bound region is '_#2r + = note: late-bound region is '?4 + = note: late-bound region is '?2 = note: number of external vids: 3 - = note: where '_#1r: '_#2r - = note: where '_#2r: '_#1r + = note: where '?1: '?2 + = note: where '?2: '?1 note: no external requirements --> $DIR/nested-closures-regions.rs:8:5 @@ -26,7 +26,7 @@ LL | for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; }; extern "rust-call" fn(()), (), ] - = note: late-bound region is '_#2r + = note: late-bound region is '?2 note: no external requirements --> $DIR/nested-closures-regions.rs:7:1 diff --git a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr index ff89dd34034..381bb0c084a 100644 --- a/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr +++ b/tests/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr @@ -9,7 +9,7 @@ LL | let c1 : () = c; | expected due to this | = note: expected unit type `()` - found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#16t, extern "rust-call" fn(()), _#15t]]` + found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, ?16t, extern "rust-call" fn(()), ?15t]]` help: use parentheses to call this closure | LL | let c1 : () = c(); diff --git a/tests/ui/closures/print/closure-print-generic-verbose-1.stderr b/tests/ui/closures/print/closure-print-generic-verbose-1.stderr index 3ab7c66d11f..9a1f18fa855 100644 --- a/tests/ui/closures/print/closure-print-generic-verbose-1.stderr +++ b/tests/ui/closures/print/closure-print-generic-verbose-1.stderr @@ -2,7 +2,7 @@ error[E0382]: use of moved value: `c` --> $DIR/closure-print-generic-verbose-1.rs:17:5 | LL | let c = to_fn_once(move|| { - | - move occurs because `c` has type `[f<T>::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'_#9r str>, T)]`, which does not implement the `Copy` trait + | - move occurs because `c` has type `[f<T>::{closure#0} closure_kind_ty=i32 closure_sig_as_fn_ptr_ty=extern "rust-call" fn(()) upvar_tys=(Foo<&'?9 str>, T)]`, which does not implement the `Copy` trait ... LL | c(); | --- `c` moved due to this call diff --git a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr index 5bbf84f963d..2a4d16c48dc 100644 --- a/tests/ui/closures/print/closure-print-generic-verbose-2.stderr +++ b/tests/ui/closures/print/closure-print-generic-verbose-2.stderr @@ -9,7 +9,7 @@ LL | let c1 : () = c; | expected due to this | = note: expected unit type `()` - found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#16t, extern "rust-call" fn(()), _#15t]]` + found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, ?16t, extern "rust-call" fn(()), ?15t]]` help: use parentheses to call this closure | LL | let c1 : () = c(); diff --git a/tests/ui/closures/print/closure-print-verbose.stderr b/tests/ui/closures/print/closure-print-verbose.stderr index 083717b3334..9e219435e5c 100644 --- a/tests/ui/closures/print/closure-print-verbose.stderr +++ b/tests/ui/closures/print/closure-print-verbose.stderr @@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a }; | expected due to this | = note: expected fn pointer `fn(u8) -> u8` - found closure `[main::{closure#0} closure_substs=(unavailable) substs=[i8, extern "rust-call" fn((u8,)) -> u8, _#6t]]` + found closure `[main::{closure#0} closure_substs=(unavailable) substs=[i8, extern "rust-call" fn((u8,)) -> u8, ?6t]]` note: closures can only be coerced to `fn` types if they do not capture any variables --> $DIR/closure-print-verbose.rs:10:39 | diff --git a/tests/ui/closures/static-closures-with-nonstatic-return.rs b/tests/ui/closures/static-closures-with-nonstatic-return.rs new file mode 100644 index 00000000000..b5f0684bae9 --- /dev/null +++ b/tests/ui/closures/static-closures-with-nonstatic-return.rs @@ -0,0 +1,15 @@ +// check-pass +// known-bug: #84366 + +// Should fail. Associated types of 'static types should be `'static`, but +// argument-free closures can be `'static` and return non-`'static` types. + +#[allow(dead_code)] +fn foo<'a>() { + let closure = || -> &'a str { "" }; + assert_static(closure); +} + +fn assert_static<T: 'static>(_: T) {} + +fn main() {} diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.rs b/tests/ui/codegen/freeze-on-polymorphic-projection.rs new file mode 100644 index 00000000000..edc79f8fd94 --- /dev/null +++ b/tests/ui/codegen/freeze-on-polymorphic-projection.rs @@ -0,0 +1,19 @@ +// build-pass +// compile-flags: -Copt-level=1 --crate-type=lib + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +pub unsafe trait Storage { + type Handle; +} + +pub unsafe trait MultipleStorage: Storage {} + +default unsafe impl<S> Storage for S where S: MultipleStorage {} + +// Make sure that we call is_freeze on `(S::Handle,)` in the param-env of `ice`, +// instead of in an empty, reveal-all param-env. +pub fn ice<S: Storage>(boxed: (S::Handle,)) -> (S::Handle,) { + boxed +} diff --git a/tests/ui/codegen/freeze-on-polymorphic-projection.stderr b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr new file mode 100644 index 00000000000..903cb2ff6aa --- /dev/null +++ b/tests/ui/codegen/freeze-on-polymorphic-projection.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/freeze-on-polymorphic-projection.rs:4:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/codemap_tests/two_files_data.rs b/tests/ui/codemap_tests/two_files_data.rs index b4d2f5d3c6d..6abeac0dd2e 100644 --- a/tests/ui/codemap_tests/two_files_data.rs +++ b/tests/ui/codemap_tests/two_files_data.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) trait Foo { } diff --git a/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs new file mode 100644 index 00000000000..bb46498f90e --- /dev/null +++ b/tests/ui/coherence/indirect-impl-for-trait-obj-coherence.rs @@ -0,0 +1,25 @@ +// check-pass +// known-bug: #57893 + +// Should fail. Because we see an impl that uses a certain associated type, we +// type-check assuming that impl is used. However, this conflicts with the +// "implicit impl" that we get for trait objects, violating coherence. + +trait Object<U> { + type Output; +} + +impl<T: ?Sized, U> Object<U> for T { + type Output = U; +} + +fn foo<T: ?Sized, U>(x: <T as Object<U>>::Output) -> U { + x +} + +#[allow(dead_code)] +fn transmute<T, U>(x: T) -> U { + foo::<dyn Object<U, Output = T>, U>(x) +} + +fn main() {} diff --git a/tests/ui/conditional-compilation/module_with_cfg.rs b/tests/ui/conditional-compilation/module_with_cfg.rs index 56c4baadf22..55c8381cffe 100644 --- a/tests/ui/conditional-compilation/module_with_cfg.rs +++ b/tests/ui/conditional-compilation/module_with_cfg.rs @@ -1,3 +1,3 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) #![cfg_attr(all(), cfg(FALSE))] diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index c0404d35b08..ae9207cf855 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(generic_const_exprs, adt_const_params, const_trait_impl)] #![allow(incomplete_features)] @@ -26,7 +28,6 @@ struct Evaluatable2<const N: usize>; fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) { bar2::<{ std::ops::Add::add(N, N) }>(); - //~^ error: unconstrained generic constant // FIXME(generic_const_exprs) make this not an error } diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index d18c7916f5f..7f28771cee8 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,10 +1,11 @@ -error: unconstrained generic constant - --> $DIR/unify-op-with-fn-call.rs:28:12 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/unify-op-with-fn-call.rs:10:12 | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl const std::ops::Add for Foo { + | ^^^^^^^^^^^^^ | - = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to previous error diff --git a/tests/ui/const-generics/occurs-check/unused-substs-2.rs b/tests/ui/const-generics/occurs-check/unused-substs-2.rs index 9b1212694f5..84e24d1a3f5 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-2.rs +++ b/tests/ui/const-generics/occurs-check/unused-substs-2.rs @@ -1,9 +1,9 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] -// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst. +// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(?1t)` subst. // -// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty<ct>` we introduced an +// If we are then able to infer `ty::Infer(TyVar(?1t) := Ty<ct>` we introduced an // artificial inference cycle. struct Foo<const N: usize>; @@ -20,8 +20,8 @@ impl<T> Bind<T> for Foo<{ 6 + 1 }> { fn main() { let (mut t, foo) = Foo::bind(); - // `t` is `ty::Infer(TyVar(_#1t))` - // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs + // `t` is `ty::Infer(TyVar(?1t))` + // `foo` contains `ty::Infer(TyVar(?1t))` in its substs t = foo; //~^ ERROR mismatched types //~| NOTE cyclic type diff --git a/tests/ui/const-generics/occurs-check/unused-substs-3.rs b/tests/ui/const-generics/occurs-check/unused-substs-3.rs index d5aeab47e62..6db18d587d3 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-3.rs +++ b/tests/ui/const-generics/occurs-check/unused-substs-3.rs @@ -1,9 +1,9 @@ #![feature(generic_const_exprs)] #![allow(incomplete_features)] -// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst. +// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(?1t)` subst. // -// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty<ct>` we introduced an +// If we are then able to infer `ty::Infer(TyVar(?1t) := Ty<ct>` we introduced an // artificial inference cycle. fn bind<T>() -> (T, [u8; 6 + 1]) { todo!() @@ -11,8 +11,8 @@ fn bind<T>() -> (T, [u8; 6 + 1]) { fn main() { let (mut t, foo) = bind(); - // `t` is `ty::Infer(TyVar(_#1t))` - // `foo` contains `ty::Infer(TyVar(_#1t))` in its substs + // `t` is `ty::Infer(TyVar(?1t))` + // `foo` contains `ty::Infer(TyVar(?1t))` in its substs t = foo; //~^ ERROR mismatched types //~| NOTE cyclic type diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index f199170018f..05f33c33946 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -4,13 +4,13 @@ error[E0308]: mismatched types LL | = [0; (i8::MAX + 1u8) as usize]; | ^^^ expected `i8`, found `u8` -error[E0277]: cannot add `u8` to `i8` in const contexts +error[E0277]: cannot add `u8` to `i8` --> $DIR/const-eval-overflow-3b.rs:16:20 | LL | = [0; (i8::MAX + 1u8) as usize]; | ^ no implementation for `i8 + u8` | - = help: the trait `~const Add<u8>` is not implemented for `i8` + = help: the trait `Add<u8>` is not implemented for `i8` = help: the following other types implement trait `Add<Rhs>`: <&'a i8 as Add<i8>> <&i8 as Add<&i8>> diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 1f8e402317a..d019f5920b5 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -4,13 +4,13 @@ error[E0308]: mismatched types LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^^^ expected `i8`, found `u8` -error[E0277]: cannot add `u8` to `i8` in const contexts +error[E0277]: cannot add `u8` to `i8` --> $DIR/const-eval-overflow-4b.rs:9:28 | LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^ no implementation for `i8 + u8` | - = help: the trait `~const Add<u8>` is not implemented for `i8` + = help: the trait `Add<u8>` is not implemented for `i8` = help: the following other types implement trait `Add<Rhs>`: <&'a i8 as Add<i8>> <&i8 as Add<&i8>> diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.rs b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs index cd7c9800775..432a05756d3 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops.rs +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -1,6 +1,6 @@ fn main() {} // unconst and bad, will thus error in miri -const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR can't compare +const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR pointers cannot // unconst and bad, will thus error in miri -const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR can't compare +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR pointers cannot diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr index 12244450e7f..1f5bca273d3 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr @@ -1,29 +1,18 @@ -error[E0277]: can't compare `*const i32` with `_` in const contexts - --> $DIR/const_raw_ptr_ops.rs:4:43 +error: pointers cannot be reliably compared during const eval + --> $DIR/const_raw_ptr_ops.rs:4:26 | LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; - | ^^ no implementation for `*const i32 == _` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `*const i32` -note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const` - --> $DIR/const_raw_ptr_ops.rs:4:43 - | -LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information -error[E0277]: can't compare `*const i32` with `_` in const contexts - --> $DIR/const_raw_ptr_ops.rs:6:44 +error: pointers cannot be reliably compared during const eval + --> $DIR/const_raw_ptr_ops.rs:6:27 | LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; - | ^^ no implementation for `*const i32 == _` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `*const i32` -note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const` - --> $DIR/const_raw_ptr_ops.rs:6:44 - | -LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const-eval/generic-slice.stderr b/tests/ui/consts/const-eval/generic-slice.stderr index c38088df4d8..ff1dc29ccfd 100644 --- a/tests/ui/consts/const-eval/generic-slice.stderr +++ b/tests/ui/consts/const-eval/generic-slice.stderr @@ -4,6 +4,8 @@ error[E0597]: `x` does not live long enough LL | impl<'a, T: 'static> Generic<'a, T> { | -- lifetime `'a` defined here ... +LL | let x: &'static [T] = &[]; + | - binding `x` declared here LL | &x | ^^ | | @@ -16,6 +18,8 @@ LL | }; error[E0597]: `x` does not live long enough --> $DIR/generic-slice.rs:27:5 | +LL | let x: &[_] = &[]; + | - binding `x` declared here LL | &x | ^^ | | diff --git a/tests/ui/consts/const-eval/issue-100878.rs b/tests/ui/consts/const-eval/issue-100878.rs index 353ce505035..bd56f854c8b 100644 --- a/tests/ui/consts/const-eval/issue-100878.rs +++ b/tests/ui/consts/const-eval/issue-100878.rs @@ -1,6 +1,8 @@ // This checks that the const-eval ICE in issue #100878 does not recur. // // build-pass + +#[allow(arithmetic_overflow)] pub fn bitshift_data(data: [u8; 1]) -> u8 { data[0] << 8 } diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs index d9a74b4f3e2..ebc5543b380 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_slice_index)] const A: [(); 5] = [(), (), (), (), ()]; diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr index 775e475dfeb..403fb5e0940 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr @@ -1,18 +1,11 @@ -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/slice/index.rs:LL:COL - | - = note: overflow executing `unchecked_sub` - | -note: inside `<std::ops::Range<usize> as SliceIndex<[()]>>::get_unchecked` - --> $SRC_DIR/core/src/slice/index.rs:LL:COL -note: inside `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` - --> $SRC_DIR/core/src/slice/mod.rs:LL:COL -note: inside `B` - --> $DIR/ub-slice-get-unchecked.rs:7:27 +error[E0015]: cannot call non-const fn `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` in constants + --> $DIR/ub-slice-get-unchecked.rs:9:29 | LL | const B: &[()] = unsafe { A.get_unchecked(3..1) }; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index 74238d0dd92..3a5d5bb46e9 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -8,11 +8,33 @@ // Don't promote const fn nop<T>(x: T) -> T { x } +// FIXME(const-hack): replace with PartialEq +#[const_trait] +trait MyEq<T> { + fn eq(self, b: T) -> bool; +} + +impl const MyEq<bool> for bool { + fn eq(self, b: bool) -> bool { + self == b + } +} + +impl const MyEq<NonDet> for bool { + fn eq(self, _: NonDet) -> bool { + true + } +} + +const fn eq<A: ~const MyEq<B>, B>(x: A, y: B) -> bool { + x.eq(y) +} + macro_rules! const_assert { ($a:expr, $b:expr) => { { - const _: () = assert!($a == $b); - assert_eq!(nop($a), nop($b)); + const _: () = assert!(eq($a, $b)); + assert!(eq(nop($a), nop($b))); } }; } @@ -47,15 +69,6 @@ macro_rules! suite_inner { #[derive(Debug)] struct NonDet; -impl const PartialEq<NonDet> for bool { - fn eq(&self, _: &NonDet) -> bool { - true - } - fn ne(&self, _: &NonDet) -> bool { - false - } -} - // The result of the `is_sign` methods are not checked for correctness, since LLVM does not // guarantee anything about the signedness of NaNs. See // https://github.com/rust-lang/rust/issues/55131. diff --git a/tests/ui/consts/const-fn-error.rs b/tests/ui/consts/const-fn-error.rs index dabbd58dbe0..50b7ce1f8c0 100644 --- a/tests/ui/consts/const-fn-error.rs +++ b/tests/ui/consts/const-fn-error.rs @@ -7,7 +7,6 @@ const fn f(x: usize) -> usize { //~| ERROR `for` is not allowed in a `const fn` //~| ERROR mutable references are not allowed in constant functions //~| ERROR cannot call non-const fn - //~| ERROR the trait bound sum += i; } sum diff --git a/tests/ui/consts/const-fn-error.stderr b/tests/ui/consts/const-fn-error.stderr index 73d235d6aec..f735b3d53ce 100644 --- a/tests/ui/consts/const-fn-error.stderr +++ b/tests/ui/consts/const-fn-error.stderr @@ -5,7 +5,7 @@ LL | / for i in 0..x { LL | | LL | | LL | | -... | +LL | | LL | | sum += i; LL | | } | |_____^ @@ -33,19 +33,6 @@ LL | for i in 0..x { = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0277]: the trait bound `std::ops::Range<usize>: Iterator` is not satisfied - --> $DIR/const-fn-error.rs:5:14 - | -LL | for i in 0..x { - | ^^^^ `std::ops::Range<usize>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<usize>` -note: the trait `Iterator` is implemented for `std::ops::Range<usize>`, but that implementation is not `const` - --> $DIR/const-fn-error.rs:5:14 - | -LL | for i in 0..x { - | ^^^^ - error[E0015]: cannot call non-const fn `<std::ops::Range<usize> as Iterator>::next` in constant functions --> $DIR/const-fn-error.rs:5:14 | @@ -55,7 +42,7 @@ LL | for i in 0..x { = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0277, E0658. +Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for.rs b/tests/ui/consts/const-for.rs index ff9c977f794..8db24853558 100644 --- a/tests/ui/consts/const-for.rs +++ b/tests/ui/consts/const-for.rs @@ -5,7 +5,6 @@ const _: () = { for _ in 0..5 {} //~^ error: cannot call //~| error: cannot convert - //~| error: the trait bound }; fn main() {} diff --git a/tests/ui/consts/const-for.stderr b/tests/ui/consts/const-for.stderr index 64f2f603b94..3fb9787c0d8 100644 --- a/tests/ui/consts/const-for.stderr +++ b/tests/ui/consts/const-for.stderr @@ -9,19 +9,6 @@ note: impl defined here, but it is not `const` = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error[E0277]: the trait bound `std::ops::Range<i32>: Iterator` is not satisfied - --> $DIR/const-for.rs:5:14 - | -LL | for _ in 0..5 {} - | ^^^^ `std::ops::Range<i32>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<i32>` -note: the trait `Iterator` is implemented for `std::ops::Range<i32>`, but that implementation is not `const` - --> $DIR/const-for.rs:5:14 - | -LL | for _ in 0..5 {} - | ^^^^ - error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants --> $DIR/const-for.rs:5:14 | @@ -31,7 +18,6 @@ LL | for _ in 0..5 {} = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index e199fd9ff8a..6b7ba8f1e32 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 // Demonstrates what's needed to make use of `?` in const contexts. diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr new file mode 100644 index 00000000000..37014f9b83f --- /dev/null +++ b/tests/ui/consts/const-try.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:15:12 + | +LL | impl const FromResidual<Error> for TryMe { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:21:12 + | +LL | impl const Try for TryMe { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index f10d1c24f7d..19cee2022ac 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_type_id)] #![feature(const_trait_impl)] diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr new file mode 100644 index 00000000000..319d2b924a8 --- /dev/null +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -0,0 +1,76 @@ +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId < TypeId` and `TypeId > TypeId` + | + = help: the trait `~const PartialOrd` is not implemented for `TypeId` +note: the trait `PartialOrd` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constants + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs index b507492970a..be11ac7264a 100644 --- a/tests/ui/consts/fn_trait_refs.rs +++ b/tests/ui/consts/fn_trait_refs.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_fn_trait_ref_impls)] #![feature(fn_traits)] diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr new file mode 100644 index 00000000000..bfebf66701b --- /dev/null +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -0,0 +1,15 @@ +error[E0635]: unknown feature `const_fn_trait_ref_impls` + --> $DIR/fn_trait_refs.rs:3:12 + | +LL | #![feature(const_fn_trait_ref_impls)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0635]: unknown feature `const_cmp` + --> $DIR/fn_trait_refs.rs:8:12 + | +LL | #![feature(const_cmp)] + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/consts/issue-25826.rs b/tests/ui/consts/issue-25826.rs index c340c30a113..f5ed5aeedc3 100644 --- a/tests/ui/consts/issue-25826.rs +++ b/tests/ui/consts/issue-25826.rs @@ -1,6 +1,6 @@ fn id<T>(t: T) -> T { t } fn main() { const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - //~^ ERROR can't compare + //~^ ERROR pointers cannot println!("{}", A); } diff --git a/tests/ui/consts/issue-25826.stderr b/tests/ui/consts/issue-25826.stderr index 905c5ee6eb4..780edd2149f 100644 --- a/tests/ui/consts/issue-25826.stderr +++ b/tests/ui/consts/issue-25826.stderr @@ -1,16 +1,10 @@ -error[E0277]: can't compare `*const ()` with `*const ()` in const contexts - --> $DIR/issue-25826.rs:3:52 +error: pointers cannot be reliably compared during const eval + --> $DIR/issue-25826.rs:3:30 | LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - | ^ no implementation for `*const () < *const ()` and `*const () > *const ()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialOrd` is not implemented for `*const ()` -note: the trait `PartialOrd` is implemented for `*const ()`, but that implementation is not `const` - --> $DIR/issue-25826.rs:3:52 - | -LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - | ^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/issue-73976-monomorphic.rs b/tests/ui/consts/issue-73976-monomorphic.rs index addcc1eaab6..a3b9510036d 100644 --- a/tests/ui/consts/issue-73976-monomorphic.rs +++ b/tests/ui/consts/issue-73976-monomorphic.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 // // This test is complement to the test in issue-73976-polymorphic.rs. // In that test we ensure that polymorphic use of type_id and type_name in patterns diff --git a/tests/ui/consts/issue-73976-monomorphic.stderr b/tests/ui/consts/issue-73976-monomorphic.stderr new file mode 100644 index 00000000000..95ab78b1b23 --- /dev/null +++ b/tests/ui/consts/issue-73976-monomorphic.stderr @@ -0,0 +1,28 @@ +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index ce21ebdb9ac..38c8129b8cf 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -7,8 +7,9 @@ struct Foo<'a> { impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec<u32>) { self.bar[0] = baz.len(); - //~^ the trait bound `Vec<usize>: ~const Index<_>` is not satisfied - //~| the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied + //~^ ERROR: cannot call + //~| ERROR: cannot call + //~| ERROR: the trait bound } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index f4683f7f536..b4e5db44e71 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -1,15 +1,10 @@ -error[E0277]: the trait bound `Vec<usize>: ~const Index<_>` is not satisfied - --> $DIR/issue-94675.rs:9:9 +error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions + --> $DIR/issue-94675.rs:9:27 | LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize` - | - = help: the trait `~const Index<_>` is not implemented for `Vec<usize>` -note: the trait `Index<_>` is implemented for `Vec<usize>`, but that implementation is not `const` - --> $DIR/issue-94675.rs:9:9 + | ^^^^^ | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied --> $DIR/issue-94675.rs:9:9 @@ -24,6 +19,17 @@ note: the trait `IndexMut<usize>` is implemented for `Vec<usize>`, but that impl LL | self.bar[0] = baz.len(); | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/issue-94675.rs:9:9 + | +LL | self.bar[0] = baz.len(); + | ^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs b/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs index 9a2775688c6..c5990a7f515 100644 --- a/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs +++ b/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs @@ -1,6 +1,6 @@ const fn cmp(x: fn(), y: fn()) -> bool { unsafe { x == y } - //~^ ERROR can't compare + //~^ ERROR pointers cannot } fn main() {} diff --git a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr index 8a1b20a3345..3845068d841 100644 --- a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr +++ b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr @@ -1,16 +1,10 @@ -error[E0277]: can't compare `fn()` with `_` in const contexts - --> $DIR/cmp_fn_pointers.rs:2:16 +error: pointers cannot be reliably compared during const eval + --> $DIR/cmp_fn_pointers.rs:2:14 | LL | unsafe { x == y } - | ^^ no implementation for `fn() == _` + | ^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `fn()` -note: the trait `PartialEq<_>` is implemented for `fn()`, but that implementation is not `const` - --> $DIR/cmp_fn_pointers.rs:2:16 - | -LL | unsafe { x == y } - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/non-sync-references-in-const.rs b/tests/ui/consts/non-sync-references-in-const.rs new file mode 100644 index 00000000000..0f668b8d469 --- /dev/null +++ b/tests/ui/consts/non-sync-references-in-const.rs @@ -0,0 +1,38 @@ +// check-pass +// known-bug: #49206 + +// Should fail. Compiles and prints 2 identical addresses, which shows 2 threads +// with the same `'static` reference to non-`Sync` struct. The problem is that +// promotion to static does not check if the type is `Sync`. + +#[allow(dead_code)] +#[derive(Debug)] +struct Foo { + value: u32, +} + +// stable negative impl trick from https://crates.io/crates/negative-impl +// see https://github.com/taiki-e/pin-project/issues/102#issuecomment-540472282 +// for details. +struct Wrapper<'a, T>(::std::marker::PhantomData<&'a ()>, T); +unsafe impl<T> Sync for Wrapper<'_, T> where T: Sync {} +unsafe impl<'a> std::marker::Sync for Foo where Wrapper<'a, *const ()>: Sync {} +fn _assert_sync<T: Sync>() {} + +fn inspect() { + let foo: &'static Foo = &Foo { value: 1 }; + println!( + "I am in thread {:?}, address: {:p}", + std::thread::current().id(), + foo as *const Foo, + ); +} + +fn main() { + // _assert_sync::<Foo>(); // uncomment this line causes compile error + // "`*const ()` cannot be shared between threads safely" + + let handle = std::thread::spawn(inspect); + inspect(); + handle.join().unwrap(); +} diff --git a/tests/ui/consts/promoted_const_call.rs b/tests/ui/consts/promoted_const_call.rs index 30ae730535c..dae6cafaebb 100644 --- a/tests/ui/consts/promoted_const_call.rs +++ b/tests/ui/consts/promoted_const_call.rs @@ -1,7 +1,9 @@ #![feature(const_mut_refs)] #![feature(const_trait_impl)] + struct Panic; impl const Drop for Panic { fn drop(&mut self) { panic!(); } } + pub const fn id<T>(x: T) -> T { x } pub const C: () = { let _: &'static _ = &id(&Panic); diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index 83cc16f6f94..1cbd8cbe699 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:7:26 + --> $DIR/promoted_const_call.rs:9:26 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -10,7 +10,7 @@ LL | }; | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:7:30 + --> $DIR/promoted_const_call.rs:9:30 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^ - temporary value is freed at the end of this statement @@ -19,7 +19,7 @@ LL | let _: &'static _ = &id(&Panic); | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:13:26 + --> $DIR/promoted_const_call.rs:15:26 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -30,7 +30,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:13:30 + --> $DIR/promoted_const_call.rs:15:30 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^ - temporary value is freed at the end of this statement @@ -39,7 +39,7 @@ LL | let _: &'static _ = &id(&Panic); | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:16:26 + --> $DIR/promoted_const_call.rs:18:26 | LL | let _: &'static _ = &&(Panic, 0).1; | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -50,7 +50,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:16:27 + --> $DIR/promoted_const_call.rs:18:27 | LL | let _: &'static _ = &&(Panic, 0).1; | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index 0c18efa0a02..a1a741e80e5 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![crate_type = "lib"] #![feature(staged_api)] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr new file mode 100644 index 00000000000..e6930da71ec --- /dev/null +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -0,0 +1,11 @@ +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/rustc-impl-const-stability.rs:15:12 + | +LL | impl const Default for Data { + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to previous error + diff --git a/tests/ui/consts/try-operator.rs b/tests/ui/consts/try-operator.rs index fe43b132cbd..ed69f492fb9 100644 --- a/tests/ui/consts/try-operator.rs +++ b/tests/ui/consts/try-operator.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(try_trait_v2)] #![feature(const_trait_impl)] diff --git a/tests/ui/consts/try-operator.stderr b/tests/ui/consts/try-operator.stderr new file mode 100644 index 00000000000..f6a651c5e66 --- /dev/null +++ b/tests/ui/consts/try-operator.stderr @@ -0,0 +1,9 @@ +error[E0635]: unknown feature `const_convert` + --> $DIR/try-operator.rs:6:12 + | +LL | #![feature(const_convert)] + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/cross/cross-file-errors/main.stderr b/tests/ui/cross/cross-file-errors/main.stderr index 293a300ed61..56eb6ad429a 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:8:9 + --> $DIR/underscore.rs:6: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 76e72a93fcc..4dd91c13ea9 100644 --- a/tests/ui/cross/cross-file-errors/underscore.rs +++ b/tests/ui/cross/cross-file-errors/underscore.rs @@ -1,6 +1,4 @@ -// We want this file only so we can test cross-file error -// messages, but we don't want it in an external crate. -// ignore-test +// ignore-test (auxiliary, used by other tests) #![crate_type = "lib"] macro_rules! underscore { diff --git a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 81f3f269432..26986684f0c 100644 --- a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -15,13 +15,13 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² | ~ -error[E0277]: cannot subtract `{integer}` from `{float}` in const contexts +error[E0277]: cannot subtract `{integer}` from `{float}` --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 | LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² | ^ no implementation for `{float} - {integer}` | - = help: the trait `~const Sub<{integer}>` is not implemented for `{float}` + = help: the trait `Sub<{integer}>` is not implemented for `{float}` = help: the following other types implement trait `Sub<Rhs>`: <&'a f32 as Sub<f32>> <&'a f64 as Sub<f64>> diff --git a/tests/ui/issues/auxiliary/issue-41394.rs b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs index 2e650efc714..2e650efc714 100644 --- a/tests/ui/issues/auxiliary/issue-41394.rs +++ b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs diff --git a/tests/ui/issues/issue-41394-rpass.rs b/tests/ui/enum-discriminant/issue-41394-rpass.rs index 37c6525234d..37c6525234d 100644 --- a/tests/ui/issues/issue-41394-rpass.rs +++ b/tests/ui/enum-discriminant/issue-41394-rpass.rs diff --git a/tests/ui/issues/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs index 07cad8796e1..07cad8796e1 100644 --- a/tests/ui/issues/issue-41394.rs +++ b/tests/ui/enum-discriminant/issue-41394.rs diff --git a/tests/ui/issues/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr index 1b5c64628a1..1b5c64628a1 100644 --- a/tests/ui/issues/issue-41394.stderr +++ b/tests/ui/enum-discriminant/issue-41394.stderr diff --git a/tests/ui/error-codes/E0026-teach.stderr b/tests/ui/error-codes/E0026-teach.stderr index 1a80edcbbe2..3d460490eb3 100644 --- a/tests/ui/error-codes/E0026-teach.stderr +++ b/tests/ui/error-codes/E0026-teach.stderr @@ -4,7 +4,7 @@ error[E0026]: struct `Thing` does not have a field named `z` LL | Thing { x, y, z } => {} | ^ struct `Thing` does not have this field | - = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. + = note: This error indicates that a struct pattern attempted to extract a nonexistent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. If you are using shorthand field patterns but want to refer to the struct field by a different name, you should rename it explicitly. diff --git a/tests/ui/extenv/issue-110547.rs b/tests/ui/extenv/issue-110547.rs new file mode 100644 index 00000000000..a6fb96ac066 --- /dev/null +++ b/tests/ui/extenv/issue-110547.rs @@ -0,0 +1,7 @@ +// compile-flags: -C debug-assertions + +fn main() { + env!{"\t"}; //~ ERROR not defined at compile time + env!("\t"); //~ ERROR not defined at compile time + env!("\u{2069}"); //~ ERROR not defined at compile time +} diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr new file mode 100644 index 00000000000..1219630d346 --- /dev/null +++ b/tests/ui/extenv/issue-110547.stderr @@ -0,0 +1,29 @@ +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:4:5 + | +LL | env!{"\t"}; + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:5:5 + | +LL | env!("\t"); + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable `` not defined at compile time + --> $DIR/issue-110547.rs:6:5 + | +LL | env!("\u{2069}"); + | ^^^^^^^^^^^^^^^^ + | + = help: use `std::env::var("")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/tests/ui/fn/fn-item-lifetime-bounds.rs b/tests/ui/fn/fn-item-lifetime-bounds.rs new file mode 100644 index 00000000000..68a1d0ce9b0 --- /dev/null +++ b/tests/ui/fn/fn-item-lifetime-bounds.rs @@ -0,0 +1,37 @@ +// check-pass +// known-bug: #84533 + +// Should fail. Lifetimes are checked correctly when `foo` is called, but NOT +// when only the lifetime parameters are instantiated. + +use std::marker::PhantomData; + +#[allow(dead_code)] +fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> { + PhantomData +} + +#[allow(dead_code)] +#[allow(path_statements)] +fn caller<'b, 'a>() { + foo::<'b, 'a>; +} + +// In contrast to above, below code correctly does NOT compile. +// fn caller<'b, 'a>() { +// foo::<'b, 'a>(); +// } + +// error: lifetime may not live long enough +// --> src/main.rs:22:5 +// | +// 21 | fn caller<'b, 'a>() { +// | -- -- lifetime `'a` defined here +// | | +// | lifetime `'b` defined here +// 22 | foo::<'b, 'a>(); +// | ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b` +// | +// = help: consider adding the following bound: `'a: 'b` + +fn main() {} diff --git a/tests/ui/fn/implied-bounds-impl-header-projections.rs b/tests/ui/fn/implied-bounds-impl-header-projections.rs new file mode 100644 index 00000000000..28cec805032 --- /dev/null +++ b/tests/ui/fn/implied-bounds-impl-header-projections.rs @@ -0,0 +1,31 @@ +// check-pass +// known-bug: #100051 + +// Should fail. Implied bounds from projections in impl headers can create +// improper lifetimes. Variant of issue #98543 which was fixed by #99217. + +trait Trait { + type Type; +} + +impl<T> Trait for T { + type Type = (); +} + +trait Extend<'a, 'b> { + fn extend(self, s: &'a str) -> &'b str; +} + +impl<'a, 'b> Extend<'a, 'b> for <&'b &'a () as Trait>::Type +where + for<'what, 'ever> &'what &'ever (): Trait, +{ + fn extend(self, s: &'a str) -> &'b str { + s + } +} + +fn main() { + let y = <() as Extend<'_, '_>>::extend((), &String::from("Hello World")); + println!("{}", y); +} diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr +++ b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr +++ b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr +++ b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.stderr b/tests/ui/generator/auto-trait-regions.stderr deleted file mode 100644 index 165748d4430..00000000000 --- a/tests/ui/generator/auto-trait-regions.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:48:24 - | -LL | let a = A(&mut true, &mut true, No); - | ^^^^ - temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -... -LL | assert_foo(a); - | - borrow later used here - | - = note: consider using a `let` binding to create a longer lived value - -error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:48:35 - | -LL | let a = A(&mut true, &mut true, No); - | ^^^^ - temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -... -LL | assert_foo(a); - | - borrow later used here - | - = note: consider using a `let` binding to create a longer lived value - -error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:34:5 - | -LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`... - = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef` - -error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:54:5 - | -LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... - = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/generator/issue-57084.rs b/tests/ui/generator/issue-57084.rs index 2a5c3dd0570..fbed78ff280 100644 --- a/tests/ui/generator/issue-57084.rs +++ b/tests/ui/generator/issue-57084.rs @@ -1,5 +1,5 @@ // This issue reproduces an ICE on compile (E.g. fails on 2018-12-19 nightly). -// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '_#1r" +// "cannot relate bound region: ReLateBound(DebruijnIndex(1), BrAnon(1)) <= '?1" // run-pass // edition:2018 #![feature(generators,generator_trait)] diff --git a/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs new file mode 100644 index 00000000000..5b10aab4b3f --- /dev/null +++ b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs @@ -0,0 +1,5 @@ +pub trait Foo { + type Gat<T> + where + T: std::fmt::Display; +} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.rs b/tests/ui/generic-associated-types/missing-item-sugg.rs new file mode 100644 index 00000000000..35d573d8188 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.rs @@ -0,0 +1,11 @@ +// aux-build:missing-item-sugg.rs + +extern crate missing_item_sugg; + +struct Local; +impl missing_item_sugg::Foo for Local { + //~^ ERROR not all trait items implemented, missing: `Gat` +} +//~^ HELP implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;` + +fn main() {} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.stderr b/tests/ui/generic-associated-types/missing-item-sugg.stderr new file mode 100644 index 00000000000..378115f6d38 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `Gat` + --> $DIR/missing-item-sugg.rs:6:1 + | +LL | impl missing_item_sugg::Foo for Local { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation + | + = help: implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs new file mode 100644 index 00000000000..d89c1e03688 --- /dev/null +++ b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs @@ -0,0 +1,3 @@ +pub fn const_arg<const N: usize, T>() {} + +pub fn lt_arg<'a: 'a>() {} diff --git a/tests/ui/generics/foreign-generic-mismatch.rs b/tests/ui/generics/foreign-generic-mismatch.rs new file mode 100644 index 00000000000..403fd73d7df --- /dev/null +++ b/tests/ui/generics/foreign-generic-mismatch.rs @@ -0,0 +1,10 @@ +// aux-build: foreign-generic-mismatch.rs + +extern crate foreign_generic_mismatch; + +fn main() { + foreign_generic_mismatch::const_arg::<()>(); + //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied + foreign_generic_mismatch::lt_arg::<'static, 'static>(); + //~^ ERROR function takes 1 lifetime argument but 2 lifetime arguments were supplied +} diff --git a/tests/ui/generics/foreign-generic-mismatch.stderr b/tests/ui/generics/foreign-generic-mismatch.stderr new file mode 100644 index 00000000000..5322b3f919d --- /dev/null +++ b/tests/ui/generics/foreign-generic-mismatch.stderr @@ -0,0 +1,35 @@ +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/foreign-generic-mismatch.rs:6:31 + | +LL | foreign_generic_mismatch::const_arg::<()>(); + | ^^^^^^^^^ -- supplied 1 generic argument + | | + | expected 2 generic arguments + | +note: function defined here, with 2 generic parameters: `N`, `T` + --> $DIR/auxiliary/foreign-generic-mismatch.rs:1:8 + | +LL | pub fn const_arg<const N: usize, T>() {} + | ^^^^^^^^^ -------------- - +help: add missing generic argument + | +LL | foreign_generic_mismatch::const_arg::<(), T>(); + | +++ + +error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/foreign-generic-mismatch.rs:8:31 + | +LL | foreign_generic_mismatch::lt_arg::<'static, 'static>(); + | ^^^^^^ ------- help: remove this lifetime argument + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'a` + --> $DIR/auxiliary/foreign-generic-mismatch.rs:3:8 + | +LL | pub fn lt_arg<'a: 'a>() {} + | ^^^^^^ -- + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr index e6c750d0e42..aa4ee75bb75 100644 --- a/tests/ui/impl-trait/auto-trait-leak.stderr +++ b/tests/ui/impl-trait/auto-trait-leak.stderr @@ -9,7 +9,7 @@ note: ...which requires borrow-checking `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... +note: ...which requires promoting constants in MIR for `cycle1`... --> $DIR/auto-trait-leak.rs:12:1 | LL | fn cycle1() -> impl Clone { @@ -55,7 +55,7 @@ note: ...which requires borrow-checking `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... +note: ...which requires promoting constants in MIR for `cycle2`... --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs new file mode 100644 index 00000000000..6b9d14941f2 --- /dev/null +++ b/tests/ui/impl-trait/issue-108591.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct MyTy<'a>(Vec<u8>, &'a ()); + +impl MyTy<'_> { + fn one(&mut self) -> &mut impl Sized { + &mut self.0 + } + fn two(&mut self) -> &mut (impl Sized + 'static) { + self.one() + } +} + +type Opaque<'a> = impl Sized; +fn define<'a>() -> Opaque<'a> {} + +fn test<'a>() { + None::<&'static Opaque<'a>>; +} + +fn one<'a, 'b: 'b>() -> &'a impl Sized { + &() +} +fn two<'a, 'b>() { + one::<'a, 'b>(); +} + +fn main() {} diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs new file mode 100644 index 00000000000..58a0ed9bf1a --- /dev/null +++ b/tests/ui/impl-trait/issue-108592.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +fn opaque<'a: 'a>() -> impl Sized {} +fn assert_static<T: 'static>(_: T) {} + +fn test_closure() { + let closure = |_| { + assert_static(opaque()); + }; + closure(&opaque()); +} + +type Opaque<'a> = impl Sized; +fn define<'a>() -> Opaque<'a> {} + +fn test_tait(_: &Opaque<'_>) { + None::<&'static Opaque<'_>>; +} + +fn main() {} diff --git a/tests/ui/issues/issue-36792.rs b/tests/ui/impl-trait/issue-36792.rs index 99ae633dd0e..99ae633dd0e 100644 --- a/tests/ui/issues/issue-36792.rs +++ b/tests/ui/impl-trait/issue-36792.rs diff --git a/tests/ui/impl-trait/wf-eval-order.rs b/tests/ui/impl-trait/wf-eval-order.rs index c7d6bb87096..8638fc2e775 100644 --- a/tests/ui/impl-trait/wf-eval-order.rs +++ b/tests/ui/impl-trait/wf-eval-order.rs @@ -31,9 +31,9 @@ fn main() { // // - `wf(typeof(x))` because we use a projection candidate. // - `<i32 as B>::V: Clone` because that's a bound on the trait. - // - `<i32 as B>::V` normalizes to `_#1` where `<i32 as A>::U == _#1` + // - `<i32 as B>::V` normalizes to `?1t` where `<i32 as A>::U == ?1t` // - // This all works if we evaluate `<i32 as A>::U == _#1` before + // This all works if we evaluate `<i32 as A>::U == ?1t` before // `<i32 as B>::V`, but we previously had the opposite order. let x = hide(X(0)); } diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs new file mode 100644 index 00000000000..1f5562497c1 --- /dev/null +++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs @@ -0,0 +1,16 @@ +// check-pass +// known-bug: #25860 + +// Should fail. The combination of variance and implied bounds for nested +// references allows us to infer a longer lifetime than we can prove. + +static UNIT: &'static &'static () = &&(); + +fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v } + +fn bad<'a, T>(x: &'a T) -> &'static T { + let f: fn(_, &'a T) -> &'static T = foo; + f(UNIT, x) +} + +fn main() {} diff --git a/tests/ui/implied-bounds/implied-bounds-on-trait-hierarchy.rs b/tests/ui/implied-bounds/implied-bounds-on-trait-hierarchy.rs new file mode 100644 index 00000000000..9c26cd59d10 --- /dev/null +++ b/tests/ui/implied-bounds/implied-bounds-on-trait-hierarchy.rs @@ -0,0 +1,39 @@ +// check-pass +// known-bug: #84591 + +// Should fail. Subtrait can incorrectly extend supertrait lifetimes even when +// supertrait has weaker implied bounds than subtrait. Strongly related to +// issue #25860. + +trait Subtrait<T>: Supertrait {} +trait Supertrait { + fn action(self); +} + +fn subs_to_soup<T, U>(x: T) +where + T: Subtrait<U>, +{ + soup(x) +} + +fn soup<T: Supertrait>(x: T) { + x.action(); +} + +impl<'a, 'b: 'a> Supertrait for (&'b str, &mut &'a str) { + fn action(self) { + *self.1 = self.0; + } +} + +impl<'a, 'b> Subtrait<&'a &'b str> for (&'b str, &mut &'a str) {} + +fn main() { + let mut d = "hi"; + { + let x = "Hello World".to_string(); + subs_to_soup((x.as_str(), &mut d)); + } + println!("{}", d); +} diff --git a/tests/ui/inline-const/const-match-pat-lifetime-err.rs b/tests/ui/inline-const/const-match-pat-lifetime-err.rs index 436b8037f30..366ad26bb27 100644 --- a/tests/ui/inline-const/const-match-pat-lifetime-err.rs +++ b/tests/ui/inline-const/const-match-pat-lifetime-err.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (This is currently broken) #![allow(incomplete_features)] #![feature(const_mut_refs)] diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs index 1f7b341a97e..85e12463a90 100644 --- a/tests/ui/issues/issue-25901.rs +++ b/tests/ui/issues/issue-25901.rs @@ -2,7 +2,7 @@ struct A; struct B; static S: &'static B = &A; -//~^ ERROR the trait bound +//~^ ERROR cannot perform deref coercion use std::ops::Deref; diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index b9cac32229a..1427e43854f 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -1,15 +1,24 @@ -error[E0277]: the trait bound `A: Deref` is not satisfied +error[E0015]: cannot perform deref coercion on `A` in statics --> $DIR/issue-25901.rs:4:24 | LL | static S: &'static B = &A; - | ^^ the trait `~const Deref` is not implemented for `A` + | ^^ | -note: the trait `Deref` is implemented for `A`, but that implementation is not `const` - --> $DIR/issue-25901.rs:4:24 + = note: attempting to deref into `B` +note: deref defined here + --> $DIR/issue-25901.rs:10:5 | -LL | static S: &'static B = &A; - | ^^ +LL | type Target = B; + | ^^^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/issue-25901.rs:9:1 + | +LL | impl Deref for A { + | ^^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/issues/issue-33287.rs b/tests/ui/issues/issue-33287.rs index 770eb7c02bb..b3f87305781 100644 --- a/tests/ui/issues/issue-33287.rs +++ b/tests/ui/issues/issue-33287.rs @@ -1,6 +1,7 @@ // build-pass #![allow(dead_code)] #![allow(unused_variables)] +#![allow(unconditional_panic)] const A: [u32; 1] = [0]; fn test() { diff --git a/tests/ui/issues/issue-3344.stderr b/tests/ui/issues/issue-3344.stderr index 11d5999672e..e849f5d0490 100644 --- a/tests/ui/issues/issue-3344.stderr +++ b/tests/ui/issues/issue-3344.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp` LL | impl PartialOrd for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | - = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }` + = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/issues/issue-49298.rs b/tests/ui/issues/issue-49298.rs index e3ffa8e7c6e..6e58fa12ca7 100644 --- a/tests/ui/issues/issue-49298.rs +++ b/tests/ui/issues/issue-49298.rs @@ -6,7 +6,7 @@ // where #54986 is implemented and #54987 is *not* implemented. For // now: just ignore it // -// ignore-test +// ignore-test (#54987) // This test is checking that the space allocated for `x.1` does not // overlap with `y`. (The reason why such a thing happened at one diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr index 53ecc6112ff..3d527eb6b4e 100644 --- a/tests/ui/issues/issue-50582.stderr +++ b/tests/ui/issues/issue-50582.stderr @@ -7,13 +7,13 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information = help: add `#![feature(const_for)]` to the crate attributes to enable -error[E0277]: cannot add `()` to `{integer}` in const contexts +error[E0277]: cannot add `()` to `{integer}` --> $DIR/issue-50582.rs:2:18 | LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | ^ no implementation for `{integer} + ()` | - = help: the trait `~const Add<()>` is not implemented for `{integer}` + = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add<Rhs>`: <&'a f32 as Add<f32>> <&'a f64 as Add<f64>> diff --git a/tests/ui/issues/issue-59756.rs b/tests/ui/issues/issue-59756.rs index d6df0592be3..3742f31abad 100644 --- a/tests/ui/issues/issue-59756.rs +++ b/tests/ui/issues/issue-59756.rs @@ -1,5 +1,5 @@ // run-rustfix -// ignore-test +// ignore-test (rustfix needs multiple suggestions) // // FIXME: Re-enable this test once we support choosing // between multiple mutually exclusive suggestions for the same span diff --git a/tests/ui/issues/issue-6458-1.rs b/tests/ui/issues/issue-6458-1.rs deleted file mode 100644 index 184e4832b90..00000000000 --- a/tests/ui/issues/issue-6458-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-fail -// error-pattern:explicit panic -// ignore-emscripten no processes - -fn foo<T>(t: T) {} -fn main() { - foo(panic!()) -} diff --git a/tests/ui/issues/issue-6458-2.rs b/tests/ui/issues/issue-6458-2.rs deleted file mode 100644 index b18cae3ed1a..00000000000 --- a/tests/ui/issues/issue-6458-2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - // Unconstrained type: - format!("{:?}", None); - //~^ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/issues/issue-6458-2.stderr b/tests/ui/issues/issue-6458-2.stderr deleted file mode 100644 index 8dbdd9a2735..00000000000 --- a/tests/ui/issues/issue-6458-2.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458-2.rs:3:21 - | -LL | format!("{:?}", None); - | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` - | -help: consider specifying the generic argument - | -LL | format!("{:?}", None::<T>); - | +++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-6458-3.rs b/tests/ui/issues/issue-6458-3.rs deleted file mode 100644 index d4f8886e9b0..00000000000 --- a/tests/ui/issues/issue-6458-3.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::mem; - -fn main() { - mem::transmute(0); - //~^ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/issues/issue-6458-3.stderr b/tests/ui/issues/issue-6458-3.stderr deleted file mode 100644 index 520efccae51..00000000000 --- a/tests/ui/issues/issue-6458-3.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458-3.rs:4:5 - | -LL | mem::transmute(0); - | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute` - | -help: consider specifying the generic arguments - | -LL | mem::transmute::<i32, Dst>(0); - | ++++++++++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-6458-4.rs b/tests/ui/issues/issue-6458-4.rs deleted file mode 100644 index 054a5c15c3f..00000000000 --- a/tests/ui/issues/issue-6458-4.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types - Err("bar".to_string()); -} - -fn main() { - foo(false); -} diff --git a/tests/ui/issues/issue-6458-4.stderr b/tests/ui/issues/issue-6458-4.stderr deleted file mode 100644 index 66ccfdff236..00000000000 --- a/tests/ui/issues/issue-6458-4.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-6458-4.rs:1:20 - | -LL | fn foo(b: bool) -> Result<bool,String> { - | --- ^^^^^^^^^^^^^^^^^^^ expected `Result<bool, String>`, found `()` - | | - | implicitly returns `()` as its body has no tail or `return` expression -LL | Err("bar".to_string()); - | - help: remove this semicolon to return this value - | - = note: expected enum `Result<bool, String>` - found unit type `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-6458.rs b/tests/ui/issues/issue-6458.rs deleted file mode 100644 index 16718e90deb..00000000000 --- a/tests/ui/issues/issue-6458.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::marker; - -pub struct TypeWithState<State>(marker::PhantomData<State>); -pub struct MyState; - -pub fn foo<State>(_: TypeWithState<State>) {} - -pub fn bar() { - foo(TypeWithState(marker::PhantomData)); - //~^ ERROR type annotations needed [E0282] -} - -fn main() { -} diff --git a/tests/ui/issues/issue-6458.stderr b/tests/ui/issues/issue-6458.stderr deleted file mode 100644 index 2e93c13855f..00000000000 --- a/tests/ui/issues/issue-6458.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458.rs:9:22 - | -LL | foo(TypeWithState(marker::PhantomData)); - | ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` - | -help: consider specifying the generic argument - | -LL | foo(TypeWithState(marker::PhantomData::<T>)); - | +++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/lifetimes/issue-105675.rs b/tests/ui/lifetimes/issue-105675.rs new file mode 100644 index 00000000000..58d8be8b65f --- /dev/null +++ b/tests/ui/lifetimes/issue-105675.rs @@ -0,0 +1,14 @@ +fn thing(x: impl FnOnce(&u32, &u32, u32)) {} + +fn main() { + let f = | _ , y: &u32 , z | (); + thing(f); + //~^ ERROR mismatched types + //~^^ ERROR mismatched types + let f = | x, y: _ , z: u32 | (); + thing(f); + //~^ ERROR mismatched types + //~^^ ERROR mismatched types + //~^^^ ERROR implementation of `FnOnce` is not general enough + //~^^^^ ERROR implementation of `FnOnce` is not general enough +} diff --git a/tests/ui/lifetimes/issue-105675.stderr b/tests/ui/lifetimes/issue-105675.stderr new file mode 100644 index 00000000000..66415f72bcb --- /dev/null +++ b/tests/ui/lifetimes/issue-105675.stderr @@ -0,0 +1,109 @@ +error[E0308]: mismatched types + --> $DIR/issue-105675.rs:5:5 + | +LL | thing(f); + | ^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a u32, &'b u32, u32)>` + found trait `for<'a> FnOnce<(&u32, &'a u32, u32)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-105675.rs:4:13 + | +LL | let f = | _ , y: &u32 , z | (); + | ^^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-105675.rs:1:18 + | +LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the type of the closure parameters + | +LL | let f = |_: &_, y: &u32, z| (); + | ~~~~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-105675.rs:5:5 + | +LL | thing(f); + | ^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a u32, &'b u32, u32)>` + found trait `for<'a> FnOnce<(&u32, &'a u32, u32)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-105675.rs:4:13 + | +LL | let f = | _ , y: &u32 , z | (); + | ^^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-105675.rs:1:18 + | +LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/issue-105675.rs:9:5 + | +LL | thing(f); + | ^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a u32, &'b u32, u32)>` + found trait `FnOnce<(&u32, &u32, u32)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-105675.rs:8:13 + | +LL | let f = | x, y: _ , z: u32 | (); + | ^^^^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-105675.rs:1:18 + | +LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the type of the closure parameters + | +LL | let f = |x: &_, y: &_, z: u32| (); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error[E0308]: mismatched types + --> $DIR/issue-105675.rs:9:5 + | +LL | thing(f); + | ^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a, 'b> FnOnce<(&'a u32, &'b u32, u32)>` + found trait `FnOnce<(&u32, &u32, u32)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/issue-105675.rs:8:13 + | +LL | let f = | x, y: _ , z: u32 | (); + | ^^^^^^^^^^^^^^^^^^^^^ +note: the lifetime requirement is introduced here + --> $DIR/issue-105675.rs:1:18 + | +LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: consider specifying the type of the closure parameters + | +LL | let f = |x: &_, y: &_, z: u32| (); + | ~~~~~~~~~~~~~~~~~~~~~~ + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-105675.rs:9:5 + | +LL | thing(f); + | ^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 u32, &u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2` + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-105675.rs:9:5 + | +LL | thing(f); + | ^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&u32, &'2 u32, u32)` must implement `FnOnce<(&u32, &'1 u32, u32)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&u32, &'2 u32, u32)>`, for some specific lifetime `'2` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-36744-without-calls.rs b/tests/ui/lifetimes/issue-36744-without-calls.rs index dc5dc4f13c0..dc5dc4f13c0 100644 --- a/tests/ui/issues/issue-36744-without-calls.rs +++ b/tests/ui/lifetimes/issue-36744-without-calls.rs diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr index 7ae6789285b..3879f35505c 100644 --- a/tests/ui/lifetimes/issue-69314.stderr +++ b/tests/ui/lifetimes/issue-69314.stderr @@ -12,6 +12,8 @@ LL | async fn f2(m: Msg<'_>) {} error[E0597]: `buf` does not live long enough --> $DIR/issue-69314.rs:14:19 | +LL | let mut buf = [0; 512]; + | ------- binding `buf` declared here LL | let m2 = &buf[..]; | ^^^ borrowed value does not live long enough LL | let m = Self::g(m2).await; diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr index c5f654b37bf..75fd87b3fe9 100644 --- a/tests/ui/lifetimes/issue-79187-2.stderr +++ b/tests/ui/lifetimes/issue-79187-2.stderr @@ -43,6 +43,10 @@ note: the lifetime requirement is introduced here | LL | fn take_foo(_: impl Foo) {} | ^^^ +help: consider specifying the type of the closure parameters + | +LL | take_foo(|a: &_| a); + | ~~~~~~~ error[E0308]: mismatched types --> $DIR/issue-79187-2.rs:11:5 diff --git a/tests/ui/lifetimes/issue-79187.stderr b/tests/ui/lifetimes/issue-79187.stderr index ee6e7b89d5f..209f2b7b739 100644 --- a/tests/ui/lifetimes/issue-79187.stderr +++ b/tests/ui/lifetimes/issue-79187.stderr @@ -16,6 +16,10 @@ note: the lifetime requirement is introduced here | LL | fn thing(x: impl FnOnce(&u32)) {} | ^^^^^^^^^^^^ +help: consider specifying the type of the closure parameters + | +LL | let f = |_: &_| (); + | ~~~~~~~ error: implementation of `FnOnce` is not general enough --> $DIR/issue-79187.rs:5:5 diff --git a/tests/ui-fulldeps/lint-group-denied-lint-allowed.rs b/tests/ui/lint-group-denied-lint-allowed.rs index 7498745f206..8156b6ef617 100644 --- a/tests/ui-fulldeps/lint-group-denied-lint-allowed.rs +++ b/tests/ui/lint-group-denied-lint-allowed.rs @@ -1,4 +1,3 @@ -// aux-build:lint-group-plugin-test.rs // check-pass // compile-flags: -D unused -A unused-variables diff --git a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs b/tests/ui/lint-group-forbid-always-trumps-cli.rs index fc19bc03906..77b792f98d5 100644 --- a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.rs +++ b/tests/ui/lint-group-forbid-always-trumps-cli.rs @@ -1,4 +1,3 @@ -// aux-build:lint-group-plugin-test.rs // compile-flags: -F unused -A unused fn main() { diff --git a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr b/tests/ui/lint-group-forbid-always-trumps-cli.stderr index 6bab367b0d1..8910af87ca2 100644 --- a/tests/ui-fulldeps/lint-group-forbid-always-trumps-cli.stderr +++ b/tests/ui/lint-group-forbid-always-trumps-cli.stderr @@ -1,5 +1,5 @@ error: unused variable: `x` - --> $DIR/lint-group-forbid-always-trumps-cli.rs:5:9 + --> $DIR/lint-group-forbid-always-trumps-cli.rs:4:9 | LL | let x = 1; | ^ help: if this is intentional, prefix it with an underscore: `_x` diff --git a/tests/ui/lint/dead-code/closure-bang.rs b/tests/ui/lint/dead-code/closure-bang.rs index 8e8636b1180..bca131a15d3 100644 --- a/tests/ui/lint/dead-code/closure-bang.rs +++ b/tests/ui/lint/dead-code/closure-bang.rs @@ -1,9 +1,7 @@ -// ignore-test FIXME(#20574) - #![deny(unreachable_code)] fn main() { - let x = || panic!(); + let x = || -> ! { panic!() }; x(); println!("Foo bar"); //~ ERROR: unreachable statement } diff --git a/tests/ui/lint/dead-code/closure-bang.stderr b/tests/ui/lint/dead-code/closure-bang.stderr new file mode 100644 index 00000000000..119ce11e34a --- /dev/null +++ b/tests/ui/lint/dead-code/closure-bang.stderr @@ -0,0 +1,17 @@ +error: unreachable statement + --> $DIR/closure-bang.rs:6:5 + | +LL | x(); + | --- any code following this expression is unreachable +LL | println!("Foo bar"); + | ^^^^^^^^^^^^^^^^^^^ unreachable statement + | +note: the lint level is defined here + --> $DIR/closure-bang.rs:1:9 + | +LL | #![deny(unreachable_code)] + | ^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs new file mode 100644 index 00000000000..2c6fcef2500 --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs @@ -0,0 +1,42 @@ +// check-pass + +#![feature(offset_of)] +#![deny(dead_code)] + +// This struct contains a projection that can only be normalized after getting the field type. +struct A<T: Project> { + a: <T as Project>::EquateParamTo, +} + +// This is the inner struct that we want to get. +struct MyFieldIsNotDead { + not_dead: u8, +} + +// These are some helpers. +// Inside the param env of `test`, we want to make it so that it considers T=MyFieldIsNotDead. +struct GenericIsEqual<T>(T); +trait Project { + type EquateParamTo; +} +impl<T> Project for GenericIsEqual<T> { + type EquateParamTo = T; +} + +fn test<T>() -> usize +where + GenericIsEqual<T>: Project<EquateParamTo = MyFieldIsNotDead>, +{ + // The first field of the A that we construct here is + // `<GenericIsEqual<T>> as Project>::EquateParamTo`. + // Typeck normalizes this and figures that the not_dead field is totally fine and accessible. + // But importantly, the normalization ends up with T, which, as we've declared in our param + // env is MyFieldDead. When we're in the param env of the `a` field, the where bound above + // is not in scope, so we don't know what T is - it's generic. + // If we use the wrong param env, the lint will ICE. + std::mem::offset_of!(A<GenericIsEqual<T>>, a.not_dead) +} + +fn main() { + test::<MyFieldIsNotDead>(); +} diff --git a/tests/ui/lint/dead-code/offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs new file mode 100644 index 00000000000..da91de3862f --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of.rs @@ -0,0 +1,44 @@ +#![feature(offset_of)] +#![deny(dead_code)] + +use std::mem::offset_of; + +struct Alpha { + a: (), + b: (), //~ ERROR field `b` is never read + c: Beta, +} + +struct Beta { + a: (), //~ ERROR field `a` is never read + b: (), +} + +struct Gamma { + a: (), //~ ERROR field `a` is never read + b: (), +} + +struct Delta { + a: (), + b: (), //~ ERROR field `b` is never read +} + +trait Trait { + type Assoc; +} +impl Trait for () { + type Assoc = Delta; +} + +struct Project<T: Trait> { + a: u8, //~ ERROR field `a` is never read + b: <T as Trait>::Assoc, +} + +fn main() { + offset_of!(Alpha, a); + offset_of!(Alpha, c.b); + offset_of!((Gamma,), 0.b); + offset_of!(Project::<()>, b.a); +} diff --git a/tests/ui/lint/dead-code/offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr new file mode 100644 index 00000000000..ed2916461cd --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of.stderr @@ -0,0 +1,50 @@ +error: field `b` is never read + --> $DIR/offset-of.rs:8:5 + | +LL | struct Alpha { + | ----- field in this struct +LL | a: (), +LL | b: (), + | ^ + | +note: the lint level is defined here + --> $DIR/offset-of.rs:2:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: field `a` is never read + --> $DIR/offset-of.rs:13:5 + | +LL | struct Beta { + | ---- field in this struct +LL | a: (), + | ^ + +error: field `a` is never read + --> $DIR/offset-of.rs:18:5 + | +LL | struct Gamma { + | ----- field in this struct +LL | a: (), + | ^ + +error: field `b` is never read + --> $DIR/offset-of.rs:24:5 + | +LL | struct Delta { + | ----- field in this struct +LL | a: (), +LL | b: (), + | ^ + +error: field `a` is never read + --> $DIR/offset-of.rs:35:5 + | +LL | struct Project<T: Trait> { + | ------- field in this struct +LL | a: u8, + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/lint/issue-110573.rs b/tests/ui/lint/issue-110573.rs new file mode 100644 index 00000000000..d9f0868b765 --- /dev/null +++ b/tests/ui/lint/issue-110573.rs @@ -0,0 +1,12 @@ +// check-pass + +#![deny(warnings)] + +pub struct Struct; + +impl Struct { + #[allow(non_upper_case_globals)] + pub const Const: () = (); +} + +fn main() {} diff --git a/tests/ui/issues/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 f30d7e2edcc..f30d7e2edcc 100644 --- a/tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs diff --git a/tests/ui/lint/lint-non-uppercase-trait-assoc-const.rs b/tests/ui/lint/lint-non-uppercase-trait-assoc-const.rs new file mode 100644 index 00000000000..4409611c200 --- /dev/null +++ b/tests/ui/lint/lint-non-uppercase-trait-assoc-const.rs @@ -0,0 +1,15 @@ +#![deny(non_upper_case_globals)] + +trait Trait { + const item: usize; + //~^ ERROR associated constant `item` should have an upper case name [non_upper_case_globals] +} + +struct Foo; + +impl Trait for Foo { + const item: usize = 5; + // ^^^ there should be no error here (in the trait `impl`) +} + +fn main() {} diff --git a/tests/ui/lint/lint-non-uppercase-trait-assoc-const.stderr b/tests/ui/lint/lint-non-uppercase-trait-assoc-const.stderr new file mode 100644 index 00000000000..98d8d1dd27f --- /dev/null +++ b/tests/ui/lint/lint-non-uppercase-trait-assoc-const.stderr @@ -0,0 +1,14 @@ +error: associated constant `item` should have an upper case name + --> $DIR/lint-non-uppercase-trait-assoc-const.rs:4:11 + | +LL | const item: usize; + | ^^^^ help: convert the identifier to upper case: `ITEM` + | +note: the lint level is defined here + --> $DIR/lint-non-uppercase-trait-assoc-const.rs:1:9 + | +LL | #![deny(non_upper_case_globals)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/lint/lint-uppercase-variables.stderr b/tests/ui/lint/lint-uppercase-variables.stderr index 42ec9364bc6..9220828014f 100644 --- a/tests/ui/lint/lint-uppercase-variables.stderr +++ b/tests/ui/lint/lint-uppercase-variables.stderr @@ -12,12 +12,6 @@ error[E0170]: pattern binding `Foo` is named the same as one of the variants of LL | let Foo = foo::Foo::Foo; | ^^^ help: to match on the variant, qualify the path: `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 - | -LL | fn in_param(Foo: foo::Foo) {} - | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` - warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | @@ -37,6 +31,12 @@ warning: unused variable: `Foo` LL | let Foo = foo::Foo::Foo; | ^^^ help: if this is intentional, prefix it with an underscore: `_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 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:33:17 | diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr index 2c35647b8a3..4852c331396 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -1,15 +1,3 @@ -error: unused variable: `this_is_my_function` - --> $DIR/expect_nested_lint_levels.rs:48:9 - | -LL | let this_is_my_function = 3; - | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` - | -note: the lint level is defined here - --> $DIR/expect_nested_lint_levels.rs:45:10 - | -LL | #[forbid(unused_variables)] - | ^^^^^^^^^^^^^^^^ - warning: variable does not need to be mutable --> $DIR/expect_nested_lint_levels.rs:36:13 | @@ -25,6 +13,18 @@ note: the lint level is defined here LL | unused_mut, | ^^^^^^^^^^ +error: unused variable: `this_is_my_function` + --> $DIR/expect_nested_lint_levels.rs:48:9 + | +LL | let this_is_my_function = 3; + | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` + | +note: the lint level is defined here + --> $DIR/expect_nested_lint_levels.rs:45:10 + | +LL | #[forbid(unused_variables)] + | ^^^^^^^^^^^^^^^^ + warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:7:5 | 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 5942fa8aeb4..169f03aed94 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 @@ -12,12 +12,6 @@ warning: unused variable: `fox_name` 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:43:9 - | -LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` - warning: variable does not need to be mutable --> $DIR/force_warn_expected_lints_fulfilled.rs:32:9 | @@ -28,6 +22,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: `this_should_fulfill_the_expectation` + --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9 + | +LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` + warning: denote infinite loops with `loop { ... }` --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5 | diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed index 71ebaea8ed2..9c52ca5577e 100644 --- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed +++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.fixed @@ -21,17 +21,32 @@ fn lint_on_top_level() { let _ = |a: u8| 0; //~ ERROR unnecessary parentheses around pattern } -fn _no_lint_attr() { +fn no_lint_attr() { let _x = #[allow(dead_code)] (1 + 2); } -fn _no_lint_yeet() -> Result<(), ()> { +fn no_lint_yeet() -> Result<(), ()> { #[allow(unreachable_code)] if (do yeet) {} Ok(()) } +fn no_lint_ops() { + #![allow(unreachable_code, irrefutable_let_patterns)] + if ((..{}) == ..{}) {} + if (!return) {} + loop { match (() = () = () = break {}) {} } + while let () = (*&mut false |= true && return) {} +} + +fn lint_break_if_not_followed_by_block() { + #![allow(unreachable_code)] + loop { if break {} } //~ ERROR unnecessary parentheses + loop { if break ({ println!("hello") }) {} } //~ ERROR unnecessary parentheses + loop { if (break { println!("hello") }) {} } +} + // Don't lint in these cases (#64106). fn or_patterns_no_lint() { match Box::new(0) { diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs index 28b662dd024..196ecf0c1bb 100644 --- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs +++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.rs @@ -21,17 +21,32 @@ fn lint_on_top_level() { let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern } -fn _no_lint_attr() { +fn no_lint_attr() { let _x = #[allow(dead_code)] (1 + 2); } -fn _no_lint_yeet() -> Result<(), ()> { +fn no_lint_yeet() -> Result<(), ()> { #[allow(unreachable_code)] if (do yeet) {} Ok(()) } +fn no_lint_ops() { + #![allow(unreachable_code, irrefutable_let_patterns)] + if ((..{}) == ..{}) {} + if (!return) {} + loop { match (() = () = () = break {}) {} } + while let () = (*&mut false |= true && return) {} +} + +fn lint_break_if_not_followed_by_block() { + #![allow(unreachable_code)] + loop { if (break) {} } //~ ERROR unnecessary parentheses + loop { if (break ({ println!("hello") })) {} } //~ ERROR unnecessary parentheses + loop { if (break { println!("hello") }) {} } +} + // Don't lint in these cases (#64106). fn or_patterns_no_lint() { match Box::new(0) { diff --git a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr index a5e69e6d938..f916bba8194 100644 --- a/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr +++ b/tests/ui/lint/unused/issue-54538-unused-parens-lint.stderr @@ -75,8 +75,32 @@ LL - let _ = |(a): u8| 0; LL + let _ = |a: u8| 0; | +error: unnecessary parentheses around `if` condition + --> $DIR/issue-54538-unused-parens-lint.rs:45:15 + | +LL | loop { if (break) {} } + | ^ ^ + | +help: remove these parentheses + | +LL - loop { if (break) {} } +LL + loop { if break {} } + | + +error: unnecessary parentheses around `if` condition + --> $DIR/issue-54538-unused-parens-lint.rs:46:15 + | +LL | loop { if (break ({ println!("hello") })) {} } + | ^ ^ + | +help: remove these parentheses + | +LL - loop { if (break ({ println!("hello") })) {} } +LL + loop { if break ({ println!("hello") }) {} } + | + error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:56:12 + --> $DIR/issue-54538-unused-parens-lint.rs:71:12 | LL | if let (0 | 1) = 0 {} | ^ ^ @@ -88,7 +112,7 @@ LL + if let 0 | 1 = 0 {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:57:13 + --> $DIR/issue-54538-unused-parens-lint.rs:72:13 | LL | if let ((0 | 1),) = (0,) {} | ^ ^ @@ -100,7 +124,7 @@ LL + if let (0 | 1,) = (0,) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:58:13 + --> $DIR/issue-54538-unused-parens-lint.rs:73:13 | LL | if let [(0 | 1)] = [0] {} | ^ ^ @@ -112,7 +136,7 @@ LL + if let [0 | 1] = [0] {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:59:16 + --> $DIR/issue-54538-unused-parens-lint.rs:74:16 | LL | if let 0 | (1 | 2) = 0 {} | ^ ^ @@ -124,7 +148,7 @@ LL + if let 0 | 1 | 2 = 0 {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:61:15 + --> $DIR/issue-54538-unused-parens-lint.rs:76:15 | LL | if let TS((0 | 1)) = TS(0) {} | ^ ^ @@ -136,7 +160,7 @@ LL + if let TS(0 | 1) = TS(0) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:63:20 + --> $DIR/issue-54538-unused-parens-lint.rs:78:20 | LL | if let NS { f: (0 | 1) } = (NS { f: 0 }) {} | ^ ^ @@ -148,7 +172,7 @@ LL + if let NS { f: 0 | 1 } = (NS { f: 0 }) {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:73:9 + --> $DIR/issue-54538-unused-parens-lint.rs:88:9 | LL | (_) => {} | ^ ^ @@ -160,7 +184,7 @@ LL + _ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:74:9 + --> $DIR/issue-54538-unused-parens-lint.rs:89:9 | LL | (y) => {} | ^ ^ @@ -172,7 +196,7 @@ LL + y => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:75:9 + --> $DIR/issue-54538-unused-parens-lint.rs:90:9 | LL | (ref r) => {} | ^ ^ @@ -184,7 +208,7 @@ LL + ref r => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:76:9 + --> $DIR/issue-54538-unused-parens-lint.rs:91:9 | LL | (e @ 1...2) => {} | ^ ^ @@ -196,7 +220,7 @@ LL + e @ 1...2 => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:82:9 + --> $DIR/issue-54538-unused-parens-lint.rs:97:9 | LL | (e @ &(1...2)) => {} | ^ ^ @@ -208,7 +232,7 @@ LL + e @ &(1...2) => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:83:10 + --> $DIR/issue-54538-unused-parens-lint.rs:98:10 | LL | &(_) => {} | ^ ^ @@ -220,7 +244,7 @@ LL + &_ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:94:9 + --> $DIR/issue-54538-unused-parens-lint.rs:109:9 | LL | (_) => {} | ^ ^ @@ -232,7 +256,7 @@ LL + _ => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:95:9 + --> $DIR/issue-54538-unused-parens-lint.rs:110:9 | LL | (y) => {} | ^ ^ @@ -244,7 +268,7 @@ LL + y => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:96:9 + --> $DIR/issue-54538-unused-parens-lint.rs:111:9 | LL | (ref r) => {} | ^ ^ @@ -256,7 +280,7 @@ LL + ref r => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:97:9 + --> $DIR/issue-54538-unused-parens-lint.rs:112:9 | LL | (e @ 1..=2) => {} | ^ ^ @@ -268,7 +292,7 @@ LL + e @ 1..=2 => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:103:9 + --> $DIR/issue-54538-unused-parens-lint.rs:118:9 | LL | (e @ &(1..=2)) => {} | ^ ^ @@ -280,7 +304,7 @@ LL + e @ &(1..=2) => {} | error: unnecessary parentheses around pattern - --> $DIR/issue-54538-unused-parens-lint.rs:104:10 + --> $DIR/issue-54538-unused-parens-lint.rs:119:10 | LL | &(_) => {} | ^ ^ @@ -291,5 +315,5 @@ LL - &(_) => {} LL + &_ => {} | -error: aborting due to 24 previous errors +error: aborting due to 26 previous errors diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index fd9a5bcbfc4..09729eeba79 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -10,12 +10,6 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ -error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:14:5 - | -LL | b: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_b` - error: unused variable: `a` --> $DIR/lint-unused-variables.rs:22:9 | @@ -23,6 +17,12 @@ LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:14:5 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` --> $DIR/lint-unused-variables.rs:29:9 | LL | b: i32, diff --git a/tests/ui/liveness/liveness-consts.stderr b/tests/ui/liveness/liveness-consts.stderr index 6199ea96c98..016debdd396 100644 --- a/tests/ui/liveness/liveness-consts.stderr +++ b/tests/ui/liveness/liveness-consts.stderr @@ -1,10 +1,9 @@ -warning: variable `a` is assigned to, but never used - --> $DIR/liveness-consts.rs:7:13 +warning: unused variable: `e` + --> $DIR/liveness-consts.rs:24:13 | -LL | let mut a = 0; - | ^ +LL | let e = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_e` | - = note: consider using `_a` instead note: the lint level is defined here --> $DIR/liveness-consts.rs:2:9 | @@ -12,21 +11,6 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` -warning: value assigned to `b` is never read - --> $DIR/liveness-consts.rs:17:5 - | -LL | b += 1; - | ^ - | - = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - -warning: unused variable: `e` - --> $DIR/liveness-consts.rs:24:13 - | -LL | let e = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_e` - warning: unused variable: `s` --> $DIR/liveness-consts.rs:33:24 | @@ -39,6 +23,29 @@ warning: unused variable: `z` 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: unused variable: `z` + --> $DIR/liveness-consts.rs:60:13 + | +LL | let z = 42; + | ^ 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 + | +LL | let mut a = 0; + | ^ + | + = note: consider using `_a` instead + +warning: value assigned to `b` is never read + --> $DIR/liveness-consts.rs:17:5 + | +LL | b += 1; + | ^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` + warning: value assigned to `t` is never read --> $DIR/liveness-consts.rs:42:9 | @@ -53,11 +60,5 @@ warning: unused variable: `w` LL | let w = 10; | ^ help: if this is intentional, prefix it with an underscore: `_w` -warning: unused variable: `z` - --> $DIR/liveness-consts.rs:60:13 - | -LL | let z = 42; - | ^ help: if this is intentional, prefix it with an underscore: `_z` - warning: 8 warnings emitted diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/macros/issue-26094.rs index 2742529edd3..2742529edd3 100644 --- a/tests/ui/issues/issue-26094.rs +++ b/tests/ui/macros/issue-26094.rs diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/macros/issue-26094.stderr index ecdf48470f7..ecdf48470f7 100644 --- a/tests/ui/issues/issue-26094.stderr +++ b/tests/ui/macros/issue-26094.stderr diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs index 45a30857413..45a30857413 100644 --- a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr index 89aeafebac4..89aeafebac4 100644 --- a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr diff --git a/tests/ui/macros/macro-expanded-include/foo/mod.rs b/tests/ui/macros/macro-expanded-include/foo/mod.rs index cff110470f2..2e4c4c7f8a9 100644 --- a/tests/ui/macros/macro-expanded-include/foo/mod.rs +++ b/tests/ui/macros/macro-expanded-include/foo/mod.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) macro_rules! m { () => { include!("file.txt"); } diff --git a/tests/ui/user-defined-macro-rules.rs b/tests/ui/macros/user-defined-macro-rules.rs index 09e071ec454..09e071ec454 100644 --- a/tests/ui/user-defined-macro-rules.rs +++ b/tests/ui/macros/user-defined-macro-rules.rs diff --git a/tests/ui/match/issue-26996.rs b/tests/ui/match/issue-26996.rs index 84037b72a27..9ea4545268b 100644 --- a/tests/ui/match/issue-26996.rs +++ b/tests/ui/match/issue-26996.rs @@ -4,7 +4,7 @@ // where #54986 is implemented and #54987 is *not* implemented. For // now: just ignore it // -// ignore-test +// ignore-test (#54987) // This test is checking that the write to `c.0` (which has been moved out of) // won't overwrite the state in `c2`. diff --git a/tests/ui/match/issue-27021.rs b/tests/ui/match/issue-27021.rs index ef3b114a5fa..9630e9a0327 100644 --- a/tests/ui/match/issue-27021.rs +++ b/tests/ui/match/issue-27021.rs @@ -4,7 +4,7 @@ // where #54986 is implemented and #54987 is *not* implemented. For // now: just ignore it // -// ignore-test +// ignore-test (#54987) // These are variants of issue-26996.rs. In all cases we are writing // into a record field that has been moved out of, and ensuring that diff --git a/tests/ui/meta/no_std-extern-libc.rs b/tests/ui/meta/no_std-extern-libc.rs new file mode 100644 index 00000000000..763ea740a27 --- /dev/null +++ b/tests/ui/meta/no_std-extern-libc.rs @@ -0,0 +1,7 @@ +// Test that `download-rustc` doesn't put duplicate copies of libc in the sysroot. +// check-pass +#![crate_type = "lib"] +#![no_std] +#![feature(rustc_private)] + +extern crate libc; diff --git a/tests/ui/mir/validate/storage-live.stderr b/tests/ui/mir/validate/storage-live.stderr index b586a865849..720fb0a90b0 100644 --- a/tests/ui/mir/validate/storage-live.stderr +++ b/tests/ui/mir/validate/storage-live.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:8 ~ storage_live[HASH]::multiple_storage), const_param_did: None }) (before pass CheckPackedRef) at bb0[1]: +error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (before pass CheckPackedRef) at bb0[1]: StorageLive(_1) which already has storage here --> $DIR/storage-live.rs:22:13 | @@ -9,5 +9,5 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: #0 [mir_const] preparing `multiple_storage` for borrow checking -#1 [mir_promoted] processing MIR for `multiple_storage` +#1 [mir_promoted] promoting constants in MIR for `multiple_storage` end of query stack diff --git a/tests/ui/mismatched_types/closure-mismatch.rs b/tests/ui/mismatched_types/closure-mismatch.rs index b0644e79611..4eb33497c39 100644 --- a/tests/ui/mismatched_types/closure-mismatch.rs +++ b/tests/ui/mismatched_types/closure-mismatch.rs @@ -8,4 +8,7 @@ fn main() { baz(|_| ()); //~^ ERROR implementation of `FnOnce` is not general enough //~| ERROR mismatched types + baz(|x| ()); + //~^ ERROR implementation of `FnOnce` is not general enough + //~| ERROR mismatched types } diff --git a/tests/ui/mismatched_types/closure-mismatch.stderr b/tests/ui/mismatched_types/closure-mismatch.stderr index a7ef8fa0892..c5b8270ba84 100644 --- a/tests/ui/mismatched_types/closure-mismatch.stderr +++ b/tests/ui/mismatched_types/closure-mismatch.stderr @@ -25,7 +25,43 @@ note: the lifetime requirement is introduced here | LL | fn baz<T: Foo>(_: T) {} | ^^^ +help: consider specifying the type of the closure parameters + | +LL | baz(|_: &_| ()); + | ~~~~~~~ + +error: implementation of `FnOnce` is not general enough + --> $DIR/closure-mismatch.rs:11:5 + | +LL | baz(|x| ()); + | ^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2` + +error[E0308]: mismatched types + --> $DIR/closure-mismatch.rs:11:5 + | +LL | baz(|x| ()); + | ^^^^^^^^^^^ one type is more general than the other + | + = note: expected trait `for<'a> Fn<(&'a (),)>` + found trait `Fn<(&(),)>` +note: this closure does not fulfill the lifetime requirements + --> $DIR/closure-mismatch.rs:11:9 + | +LL | baz(|x| ()); + | ^^^ +note: the lifetime requirement is introduced here + --> $DIR/closure-mismatch.rs:5:11 + | +LL | fn baz<T: Foo>(_: T) {} + | ^^^ +help: consider specifying the type of the closure parameters + | +LL | baz(|x: &_| ()); + | ~~~~~~~ -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/missing/missing-items/m2.stderr b/tests/ui/missing/missing-items/m2.stderr index d18fb443aa4..835c9b2aa48 100644 --- a/tests/ui/missing/missing-items/m2.stderr +++ b/tests/ui/missing/missing-items/m2.stderr @@ -5,7 +5,7 @@ LL | impl m1::X for X { | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation | = help: implement the missing item: `const CONSTANT: u32 = 42;` - = help: implement the missing item: `type Type = Type;` + = help: implement the missing item: `type Type = /* Type */;` = help: implement the missing item: `fn method(&self, _: String) -> <Self as m1::X>::Type { todo!() }` = help: implement the missing item: `fn method2(self: Box<Self>, _: String) -> <Self as m1::X>::Type { todo!() }` = help: implement the missing item: `fn method3(_: &Self, _: String) -> <Self as m1::X>::Type { todo!() }` diff --git a/tests/ui/never_type/issue-52443.rs b/tests/ui/never_type/issue-52443.rs index 4669d7c1a35..0498a8a1625 100644 --- a/tests/ui/never_type/issue-52443.rs +++ b/tests/ui/never_type/issue-52443.rs @@ -11,5 +11,4 @@ fn main() { //~| ERROR cannot convert //~| ERROR mutable references //~| ERROR cannot call - //~| ERROR the trait bound } diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index 1233bdc5d1f..99dfce86903 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -58,19 +58,6 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0277]: the trait bound `RangeFrom<usize>: Iterator` is not satisfied - --> $DIR/issue-52443.rs:9:21 - | -LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ `RangeFrom<usize>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `RangeFrom<usize>` -note: the trait `Iterator` is implemented for `RangeFrom<usize>`, but that implementation is not `const` - --> $DIR/issue-52443.rs:9:21 - | -LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ - error[E0015]: cannot call non-const fn `<RangeFrom<usize> as Iterator>::next` in constants --> $DIR/issue-52443.rs:9:21 | @@ -80,7 +67,7 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0277, E0308, E0658. +Some errors have detailed explanations: E0015, E0308, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr index c0d95ddaa07..61233fd8407 100644 --- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -17,7 +17,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | - - ^^^^^^ assignment requires that `'1` must outlive `'2` | | | | | has type `&'1 i32` - | has type `&'_#2r mut &'2 i32` + | has type `&'?2 mut &'2 i32` note: no external requirements --> $DIR/escape-argument-callee.rs:20:1 diff --git a/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr b/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr index 4fbd5eb19a5..c00a31ef8e1 100644 --- a/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/tests/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -7,10 +7,10 @@ LL | let mut closure1 = || p = &y; = note: defining type: test::{closure#0}::{closure#0} with closure substs [ i16, extern "rust-call" fn(()), - (&'_#1r mut &'_#2r i32, &'_#3r i32), + (&'?1 mut &'?2 i32, &'?3 i32), ] = note: number of external vids: 4 - = note: where '_#3r: '_#2r + = note: where '?3: '?2 note: external requirements --> $DIR/escape-upvar-nested.rs:20:27 @@ -21,10 +21,10 @@ LL | let mut closure = || { = note: defining type: test::{closure#0} with closure substs [ i16, extern "rust-call" fn(()), - (&'_#1r mut &'_#2r i32, &'_#3r i32), + (&'?1 mut &'?2 i32, &'?3 i32), ] = note: number of external vids: 4 - = note: where '_#3r: '_#2r + = note: where '?3: '?2 note: no external requirements --> $DIR/escape-upvar-nested.rs:13:1 diff --git a/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr b/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr index bc1ceac5bf0..2d67e6e7d72 100644 --- a/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/tests/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -7,10 +7,10 @@ LL | let mut closure = || p = &y; = note: defining type: test::{closure#0} with closure substs [ i16, extern "rust-call" fn(()), - (&'_#1r mut &'_#2r i32, &'_#3r i32), + (&'?1 mut &'?2 i32, &'?3 i32), ] = note: number of external vids: 4 - = note: where '_#3r: '_#2r + = note: where '?3: '?2 note: no external requirements --> $DIR/escape-upvar-ref.rs:17:1 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 5a7b12732df..ba42576d403 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -6,20 +6,20 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| { | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'_#3r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?3 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#4r - = note: late-bound region is '_#5r - = note: late-bound region is '_#6r + = note: late-bound region is '?4 + = note: late-bound region is '?5 + = note: late-bound region is '?6 error: lifetime may not live long enough --> $DIR/propagate-approximated-fail-no-postdom.rs:46:13 | LL | |_outlives1, _outlives2, _outlives3, x, y| { - | ---------- ---------- has type `Cell<&'2 &'_#3r u32>` + | ---------- ---------- has type `Cell<&'2 &'?3 u32>` | | - | has type `Cell<&'_#1r &'1 u32>` + | has type `Cell<&'?1 &'1 u32>` ... LL | demand_y(x, y, p) | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr index db2ecc779ef..9dd6e02081f 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -6,13 +6,13 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#3r - = note: late-bound region is '_#4r + = note: late-bound region is '?3 + = note: late-bound region is '?4 = note: number of external vids: 5 - = note: where '_#1r: '_#2r + = note: where '?1: '?2 note: no external requirements --> $DIR/propagate-approximated-ref.rs:42:1 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 1d9dafbe55f..e2f5576d395 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 @@ -6,7 +6,7 @@ LL | foo(cell, |cell_a, cell_x| { | = note: defining type: case1::{closure#0} with closure substs [ i32, - for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)), (), ] @@ -36,11 +36,11 @@ LL | foo(cell, |cell_a, cell_x| { | = note: defining type: case2::{closure#0} with closure substs [ i32, - for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'_#1r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)), (), ] = note: number of external vids: 2 - = note: where '_#1r: '_#0r + = note: where '?1: '?0 note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1 diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index 85f7fe35c0a..383fb471ad3 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -6,13 +6,13 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#2r - = note: late-bound region is '_#3r + = note: late-bound region is '?2 + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where '_#1r: '_#0r + = note: where '?1: '?0 note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:31:1 @@ -40,7 +40,7 @@ LL | | }); | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `Cell<&'_#9r u32>`, which makes the generic argument `&'_#9r u32` invariant + = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant = note: the struct `Cell<T>` is invariant over the parameter `T` = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index 7194843e203..ac346c0b110 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -6,13 +6,13 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&'_#2r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#3r - = note: late-bound region is '_#4r + = note: late-bound region is '?3 + = note: late-bound region is '?4 = note: number of external vids: 5 - = note: where '_#1r: '_#0r + = note: where '?1: '?0 note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:34:1 @@ -40,7 +40,7 @@ LL | | }); | |______`cell_a` escapes the function body here | argument requires that `'a` must outlive `'static` | - = note: requirement occurs because of the type `Cell<&'_#10r u32>`, which makes the generic argument `&'_#10r u32` invariant + = note: requirement occurs because of the type `Cell<&'?10 u32>`, which makes the generic argument `&'?10 u32` invariant = note: the struct `Cell<T>` is invariant over the parameter `T` = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr index 71f8a1c67c6..b217ae19773 100644 --- a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -6,13 +6,13 @@ LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { | = note: defining type: test::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#3r - = note: late-bound region is '_#4r + = note: late-bound region is '?3 + = note: late-bound region is '?4 = note: number of external vids: 5 - = note: where '_#1r: '_#2r + = note: where '?1: '?2 note: no external requirements --> $DIR/propagate-approximated-val.rs:35:1 diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index e1cb97b1c7d..f31478b6d1c 100644 --- a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -6,12 +6,12 @@ LL | |_outlives1, _outlives2, x, y| { | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'_#2r u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where '_#1r: '_#2r + = note: where '?1: '?2 note: no external requirements --> $DIR/propagate-despite-same-free-region.rs:39:1 diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index b66e8391c01..1509ade87fa 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -6,19 +6,19 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#2r - = note: late-bound region is '_#3r + = note: late-bound region is '?2 + = note: late-bound region is '?3 error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { - | --------- - has type `&'_#7r Cell<&'1 u32>` + | --------- - has type `&'?7 Cell<&'1 u32>` | | - | has type `&'_#5r Cell<&'2 &'_#1r u32>` + | has type `&'?5 Cell<&'2 &'?1 u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index 49641fd06fd..c85a9872e21 100644 --- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -6,19 +6,19 @@ LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y | = note: defining type: supply::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'_#1r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'_#2r u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), + for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)), (), ] - = note: late-bound region is '_#3r - = note: late-bound region is '_#4r + = note: late-bound region is '?3 + = note: late-bound region is '?4 error: lifetime may not live long enough --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { - | ---------- ---------- has type `&'_#8r Cell<&'2 &'_#2r u32>` + | ---------- ---------- has type `&'?8 Cell<&'2 &'?2 u32>` | | - | has type `&'_#6r Cell<&'1 &'_#1r u32>` + | has type `&'?6 Cell<&'1 &'?1 u32>` LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` diff --git a/tests/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/tests/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 038a5e11f88..05e274ab220 100644 --- a/tests/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/tests/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -4,13 +4,13 @@ note: external requirements LL | establish_relationships(value, |value| { | ^^^^^^^ | - = note: defining type: supply::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: supply::<'?1, T>::{closure#0} with closure substs [ i32, extern "rust-call" fn((T,)), (), ] = note: number of external vids: 2 - = note: where T: '_#1r + = note: where T: '?1 note: no external requirements --> $DIR/propagate-from-trait-match.rs:28:1 @@ -20,7 +20,7 @@ LL | | where LL | | T: Trait<'a>, | |_________________^ | - = note: defining type: supply::<'_#1r, T> + = note: defining type: supply::<'?1, T> error[E0309]: the parameter type `T` may not live long enough --> $DIR/propagate-from-trait-match.rs:43:9 diff --git a/tests/ui/nll/member-constraints/min-choice.rs b/tests/ui/nll/member-constraints/min-choice.rs index 14b4dae7abf..f4aca69e19f 100644 --- a/tests/ui/nll/member-constraints/min-choice.rs +++ b/tests/ui/nll/member-constraints/min-choice.rs @@ -1,5 +1,5 @@ -// Assuming that the hidden type in these tests is `&'_#15r u8`, -// we have a member constraint: `'_#15r member ['static, 'a, 'b, 'c]`. +// Assuming that the hidden type in these tests is `&'?15 u8`, +// we have a member constraint: `'?15 member ['static, 'a, 'b, 'c]`. // // Make sure we pick up the minimum non-ambiguous region among them. // We will have to exclude `['b, 'c]` because they're incomparable, diff --git a/tests/ui/nll/member-constraints/nested-impl-trait-fail.rs b/tests/ui/nll/member-constraints/nested-impl-trait-fail.rs index 66ff828a84f..ceb417f84f3 100644 --- a/tests/ui/nll/member-constraints/nested-impl-trait-fail.rs +++ b/tests/ui/nll/member-constraints/nested-impl-trait-fail.rs @@ -5,9 +5,9 @@ trait Cap<'a> {} impl<T> Cap<'_> for T {} -// Assuming the hidden type is `[&'_#15r u8; 1]`, we have two distinct member constraints: -// - '_#15r member ['static, 'a, 'b] // from outer impl-trait -// - '_#15r member ['static, 'a, 'b] // from inner impl-trait +// Assuming the hidden type is `[&'?15 u8; 1]`, we have two distinct member constraints: +// - '?15 member ['static, 'a, 'b] // from outer impl-trait +// - '?15 member ['static, 'a, 'b] // from inner impl-trait // To satisfy both we can choose 'a or 'b, so it's a failure due to ambiguity. fn fail_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a> + Cap<'b>> where diff --git a/tests/ui/nll/member-constraints/nested-impl-trait-pass.rs b/tests/ui/nll/member-constraints/nested-impl-trait-pass.rs index 15540cb460e..4be0f02acf2 100644 --- a/tests/ui/nll/member-constraints/nested-impl-trait-pass.rs +++ b/tests/ui/nll/member-constraints/nested-impl-trait-pass.rs @@ -5,9 +5,9 @@ trait Cap<'a> {} impl<T> Cap<'_> for T {} -// Assuming the hidden type is `[&'_#15r u8; 1]`, we have two distinct member constraints: -// - '_#15r member ['static, 'a, 'b] // from outer impl-trait -// - '_#15r member ['static, 'a] // from inner impl-trait +// Assuming the hidden type is `[&'?15 u8; 1]`, we have two distinct member constraints: +// - '?15 member ['static, 'a, 'b] // from outer impl-trait +// - '?15 member ['static, 'a] // from inner impl-trait // To satisfy both we can only choose 'a. fn pass_early_bound<'s, 'a, 'b>(a: &'s u8) -> impl IntoIterator<Item = impl Cap<'a>> + Cap<'b> where diff --git a/tests/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/tests/ui/nll/ty-outlives/projection-no-regions-closure.stderr index 4933b934868..4eefb180ee5 100644 --- a/tests/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/tests/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -4,13 +4,13 @@ note: external requirements LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^ | - = note: defining type: no_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: no_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>, + extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '?2)>, (), ] = note: number of external vids: 3 - = note: where <T as std::iter::Iterator>::Item: '_#2r + = note: where <T as std::iter::Iterator>::Item: '?2 note: no external requirements --> $DIR/projection-no-regions-closure.rs:21:1 @@ -20,7 +20,7 @@ LL | | where LL | | T: Iterator, | |________________^ | - = note: defining type: no_region::<'_#1r, T> + = note: defining type: no_region::<'?1, T> error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough --> $DIR/projection-no-regions-closure.rs:25:31 @@ -37,13 +37,13 @@ note: external requirements LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^ | - = note: defining type: correct_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: correct_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#2r)>, + extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '?2)>, (), ] = note: number of external vids: 3 - = note: where <T as std::iter::Iterator>::Item: '_#2r + = note: where <T as std::iter::Iterator>::Item: '?2 note: no external requirements --> $DIR/projection-no-regions-closure.rs:30:1 @@ -53,7 +53,7 @@ LL | | where LL | | T: 'a + Iterator, | |_____________________^ | - = note: defining type: correct_region::<'_#1r, T> + = note: defining type: correct_region::<'?1, T> note: external requirements --> $DIR/projection-no-regions-closure.rs:42:23 @@ -61,13 +61,13 @@ note: external requirements LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^ | - = note: defining type: wrong_region::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: wrong_region::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>, + extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '?3)>, (), ] = note: number of external vids: 4 - = note: where <T as std::iter::Iterator>::Item: '_#3r + = note: where <T as std::iter::Iterator>::Item: '?3 note: no external requirements --> $DIR/projection-no-regions-closure.rs:38:1 @@ -77,7 +77,7 @@ LL | | where LL | | T: 'b + Iterator, | |_____________________^ | - = note: defining type: wrong_region::<'_#1r, '_#2r, T> + = note: defining type: wrong_region::<'?1, '?2, T> error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough --> $DIR/projection-no-regions-closure.rs:42:31 @@ -94,13 +94,13 @@ note: external requirements LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^ | - = note: defining type: outlives_region::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: outlives_region::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '_#3r)>, + extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn Anything + '?3)>, (), ] = note: number of external vids: 4 - = note: where <T as std::iter::Iterator>::Item: '_#3r + = note: where <T as std::iter::Iterator>::Item: '?3 note: no external requirements --> $DIR/projection-no-regions-closure.rs:47:1 @@ -111,7 +111,7 @@ LL | | T: 'b + Iterator, LL | | 'b: 'a, | |___________^ | - = note: defining type: outlives_region::<'_#1r, '_#2r, T> + = note: defining type: outlives_region::<'?1, '?2, T> error: aborting due to 2 previous errors diff --git a/tests/ui/nll/ty-outlives/projection-one-region-closure.stderr b/tests/ui/nll/ty-outlives/projection-one-region-closure.stderr index 11ada59c066..986c2bd2182 100644 --- a/tests/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/tests/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -4,15 +4,15 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_late::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_late::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where T: '_#2r - = note: where '_#1r: '_#2r + = note: where T: '?2 + = note: where '?1: '?2 note: no external requirements --> $DIR/projection-one-region-closure.rs:41:1 @@ -22,7 +22,7 @@ LL | | where LL | | T: Anything<'b>, | |____________________^ | - = note: defining type: no_relationships_late::<'_#1r, T> + = note: defining type: no_relationships_late::<'?1, T> error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:45:39 @@ -54,14 +54,14 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_early::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where T: '_#3r - = note: where '_#2r: '_#3r + = note: where T: '?3 + = note: where '?2: '?3 note: no external requirements --> $DIR/projection-one-region-closure.rs:51:1 @@ -72,7 +72,7 @@ LL | | T: Anything<'b>, LL | | 'a: 'a, | |___________^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> + = note: defining type: no_relationships_early::<'?1, '?2, T> error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:56:39 @@ -104,13 +104,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: projection_outlives::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where <T as Anything<'_#2r>>::AssocType: '_#3r + = note: where <T as Anything<'?2>>::AssocType: '?3 note: no external requirements --> $DIR/projection-one-region-closure.rs:62:1 @@ -121,7 +121,7 @@ LL | | T: Anything<'b>, LL | | T::AssocType: 'a, | |_____________________^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T> + = note: defining type: projection_outlives::<'?1, '?2, T> note: external requirements --> $DIR/projection-one-region-closure.rs:80:29 @@ -129,14 +129,14 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: elements_outlive::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where T: '_#3r - = note: where '_#2r: '_#3r + = note: where T: '?3 + = note: where '?2: '?3 note: no external requirements --> $DIR/projection-one-region-closure.rs:74:1 @@ -148,7 +148,7 @@ LL | | T: 'a, LL | | 'b: 'a, | |___________^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T> + = note: defining type: elements_outlive::<'?1, '?2, T> error: aborting due to 4 previous errors diff --git a/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index 47d4f2e46c6..25cc60d8141 100644 --- a/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -4,14 +4,14 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_late::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_late::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where '_#1r: '_#2r + = note: where '?1: '?2 note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:33:1 @@ -21,7 +21,7 @@ LL | | where LL | | T: Anything<'b>, | |____________________^ | - = note: defining type: no_relationships_late::<'_#1r, T> + = note: defining type: no_relationships_late::<'?1, T> error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:37:39 @@ -42,13 +42,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_early::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where '_#2r: '_#3r + = note: where '?2: '?3 note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:42:1 @@ -59,7 +59,7 @@ LL | | T: Anything<'b>, LL | | 'a: 'a, | |___________^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> + = note: defining type: no_relationships_early::<'?1, '?2, T> error: lifetime may not live long enough --> $DIR/projection-one-region-trait-bound-closure.rs:47:39 @@ -80,13 +80,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: projection_outlives::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where <T as Anything<'_#2r>>::AssocType: '_#3r + = note: where <T as Anything<'?2>>::AssocType: '?3 note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:52:1 @@ -97,7 +97,7 @@ LL | | T: Anything<'b>, LL | | T::AssocType: 'a, | |_____________________^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T> + = note: defining type: projection_outlives::<'?1, '?2, T> note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:69:29 @@ -105,13 +105,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: elements_outlive::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where '_#2r: '_#3r + = note: where '?2: '?3 note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:64:1 @@ -122,7 +122,7 @@ LL | | T: Anything<'b>, LL | | 'b: 'a, | |___________^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T> + = note: defining type: elements_outlive::<'?1, '?2, T> note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:81:29 @@ -130,13 +130,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: one_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: one_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] = note: number of external vids: 3 - = note: where '_#1r: '_#2r + = note: where '?1: '?2 note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:73:1 @@ -146,7 +146,7 @@ LL | | where LL | | T: Anything<'a>, | |____________________^ | - = note: defining type: one_region::<'_#1r, T> + = note: defining type: one_region::<'?1, T> error: aborting due to 2 previous errors diff --git a/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr index b27186b0537..5a092d7b849 100644 --- a/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr +++ b/tests/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr @@ -4,12 +4,12 @@ note: no external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_late::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_late::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:32:1 @@ -19,7 +19,7 @@ LL | | where LL | | T: Anything<'b>, | |____________________^ | - = note: defining type: no_relationships_late::<'_#1r, T> + = note: defining type: no_relationships_late::<'?1, T> note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:45:29 @@ -27,9 +27,9 @@ note: no external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_early::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] @@ -42,7 +42,7 @@ LL | | T: Anything<'b>, LL | | 'a: 'a, | |___________^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> + = note: defining type: no_relationships_early::<'?1, '?2, T> note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:64:29 @@ -50,9 +50,9 @@ note: no external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: projection_outlives::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] @@ -65,7 +65,7 @@ LL | | T: Anything<'b>, LL | | T::AssocType: 'a, | |_____________________^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, T> + = note: defining type: projection_outlives::<'?1, '?2, T> note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:73:29 @@ -73,9 +73,9 @@ note: no external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: elements_outlive::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] @@ -88,7 +88,7 @@ LL | | T: Anything<'b>, LL | | 'b: 'a, | |___________^ | - = note: defining type: elements_outlive::<'_#1r, '_#2r, T> + = note: defining type: elements_outlive::<'?1, '?2, T> note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:85:29 @@ -96,9 +96,9 @@ note: no external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: one_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: one_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] @@ -110,5 +110,5 @@ LL | | where LL | | T: Anything<'a>, | |____________________^ | - = note: defining type: one_region::<'_#1r, T> + = note: defining type: one_region::<'?1, T> diff --git a/tests/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/tests/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 530dd86819d..51283aa8828 100644 --- a/tests/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/tests/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -4,14 +4,14 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_late::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_late::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] - = note: late-bound region is '_#4r + = note: late-bound region is '?4 = note: number of external vids: 5 - = note: where <T as Anything<'_#1r, '_#2r>>::AssocType: '_#3r + = note: where <T as Anything<'?1, '?2>>::AssocType: '?3 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:34:1 @@ -21,16 +21,16 @@ LL | | where LL | | T: Anything<'b, 'c>, | |________________________^ | - = note: defining type: no_relationships_late::<'_#1r, '_#2r, T> + = note: defining type: no_relationships_late::<'?1, '?2, T> -error[E0309]: the associated type `<T as Anything<'_#5r, '_#6r>>::AssocType` may not live long enough +error[E0309]: the associated type `<T as Anything<'?5, '?6>>::AssocType` may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:38:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `<T as Anything<'_#5r, '_#6r>>::AssocType: 'a`... - = note: ...so that the type `<T as Anything<'_#5r, '_#6r>>::AssocType` will meet its required lifetime bounds + = help: consider adding an explicit lifetime bound `<T as Anything<'?5, '?6>>::AssocType: 'a`... + = note: ...so that the type `<T as Anything<'?5, '?6>>::AssocType` will meet its required lifetime bounds note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 @@ -38,13 +38,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T>::{closure#0} with closure substs [ + = note: defining type: no_relationships_early::<'?1, '?2, '?3, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?4 ()>, T)), (), ] = note: number of external vids: 5 - = note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r + = note: where <T as Anything<'?2, '?3>>::AssocType: '?4 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:43:1 @@ -55,16 +55,16 @@ LL | | T: Anything<'b, 'c>, LL | | 'a: 'a, | |___________^ | - = note: defining type: no_relationships_early::<'_#1r, '_#2r, '_#3r, T> + = note: defining type: no_relationships_early::<'?1, '?2, '?3, T> -error[E0309]: the associated type `<T as Anything<'_#6r, '_#7r>>::AssocType` may not live long enough +error[E0309]: the associated type `<T as Anything<'?6, '?7>>::AssocType` may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:48:39 | LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^ | - = help: consider adding an explicit lifetime bound `<T as Anything<'_#6r, '_#7r>>::AssocType: 'a`... - = note: ...so that the type `<T as Anything<'_#6r, '_#7r>>::AssocType` will meet its required lifetime bounds + = help: consider adding an explicit lifetime bound `<T as Anything<'?6, '?7>>::AssocType: 'a`... + = note: ...so that the type `<T as Anything<'?6, '?7>>::AssocType` will meet its required lifetime bounds note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:61:29 @@ -72,13 +72,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, '_#3r, T>::{closure#0} with closure substs [ + = note: defining type: projection_outlives::<'?1, '?2, '?3, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?4 ()>, T)), (), ] = note: number of external vids: 5 - = note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r + = note: where <T as Anything<'?2, '?3>>::AssocType: '?4 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:53:1 @@ -89,7 +89,7 @@ LL | | T: Anything<'b, 'c>, LL | | T::AssocType: 'a, | |_____________________^ | - = note: defining type: projection_outlives::<'_#1r, '_#2r, '_#3r, T> + = note: defining type: projection_outlives::<'?1, '?2, '?3, T> note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:70:29 @@ -97,13 +97,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: elements_outlive1::<'_#1r, '_#2r, '_#3r, T>::{closure#0} with closure substs [ + = note: defining type: elements_outlive1::<'?1, '?2, '?3, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?4 ()>, T)), (), ] = note: number of external vids: 5 - = note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r + = note: where <T as Anything<'?2, '?3>>::AssocType: '?4 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:65:1 @@ -114,7 +114,7 @@ LL | | T: Anything<'b, 'c>, LL | | 'b: 'a, | |___________^ | - = note: defining type: elements_outlive1::<'_#1r, '_#2r, '_#3r, T> + = note: defining type: elements_outlive1::<'?1, '?2, '?3, T> note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:79:29 @@ -122,13 +122,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: elements_outlive2::<'_#1r, '_#2r, '_#3r, T>::{closure#0} with closure substs [ + = note: defining type: elements_outlive2::<'?1, '?2, '?3, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#4r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?4 ()>, T)), (), ] = note: number of external vids: 5 - = note: where <T as Anything<'_#2r, '_#3r>>::AssocType: '_#4r + = note: where <T as Anything<'?2, '?3>>::AssocType: '?4 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:74:1 @@ -139,7 +139,7 @@ LL | | T: Anything<'b, 'c>, LL | | 'c: 'a, | |___________^ | - = note: defining type: elements_outlive2::<'_#1r, '_#2r, '_#3r, T> + = note: defining type: elements_outlive2::<'?1, '?2, '?3, T> note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 @@ -147,14 +147,14 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: two_regions::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: two_regions::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r + = note: where <T as Anything<'?1, '?1>>::AssocType: '?2 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:83:1 @@ -164,7 +164,7 @@ LL | | where LL | | T: Anything<'b, 'b>, | |________________________^ | - = note: defining type: two_regions::<'_#1r, T> + = note: defining type: two_regions::<'?1, T> error: lifetime may not live long enough --> $DIR/projection-two-region-trait-bound-closure.rs:87:5 @@ -178,7 +178,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` | = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of the type `Cell<&'_#8r ()>`, which makes the generic argument `&'_#8r ()` invariant + = note: requirement occurs because of the type `Cell<&'?8 ()>`, which makes the generic argument `&'?8 ()` invariant = note: the struct `Cell<T>` is invariant over the parameter `T` = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance @@ -188,13 +188,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: two_regions_outlive::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: two_regions_outlive::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where <T as Anything<'_#2r, '_#2r>>::AssocType: '_#3r + = note: where <T as Anything<'?2, '?2>>::AssocType: '?3 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:92:1 @@ -205,7 +205,7 @@ LL | | T: Anything<'b, 'b>, LL | | 'b: 'a, | |___________^ | - = note: defining type: two_regions_outlive::<'_#1r, '_#2r, T> + = note: defining type: two_regions_outlive::<'?1, '?2, T> note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 @@ -213,13 +213,13 @@ note: external requirements LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^ | - = note: defining type: one_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: one_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] = note: number of external vids: 3 - = note: where <T as Anything<'_#1r, '_#1r>>::AssocType: '_#2r + = note: where <T as Anything<'?1, '?1>>::AssocType: '?2 note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:101:1 @@ -229,7 +229,7 @@ LL | | where LL | | T: Anything<'a, 'a>, | |________________________^ | - = note: defining type: one_region::<'_#1r, T> + = note: defining type: one_region::<'?1, T> error: aborting due to 3 previous errors diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index 2c4a0597554..04616f9b702 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -6,11 +6,11 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic::<T>::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)), + for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)), (), ] = note: number of external vids: 2 - = note: where T: '_#1r + = note: where T: '?1 note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:22:1 @@ -28,12 +28,12 @@ LL | twice(cell, value, |a, b| invoke(a, b)); | = note: defining type: generic_fail::<T>::{closure#0} with closure substs [ i16, - for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'_#1r &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)), + for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)), (), ] - = note: late-bound region is '_#2r + = note: late-bound region is '?2 = note: number of external vids: 3 - = note: where T: '_#1r + = note: where T: '?1 note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:28:1 diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs index 4343c3aee53..72b18c16732 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs +++ b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.rs @@ -19,8 +19,8 @@ where // Here, the closure winds up being required to prove that `T: // 'a`. In principle, it could know that, except that it is // type-checked in a fully generic way, and hence it winds up with - // a propagated requirement that `T: '_#2`, where `'_#2` appears - // in the return type. The caller makes the mapping from `'_#2` to + // a propagated requirement that `T: '?2`, where `'?2` appears + // in the return type. The caller makes the mapping from `'?2` to // `'a` (and subsequently reports an error). with_signature(x, |y| y) diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 35979c8bf51..d580774ff8c 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -4,13 +4,13 @@ note: external requirements LL | with_signature(x, |y| y) | ^^^ | - = note: defining type: no_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: no_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '_#2r)>, + extern "rust-call" fn((std::boxed::Box<T>,)) -> std::boxed::Box<(dyn std::fmt::Debug + '?2)>, (), ] = note: number of external vids: 3 - = note: where T: '_#2r + = note: where T: '?2 note: no external requirements --> $DIR/ty-param-closure-outlives-from-return-type.rs:15:1 @@ -20,7 +20,7 @@ LL | | where LL | | T: Debug, | |_____________^ | - = note: defining type: no_region::<'_#1r, T> + = note: defining type: no_region::<'?1, T> error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:27 diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 4c97db58c6c..3d4c11a3c54 100644 --- a/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/tests/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -6,12 +6,12 @@ LL | with_signature(a, b, |x, y| { | = note: defining type: no_region::<T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#1r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?1 ()>, T)), (), ] - = note: late-bound region is '_#2r + = note: late-bound region is '?2 = note: number of external vids: 3 - = note: where T: '_#1r + = note: where T: '?1 note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:26:1 @@ -38,13 +38,13 @@ note: external requirements LL | with_signature(a, b, |x, y| { | ^^^^^^ | - = note: defining type: correct_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: correct_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] = note: number of external vids: 3 - = note: where T: '_#2r + = note: where T: '?2 note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:38:1 @@ -54,7 +54,7 @@ LL | | where LL | | T: 'a, | |__________^ | - = note: defining type: correct_region::<'_#1r, T> + = note: defining type: correct_region::<'?1, T> note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:63:26 @@ -62,14 +62,14 @@ note: external requirements LL | with_signature(a, b, |x, y| { | ^^^^^^ | - = note: defining type: wrong_region::<'_#1r, T>::{closure#0} with closure substs [ + = note: defining type: wrong_region::<'?1, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?2 ()>, T)), (), ] - = note: late-bound region is '_#3r + = note: late-bound region is '?3 = note: number of external vids: 4 - = note: where T: '_#2r + = note: where T: '?2 note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:59:1 @@ -79,7 +79,7 @@ LL | | where LL | | T: 'b, | |__________^ | - = note: defining type: wrong_region::<'_#1r, T> + = note: defining type: wrong_region::<'?1, T> error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-where-clause.rs:65:9 @@ -98,13 +98,13 @@ note: external requirements LL | with_signature(a, b, |x, y| { | ^^^^^^ | - = note: defining type: outlives_region::<'_#1r, '_#2r, T>::{closure#0} with closure substs [ + = note: defining type: outlives_region::<'?1, '?2, T>::{closure#0} with closure substs [ i32, - extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), + extern "rust-call" fn((std::cell::Cell<&'?3 ()>, T)), (), ] = note: number of external vids: 4 - = note: where T: '_#3r + = note: where T: '?3 note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:71:1 @@ -115,7 +115,7 @@ LL | | T: 'b, LL | | 'b: 'a, | |___________^ | - = note: defining type: outlives_region::<'_#1r, '_#2r, T> + = note: defining type: outlives_region::<'?1, '?2, T> error: aborting due to 2 previous errors diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.stderr b/tests/ui/nll/user-annotations/adt-brace-enums.stderr index 9e94fd5a782..900e7e25390 100644 --- a/tests/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-brace-enums.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.stderr b/tests/ui/nll/user-annotations/adt-brace-structs.stderr index cbb7f6a55a9..d61643dc6ed 100644 --- a/tests/ui/nll/user-annotations/adt-brace-structs.stderr +++ b/tests/ui/nll/user-annotations/adt-brace-structs.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr index bca85a90d19..5b385feeedc 100644 --- a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr @@ -34,7 +34,10 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here +LL | combine( LL | SomeEnum::SomeVariant(Cell::new(&c)), | ----------^^- | | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr index d2d85ec2b9b..766da9ec00c 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr index b7bc2a10b70..2084697e7e2 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr @@ -33,7 +33,10 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here +LL | let f = SomeStruct::<&'a u32>; LL | f(&c); | --^^- | | | @@ -47,7 +50,9 @@ error[E0597]: `c` does not live long enough | LL | let f = SomeStruct::<&'a u32>; | - lifetime `'1` appears in the type of `f` -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | f(&c); | --^^- | | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr index 97d39da265f..c7480f52963 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeStruct::<&'a u32>(&c); | ^^ | | diff --git a/tests/ui/nll/user-annotations/fns.stderr b/tests/ui/nll/user-annotations/fns.stderr index 8b53e138d9b..abaa35e9516 100644 --- a/tests/ui/nll/user-annotations/fns.stderr +++ b/tests/ui/nll/user-annotations/fns.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | some_fn::<&'a u32>(&c); | -------------------^^- | | | diff --git a/tests/ui/nll/user-annotations/method-call.stderr b/tests/ui/nll/user-annotations/method-call.stderr index 3803cbf776b..b4d1ac042a2 100644 --- a/tests/ui/nll/user-annotations/method-call.stderr +++ b/tests/ui/nll/user-annotations/method-call.stderr @@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here ... +LL | let c = 66; + | - binding `c` declared here LL | a.method::<&'a u32>(b, &c); | ------------------------^^- | | | diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-3.stderr index 8cb995a03ce..4dd39e10827 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-3.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-3.stderr @@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here ... +LL | let c = 66; + | - binding `c` declared here LL | <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); | -------------------------------------------^^- | | | diff --git a/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs new file mode 100644 index 00000000000..565b7e86fc4 --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to negate with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +#![allow(arithmetic_overflow)] + +use std::num::NonZeroI8; + +fn main() { + let _x = -NonZeroI8::new(i8::MIN).unwrap(); +} diff --git a/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs b/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs index 4c6929d6627..088b2fcdd14 100644 --- a/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs +++ b/tests/ui/numbers-arithmetic/saturating-float-casts-impl.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction. // diff --git a/tests/ui/object-safety/assoc_const_bounds.rs b/tests/ui/object-safety/assoc_const_bounds.rs new file mode 100644 index 00000000000..94b1f63165b --- /dev/null +++ b/tests/ui/object-safety/assoc_const_bounds.rs @@ -0,0 +1,13 @@ +trait Foo<T> { + const BAR: bool + where //~ ERROR: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found keyword `where` + Self: Sized; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} +fn bar(_: &dyn Foo<i32>) {} + +fn main() {} diff --git a/tests/ui/object-safety/assoc_const_bounds.stderr b/tests/ui/object-safety/assoc_const_bounds.stderr new file mode 100644 index 00000000000..09bc11e178a --- /dev/null +++ b/tests/ui/object-safety/assoc_const_bounds.stderr @@ -0,0 +1,15 @@ +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found keyword `where` + --> $DIR/assoc_const_bounds.rs:3:9 + | +LL | trait Foo<T> { + | - while parsing this item list starting here +LL | const BAR: bool + | - expected one of 7 possible tokens +LL | where + | ^^^^^ unexpected token +LL | Self: Sized; +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/tests/ui/object-safety/assoc_const_bounds_sized.rs b/tests/ui/object-safety/assoc_const_bounds_sized.rs new file mode 100644 index 00000000000..2a76e5dce2b --- /dev/null +++ b/tests/ui/object-safety/assoc_const_bounds_sized.rs @@ -0,0 +1,9 @@ +trait Foo { + const BAR: bool + where //~ ERROR: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found keyword `where` + Self: Sized; +} + +fn foo(_: &dyn Foo) {} + +fn main() {} diff --git a/tests/ui/object-safety/assoc_const_bounds_sized.stderr b/tests/ui/object-safety/assoc_const_bounds_sized.stderr new file mode 100644 index 00000000000..e1f57f67795 --- /dev/null +++ b/tests/ui/object-safety/assoc_const_bounds_sized.stderr @@ -0,0 +1,15 @@ +error: expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `=`, found keyword `where` + --> $DIR/assoc_const_bounds_sized.rs:3:9 + | +LL | trait Foo { + | - while parsing this item list starting here +LL | const BAR: bool + | - expected one of 7 possible tokens +LL | where + | ^^^^^ unexpected token +LL | Self: Sized; +LL | } + | - the item list ends here + +error: aborting due to previous error + diff --git a/tests/ui/object-safety/assoc_type_bounds.rs b/tests/ui/object-safety/assoc_type_bounds.rs new file mode 100644 index 00000000000..9abf7939c43 --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds.rs @@ -0,0 +1,13 @@ +trait Foo<T> { + type Bar + where + T: Cake; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified +fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified + +fn main() {} diff --git a/tests/ui/object-safety/assoc_type_bounds.stderr b/tests/ui/object-safety/assoc_type_bounds.stderr new file mode 100644 index 00000000000..a1396dc3ad4 --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds.stderr @@ -0,0 +1,21 @@ +error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified + --> $DIR/assoc_type_bounds.rs:10:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn foo(_: &dyn Foo<()>) {} + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + +error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified + --> $DIR/assoc_type_bounds.rs:11:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn bar(_: &dyn Foo<i32>) {} + | ^^^^^^^^ help: specify the associated type: `Foo<i32, Bar = Type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/object-safety/assoc_type_bounds2.rs b/tests/ui/object-safety/assoc_type_bounds2.rs new file mode 100644 index 00000000000..0112123fd42 --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds2.rs @@ -0,0 +1,13 @@ +trait Foo<T> { + type Bar + where + Self: Foo<()>; +} + +trait Cake {} +impl Cake for () {} + +fn foo(_: &dyn Foo<()>) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified +fn bar(_: &dyn Foo<i32>) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified + +fn main() {} diff --git a/tests/ui/object-safety/assoc_type_bounds2.stderr b/tests/ui/object-safety/assoc_type_bounds2.stderr new file mode 100644 index 00000000000..7a3c0e02d48 --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds2.stderr @@ -0,0 +1,21 @@ +error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified + --> $DIR/assoc_type_bounds2.rs:10:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn foo(_: &dyn Foo<()>) {} + | ^^^^^^^ help: specify the associated type: `Foo<(), Bar = Type>` + +error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified + --> $DIR/assoc_type_bounds2.rs:11:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn bar(_: &dyn Foo<i32>) {} + | ^^^^^^^^ help: specify the associated type: `Foo<i32, Bar = Type>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/object-safety/assoc_type_bounds_sized.rs b/tests/ui/object-safety/assoc_type_bounds_sized.rs new file mode 100644 index 00000000000..61ad3cf9dc6 --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds_sized.rs @@ -0,0 +1,9 @@ +trait Foo { + type Bar + where + Self: Sized; +} + +fn foo(_: &dyn Foo) {} //~ ERROR: the value of the associated type `Bar` (from trait `Foo`) must be specified + +fn main() {} diff --git a/tests/ui/object-safety/assoc_type_bounds_sized.stderr b/tests/ui/object-safety/assoc_type_bounds_sized.stderr new file mode 100644 index 00000000000..49d624f9b1d --- /dev/null +++ b/tests/ui/object-safety/assoc_type_bounds_sized.stderr @@ -0,0 +1,12 @@ +error[E0191]: the value of the associated type `Bar` (from trait `Foo`) must be specified + --> $DIR/assoc_type_bounds_sized.rs:7:16 + | +LL | type Bar + | -------- `Bar` defined here +... +LL | fn foo(_: &dyn Foo) {} + | ^^^ help: specify the associated type: `Foo<Bar = Type>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0191`. diff --git a/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs new file mode 100644 index 00000000000..088086cc580 --- /dev/null +++ b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs @@ -0,0 +1,33 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.0")] + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct Unstable { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct Stable { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableField { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableFieldType { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: Unstable, +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableWithStableFieldType { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: Stable, +} diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs new file mode 100644 index 00000000000..163b07454ec --- /dev/null +++ b/tests/ui/offset-of/offset-of-arg-count.rs @@ -0,0 +1,9 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +fn main() { + offset_of!(NotEnoughArguments); //~ ERROR expected one of + offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments + offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments +} diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr new file mode 100644 index 00000000000..ebecc982c51 --- /dev/null +++ b/tests/ui/offset-of/offset-of-arg-count.stderr @@ -0,0 +1,20 @@ +error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>` + --> $DIR/offset-of-arg-count.rs:6:16 + | +LL | offset_of!(NotEnoughArguments); + | ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<` + +error: expected 2 arguments + --> $DIR/offset-of-arg-count.rs:7:5 + | +LL | offset_of!(NotEnoughArgumentsWithAComma, ); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected 2 arguments + --> $DIR/offset-of-arg-count.rs:8:5 + | +LL | offset_of!(Container, field, too many arguments); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs new file mode 100644 index 00000000000..a0269ca2d12 --- /dev/null +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -0,0 +1,33 @@ +#![feature(offset_of, extern_types)] + +use std::mem::offset_of; + +struct Alpha { + x: u8, + y: u16, + z: [u8], +} + +trait Trait {} + +struct Beta { + x: u8, + y: u16, + z: dyn Trait, +} + +extern { + type Extern; +} + +struct Gamma { + x: u8, + y: u16, + z: Extern, +} + +fn main() { + offset_of!(Alpha, z); //~ ERROR the size for values of type + offset_of!(Beta, z); //~ ERROR the size for values of type + offset_of!(Gamma, z); //~ ERROR the size for values of type +} diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr new file mode 100644 index 00000000000..8e88015b07a --- /dev/null +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -0,0 +1,27 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:30:5 + | +LL | offset_of!(Alpha, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:31:5 + | +LL | offset_of!(Beta, z); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` + +error[E0277]: the size for values of type `Extern` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:32:5 + | +LL | offset_of!(Gamma, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `Extern` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs new file mode 100644 index 00000000000..d73505821ff --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -0,0 +1,13 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +enum Alpha { + One(u8), + Two(u8), +} + +fn main() { + offset_of!(Alpha::One, 0); //~ ERROR expected type, found variant `Alpha::One` + offset_of!(Alpha, Two.0); //~ ERROR no field `Two` on type `Alpha` +} diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr new file mode 100644 index 00000000000..6958d199fbd --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -0,0 +1,19 @@ +error[E0573]: expected type, found variant `Alpha::One` + --> $DIR/offset-of-enum.rs:11:16 + | +LL | offset_of!(Alpha::One, 0); + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Alpha` + +error[E0609]: no field `Two` on type `Alpha` + --> $DIR/offset-of-enum.rs:12:23 + | +LL | offset_of!(Alpha, Two.0); + | ^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0573, E0609. +For more information about an error, try `rustc --explain E0573`. diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs new file mode 100644 index 00000000000..0291b7825ca --- /dev/null +++ b/tests/ui/offset-of/offset-of-private.rs @@ -0,0 +1,16 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +mod m { + #[repr(C)] + pub struct Foo { + pub public: u8, + private: u8, + } +} + +fn main() { + offset_of!(m::Foo, public); + offset_of!(m::Foo, private); //~ ERROR field `private` of struct `Foo` is private +} diff --git a/tests/ui/offset-of/offset-of-private.stderr b/tests/ui/offset-of/offset-of-private.stderr new file mode 100644 index 00000000000..8a186dd5a02 --- /dev/null +++ b/tests/ui/offset-of/offset-of-private.stderr @@ -0,0 +1,9 @@ +error[E0616]: field `private` of struct `Foo` is private + --> $DIR/offset-of-private.rs:15:24 + | +LL | offset_of!(m::Foo, private); + | ^^^^^^^ private field + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0616`. diff --git a/tests/ui/offset-of/offset-of-unstable-with-feature.rs b/tests/ui/offset-of/offset-of-unstable-with-feature.rs new file mode 100644 index 00000000000..7d2eb46c056 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable-with-feature.rs @@ -0,0 +1,20 @@ +// check-pass +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of, unstable_test_feature)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!(Unstable, unstable); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); + offset_of!(UnstableWithStableFieldType, unstable); + offset_of!(UnstableWithStableFieldType, unstable.stable); +} diff --git a/tests/ui/offset-of/offset-of-unstable.rs b/tests/ui/offset-of/offset-of-unstable.rs new file mode 100644 index 00000000000..1e19f2091f2 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.rs @@ -0,0 +1,31 @@ +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!( + //~^ ERROR use of unstable library feature + Unstable, //~ ERROR use of unstable library feature + unstable + ); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); //~ ERROR use of unstable library feature + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); //~ ERROR use of unstable library feature + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable + ); + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable.stable + ); +} diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr new file mode 100644 index 00000000000..25811a061d7 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.stderr @@ -0,0 +1,79 @@ +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:14:9 + | +LL | Unstable, + | ^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:23:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:28:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:12:5 + | +LL | / offset_of!( +LL | | +LL | | Unstable, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:18:5 + | +LL | offset_of!(StableWithUnstableField, unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:20:5 + | +LL | offset_of!(StableWithUnstableFieldType, stable.unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:21:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:26:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable.stable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs index 39ffe86dd49..be83eb74843 100644 --- a/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs +++ b/tests/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -1,6 +1,6 @@ // This test has been spuriously failing a lot recently (#92000). // Ignore it until the underlying issue is fixed. -// ignore-test +// ignore-test (#92000) // Regression test for #87481: short backtrace formatting cut off the entire stack trace. diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 9305facc406..3ce48b1a72f 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -54,14 +54,6 @@ LL | ref mut a @ box ref b => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:54:11 - | -LL | fn f5(ref mut a @ box ref b: Box<NC>) { - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - error[E0382]: borrow of moved value --> $DIR/borrowck-pat-at-and-box.rs:31:9 | @@ -120,6 +112,14 @@ LL | ref mut a @ box ref b => { LL | drop(b); | - immutable borrow later used here +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:54:11 + | +LL | fn f5(ref mut a @ box ref b: Box<NC>) { + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:54:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index 13989ebadcb..1ed019f0a69 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -286,78 +286,6 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref mut a @ Some([ref b, ref mut c]) => {} | +++ -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 - | -LL | fn f1(a @ ref b: U) {} - | ^ ----- value borrowed here after move - | | - | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f1(ref a @ ref b: U) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^ ----- value borrowed here after move - | | - | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- value borrowed here after move - | | - | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 - | -LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} - | ^ --------- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} - | +++ - error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9 | @@ -447,6 +375,63 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | value moved here +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 + | +LL | fn f1(a @ ref b: U) {} + | ^ ----- value borrowed here after move + | | + | value moved into `a` here + | move occurs because `a` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f1(ref a @ ref b: U) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^ ----- value borrowed here after move + | | + | value moved into `b` here + | move occurs because `b` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- value borrowed here after move + | | + | value moved into `d` here + | move occurs because `d` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} + | +++ + error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 | @@ -457,6 +442,21 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | ^ --------- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} + | +++ + error: aborting due to 33 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 00593b2a98f..c8c4d9b8fdb 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -166,48 +166,6 @@ LL | ref mut a @ Some([b, mut c]) => {} | | value is moved into `b` here | value is mutably borrowed by `a` here -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 - | -LL | fn f1(ref a @ b: U) {} - | ^^^^^ - value is moved into `b` here - | | - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- - value is moved into `e` here - | | | - | | value is moved into `c` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- value is moved into `c` here - | | - | value is borrowed by `b` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ - value is moved into `e` here - | | - | value is borrowed by `d` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 - | -LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} - | ^^^^^^^^^ - ----- value is moved into `c` here - | | | - | | value is moved into `b` here - | value is mutably borrowed by `a` here - error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9 | @@ -306,6 +264,14 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {} | +++ +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 + | +LL | fn f1(ref a @ b: U) {} + | ^^^^^ - value is moved into `b` here + | | + | value is borrowed by `a` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 | @@ -315,6 +281,31 @@ LL | fn f1(ref a @ b: U) {} | value borrowed here after move | move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- - value is moved into `e` here + | | | + | | value is moved into `c` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- value is moved into `c` here + | | + | value is borrowed by `b` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ - value is moved into `e` here + | | + | value is borrowed by `d` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 | @@ -335,6 +326,15 @@ LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | = note: move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 + | +LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + | ^^^^^^^^^ - ----- value is moved into `c` here + | | | + | | value is moved into `b` here + | value is mutably borrowed by `a` here + error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index d6409d1b643..c0a6558a1bf 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -221,47 +221,6 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | | value is borrowed by `b` here | value is mutably borrowed by `a` here -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 - | -LL | fn f1(ref a @ ref mut b: U) {} - | ^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 - | -LL | fn f2(ref mut a @ ref b: U) {} - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 - | -LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - | ^^^^^ ----------- value is mutably borrowed by `mid` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31 | @@ -398,6 +357,47 @@ LL | LL | *b = U; | ------ mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 + | +LL | fn f1(ref a @ ref mut b: U) {} + | ^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 + | +LL | fn f2(ref mut a @ ref b: U) {} + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 + | +LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} + | ^^^^^ ----------- value is mutably borrowed by `mid` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 24189d0615c..c634ea470c5 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -194,50 +194,6 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 - | -LL | fn f1(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 - | -LL | fn f2(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 - | -LL | ref mut a @ [ - | ^^^^^^^^^ value is mutably borrowed by `a` here -LL | -LL | [ref b @ .., _], - | ----- value is borrowed by `b` here -LL | [_, ref mut mid @ ..], - | ----------- value is mutably borrowed by `mid` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is mutably borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | @@ -304,6 +260,50 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 + | +LL | fn f1(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 + | +LL | fn f2(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 + | +LL | ref mut a @ [ + | ^^^^^^^^^ value is mutably borrowed by `a` here +LL | +LL | [ref b @ .., _], + | ----- value is borrowed by `b` here +LL | [_, ref mut mid @ ..], + | ----------- value is mutably borrowed by `mid` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is mutably borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 | diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr index 84888f6fb2f..32d49d25f02 100644 --- a/tests/ui/polymorphization/generators.stderr +++ b/tests/ui/polymorphization/generators.stderr @@ -15,12 +15,6 @@ LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + LL | || { | ^^ -note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 35:7], u32, u32>` - --> $DIR/generators.rs:86:5 - | -LL | finish(unused_type::<u32>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: item has unused generic parameters --> $DIR/generators.rs:60:5 | @@ -29,11 +23,5 @@ LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Retu LL | || { | ^^ -note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 60:7], u32, u32>` - --> $DIR/generators.rs:89:5 - | -LL | finish(unused_const::<1u32>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/polymorphization/predicates.stderr b/tests/ui/polymorphization/predicates.stderr index 80bb2af25cc..a3b2f75b12d 100644 --- a/tests/ui/polymorphization/predicates.stderr +++ b/tests/ui/polymorphization/predicates.stderr @@ -1,4 +1,10 @@ error: item has unused generic parameters + --> $DIR/predicates.rs:10:4 + | +LL | fn bar<I>() { + | ^^^ - generic parameter `I` is unused + +error: item has unused generic parameters --> $DIR/predicates.rs:15:4 | LL | fn foo<I, T>(_: I) @@ -35,17 +41,5 @@ error: item has unused generic parameters LL | fn foobar<F, G>() -> usize | ^^^^^^ - generic parameter `F` is unused -error: item has unused generic parameters - --> $DIR/predicates.rs:10:4 - | -LL | fn bar<I>() { - | ^^^ - generic parameter `I` is unused - -note: the above error was encountered while instantiating `fn foo::<std::slice::Iter<'_, u32>, T>` - --> $DIR/predicates.rs:86:5 - | -LL | foo(x.iter()); - | ^^^^^^^^^^^^^ - error: aborting due to 6 previous errors diff --git a/tests/ui/polymorphization/type_parameters/closures.stderr b/tests/ui/polymorphization/type_parameters/closures.stderr index 94a4a08bd2f..5c3b46c6041 100644 --- a/tests/ui/polymorphization/type_parameters/closures.stderr +++ b/tests/ui/polymorphization/type_parameters/closures.stderr @@ -44,21 +44,6 @@ LL | pub fn unused_all<G: Default>() -> u32 { | ^^^^^^^^^^ - generic parameter `G` is unused error: item has unused generic parameters - --> $DIR/closures.rs:128:23 - | -LL | pub fn used_impl<G: Default>() -> u32 { - | - generic parameter `G` is unused -LL | -LL | let add_one = |x: u32| { - | ^^^^^^^^ - -error: item has unused generic parameters - --> $DIR/closures.rs:126:12 - | -LL | pub fn used_impl<G: Default>() -> u32 { - | ^^^^^^^^^ - generic parameter `G` is unused - -error: item has unused generic parameters --> $DIR/closures.rs:115:23 | LL | impl<F: Default> Foo<F> { @@ -76,5 +61,20 @@ LL | impl<F: Default> Foo<F> { LL | pub fn used_fn<G: Default>() -> u32 { | ^^^^^^^ +error: item has unused generic parameters + --> $DIR/closures.rs:128:23 + | +LL | pub fn used_impl<G: Default>() -> u32 { + | - generic parameter `G` is unused +LL | +LL | let add_one = |x: u32| { + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:126:12 + | +LL | pub fn used_impl<G: Default>() -> u32 { + | ^^^^^^^^^ - generic parameter `G` is unused + error: aborting due to 9 previous errors diff --git a/tests/ui/privacy/privacy2.stderr b/tests/ui/privacy/privacy2.stderr index 882f314655d..c2a33ce1f59 100644 --- a/tests/ui/privacy/privacy2.stderr +++ b/tests/ui/privacy/privacy2.stderr @@ -23,13 +23,7 @@ LL | pub fn foo() {} error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0432, E0603. For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/privacy/privacy3.stderr b/tests/ui/privacy/privacy3.stderr index 42ce456d962..22c1e48b07d 100644 --- a/tests/ui/privacy/privacy3.stderr +++ b/tests/ui/privacy/privacy3.stderr @@ -6,12 +6,6 @@ LL | use bar::gpriv; error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/proc-macro/module.rs b/tests/ui/proc-macro/module.rs index 5777ed89983..a750083c607 100644 --- a/tests/ui/proc-macro/module.rs +++ b/tests/ui/proc-macro/module.rs @@ -1 +1 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) diff --git a/tests/ui/proc-macro/module_with_attrs.rs b/tests/ui/proc-macro/module_with_attrs.rs index 63e66a62ac3..0b2604f95b6 100644 --- a/tests/ui/proc-macro/module_with_attrs.rs +++ b/tests/ui/proc-macro/module_with_attrs.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) #![rustfmt::skip] #![print_attr] diff --git a/tests/ui/proc-macro/outer/inner.rs b/tests/ui/proc-macro/outer/inner.rs index 5777ed89983..a750083c607 100644 --- a/tests/ui/proc-macro/outer/inner.rs +++ b/tests/ui/proc-macro/outer/inner.rs @@ -1 +1 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) diff --git a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs index 9501980fa55..889f399a7f2 100644 --- a/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs +++ b/tests/ui/proc-macro/pretty-print-hack/allsorts-rental-0.5.6/src/lib.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) #[derive(Print)] enum ProceduralMasqueradeDummyType { diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs index 9501980fa55..889f399a7f2 100644 --- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs +++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.5/src/lib.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) #[derive(Print)] enum ProceduralMasqueradeDummyType { diff --git a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs index 9501980fa55..889f399a7f2 100644 --- a/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs +++ b/tests/ui/proc-macro/pretty-print-hack/rental-0.5.6/src/lib.rs @@ -1,4 +1,4 @@ -// ignore-test +// ignore-test (auxiliary, used by other tests) #[derive(Print)] enum ProceduralMasqueradeDummyType { diff --git a/tests/ui/proc-macro/test-same-crate.rs b/tests/ui/proc-macro/test-same-crate.rs new file mode 100644 index 00000000000..c13f384fa3a --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.rs @@ -0,0 +1,16 @@ +// compile-flags: --test +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn mac(input: TokenStream) -> TokenStream { loop {} } + +#[cfg(test)] +mod test { + #[test] + fn t() { crate::mac!(A) } + //~^ ERROR can't use a procedural macro from the same crate that defines it + //~| HELP you can define integration tests in a directory named `tests` +} diff --git a/tests/ui/proc-macro/test-same-crate.stderr b/tests/ui/proc-macro/test-same-crate.stderr new file mode 100644 index 00000000000..5d12e149c3c --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.stderr @@ -0,0 +1,10 @@ +error: can't use a procedural macro from the same crate that defines it + --> $DIR/test-same-crate.rs:13:14 + | +LL | fn t() { crate::mac!(A) } + | ^^^^^^^^^^ + | + = help: you can define integration tests in a directory named `tests` + +error: aborting due to previous error + diff --git a/tests/ui/process/process-sigpipe.rs b/tests/ui/process/process-sigpipe.rs index 7ae14c6b84d..4f4db119115 100644 --- a/tests/ui/process/process-sigpipe.rs +++ b/tests/ui/process/process-sigpipe.rs @@ -8,14 +8,14 @@ // libstd ignores SIGPIPE, and other libraries may set signal masks. // Make sure that these behaviors don't get inherited to children // spawned via std::process, since they're needed for traditional UNIX -// filter behavior. This test checks that `yes | head` terminates +// filter behavior. +// This test checks that `while echo y ; do : ; done | head` terminates // (instead of running forever), and that it does not print an error // message about a broken pipe. // ignore-emscripten no threads support // ignore-vxworks no 'sh' // ignore-fuchsia no 'sh' -// ignore-nto no 'yes' use std::process; use std::thread; @@ -27,7 +27,11 @@ fn main() { thread::sleep_ms(5000); process::exit(1); }); - let output = process::Command::new("sh").arg("-c").arg("yes | head").output().unwrap(); + let output = process::Command::new("sh") + .arg("-c") + .arg("while echo y ; do : ; done | head") + .output() + .unwrap(); assert!(output.status.success()); assert!(output.stderr.len() == 0); } diff --git a/tests/ui/repr/repr-transparent.stderr b/tests/ui/repr/repr-transparent.stderr index f1c570b9523..cb1e2337776 100644 --- a/tests/ui/repr/repr-transparent.stderr +++ b/tests/ui/repr/repr-transparent.stderr @@ -58,7 +58,7 @@ error[E0731]: transparent enum needs exactly one variant, but has 2 LL | enum MultipleVariants { | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2 LL | Foo(String), - | --- + | --- variant here LL | Bar, | --- too many variants in `MultipleVariants` diff --git a/tests/ui/repr/transparent-enum-too-many-variants.stderr b/tests/ui/repr/transparent-enum-too-many-variants.stderr index fb44757efaf..1a500257f48 100644 --- a/tests/ui/repr/transparent-enum-too-many-variants.stderr +++ b/tests/ui/repr/transparent-enum-too-many-variants.stderr @@ -5,6 +5,8 @@ LL | enum Foo { | ^^^^^^^^ needs exactly one variant, but has 2 LL | A(u8), B(u8), | - - too many variants in `Foo` + | | + | variant here error: aborting due to previous error diff --git a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr index 6d18d295cfc..16e1af46059 100644 --- a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -10,6 +10,12 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:41: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:30:23 | @@ -22,12 +28,6 @@ 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:41: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:48:27 | diff --git a/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs index 7d9dae52cf1..96790a87311 100644 --- a/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] struct NonConstAdd(i32); @@ -17,7 +19,6 @@ trait Foo { impl const Foo for NonConstAdd { type Bar = NonConstAdd; - //~^ ERROR: cannot add `NonConstAdd` to `NonConstAdd` in const contexts } #[const_trait] diff --git a/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr index 89177b0f1ac..0cffae1da8d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr @@ -1,21 +1,8 @@ -error[E0277]: cannot add `NonConstAdd` to `NonConstAdd` in const contexts - --> $DIR/assoc-type.rs:19:16 - | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd` - | - = help: the trait `~const Add` is not implemented for `NonConstAdd` -note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const` - --> $DIR/assoc-type.rs:19:16 - | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ -note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:15:15 +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/assoc-type.rs:17:22 | LL | type Bar: ~const std::ops::Add; - | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar` + | ^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs index b64161b6aa0..ae0c2e6bcfa 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr new file mode 100644 index 00000000000..ff53eea1110 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:7:12 + | +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:15:12 + | +LL | impl const PartialEq for Int { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs index 50c46579086..5120e6bfb41 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] #[const_trait] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr new file mode 100644 index 00000000000..02d53cc78ee --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-in-impl.rs:9:16 + | +LL | impl<T: ~const PartialEq> const MyPartialEq for T { + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs index b00ff1f2fac..3febb328a83 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs @@ -1,6 +1,6 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr new file mode 100644 index 00000000000..529a472e0bd --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -0,0 +1,23 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-chain.rs:9:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:18:32 + | +LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:22:40 + | +LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs index c8ded0fa7ea..e618160d3b6 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr new file mode 100644 index 00000000000..bdc6ccc8aec --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -0,0 +1,23 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-dup-bound.rs:7:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:18:44 + | +LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:25:37 + | +LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs index 2bc5ee512c5..fe1abbf4207 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -1,8 +1,9 @@ +// known-bug: #110395 #![feature(const_trait_impl)] pub const fn equals_self<T: PartialEq>(t: &T) -> bool { *t == *t - //~^ ERROR can't compare + // (remove this) ~^ ERROR can't compare } fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr index 31e6dbdab22..3963f64ad32 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr @@ -1,15 +1,28 @@ -error[E0277]: can't compare `T` with `_` in const contexts - --> $DIR/call-generic-method-fail.rs:4:8 +error[E0277]: can't compare `T` with `T` in const contexts + --> $DIR/call-generic-method-fail.rs:5:5 | LL | *t == *t - | ^^ no implementation for `T == _` + | ^^^^^^^^ no implementation for `T == T` | -note: the trait `PartialEq<_>` is implemented for `T`, but that implementation is not `const` - --> $DIR/call-generic-method-fail.rs:4:8 +note: the trait `PartialEq` is implemented for `T`, but that implementation is not `const` + --> $DIR/call-generic-method-fail.rs:5:5 | LL | *t == *t - | ^^ + | ^^^^^^^^ -error: aborting due to previous error +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/call-generic-method-fail.rs:5:5 + | +LL | *t == *t + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider further restricting this bound + | +LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool { + | ++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs index 40565d1b76a..09f35a27737 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs @@ -1,6 +1,6 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr new file mode 100644 index 00000000000..7fbe89dba3c --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -0,0 +1,17 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-pass.rs:9:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-pass.rs:18:32 + | +LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs index f66d63da693..9ba19e800dd 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -1,9 +1,10 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] pub struct Int(i32); impl const std::ops::Add for i32 { - //~^ ERROR only traits defined in the current crate can be implemented for primitive types type Output = Self; fn add(self, rhs: Self) -> Self { @@ -20,7 +21,6 @@ impl std::ops::Add for Int { } impl const std::ops::Add for Int { - //~^ ERROR conflicting implementations of trait type Output = Self; fn add(self, rhs: Self) -> Self { diff --git a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 36a09add4d3..4f858d61eeb 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,25 +1,20 @@ -error[E0117]: only traits defined in the current crate can be implemented for primitive types - --> $DIR/const-and-non-const-impl.rs:5:1 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:7:12 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^-------------^^^^^--- - | | | | - | | | `i32` is not defined in the current crate - | | `i32` is not defined in the current crate - | impl doesn't use only types from inside the current crate + | ^^^^^^^^^^^^^ | - = note: define and implement a trait or new type instead + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0119]: conflicting implementations of trait `Add` for type `Int` - --> $DIR/const-and-non-const-impl.rs:22:1 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:23:12 | -LL | impl std::ops::Add for Int { - | -------------------------- first implementation here -... LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 2 previous errors -Some errors have detailed explanations: E0117, E0119. -For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs index b5f19e40c03..b4cc7a9e17e 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] #[const_trait] @@ -14,6 +16,5 @@ const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 { } const _: () = assert!(need_const_closure(Tr::a) == 42); -//~^ ERROR: the trait bound fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index ffc24ec6e92..112416a3543 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied in `fn(()) -> i32 {<() as Tr>::a}` - --> $DIR/const-closure-trait-method-fail.rs:16:23 + --> $DIR/const-closure-trait-method-fail.rs:18:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/const-closure-trait-method-fail.rs:16:23 + --> $DIR/const-closure-trait-method-fail.rs:18:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closures.rs b/tests/ui/rfc-2632-const-trait-impl/const-closures.rs index 755d8539839..7c55b51c8f5 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closures.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-closures.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr index bcdc80f82f8..13350a6d14a 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr @@ -1,50 +1,26 @@ -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:23:25 | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { + | ^^^^ | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:29:26 | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +LL | const fn check<T: ~const Destruct>(_: T) {} + | ^^^^^^^^ -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:39:9 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:39:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:37:1 + | ^^^^ | -LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 6a252c5d37b..3de9d37d493 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,4 +1,4 @@ -// revisions: stock precise +// known-bug: #110395 #![feature(const_trait_impl)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] @@ -29,15 +29,12 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { const fn check<T: ~const Destruct>(_: T) {} const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - //~^ ERROR the trait bound ConstDropImplWithBounds(PhantomData) - //~^ ERROR the trait bound ); struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { -//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not fn drop(&mut self) { T::a(); } diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr new file mode 100644 index 00000000000..375f5d2c52d --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -0,0 +1,50 @@ +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:32:5 + | +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:32:5 + | +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not + --> $DIR/const-drop-fail-2.rs:37:9 + | +LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { + | ^^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail-2.rs:35:1 + | +LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr index bcdc80f82f8..13350a6d14a 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr @@ -1,50 +1,26 @@ -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:23:25 | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { + | ^^^^ | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:29:26 | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +LL | const fn check<T: ~const Destruct>(_: T) {} + | ^^^^^^^^ -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:39:9 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:39:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:37:1 + | ^^^^ | -LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 40caada51d7..e745cbd2442 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -11,7 +11,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | | } = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -36,7 +36,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:16:8 + --> $DIR/const-drop-fail.rs:18:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index c4bdb9ef5e5..1c37648ff1c 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + // revisions: stock precise #![feature(const_trait_impl)] #![feature(const_mut_refs)] @@ -24,8 +26,6 @@ const fn check<T: ~const Destruct>(_: T) {} macro_rules! check_all { ($($exp:expr),*$(,)?) => {$( const _: () = check($exp); - //~^ ERROR can't drop - //~| ERROR can't drop )*}; } diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 40caada51d7..e745cbd2442 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -11,7 +11,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | | } = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -36,7 +36,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:16:8 + --> $DIR/const-drop-fail.rs:18:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs index 0622f96e70d..f396deff4fe 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![allow(incomplete_features)] #![feature( associated_type_bounds, diff --git a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr new file mode 100644 index 00000000000..f9078e22791 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -0,0 +1,39 @@ +error[E0635]: unknown feature `const_cmp` + --> $DIR/const-impl-trait.rs:6:5 + | +LL | const_cmp, + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:12:30 + | +LL | const fn cmp(a: &impl ~const PartialEq) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:16:30 + | +LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:20 + | +LL | -> impl ~const PartialEq + ~const Destruct + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:24:29 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:28:29 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs index 348ca0ab190..dba3ad7f870 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -1,4 +1,5 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature +//~^ ERROR not marked with `#[const_trait]` pub struct S; fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index cc9bdd2715f..6a81f96d88d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -6,6 +6,16 @@ LL | #[derive_const(Default)] | = help: add `#![feature(derive_const)]` to the crate attributes to enable -error: aborting due to previous error +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-gate.rs:1:16 + | +LL | #[derive_const(Default)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (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 E0658`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs index ed6699f3724..b575ea8dae2 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -1,3 +1,4 @@ +// known-bug: #110395 #![feature(derive_const)] pub struct A; @@ -8,7 +9,5 @@ impl Default for A { #[derive_const(Default)] pub struct S(A); -//~^ cannot call non-const fn -//~| the trait bound fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 653037ef398..1c69ad43171 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -1,38 +1,12 @@ -error[E0277]: the trait bound `A: Default` is not satisfied - --> $DIR/derive-const-non-const-type.rs:10:14 +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-non-const-type.rs:10:16 | LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ the trait `~const Default` is not implemented for `A` + | ^^^^^^^ | -note: the trait `Default` is implemented for `A`, but that implementation is not `const` - --> $DIR/derive-const-non-const-type.rs:10:14 - | -LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `A` with `#[derive(Default)]` - | -LL + #[derive(Default)] -LL | pub struct A; - | - -error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions - --> $DIR/derive-const-non-const-type.rs:10:14 - | -LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs index d1fbeac8598..69098542b7e 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] pub struct A; diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr new file mode 100644 index 00000000000..88054096e63 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -0,0 +1,53 @@ +error[E0635]: unknown feature `const_cmp` + --> $DIR/derive-const-use.rs:2:30 + | +LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + | ^^^^^^^^^ + +error[E0635]: unknown feature `const_default_impls` + --> $DIR/derive-const-use.rs:2:41 + | +LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + | ^^^^^^^^^^^^^^^^^^^ + +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:6:12 + | +LL | impl const Default for A { + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:10:12 + | +LL | impl const PartialEq for A { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:14:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:14:25 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs index 72edfbc97e4..2a5d0176ba0 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(derive_const)] #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr new file mode 100644 index 00000000000..fa78326587c --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-with-params.rs:6:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/derive-const-with-params.rs:6:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs b/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs index 5495b531cff..d665c4479c9 100644 --- a/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs +++ b/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr new file mode 100644 index 00000000000..1b21d7c0e0e --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr @@ -0,0 +1,11 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/generic-bound.rs:16:15 + | +LL | impl<T> const std::ops::Add for S<T> { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs index 1a4509b1869..dff8a244453 100644 --- a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs +++ b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr new file mode 100644 index 00000000000..cfdda4713a7 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/non-const-op-in-closure-in-const.rs:10:51 + | +LL | impl<A, B> const Convert<B> for A where B: ~const From<A> { + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs index 9ab170f0920..5c2a3f80170 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs @@ -11,13 +11,16 @@ pub trait A { fn a() -> u32; } -impl<T: ~const Default> const A for T { +#[const_trait] +pub trait Spec {} + +impl<T: ~const Spec> const A for T { default fn a() -> u32 { 2 } } -impl<T: Default + Sup> A for T { +impl<T: Spec + Sup> A for T { //~^ ERROR: cannot specialize //~| ERROR: missing `~const` qualifier fn a() -> u32 { diff --git a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr index 843fc6ce84d..1ffdc50e589 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -1,14 +1,14 @@ error: cannot specialize on const impl with non-const impl - --> $DIR/specializing-constness.rs:20:1 + --> $DIR/specializing-constness.rs:23:1 | -LL | impl<T: Default + Sup> A for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<T: Spec + Sup> A for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing `~const` qualifier for specialization - --> $DIR/specializing-constness.rs:20:9 + --> $DIR/specializing-constness.rs:23:9 | -LL | impl<T: Default + Sup> A for T { - | ^^^^^^^ +LL | impl<T: Spec + Sup> A for T { + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr new file mode 100644 index 00000000000..78aab9469e8 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr @@ -0,0 +1,9 @@ +error[E0635]: unknown feature `const_default_impls` + --> $DIR/std-impl-gate.rs:6:46 + | +LL | #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs index 2f54c09e31c..e9e5e0235df 100644 --- a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs +++ b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs @@ -1,7 +1,7 @@ // This tests feature gates for const impls in the standard library. // revisions: stock gated -//[gated] run-pass +//[gated] known-bug: #110395 #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))] diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs index 334fc4cb847..8d56295e738 100644 --- a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(staged_api)] #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr new file mode 100644 index 00000000000..35dc1ca129b --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs b/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs new file mode 100644 index 00000000000..7d7cb967c66 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/trait-method-ptr-in-consts-ice.rs @@ -0,0 +1,23 @@ +// check-pass + +struct LazyLock<T> { + data: (Option<T>, fn() -> T), +} + +impl<T> LazyLock<T> { + pub const fn new(f: fn() -> T) -> LazyLock<T> { + LazyLock { data: (None, f) } + } +} + +struct A<T = i32>(Option<T>); + +impl<T> Default for A<T> { + fn default() -> Self { + A(None) + } +} + +static EMPTY_SET: LazyLock<A<i32>> = LazyLock::new(A::default); + +fn main() {} diff --git a/tests/ui/span/issue-23729.stderr b/tests/ui/span/issue-23729.stderr index f88ce6c88db..cd854e61f2f 100644 --- a/tests/ui/span/issue-23729.stderr +++ b/tests/ui/span/issue-23729.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item` LL | impl Iterator for Recurrence { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation | - = help: implement the missing item: `type Item = Type;` + = help: implement the missing item: `type Item = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr index 46a820f1b76..83a9e8c9b98 100644 --- a/tests/ui/span/issue-23827.stderr +++ b/tests/ui/span/issue-23827.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output` LL | impl<C: Component> FnOnce<(C,)> for Prototype { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation | - = help: implement the missing item: `type Output = Type;` + = help: implement the missing item: `type Output = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-24356.stderr b/tests/ui/span/issue-24356.stderr index a1f9b255020..cf666e8b4a7 100644 --- a/tests/ui/span/issue-24356.stderr +++ b/tests/ui/span/issue-24356.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target` LL | impl Deref for Thing { | ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation | - = help: implement the missing item: `type Target = Type;` + = help: implement the missing item: `type Target = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/send-is-not-static-std-sync-2.stderr b/tests/ui/span/send-is-not-static-std-sync-2.stderr index b0267fa6f43..c825cc8d668 100644 --- a/tests/ui/span/send-is-not-static-std-sync-2.stderr +++ b/tests/ui/span/send-is-not-static-std-sync-2.stderr @@ -25,8 +25,6 @@ LL | }; error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:31:25 | -LL | let (_tx, rx) = { - | --- borrow later used here LL | let x = 1; | - binding `x` declared here LL | let (tx, rx) = mpsc::channel(); diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs index 05ba4c8d45d..b1ec58c3df3 100644 --- a/tests/ui/specialization/const_trait_impl.rs +++ b/tests/ui/specialization/const_trait_impl.rs @@ -1,4 +1,5 @@ -// check-pass +// known-bug: #110395 + #![feature(const_trait_impl, min_specialization, rustc_attrs)] #[rustc_specialization_trait] diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr new file mode 100644 index 00000000000..d13cd8f5555 --- /dev/null +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -0,0 +1,20 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:34:16 + | +LL | impl<T: ~const Default> const A for T { + | ^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:40:16 + | +LL | impl<T: ~const Default + ~const Sup> const A for T { + | ^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:46:16 + | +LL | impl<T: ~const Default + ~const Sub> const A for T { + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/static/issue-18118.stderr b/tests/ui/static/issue-18118.stderr index 49798a148de..035be2b1202 100644 --- a/tests/ui/static/issue-18118.stderr +++ b/tests/ui/static/issue-18118.stderr @@ -1,6 +1,8 @@ error[E0597]: `p` does not live long enough --> $DIR/issue-18118.rs:4:9 | +LL | let p = 3; + | - binding `p` declared here LL | &p | ^^ | | diff --git a/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs new file mode 100644 index 00000000000..b026035a6a1 --- /dev/null +++ b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs @@ -0,0 +1,16 @@ +pub trait TraitB { + type Item; +} + +pub trait TraitA<A> { + type Type; + + fn bar<T>(_: T) -> Self; + + fn baz<T>(_: T) -> Self + where + T: TraitB, + <T as TraitB>::Item: Copy; + + const A: usize; +} diff --git a/tests/ui/suggestions/issue-109436.stderr b/tests/ui/suggestions/issue-109436.stderr index 48518b33d12..c479326f935 100644 --- a/tests/ui/suggestions/issue-109436.stderr +++ b/tests/ui/suggestions/issue-109436.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Into<_>` is not satisfied --> $DIR/issue-109436.rs:12:22 | LL | let b: Bar = foo.into(); - | ^^^^ the trait `~const Into<_>` is not implemented for `Foo` + | ^^^^ the trait `Into<_>` is not implemented for `Foo` | = note: required for `Foo` to implement `Into<Bar>` help: consider borrowing here diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.rs b/tests/ui/suggestions/issue-71394-no-from-impl.rs index 0c35deb51e7..63f12a91282 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.rs +++ b/tests/ui/suggestions/issue-71394-no-from-impl.rs @@ -1,3 +1,8 @@ +// ignore-wasm +// ignore-msvc +// ignore-emscripten +// ignore-uwp + fn main() { let data: &[u8] = &[0; 10]; let _: &[i8] = data.into(); diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index a5e6f5b5ffc..5c36a385a46 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -1,10 +1,11 @@ error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied - --> $DIR/issue-71394-no-from-impl.rs:3:25 + --> $DIR/issue-71394-no-from-impl.rs:8:25 | LL | let _: &[i8] = data.into(); | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]` | = help: the following other types implement trait `From<T>`: + <&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>> <[T; LANES] as From<Simd<T, LANES>>> <[bool; LANES] as From<Mask<T, LANES>>> = note: required for `&[u8]` to implement `Into<&[i8]>` diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed deleted file mode 100644 index a0cb39a3f8a..00000000000 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed +++ /dev/null @@ -1,21 +0,0 @@ -// run-rustfix -trait TraitB { - type Item; -} - -trait TraitA<A> { - type Type; - fn bar<T>(_: T) -> Self; - fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; -} - -struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented -fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() } -fn bar<T>(_: T) -> Self { todo!() } -type Type = Type; -} - -fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs index c80ede1b2be..11e0c9a3a72 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs @@ -1,18 +1,15 @@ -// run-rustfix -trait TraitB { - type Item; -} +// aux-build:missing-assoc-fn-applicable-suggestions.rs -trait TraitA<A> { - type Type; - fn bar<T>(_: T) -> Self; - fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; -} +extern crate missing_assoc_fn_applicable_suggestions; +use missing_assoc_fn_applicable_suggestions::TraitA; struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented +impl TraitA<()> for S { + //~^ ERROR not all trait items implemented } +//~^ HELP implement the missing item: `type Type = /* Type */;` +//~| HELP implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }` +//~| HELP implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }` +//~| HELP implement the missing item: `const A: usize = 42;` fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr index 4c75fbe4c78..4c2d2776d3d 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr @@ -1,15 +1,13 @@ -error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz` - --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1 +error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A` + --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1 | -LL | type Type; - | --------- `Type` from trait -LL | fn bar<T>(_: T) -> Self; - | ------------------------ `bar` from trait -LL | fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; - | ------------------------------------------------------------------- `baz` from trait -... LL | impl TraitA<()> for S { - | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation + | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation + | + = help: implement the missing item: `type Type = /* Type */;` + = help: implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }` + = help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }` + = help: implement the missing item: `const A: usize = 42;` error: aborting due to previous error diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr index 136ec2152e0..77fa9562878 100644 --- a/tests/ui/suggestions/missing-assoc-fn.stderr +++ b/tests/ui/suggestions/missing-assoc-fn.stderr @@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter` LL | impl FromIterator<()> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation | - = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }` + = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }` error: aborting due to 3 previous errors diff --git a/tests/ui/traits/infer-from-object-issue-26952.rs b/tests/ui/traits/infer-from-object-issue-26952.rs index ed258dbb24c..9544b4f2088 100644 --- a/tests/ui/traits/infer-from-object-issue-26952.rs +++ b/tests/ui/traits/infer-from-object-issue-26952.rs @@ -1,8 +1,8 @@ // run-pass #![allow(dead_code)] #![allow(unused_variables)] -// Test that when we match a trait reference like `Foo<A>: Foo<_#0t>`, -// we unify with `_#0t` with `A`. In this code, if we failed to do +// Test that when we match a trait reference like `Foo<A>: Foo<?0t>`, +// we unify with `?0t` with `A`. In this code, if we failed to do // that, then you get an unconstrained type-variable in `call`. // // Also serves as a regression test for issue #26952, though the test diff --git a/tests/ui/issues/issue-22384.rs b/tests/ui/traits/issue-22384.rs index 98988f27ecc..98988f27ecc 100644 --- a/tests/ui/issues/issue-22384.rs +++ b/tests/ui/traits/issue-22384.rs diff --git a/tests/ui/issues/issue-22384.stderr b/tests/ui/traits/issue-22384.stderr index 1f767a443d0..1f767a443d0 100644 --- a/tests/ui/issues/issue-22384.stderr +++ b/tests/ui/traits/issue-22384.stderr diff --git a/tests/ui/traits/new-solver/borrowck-error.rs b/tests/ui/traits/new-solver/borrowck-error.rs new file mode 100644 index 00000000000..4787a2c7e11 --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next + +use std::collections::HashMap; + +fn foo() -> &'static HashMap<i32, i32> +{ + &HashMap::new() + //~^ ERROR cannot return reference to temporary value +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/borrowck-error.stderr b/tests/ui/traits/new-solver/borrowck-error.stderr new file mode 100644 index 00000000000..a7d8201747a --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/borrowck-error.rs:7:5 + | +LL | &HashMap::new() + | ^-------------- + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/traits/new-solver/int-var-alias-eq.rs b/tests/ui/traits/new-solver/int-var-alias-eq.rs index 2da387db4a9..790197e2d97 100644 --- a/tests/ui/traits/new-solver/int-var-alias-eq.rs +++ b/tests/ui/traits/new-solver/int-var-alias-eq.rs @@ -1,7 +1,7 @@ // check-pass // compile-flags: -Ztrait-solver=next -// HIR typeck ends up equating `<_#0i as Add>::Output == _#0i`. +// HIR typeck ends up equating `<?0i as Add>::Output == ?0i`. // Want to make sure that we emit an alias-eq goal for this, // instead of treating it as a type error and bailing. diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.rs b/tests/ui/traits/new-solver/negative-coherence-bounds.rs new file mode 100644 index 00000000000..5436b02c3de --- /dev/null +++ b/tests/ui/traits/new-solver/negative-coherence-bounds.rs @@ -0,0 +1,40 @@ +// check-pass + +// This test verifies that negative trait predicate cannot be satisfied from a +// positive param-env candidate. + +// Negative coherence is one of the only places where we actually construct and +// evaluate negative predicates. Specifically, when verifying whether the first +// and second impls below overlap, we do not want to consider them disjoint, +// otherwise the second impl would be missing an associated type `type Item` +// which is provided by the first impl that it is specializing. + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete +#![feature(with_negative_coherence)] + +trait BoxIter { + type Item; + + fn last(self) -> Option<Self::Item>; +} + +impl<I: Iterator + ?Sized> BoxIter for Box<I> { + type Item = I::Item; + + default fn last(self) -> Option<I::Item> { + todo!() + } +} + +// When checking that this impl does/doesn't overlap the one above, we evaluate +// a negative version of all of the where-clause predicates of the impl below. +// For `I: !Iterator`, we should make sure that the param-env clause `I: Iterator` +// from above doesn't satisfy this predicate. +impl<I: Iterator> BoxIter for Box<I> { + fn last(self) -> Option<I::Item> { + (*self).last() + } +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/negative-coherence-bounds.stderr b/tests/ui/traits/new-solver/negative-coherence-bounds.stderr new file mode 100644 index 00000000000..4127f51f56d --- /dev/null +++ b/tests/ui/traits/new-solver/negative-coherence-bounds.stderr @@ -0,0 +1,12 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/negative-coherence-bounds.rs:12:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs index cde2059ca9b..3c7fc0d813d 100644 --- a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs @@ -1,7 +1,7 @@ // compile-flags: -Ztrait-solver=next // When we're solving `<T as Foo>::Assoc = i32`, we actually first solve -// `<T as Foo>::Assoc = _#1t`, then unify `_#1t` with `i32`. That goal +// `<T as Foo>::Assoc = ?1t`, then unify `?1t` with `i32`. That goal // with the inference variable is ambiguous when there are >1 param-env // candidates. diff --git a/tests/ui/transmutability/issue-110467.rs b/tests/ui/transmutability/issue-110467.rs new file mode 100644 index 00000000000..358733b9832 --- /dev/null +++ b/tests/ui/transmutability/issue-110467.rs @@ -0,0 +1,17 @@ +// check-pass +#![crate_type = "lib"] +#![feature(transmutability)] +use std::mem::BikeshedIntrinsicFrom; +pub struct Context; + +pub fn is_maybe_transmutable<Src, Dst>() +where + Dst: BikeshedIntrinsicFrom<Src, Context>, +{ +} + +// The `T` here should not have any effect on checking +// if transmutability is allowed or not. +fn function_with_generic<T>() { + is_maybe_transmutable::<(), ()>(); +} diff --git a/tests/ui/transmutability/references.current.stderr b/tests/ui/transmutability/references.current.stderr index ecb095354a5..819c9b92bc8 100644 --- a/tests/ui/transmutability/references.current.stderr +++ b/tests/ui/transmutability/references.current.stderr @@ -1,8 +1,8 @@ -error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context` +error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context` --> $DIR/references.rs:29:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&'static Unit` does not have a well-specified layout + | ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout | note: required by a bound in `is_maybe_transmutable` --> $DIR/references.rs:16:14 diff --git a/tests/ui/transmutability/references.next.stderr b/tests/ui/transmutability/references.next.stderr index ecb095354a5..819c9b92bc8 100644 --- a/tests/ui/transmutability/references.next.stderr +++ b/tests/ui/transmutability/references.next.stderr @@ -1,8 +1,8 @@ -error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context` +error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context` --> $DIR/references.rs:29:52 | LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); - | ^^^^^^^^^^^^^ `&'static Unit` does not have a well-specified layout + | ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout | note: required by a bound in `is_maybe_transmutable` --> $DIR/references.rs:16:14 diff --git a/tests/ui/transmutability/region-infer.rs b/tests/ui/transmutability/region-infer.rs new file mode 100644 index 00000000000..09f60277688 --- /dev/null +++ b/tests/ui/transmutability/region-infer.rs @@ -0,0 +1,22 @@ +#![feature(transmutability)] + +use std::mem::{Assume, BikeshedIntrinsicFrom}; +pub struct Context; + +#[repr(C)] +struct W<'a>(&'a ()); + +fn test<'a>() +where + W<'a>: BikeshedIntrinsicFrom< + (), + Context, + { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, + >, +{ +} + +fn main() { + test(); + //~^ ERROR `()` cannot be safely transmuted into `W<'_>` +} diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr new file mode 100644 index 00000000000..d6b65e9e4a0 --- /dev/null +++ b/tests/ui/transmutability/region-infer.stderr @@ -0,0 +1,23 @@ +error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scope of `Context` + --> $DIR/region-infer.rs:20:5 + | +LL | test(); + | ^^^^ `W<'_>` does not have a well-specified layout + | +note: required by a bound in `test` + --> $DIR/region-infer.rs:11:12 + | +LL | fn test<'a>() + | ---- required by a bound in this function +LL | where +LL | W<'a>: BikeshedIntrinsicFrom< + | ____________^ +LL | | (), +LL | | Context, +LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, +LL | | >, + | |_________^ required by this bound in `test` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index 758ff31ff70..e24cb11288e 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -115,7 +115,7 @@ LL | Self::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - Self::SVariant::<()> { v: () }; LL + Enum::<()>::SVariant { v: () }; @@ -196,7 +196,7 @@ LL | Self::<()>::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - Self::<()>::SVariant::<()> { v: () }; LL + Enum::<()>::SVariant { v: () }; @@ -359,7 +359,7 @@ LL | Alias::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - Alias::SVariant::<()> { v: () }; LL + Alias::<()>::SVariant { v: () }; @@ -374,7 +374,7 @@ LL | Alias::<()>::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - Alias::<()>::SVariant::<()> { v: () }; LL + Alias::<()>::SVariant { v: () }; @@ -389,7 +389,7 @@ LL | AliasFixed::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - AliasFixed::SVariant::<()> { v: () }; LL + AliasFixed::<()>::SVariant { v: () }; @@ -432,7 +432,7 @@ LL | AliasFixed::<()>::SVariant::<()> { v: () }; | not allowed on this type | = note: enum variants can't have type parameters -help: you might have meant to specity type parameters on enum `Enum` +help: you might have meant to specify type parameters on enum `Enum` | LL - AliasFixed::<()>::SVariant::<()> { v: () }; LL + AliasFixed::<()>::SVariant { v: () }; diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr index 576fc6a4f8d..c943a4918ba 100644 --- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -29,7 +29,7 @@ note: ...which requires borrow-checking `Alpha::V3::{constant#0}`... | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `Alpha::V3::{constant#0}`... +note: ...which requires promoting constants in MIR for `Alpha::V3::{constant#0}`... --> $DIR/self-in-enum-definition.rs:5:10 | LL | V3 = Self::V1 {} as u8 + 2, diff --git a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs index 475f4724ff2..3ff20d99ad8 100644 --- a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs +++ b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs @@ -12,7 +12,7 @@ // Basic test mod test1 { - // Hidden type = Closure['_#0r] + // Hidden type = Closure['?0] type Opaque = impl Sized; fn define<'a: 'a>() -> Opaque { @@ -24,8 +24,8 @@ mod test1 { mod test2 { trait Trait {} - // Hidden type = Closure['a, '_#0r, '_#1r] - // Constraints = [('_#0r: 'a), ('a: '_#1r)] + // Hidden type = Closure['a, '?0, '?1] + // Constraints = [('?0: 'a), ('a: '?1)] type Opaque<'a> where &'a (): Trait, @@ -45,8 +45,8 @@ mod test2 { mod test3 { trait Trait {} - // Hidden type = Closure['a, 'b, '_#0r] - // Constraints = [('_#0r: 'a), ('_#0r: 'b)] + // Hidden type = Closure['a, 'b, '?0] + // Constraints = [('?0: 'a), ('?0: 'b)] type Opaque<'a, 'b> where (&'a (), &'b ()): Trait, diff --git a/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs index af6d5010920..82cc823e494 100644 --- a/tests/ui/type-alias-impl-trait/issue-65918.rs +++ b/tests/ui/type-alias-impl-trait/issue-65918.rs @@ -1,5 +1,3 @@ -// ignore-test: This now ICEs again. - // build-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/typeck/bad-index-due-to-nested.rs b/tests/ui/typeck/bad-index-due-to-nested.rs new file mode 100644 index 00000000000..2564b530004 --- /dev/null +++ b/tests/ui/typeck/bad-index-due-to-nested.rs @@ -0,0 +1,27 @@ +use std::hash::Hash; +use std::marker::PhantomData; +use std::ops::Index; + +struct HashMap<K, V>(PhantomData<(K, V)>); + +impl<K, V> Index<&K> for HashMap<K, V> +where + K: Hash, + V: Copy, +{ + type Output = V; + + fn index(&self, k: &K) -> &V { + todo!() + } +} + +fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { + map[k] + //~^ ERROR the trait bound `K: Hash` is not satisfied + //~| ERROR the trait bound `V: Copy` is not satisfied + //~| ERROR mismatched types + //~| ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/typeck/bad-index-due-to-nested.stderr b/tests/ui/typeck/bad-index-due-to-nested.stderr new file mode 100644 index 00000000000..e03b06b336e --- /dev/null +++ b/tests/ui/typeck/bad-index-due-to-nested.stderr @@ -0,0 +1,64 @@ +error[E0277]: the trait bound `K: Hash` is not satisfied + --> $DIR/bad-index-due-to-nested.rs:20:5 + | +LL | map[k] + | ^^^ the trait `Hash` is not implemented for `K` + | +note: required by a bound in `<HashMap<K, V> as Index<&K>>` + --> $DIR/bad-index-due-to-nested.rs:9:8 + | +LL | K: Hash, + | ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` +help: consider restricting type parameter `K` + | +LL | fn index<'a, K: std::hash::Hash, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { + | +++++++++++++++++ + +error[E0277]: the trait bound `V: Copy` is not satisfied + --> $DIR/bad-index-due-to-nested.rs:20:5 + | +LL | map[k] + | ^^^ the trait `Copy` is not implemented for `V` + | +note: required by a bound in `<HashMap<K, V> as Index<&K>>` + --> $DIR/bad-index-due-to-nested.rs:10:8 + | +LL | V: Copy, + | ^^^^ required by this bound in `<HashMap<K, V> as Index<&K>>` +help: consider restricting type parameter `V` + | +LL | fn index<'a, K, V: std::marker::Copy>(map: &'a HashMap<K, V>, k: K) -> &'a V { + | +++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/bad-index-due-to-nested.rs:20:9 + | +LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { + | - this type parameter +LL | map[k] + | ^ + | | + | expected `&K`, found type parameter `K` + | help: consider borrowing here: `&k` + | + = note: expected reference `&K` + found type parameter `K` + +error[E0308]: mismatched types + --> $DIR/bad-index-due-to-nested.rs:20:5 + | +LL | fn index<'a, K, V>(map: &'a HashMap<K, V>, k: K) -> &'a V { + | - this type parameter ----- expected `&'a V` because of return type +LL | map[k] + | ^^^^^^ + | | + | expected `&V`, found type parameter `V` + | help: consider borrowing here: `&map[k]` + | + = note: expected reference `&'a V` + found type parameter `V` + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.rs b/tests/ui/typeck/bad-recursive-type-sig-infer.rs new file mode 100644 index 00000000000..9812d8c3811 --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.rs @@ -0,0 +1,11 @@ +fn a() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn b() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn main() {} diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.stderr b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr new file mode 100644 index 00000000000..e145da5623a --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:1:11 + | +LL | fn a() -> _ { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:6:11 + | +LL | fn b() -> _ { + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs new file mode 100644 index 00000000000..03602144e50 --- /dev/null +++ b/tests/ui/typeck/pin-unsound-issue-85099-derefmut.rs @@ -0,0 +1,68 @@ +// check-pass +// known-bug: #85099 + +// Should fail. Can coerce `Pin<T>` into `Pin<U>` where +// `T: Deref<Target: Unpin>` and `U: Deref<Target: !Unpin>`, using the +// `CoerceUnsized` impl on `Pin` and an unorthodox `DerefMut` impl for +// `Pin<&_>`. + +// This should not be allowed, since one can unpin `T::Target` (since it is +// `Unpin`) to gain unpinned access to the previously pinned `U::Target` (which +// is `!Unpin`) and then move it. + +use std::{ + cell::{RefCell, RefMut}, + future::Future, + ops::DerefMut, + pin::Pin, +}; + +struct SomeLocalStruct<'a, Fut>(&'a RefCell<Fut>); + +trait SomeTrait<'a, Fut> { + #[allow(clippy::mut_from_ref)] + fn deref_helper(&self) -> &mut (dyn SomeTrait<'a, Fut> + 'a) { + unimplemented!() + } + fn downcast(self: Pin<&mut Self>) -> Pin<&mut Fut> { + unimplemented!() + } +} + +impl<'a, Fut: Future<Output = ()>> SomeTrait<'a, Fut> for SomeLocalStruct<'a, Fut> { + fn deref_helper(&self) -> &mut (dyn SomeTrait<'a, Fut> + 'a) { + let x = Box::new(self.0.borrow_mut()); + let x: &'a mut RefMut<'a, Fut> = Box::leak(x); + &mut **x + } +} +impl<'a, Fut: Future<Output = ()>> SomeTrait<'a, Fut> for Fut { + fn downcast(self: Pin<&mut Self>) -> Pin<&mut Fut> { + self + } +} + +impl<'b, 'a, Fut> DerefMut for Pin<&'b dyn SomeTrait<'a, Fut>> { + fn deref_mut<'c>( + self: &'c mut Pin<&'b dyn SomeTrait<'a, Fut>>, + ) -> &'c mut (dyn SomeTrait<'a, Fut> + 'b) { + self.deref_helper() + } +} + +// obviously a "working" function with this signature is problematic +pub fn unsound_pin<Fut: Future<Output = ()>>( + fut: Fut, + callback: impl FnOnce(Pin<&mut Fut>), +) -> Fut { + let cell = RefCell::new(fut); + let s: &SomeLocalStruct<'_, Fut> = &SomeLocalStruct(&cell); + let p: Pin<Pin<&SomeLocalStruct<'_, Fut>>> = Pin::new(Pin::new(s)); + let mut p: Pin<Pin<&dyn SomeTrait<'_, Fut>>> = p; + let r: Pin<&mut dyn SomeTrait<'_, Fut>> = p.as_mut(); + let f: Pin<&mut Fut> = r.downcast(); + callback(f); + cell.into_inner() +} + +fn main() {} diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index a450dbb82d1..46aed0f603e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -227,6 +227,4 @@ fn evens_squared(n: usize) -> _ { } const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); -//~^ ERROR the trait bound -//~| ERROR the trait bound -//~| ERROR the placeholder +//~^ ERROR the placeholder diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bc6c9fd0779..bc02547c65e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -437,37 +437,17 @@ LL | fn evens_squared(n: usize) -> _ { | not allowed in type signatures | help: replace with an appropriate return type: `impl Iterator<Item = usize>` -error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied - --> $DIR/typeck_type_placeholder_item.rs:229:22 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^ `std::ops::Range<{integer}>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>` -note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const` - --> $DIR/typeck_type_placeholder_item.rs:229:14 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^ - -error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied - --> $DIR/typeck_type_placeholder_item.rs:229:45 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:229:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator + | ^ not allowed in type signatures | - = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` -note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const` +note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named --> $DIR/typeck_type_placeholder_item.rs:229:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:229:10 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^ not allowed in type signatures + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:140:31 @@ -677,7 +657,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error: aborting due to 73 previous errors +error: aborting due to 71 previous errors -Some errors have detailed explanations: E0121, E0277, E0282, E0403. +Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/wf/wf-in-fn-type-implicit.rs b/tests/ui/wf/wf-in-fn-type-implicit.rs new file mode 100644 index 00000000000..c5ff92c8875 --- /dev/null +++ b/tests/ui/wf/wf-in-fn-type-implicit.rs @@ -0,0 +1,37 @@ +// check-pass +// known-bug: #104005 + +// Should fail. Function type parameters with implicit type annotations are not +// checked for well-formedness, which allows incorrect borrowing. + +// In contrast, user annotations are always checked for well-formedness, and the +// commented code below is correctly rejected by the borrow checker. + +use std::fmt::Display; + +trait Displayable { + fn display(self) -> Box<dyn Display>; +} + +impl<T: Display> Displayable for (T, Option<&'static T>) { + fn display(self) -> Box<dyn Display> { + Box::new(self.0) + } +} + +fn extend_lt<T, U>(val: T) -> Box<dyn Display> +where + (T, Option<U>): Displayable, +{ + Displayable::display((val, None)) +} + +fn main() { + // *incorrectly* compiles + let val = extend_lt(&String::from("blah blah blah")); + println!("{}", val); + + // *correctly* fails to compile + // let val = extend_lt::<_, &_>(&String::from("blah blah blah")); + // println!("{}", val); +} diff --git a/tests/ui/wf/wf-in-where-clause-static.rs b/tests/ui/wf/wf-in-where-clause-static.rs new file mode 100644 index 00000000000..86722afdf9f --- /dev/null +++ b/tests/ui/wf/wf-in-where-clause-static.rs @@ -0,0 +1,23 @@ +// check-pass +// known-bug: #98117 + +// Should fail. Functions are responsible for checking the well-formedness of +// their own where clauses, so this should fail and require an explicit bound +// `T: 'static`. + +use std::fmt::Display; + +trait Static: 'static {} +impl<T> Static for &'static T {} + +fn foo<S: Display>(x: S) -> Box<dyn Display> +where + &'static S: Static, +{ + Box::new(x) +} + +fn main() { + let s = foo(&String::from("blah blah blah")); + println!("{}", s); +} diff --git a/tests/ui/wf/wf-normalization-sized.rs b/tests/ui/wf/wf-normalization-sized.rs new file mode 100644 index 00000000000..473fc79a8a3 --- /dev/null +++ b/tests/ui/wf/wf-normalization-sized.rs @@ -0,0 +1,19 @@ +// check-pass +// known-bug: #100041 + +// Should fail. Normalization can bypass well-formedness checking. +// `[[[[[[u8]]]]]]` is not a well-formed type since size of type `[u8]` cannot +// be known at compile time (since `Sized` is not implemented for `[u8]`). + +trait WellUnformed { + type RequestNormalize; +} + +impl<T: ?Sized> WellUnformed for T { + type RequestNormalize = (); +} + +const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = (); +const _: <Vec<str> as WellUnformed>::RequestNormalize = (); + +fn main() {} |
