diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index f4e409e0d491..03584aed08d9 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -56,7 +56,7 @@ jobs: - name: install the bootstrap toolchain run: | # Extract the stage0 version - TOOLCHAIN=$(jq -r '.compiler | {version,date} | join("-")' -- src/stage0.json) + TOOLCHAIN=$(awk -F= '{a[$1]=$2} END {print(a["compiler_version"] "-" a["compiler_date"])}' src/stage0) # Install and set as default rustup toolchain install --no-self-update --profile minimal $TOOLCHAIN rustup default $TOOLCHAIN diff --git a/Cargo.lock b/Cargo.lock index aa73df55cb98..df4e4f326135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "ammonia" @@ -141,56 +141,57 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-lossy" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a0444767dbd4aea9355cb47a370eb184dbfe918875e127eff52cb9d1638181" +checksum = "6fcff6599f06e21b0165c85052ccd6e67dc388ddd1c516a9dc5f55dc8cacf004" dependencies = [ "anstyle", ] [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-svg" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6ddad447b448d6d5db36b31cbd3ff27c7af071619501998eeceab01968287a" +checksum = "bbbf0bf947d663010f0b4132f28ca08da9151f3b9035fa7578a38de521c1d1aa" dependencies = [ "anstream", "anstyle", @@ -201,9 +202,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -211,9 +212,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" dependencies = [ "backtrace", ] @@ -256,7 +257,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -276,9 +277,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -380,27 +381,24 @@ name = "bump-stage0" version = "0.1.0" dependencies = [ "anyhow", + "build_helper", "curl", "indexmap", "serde", - "serde_json", "toml 0.5.11", ] [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" -dependencies = [ - "packed_simd", -] +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "byteorder" @@ -509,7 +507,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -579,9 +577,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" +checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" dependencies = [ "clap", ] @@ -595,7 +593,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -622,7 +620,7 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.58", + "syn 2.0.62", "tempfile", "termize", "tokio", @@ -716,23 +714,23 @@ dependencies = [ [[package]] name = "color-print" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a858372ff14bab9b1b30ea504f2a4bc534582aee3e42ba2d41d2a7baba63d5d" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" dependencies = [ "color-print-proc-macro", ] [[package]] name = "color-print-proc-macro" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e37866456a721d0a404439a1adae37a31be4e0055590d053dfe6981e05003f" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" dependencies = [ "nom", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.62", ] [[package]] @@ -749,9 +747,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -978,7 +976,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -989,7 +987,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1004,7 +1002,7 @@ version = "0.1.80" dependencies = [ "itertools 0.12.1", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1045,7 +1043,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1055,7 +1053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1078,7 +1076,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1167,14 +1165,14 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "dissimilar" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" +checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" [[package]] name = "dlmalloc" @@ -1191,9 +1189,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elasticlunr-rs" @@ -1218,9 +1216,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] @@ -1233,9 +1231,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -1271,9 +1269,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1314,9 +1312,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] name = "fastrand" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "field-offset" @@ -1336,15 +1334,15 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1352,9 +1350,9 @@ dependencies = [ [[package]] name = "fluent-bundle" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493" dependencies = [ "fluent-langneg", "fluent-syntax", @@ -1377,9 +1375,9 @@ dependencies = [ [[package]] name = "fluent-syntax" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ "thiserror", ] @@ -1505,7 +1503,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -1577,9 +1575,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06fddc2749e0528d2813f95e050e87e52c8cbbae56223b9babf73b3e53b0cc6" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "libc", @@ -1663,9 +1661,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", @@ -1943,7 +1941,7 @@ checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -2055,9 +2053,9 @@ dependencies = [ [[package]] name = "intl-memoizer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda" dependencies = [ "type-map", "unic-langid", @@ -2078,6 +2076,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -2114,9 +2118,9 @@ dependencies = [ [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] @@ -2219,7 +2223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -2296,9 +2300,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2384,7 +2388,7 @@ dependencies = [ "memchr", "once_cell", "opener", - "pulldown-cmark 0.10.2", + "pulldown-cmark 0.10.3", "regex", "serde", "serde_json", @@ -2615,12 +2619,11 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2717,7 +2720,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -2782,16 +2785,6 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -[[package]] -name = "packed_simd" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d" -dependencies = [ - "cfg-if", - "num-traits", -] - [[package]] name = "pad" version = "0.1.6" @@ -2837,9 +2830,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -2847,15 +2840,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -2890,9 +2883,9 @@ dependencies = [ [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -2901,9 +2894,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -2911,22 +2904,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", @@ -3080,9 +3073,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -3126,9 +3119,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0530d13d87d1f549b66a3e8d0c688952abe5994e204ed62615baaf25dc029c" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.5.0", "memchr", @@ -3138,9 +3131,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-escape" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b" +checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3" [[package]] name = "punycode" @@ -3156,9 +3149,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -3261,6 +3254,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "redox_users" version = "0.4.5" @@ -3436,9 +3438,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -3999,7 +4001,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "unic-langid", ] @@ -4133,7 +4135,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -4280,7 +4282,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -4367,6 +4369,7 @@ dependencies = [ "rustc_hir", "rustc_index", "rustc_infer", + "rustc_lint", "rustc_macros", "rustc_middle", "rustc_pattern_analysis", @@ -4835,9 +4838,20 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", + "rustc_type_ir_macros", "smallvec", ] +[[package]] +name = "rustc_type_ir_macros" +version = "0.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.62", + "synstructure", +] + [[package]] name = "rustc_version" version = "0.4.0" @@ -4932,7 +4946,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -4967,9 +4981,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", @@ -4989,9 +5003,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "ruzstd" @@ -5017,9 +5031,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -5053,11 +5067,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -5066,9 +5080,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -5080,49 +5094,49 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.3", + "self_cell 1.0.4", ] [[package]] name = "self_cell" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap", "itoa", @@ -5229,9 +5243,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -5427,9 +5441,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.58" +version = "2.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" +checksum = "9f660c3bfcefb88c538776b6685a0c472e3128b51e74d48793dc2a488196e8eb" dependencies = [ "proc-macro2", "quote", @@ -5450,14 +5464,14 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] name = "sysinfo" -version = "0.30.8" +version = "0.30.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b1a378e48fb3ce3a5cf04359c456c9c98ff689bcf1c1bc6e6a31f247686f275" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" dependencies = [ "cfg-if", "core-foundation-sys", @@ -5601,22 +5615,22 @@ checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -5751,16 +5765,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -5838,7 +5851,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -5922,9 +5935,9 @@ dependencies = [ [[package]] name = "type-map" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" dependencies = [ "rustc-hash", ] @@ -6007,9 +6020,9 @@ dependencies = [ [[package]] name = "unic-langid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238722e6d794ed130f91f4ea33e01fcff4f188d92337a21297892521c72df516" +checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44" dependencies = [ "unic-langid-impl", "unic-langid-macros", @@ -6017,18 +6030,18 @@ dependencies = [ [[package]] name = "unic-langid-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd55a2063fdea4ef1f8633243a7b0524cbeef1905ae04c31a1c9b9775c55bc6" +checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" dependencies = [ "tinystr", ] [[package]] name = "unic-langid-macros" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c854cefb82ff2816410ce606acbad1b3af065140907b29be9229040752b83ec" +checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e" dependencies = [ "proc-macro-hack", "tinystr", @@ -6038,13 +6051,13 @@ dependencies = [ [[package]] name = "unic-langid-macros-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4" +checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.58", + "syn 2.0.62", "unic-langid-impl", ] @@ -6115,9 +6128,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -6276,7 +6289,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "wasm-bindgen-shared", ] @@ -6310,7 +6323,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6368,11 +6381,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -6388,7 +6401,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6401,7 +6414,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.58", + "syn 2.0.62", "windows-metadata", ] @@ -6411,7 +6424,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6435,7 +6448,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -6455,17 +6468,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -6476,9 +6490,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -6488,9 +6502,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -6500,9 +6514,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -6512,9 +6532,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -6524,9 +6544,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -6536,9 +6556,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -6548,9 +6568,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -6626,28 +6646,28 @@ checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] @@ -6667,7 +6687,7 @@ checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", "synstructure", ] @@ -6690,7 +6710,7 @@ checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" dependencies = [ "proc-macro2", "quote", - "syn 2.0.58", + "syn 2.0.62", ] [[package]] diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index a8d019c98049..9f2788c87c32 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1255,7 +1255,7 @@ impl FieldsShape { /// Gets source indices of the fields by increasing offsets. #[inline] - pub fn index_by_increasing_offset(&self) -> impl Iterator + '_ { + pub fn index_by_increasing_offset(&self) -> impl ExactSizeIterator + '_ { let mut inverse_small = [0u8; 64]; let mut inverse_big = IndexVec::new(); let use_small = self.count() <= inverse_small.len(); @@ -1271,7 +1271,12 @@ impl FieldsShape { } } - (0..self.count()).map(move |i| match *self { + // Primitives don't really have fields in the way that structs do, + // but having this return an empty iterator for them is unhelpful + // since that makes them look kinda like ZSTs, which they're not. + let pseudofield_count = if let FieldsShape::Primitive = self { 1 } else { self.count() }; + + (0..pseudofield_count).map(move |i| match *self { FieldsShape::Primitive | FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { .. } => { if use_small { diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7951b7e7b75a..56d4f53f9eea 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3250,6 +3250,7 @@ pub enum ItemKind { } impl ItemKind { + /// "a" or "an" pub fn article(&self) -> &'static str { use ItemKind::*; match self { diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index a0486227f2af..2cf811e9122f 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -240,7 +240,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtPath(path) => path.tokens(), Nonterminal::NtVis(vis) => vis.tokens(), Nonterminal::NtBlock(block) => block.tokens(), - Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } fn tokens_mut(&mut self) -> Option<&mut Option> { @@ -254,7 +253,6 @@ impl HasTokens for Nonterminal { Nonterminal::NtPath(path) => path.tokens_mut(), Nonterminal::NtVis(vis) => vis.tokens_mut(), Nonterminal::NtBlock(block) => block.tokens_mut(), - Nonterminal::NtIdent(..) | Nonterminal::NtLifetime(..) => None, } } } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 0f12fd319752..0684163617fe 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -345,7 +345,7 @@ impl MetaItem { let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } } - Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &nt.0 { + Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &**nt { token::Nonterminal::NtMeta(item) => return item.meta(item.path.span), token::Nonterminal::NtPath(path) => (**path).clone(), _ => return None, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 379c2e273eb1..5c4162295bbc 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -781,10 +781,14 @@ pub fn visit_token(t: &mut Token, vis: &mut T) { *span = ident.span; return; // Avoid visiting the span for the second time. } + token::NtIdent(ident, _is_raw) => { + vis.visit_ident(ident); + } + token::NtLifetime(ident) => { + vis.visit_ident(ident); + } token::Interpolated(nt) => { let nt = Lrc::make_mut(nt); - let (nt, sp) = (&mut nt.0, &mut nt.1); - vis.visit_span(sp); visit_nonterminal(nt, vis); } _ => {} @@ -834,8 +838,6 @@ fn visit_nonterminal(nt: &mut token::Nonterminal, vis: &mut T) { token::NtPat(pat) => vis.visit_pat(pat), token::NtExpr(expr) => vis.visit_expr(expr), token::NtTy(ty) => vis.visit_ty(ty), - token::NtIdent(ident, _is_raw) => vis.visit_ident(ident), - token::NtLifetime(ident) => vis.visit_ident(ident), token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { let AttrItem { path, args, tokens } = item.deref_mut(); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 72f89737f995..d00352ea2e13 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -111,7 +111,7 @@ impl Lit { Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)), Literal(token_lit) => Some(token_lit), Interpolated(ref nt) - if let NtExpr(expr) | NtLiteral(expr) = &nt.0 + if let NtExpr(expr) | NtLiteral(expr) = &**nt && let ast::ExprKind::Lit(token_lit) = expr.kind => { Some(token_lit) @@ -318,11 +318,20 @@ pub enum TokenKind { /// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to /// treat regular and interpolated identifiers in the same way. Ident(Symbol, IdentIsRaw), + /// This identifier (and its span) is the identifier passed to the + /// declarative macro. The span in the surrounding `Token` is the span of + /// the `ident` metavariable in the macro's RHS. + NtIdent(Ident, IdentIsRaw), + /// Lifetime identifier token. /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers. /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to /// treat regular and interpolated lifetime identifiers in the same way. Lifetime(Symbol), + /// This identifier (and its span) is the lifetime passed to the + /// declarative macro. The span in the surrounding `Token` is the span of + /// the `lifetime` metavariable in the macro's RHS. + NtLifetime(Ident), /// An embedded AST node, as produced by a macro. This only exists for /// historical reasons. We'd like to get rid of it, for multiple reasons. @@ -333,7 +342,11 @@ pub enum TokenKind { /// - It prevents `Token` from implementing `Copy`. /// It adds complexity and likely slows things down. Please don't add new /// occurrences of this token kind! - Interpolated(Lrc<(Nonterminal, Span)>), + /// + /// The span in the surrounding `Token` is that of the metavariable in the + /// macro's RHS. The span within the Nonterminal is that of the fragment + /// passed to the macro at the call site. + Interpolated(Lrc), /// A doc comment token. /// `Symbol` is the doc comment's data excluding its "quotes" (`///`, `/**`, etc) @@ -440,8 +453,9 @@ impl Token { /// Note that keywords are also identifiers, so they should use this /// if they keep spans or perform edition checks. pub fn uninterpolated_span(&self) -> Span { - match &self.kind { - Interpolated(nt) => nt.0.use_span(), + match self.kind { + NtIdent(ident, _) | NtLifetime(ident) => ident.span, + Interpolated(ref nt) => nt.use_span(), _ => self.span, } } @@ -459,7 +473,7 @@ impl Token { } OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | Eof => false, + | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false, } } @@ -486,7 +500,7 @@ impl Token { PathSep | // global path Lifetime(..) | // labeled loop Pound => true, // expression attributes - Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | + Interpolated(ref nt) => matches!(&**nt, NtLiteral(..) | NtExpr(..) | NtBlock(..) | NtPath(..)), @@ -510,7 +524,7 @@ impl Token { | DotDot | DotDotDot | DotDotEq // ranges | Lt | BinOp(Shl) // associated path | PathSep => true, // global path - Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | + Interpolated(ref nt) => matches!(&**nt, NtLiteral(..) | NtPat(..) | NtBlock(..) | NtPath(..)), @@ -533,7 +547,7 @@ impl Token { Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path PathSep => true, // global path - Interpolated(ref nt) => matches!(&nt.0, NtTy(..) | NtPath(..)), + Interpolated(ref nt) => matches!(&**nt, NtTy(..) | NtPath(..)), // For anonymous structs or unions, which only appear in specific positions // (type of struct fields or union fields), we don't consider them as regular types _ => false, @@ -544,7 +558,7 @@ impl Token { pub fn can_begin_const_arg(&self) -> bool { match self.kind { OpenDelim(Delimiter::Brace) => true, - Interpolated(ref nt) => matches!(&nt.0, NtExpr(..) | NtBlock(..) | NtLiteral(..)), + Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), _ => self.can_begin_literal_maybe_minus(), } } @@ -589,7 +603,7 @@ impl Token { match self.uninterpolate().kind { Literal(..) | BinOp(Minus) => true, Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, - Interpolated(ref nt) => match &nt.0 { + Interpolated(ref nt) => match &**nt { NtLiteral(_) => true, NtExpr(e) => match &e.kind { ast::ExprKind::Lit(_) => true, @@ -609,14 +623,9 @@ impl Token { /// into the regular identifier or lifetime token it refers to, /// otherwise returns the original token. pub fn uninterpolate(&self) -> Cow<'_, Token> { - match &self.kind { - Interpolated(nt) => match &nt.0 { - NtIdent(ident, is_raw) => { - Cow::Owned(Token::new(Ident(ident.name, *is_raw), ident.span)) - } - NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)), - _ => Cow::Borrowed(self), - }, + match self.kind { + NtIdent(ident, is_raw) => Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span)), + NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)), _ => Cow::Borrowed(self), } } @@ -625,12 +634,9 @@ impl Token { #[inline] pub fn ident(&self) -> Option<(Ident, IdentIsRaw)> { // We avoid using `Token::uninterpolate` here because it's slow. - match &self.kind { - &Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), - Interpolated(nt) => match &nt.0 { - NtIdent(ident, is_raw) => Some((*ident, *is_raw)), - _ => None, - }, + match self.kind { + Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)), + NtIdent(ident, is_raw) => Some((ident, is_raw)), _ => None, } } @@ -639,12 +645,9 @@ impl Token { #[inline] pub fn lifetime(&self) -> Option { // We avoid using `Token::uninterpolate` here because it's slow. - match &self.kind { - &Lifetime(name) => Some(Ident::new(name, self.span)), - Interpolated(nt) => match &nt.0 { - NtLifetime(ident) => Some(*ident), - _ => None, - }, + match self.kind { + Lifetime(name) => Some(Ident::new(name, self.span)), + NtLifetime(ident) => Some(ident), _ => None, } } @@ -668,7 +671,7 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_whole_path(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtPath(..) = &nt.0 + && let NtPath(..) = &**nt { return true; } @@ -681,7 +684,7 @@ impl Token { /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &nt.0 + && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = &**nt { return true; } @@ -692,7 +695,7 @@ impl Token { /// Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { if let Interpolated(nt) = &self.kind - && let NtBlock(..) = &nt.0 + && let NtBlock(..) = &**nt { return true; } @@ -833,8 +836,10 @@ impl Token { Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar - | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) - | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None, + | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..) + | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof => { + return None; + } }; Some(Token::new(kind, self.span.to(joint.span))) @@ -857,8 +862,6 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), - NtIdent(Ident, IdentIsRaw), - NtLifetime(Ident), NtLiteral(P), /// Stuff inside brackets for attributes NtMeta(P), @@ -953,7 +956,6 @@ impl Nonterminal { NtPat(pat) => pat.span, NtExpr(expr) | NtLiteral(expr) => expr.span, NtTy(ty) => ty.span, - NtIdent(ident, _) | NtLifetime(ident) => ident.span, NtMeta(attr_item) => attr_item.span(), NtPath(path) => path.span, NtVis(vis) => vis.span, @@ -969,8 +971,6 @@ impl Nonterminal { NtExpr(..) => "expression", NtLiteral(..) => "literal", NtTy(..) => "type", - NtIdent(..) => "identifier", - NtLifetime(..) => "lifetime", NtMeta(..) => "attribute", NtPath(..) => "path", NtVis(..) => "visibility", @@ -979,18 +979,12 @@ impl Nonterminal { } impl PartialEq for Nonterminal { - fn eq(&self, rhs: &Self) -> bool { - match (self, rhs) { - (NtIdent(ident_lhs, is_raw_lhs), NtIdent(ident_rhs, is_raw_rhs)) => { - ident_lhs == ident_rhs && is_raw_lhs == is_raw_rhs - } - (NtLifetime(ident_lhs), NtLifetime(ident_rhs)) => ident_lhs == ident_rhs, - // FIXME: Assume that all "complex" nonterminal are not equal, we can't compare them - // correctly based on data from AST. This will prevent them from matching each other - // in macros. The comparison will become possible only when each nonterminal has an - // attached token stream from which it was parsed. - _ => false, - } + fn eq(&self, _rhs: &Self) -> bool { + // FIXME: Assume that all nonterminals are not equal, we can't compare them + // correctly based on data from AST. This will prevent them from matching each other + // in macros. The comparison will become possible only when each nonterminal has an + // attached token stream from which it was parsed. + false } } @@ -1003,12 +997,10 @@ impl fmt::Debug for Nonterminal { NtPat(..) => f.pad("NtPat(..)"), NtExpr(..) => f.pad("NtExpr(..)"), NtTy(..) => f.pad("NtTy(..)"), - NtIdent(..) => f.pad("NtIdent(..)"), NtLiteral(..) => f.pad("NtLiteral(..)"), NtMeta(..) => f.pad("NtMeta(..)"), NtPath(..) => f.pad("NtPath(..)"), NtVis(..) => f.pad("NtVis(..)"), - NtLifetime(..) => f.pad("NtLifetime(..)"), } } } diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 8e80161af1bf..fb666550e930 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -466,12 +466,6 @@ impl TokenStream { pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream { match nt { - Nonterminal::NtIdent(ident, is_raw) => { - TokenStream::token_alone(token::Ident(ident.name, *is_raw), ident.span) - } - Nonterminal::NtLifetime(ident) => { - TokenStream::token_alone(token::Lifetime(ident.name), ident.span) - } Nonterminal::NtItem(item) => TokenStream::from_ast(item), Nonterminal::NtBlock(block) => TokenStream::from_ast(block), Nonterminal::NtStmt(stmt) if let StmtKind::Empty = stmt.kind => { @@ -489,15 +483,21 @@ impl TokenStream { } fn flatten_token(token: &Token, spacing: Spacing) -> TokenTree { - match &token.kind { - token::Interpolated(nt) if let token::NtIdent(ident, is_raw) = nt.0 => { + match token.kind { + token::NtIdent(ident, is_raw) => { TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing) } - token::Interpolated(nt) => TokenTree::Delimited( + token::NtLifetime(ident) => TokenTree::Delimited( DelimSpan::from_single(token.span), DelimSpacing::new(Spacing::JointHidden, spacing), Delimiter::Invisible, - TokenStream::from_nonterminal_ast(&nt.0).flattened(), + TokenStream::token_alone(token::Lifetime(ident.name), ident.span), + ), + token::Interpolated(ref nt) => TokenTree::Delimited( + DelimSpan::from_single(token.span), + DelimSpacing::new(Spacing::JointHidden, spacing), + Delimiter::Invisible, + TokenStream::from_nonterminal_ast(&nt).flattened(), ), _ => TokenTree::Token(token.clone(), spacing), } @@ -516,7 +516,10 @@ impl TokenStream { pub fn flattened(&self) -> TokenStream { fn can_skip(stream: &TokenStream) -> bool { stream.trees().all(|tree| match tree { - TokenTree::Token(token, _) => !matches!(token.kind, token::Interpolated(_)), + TokenTree::Token(token, _) => !matches!( + token.kind, + token::NtIdent(..) | token::NtLifetime(..) | token::Interpolated(..) + ), TokenTree::Delimited(.., inner) => can_skip(inner), }) } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index f21a9cabb81b..f6e9e1a87c4b 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -1,34 +1,88 @@ -//! Routines the parser uses to classify AST nodes - -// Predicates on exprs and stmts that the pretty-printer and parser use +//! Routines the parser and pretty-printer use to classify AST nodes. +use crate::ast::ExprKind::*; use crate::{ast, token::Delimiter}; -/// Does this expression require a semicolon to be treated -/// as a statement? The negation of this: 'can this expression -/// be used as a statement without a semicolon' -- is used -/// as an early-bail-out in the parser so that, for instance, -/// if true {...} else {...} -/// |x| 5 -/// isn't parsed as (if true {...} else {...} | x) | 5 -pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { - !matches!( +/// This classification determines whether various syntactic positions break out +/// of parsing the current expression (true) or continue parsing more of the +/// same expression (false). +/// +/// For example, it's relevant in the parsing of match arms: +/// +/// ```ignore (illustrative) +/// match ... { +/// // Is this calling $e as a function, or is it the start of a new arm +/// // with a tuple pattern? +/// _ => $e ( +/// ^ ) +/// +/// // Is this an Index operation, or new arm with a slice pattern? +/// _ => $e [ +/// ^ ] +/// +/// // Is this a binary operator, or leading vert in a new arm? Same for +/// // other punctuation which can either be a binary operator in +/// // expression or unary operator in pattern, such as `&` and `-`. +/// _ => $e | +/// ^ +/// } +/// ``` +/// +/// If $e is something like `{}` or `if … {}`, then terminate the current +/// arm and parse a new arm. +/// +/// If $e is something like `path::to` or `(…)`, continue parsing the same +/// arm. +/// +/// *Almost* the same classification is used as an early bail-out for parsing +/// statements. See `expr_requires_semi_to_be_stmt`. +pub fn expr_is_complete(e: &ast::Expr) -> bool { + matches!( e.kind, - ast::ExprKind::If(..) - | ast::ExprKind::Match(..) - | ast::ExprKind::Block(..) - | ast::ExprKind::While(..) - | ast::ExprKind::Loop(..) - | ast::ExprKind::ForLoop { .. } - | ast::ExprKind::TryBlock(..) - | ast::ExprKind::ConstBlock(..) + If(..) + | Match(..) + | Block(..) + | While(..) + | Loop(..) + | ForLoop { .. } + | TryBlock(..) + | ConstBlock(..) ) } +/// Does this expression require a semicolon to be treated as a statement? +/// +/// The negation of this: "can this expression be used as a statement without a +/// semicolon" -- is used as an early bail-out when parsing statements so that, +/// for instance, +/// +/// ```ignore (illustrative) +/// if true {...} else {...} +/// |x| 5 +/// ``` +/// +/// isn't parsed as `(if true {...} else {...} | x) | 5`. +/// +/// Surprising special case: even though braced macro calls like `m! {}` +/// normally do not introduce a boundary when found at the head of a match arm, +/// they do terminate the parsing of a statement. +/// +/// ```ignore (illustrative) +/// match ... { +/// _ => m! {} (), // macro that expands to a function, which is then called +/// } +/// +/// let _ = { m! {} () }; // macro call followed by unit +/// ``` +pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { + match &e.kind { + MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace, + _ => !expr_is_complete(e), + } +} + /// If an expression ends with `}`, returns the innermost expression ending in the `}` pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> { - use ast::ExprKind::*; - loop { match &expr.kind { AddrOf(_, _, e) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a76935761f0a..c23da8aa01e4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1407,7 +1407,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, fn_kind, itctx, - precise_capturing.as_deref().map(|(args, _)| args.as_slice()), + precise_capturing.as_deref().map(|(args, span)| (args.as_slice(), *span)), ), ImplTraitContext::Universal => { if let Some(&(_, span)) = precise_capturing.as_deref() { @@ -1523,7 +1523,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option, itctx: ImplTraitContext, - precise_capturing_args: Option<&[PreciseCapturingArg]>, + precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1533,7 +1533,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); let captured_lifetimes_to_duplicate = - if let Some(precise_capturing) = precise_capturing_args { + if let Some((precise_capturing, _)) = precise_capturing_args { // We'll actually validate these later on; all we need is the list of // lifetimes to duplicate during this portion of lowering. precise_capturing @@ -1607,7 +1607,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes_to_duplicate: FxIndexSet, span: Span, opaque_ty_span: Span, - precise_capturing_args: Option<&[PreciseCapturingArg]>, + precise_capturing_args: Option<(&[PreciseCapturingArg], Span)>, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.create_def( @@ -1698,8 +1698,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { this.with_remapping(captured_to_synthesized_mapping, |this| { ( lower_item_bounds(this), - precise_capturing_args.map(|precise_capturing| { - this.lower_precise_capturing_args(precise_capturing) + precise_capturing_args.map(|(precise_capturing, span)| { + ( + this.lower_precise_capturing_args(precise_capturing), + this.lower_span(span), + ) }), ) }); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 2c176828c841..defb666e2b66 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -55,8 +55,8 @@ impl PpAnn for NoAnn {} pub struct Comments<'a> { sm: &'a SourceMap, - comments: Vec, - current: usize, + // Stored in reverse order so we can consume them by popping. + reversed_comments: Vec, } /// Returns `None` if the first `col` chars of `s` contain a non-whitespace char. @@ -182,21 +182,25 @@ fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec impl<'a> Comments<'a> { pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> { - let comments = gather_comments(sm, filename, input); - Comments { sm, comments, current: 0 } + let mut comments = gather_comments(sm, filename, input); + comments.reverse(); + Comments { sm, reversed_comments: comments } } - // FIXME: This shouldn't probably clone lmao - fn next(&self) -> Option { - self.comments.get(self.current).cloned() + fn peek(&self) -> Option<&Comment> { + self.reversed_comments.last() + } + + fn next(&mut self) -> Option { + self.reversed_comments.pop() } fn trailing_comment( - &self, + &mut self, span: rustc_span::Span, next_pos: Option, ) -> Option { - if let Some(cmnt) = self.next() { + if let Some(cmnt) = self.peek() { if cmnt.style != CommentStyle::Trailing { return None; } @@ -204,7 +208,7 @@ impl<'a> Comments<'a> { let comment_line = self.sm.lookup_char_pos(cmnt.pos); let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1)); if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line { - return Some(cmnt); + return Some(self.next().unwrap()); } } @@ -400,7 +404,8 @@ impl std::ops::DerefMut for State<'_> { /// This trait is used for both AST and HIR pretty-printing. pub trait PrintState<'a>: std::ops::Deref + std::ops::DerefMut { - fn comments(&mut self) -> &mut Option>; + fn comments(&self) -> Option<&Comments<'a>>; + fn comments_mut(&mut self) -> Option<&mut Comments<'a>>; fn ann_post(&mut self, ident: Ident); fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool); @@ -442,18 +447,18 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn maybe_print_comment(&mut self, pos: BytePos) -> bool { let mut has_comment = false; - while let Some(cmnt) = self.next_comment() { - if cmnt.pos < pos { - has_comment = true; - self.print_comment(&cmnt); - } else { + while let Some(cmnt) = self.peek_comment() { + if cmnt.pos >= pos { break; } + has_comment = true; + let cmnt = self.next_comment().unwrap(); + self.print_comment(cmnt); } has_comment } - fn print_comment(&mut self, cmnt: &Comment) { + fn print_comment(&mut self, cmnt: Comment) { match cmnt.style { CommentStyle::Mixed => { if !self.is_beginning_of_line() { @@ -517,19 +522,20 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.hardbreak(); } } - if let Some(cmnts) = self.comments() { - cmnts.current += 1; - } + } + + fn peek_comment<'b>(&'b self) -> Option<&'b Comment> where 'a: 'b { + self.comments().and_then(|c| c.peek()) } fn next_comment(&mut self) -> Option { - self.comments().as_mut().and_then(|c| c.next()) + self.comments_mut().and_then(|c| c.next()) } fn maybe_print_trailing_comment(&mut self, span: rustc_span::Span, next_pos: Option) { - if let Some(cmnts) = self.comments() { + if let Some(cmnts) = self.comments_mut() { if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) { - self.print_comment(&cmnt); + self.print_comment(cmnt); } } } @@ -537,11 +543,11 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_remaining_comments(&mut self) { // If there aren't any remaining comments, then we need to manually // make sure there is a line break at the end. - if self.next_comment().is_none() { + if self.peek_comment().is_none() { self.hardbreak(); } while let Some(cmnt) = self.next_comment() { - self.print_comment(&cmnt) + self.print_comment(cmnt) } } @@ -852,8 +858,6 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::NtBlock(e) => self.block_to_string(e), token::NtStmt(e) => self.stmt_to_string(e), token::NtPat(e) => self.pat_to_string(e), - &token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw.into()).to_string(), - token::NtLifetime(e) => e.to_string(), token::NtLiteral(e) => self.expr_to_string(e), token::NtVis(e) => self.vis_to_string(e), } @@ -915,10 +919,14 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Literal(lit) => literal_to_string(lit).into(), /* Name components */ - token::Ident(s, is_raw) => { - IdentPrinter::new(s, is_raw.into(), convert_dollar_crate).to_string().into() + token::Ident(name, is_raw) => { + IdentPrinter::new(name, is_raw.into(), convert_dollar_crate).to_string().into() } - token::Lifetime(s) => s.to_string().into(), + token::NtIdent(ident, is_raw) => { + IdentPrinter::for_ast_ident(ident, is_raw.into()).to_string().into() + } + token::Lifetime(name) => name.to_string().into(), + token::NtLifetime(ident) => ident.name.to_string().into(), /* Other */ token::DocComment(comment_kind, attr_style, data) => { @@ -926,7 +934,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } token::Eof => "".into(), - token::Interpolated(ref nt) => self.nonterminal_to_string(&nt.0).into(), + token::Interpolated(ref nt) => self.nonterminal_to_string(&nt).into(), } } @@ -994,8 +1002,12 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } impl<'a> PrintState<'a> for State<'a> { - fn comments(&mut self) -> &mut Option> { - &mut self.comments + fn comments(&self) -> Option<&Comments<'a>> { + self.comments.as_ref() + } + + fn comments_mut(&mut self) -> Option<&mut Comments<'a>> { + self.comments.as_mut() } fn ann_post(&mut self, ident: Ident) { @@ -1238,7 +1250,11 @@ impl<'a> State<'a> { if let Some((init, els)) = loc.kind.init_else_opt() { self.nbsp(); self.word_space("="); - self.print_expr(init, FixupContext::default()); + self.print_expr_cond_paren( + init, + els.is_some() && classify::expr_trailing_brace(init).is_some(), + FixupContext::default(), + ); if let Some(els) = els { self.cbox(INDENT_UNIT); self.ibox(INDENT_UNIT); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 93400c67949d..1e117c46b6e2 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -780,7 +780,7 @@ impl<'a> State<'a> { } _ => { self.end(); // Close the ibox for the pattern. - self.print_expr(body, FixupContext::new_stmt()); + self.print_expr(body, FixupContext::new_match_arm()); self.word(","); } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs index d21cb82f83b2..86d4796e9ce3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/fixup.rs @@ -49,6 +49,38 @@ pub(crate) struct FixupContext { /// No parentheses required. leftmost_subexpression_in_stmt: bool, + /// Print expression such that it can be parsed as a match arm. + /// + /// This is almost equivalent to `stmt`, but the grammar diverges a tiny bit + /// between statements and match arms when it comes to braced macro calls. + /// Macro calls with brace delimiter terminate a statement without a + /// semicolon, but do not terminate a match-arm without comma. + /// + /// ```ignore (illustrative) + /// m! {} - 1; // two statements: a macro call followed by -1 literal + /// + /// match () { + /// _ => m! {} - 1, // binary subtraction operator + /// } + /// ``` + match_arm: bool, + + /// This is almost equivalent to `leftmost_subexpression_in_stmt`, other + /// than for braced macro calls. + /// + /// If we have `m! {} - 1` as an expression, the leftmost subexpression + /// `m! {}` will need to be parenthesized in the statement case but not the + /// match-arm case. + /// + /// ```ignore (illustrative) + /// (m! {}) - 1; // subexpression needs parens + /// + /// match () { + /// _ => m! {} - 1, // no parens + /// } + /// ``` + leftmost_subexpression_in_match_arm: bool, + /// This is the difference between: /// /// ```ignore (illustrative) @@ -68,6 +100,8 @@ impl Default for FixupContext { FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, + match_arm: false, + leftmost_subexpression_in_match_arm: false, parenthesize_exterior_struct_lit: false, } } @@ -76,13 +110,16 @@ impl Default for FixupContext { impl FixupContext { /// Create the initial fixup for printing an expression in statement /// position. - /// - /// This is currently also used for printing an expression as a match-arm, - /// but this is incorrect and leads to over-parenthesizing. pub fn new_stmt() -> Self { FixupContext { stmt: true, ..FixupContext::default() } } + /// Create the initial fixup for printing an expression as the right-hand + /// side of a match arm. + pub fn new_match_arm() -> Self { + FixupContext { match_arm: true, ..FixupContext::default() } + } + /// Create the initial fixup for printing an expression as the "condition" /// of an `if` or `while`. There are a few other positions which are /// grammatically equivalent and also use this, such as the iterator @@ -106,6 +143,9 @@ impl FixupContext { FixupContext { stmt: false, leftmost_subexpression_in_stmt: self.stmt || self.leftmost_subexpression_in_stmt, + match_arm: false, + leftmost_subexpression_in_match_arm: self.match_arm + || self.leftmost_subexpression_in_match_arm, ..self } } @@ -119,7 +159,13 @@ impl FixupContext { /// example the `$b` in `$a + $b` and `-$b`, but not the one in `[$b]` or /// `$a.f($b)`. pub fn subsequent_subexpression(self) -> Self { - FixupContext { stmt: false, leftmost_subexpression_in_stmt: false, ..self } + FixupContext { + stmt: false, + leftmost_subexpression_in_stmt: false, + match_arm: false, + leftmost_subexpression_in_match_arm: false, + ..self + } } /// Determine whether parentheses are needed around the given expression to @@ -128,7 +174,8 @@ impl FixupContext { /// The documentation on `FixupContext::leftmost_subexpression_in_stmt` has /// examples. pub fn would_cause_statement_boundary(self, expr: &Expr) -> bool { - self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr) + (self.leftmost_subexpression_in_stmt && !classify::expr_requires_semi_to_be_stmt(expr)) + || (self.leftmost_subexpression_in_match_arm && classify::expr_is_complete(expr)) } /// Determine whether parentheses are needed around the given `let` diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 28c5c505f791..46011c1f43ec 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -1010,7 +1010,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { clauses.iter().any(|pred| { match pred.kind().skip_binder() { ty::ClauseKind::Trait(data) if data.self_ty() == ty => {} - ty::ClauseKind::Projection(data) if data.projection_ty.self_ty() == ty => {} + ty::ClauseKind::Projection(data) + if data.projection_term.self_ty() == ty => {} _ => return false, } tcx.any_free_region_meets(pred, |r| *r == ty::ReEarlyParam(region)) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index e58723c2ec95..167ca7ba0457 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -2059,10 +2059,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We currently do not store the `DefId` in the `ConstraintCategory` // for performances reasons. The error reporting code used by NLL only // uses the span, so this doesn't cause any problems at the moment. - Some(ObligationCauseCode::SpannedWhereClause( - CRATE_DEF_ID.to_def_id(), - predicate_span, - )) + Some(ObligationCauseCode::WhereClause(CRATE_DEF_ID.to_def_id(), predicate_span)) } else { None } diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml index a745f2801cc4..b7063f35a3e8 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml @@ -51,6 +51,14 @@ jobs: if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml index 14aa850ff5cb..1f5a6513f63b 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml @@ -98,12 +98,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install toolchain and emulator if: matrix.apt_deps != null run: | sudo apt-get update sudo apt-get install -y ${{ matrix.apt_deps }} + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare @@ -230,12 +238,20 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu + - name: Use x86_64 compiler on macOS + if: matrix.os == 'macos-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-apple-darwin' + run: rustup set default-host x86_64-apple-darwin + - name: Install MinGW toolchain if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: | sudo apt-get update sudo apt-get install -y gcc-mingw-w64-x86-64 + - name: Select XCode version + if: matrix.os == 'macos-latest' + run: sudo xcode-select -s /Applications/Xcode_14.3.1.app + - name: Prepare dependencies run: ./y.sh prepare diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml index 75ea94ee7979..70c214ce8b14 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml +++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Prepare dependencies run: ./y.sh prepare @@ -43,7 +43,7 @@ jobs: uses: actions/cache@v4 with: path: build/cg_clif - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + key: ${{ runner.os }}-rustc-test-cargo-build-target-${{ hashFiles('rust-toolchain', 'Cargo.lock') }} - name: Install ripgrep run: | diff --git a/compiler/rustc_codegen_cranelift/.gitignore b/compiler/rustc_codegen_cranelift/.gitignore index 7915fa138f8f..5a38f2acb0e2 100644 --- a/compiler/rustc_codegen_cranelift/.gitignore +++ b/compiler/rustc_codegen_cranelift/.gitignore @@ -1,8 +1,4 @@ # Build artifacts during normal use -/y.bin -/y.bin.dSYM -/y.exe -/y.pdb /download /build /dist diff --git a/compiler/rustc_codegen_cranelift/build_system/Cargo.toml b/compiler/rustc_codegen_cranelift/build_system/Cargo.toml index f47b9bc55404..feed2b6eafe8 100644 --- a/compiler/rustc_codegen_cranelift/build_system/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/build_system/Cargo.toml @@ -11,3 +11,6 @@ path = "main.rs" unstable-features = [] # for rust-analyzer # Do not add any dependencies + +[profile.dev] +debug = 1 diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index 10c3f9cfa2ce..196ff8fda754 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs @@ -267,12 +267,16 @@ fn build_clif_sysroot_for_triple( prefix.to_str().unwrap() )); } + rustflags.push("-Zunstable-options".to_owned()); + for (name, values) in EXTRA_CHECK_CFGS { + rustflags.push(check_cfg_arg(name, *values)); + } compiler.rustflags.extend(rustflags); let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs); if channel == "release" { build_cmd.arg("--release"); } - build_cmd.arg("--features").arg("compiler-builtins-no-asm backtrace panic-unwind"); + build_cmd.arg("--features").arg("backtrace panic-unwind"); build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true"); build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif"); if compiler.triple.contains("apple") { @@ -326,3 +330,34 @@ fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option { Some(target_libs) } + +// Copied from https://github.com/rust-lang/rust/blob/4fd98a4b1b100f5329c6efae18031791f64372d2/src/bootstrap/src/utils/helpers.rs#L569-L585 +/// Create a `--check-cfg` argument invocation for a given name +/// and it's values. +fn check_cfg_arg(name: &str, values: Option<&[&str]>) -> String { + // Creating a string of the values by concatenating each value: + // ',values("tvos","watchos")' or '' (nothing) when there are no values. + let next = match values { + Some(values) => { + let mut tmp = values.iter().flat_map(|val| [",", "\"", val, "\""]).collect::(); + + tmp.insert_str(1, "values("); + tmp.push(')'); + tmp + } + None => "".to_string(), + }; + format!("--check-cfg=cfg({name}{next})") +} + +const EXTRA_CHECK_CFGS: &[(&str, Option<&[&str]>)] = &[ + ("bootstrap", None), + ("stdarch_intel_sde", None), + ("no_fp_fmt_parse", None), + ("no_global_oom_handling", None), + ("no_rc", None), + ("no_sync", None), + ("netbsd10", None), + ("backtrace_in_libstd", None), + ("target_arch", Some(&["xtensa"])), +]; diff --git a/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs index cdd2bae03f8f..7dbf608f991e 100644 --- a/compiler/rustc_codegen_cranelift/build_system/main.rs +++ b/compiler/rustc_codegen_cranelift/build_system/main.rs @@ -147,9 +147,11 @@ fn main() { let rustup_toolchain_name = match (env::var("CARGO"), env::var("RUSTC"), env::var("RUSTDOC")) { (Ok(_), Ok(_), Ok(_)) => None, - (Err(_), Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), - _ => { - eprintln!("All of CARGO, RUSTC and RUSTDOC need to be set or none must be set"); + (_, Err(_), Err(_)) => Some(rustc_info::get_toolchain_name()), + vars => { + eprintln!( + "If RUSTC or RUSTDOC is set, both need to be set and in addition CARGO needs to be set: {vars:?}" + ); process::exit(1); } }; diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index 76104901474c..278f334796a9 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -77,7 +77,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[ ), TestCase::build_lib("build.alloc_system", "example/alloc_system.rs", "lib"), TestCase::build_bin_and_run("aot.alloc_example", "example/alloc_example.rs", &[]), - TestCase::jit_bin("jit.std_example", "example/std_example.rs", ""), + TestCase::jit_bin("jit.std_example", "example/std_example.rs", "arg"), TestCase::build_bin_and_run("aot.std_example", "example/std_example.rs", &["arg"]), TestCase::build_bin_and_run("aot.dst_field_align", "example/dst-field-align.rs", &[]), TestCase::build_bin_and_run( diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index efa4be7e15ac..aab20f672487 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs @@ -4,6 +4,7 @@ never_type, linkage, extern_types, + naked_functions, thread_local, repr_simd, raw_ref_op @@ -340,6 +341,7 @@ fn main() { ))] unsafe { global_asm_test(); + naked_test(); } // Both statics have a reference that points to the same anonymous allocation. @@ -395,6 +397,14 @@ global_asm! { " } +#[cfg(all(not(jit), not(no_unstable_features), target_arch = "x86_64"))] +#[naked] +extern "C" fn naked_test() { + unsafe { + asm!("ret", options(noreturn)); + } +} + #[repr(C)] enum c_void { _1, diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index 90d4ab721dae..7347b2e77899 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs @@ -210,6 +210,21 @@ struct I64X2(i64, i64); #[allow(improper_ctypes_definitions)] extern "C" fn foo(_a: I64X2) {} +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "sse4.2")] +#[cfg(not(jit))] +unsafe fn test_crc32() { + assert!(is_x86_feature_detected!("sse4.2")); + + let a = 42u32; + let b = 0xdeadbeefu64; + + assert_eq!(_mm_crc32_u8(a, b as u8), 4135334616); + assert_eq!(_mm_crc32_u16(a, b as u16), 1200687288); + assert_eq!(_mm_crc32_u32(a, b as u32), 2543798776); + assert_eq!(_mm_crc32_u64(a as u64, b as u64), 241952147); +} + #[cfg(target_arch = "x86_64")] #[target_feature(enable = "sse2")] unsafe fn test_simd() { @@ -244,10 +259,14 @@ unsafe fn test_simd() { test_mm256_shuffle_epi8(); test_mm256_permute2x128_si256(); + test_mm256_permutevar8x32_epi32(); #[rustfmt::skip] let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))); assert_eq!(mask1, 1); + + #[cfg(not(jit))] + test_crc32(); } #[cfg(target_arch = "x86_64")] @@ -447,6 +466,16 @@ unsafe fn test_mm256_permute2x128_si256() { assert_eq_m256i(r, e); } +#[cfg(target_arch = "x86_64")] +#[target_feature(enable = "avx2")] +unsafe fn test_mm256_permutevar8x32_epi32() { + let a = _mm256_setr_epi32(100, 200, 300, 400, 500, 600, 700, 800); + let idx = _mm256_setr_epi32(7, 6, 5, 4, 3, 2, 1, 0); + let r = _mm256_setr_epi32(800, 700, 600, 500, 400, 300, 200, 100); + let e = _mm256_permutevar8x32_epi32(a, idx); + assert_eq_m256i(r, e); +} + fn test_checked_mul() { let u: Option = u8::from_str_radix("1000", 10).ok(); assert_eq!(u, None); diff --git a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml index a72fa2c62a96..c8c7b45bc9a6 100644 --- a/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml +++ b/compiler/rustc_codegen_cranelift/patches/stdlib-lock.toml @@ -42,9 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.90" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain index de340cf8c35c..a2ba79cbe903 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain +++ b/compiler/rustc_codegen_cranelift/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-04-23" +channel = "nightly-2024-05-13" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 8580f4557e88..689cda21643c 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh @@ -44,6 +44,7 @@ rm tests/incremental/hashes/statics.rs # same rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support +rm tests/ui/delegation/fn-header.rs # unsized locals rm -r tests/run-pass-valgrind/unsized-locals @@ -87,6 +88,7 @@ rm -r tests/run-make/no-builtins-attribute # same rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific +rm -r tests/run-make/print-to-output # requires --print relocation-models # requires asm, llvm-ir and/or llvm-bc emit support # ============================================= @@ -151,7 +153,7 @@ index 9607ff02f96..b7d97caf9a2 100644 let mut cmd = setup_common(); - let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); - cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd } + Self { cmd, stdin: None } } EOF diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 6f346af25c6d..4bcef15ad047 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -412,7 +412,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( Err(instance) => Some(instance), } } - InstanceDef::DropGlue(_, None) => { + InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) => { // empty drop glue - a nop. let dest = target.expect("Non terminating drop_in_place_real???"); let ret_block = fx.get_block(dest); @@ -597,7 +597,9 @@ pub(crate) fn codegen_drop<'tcx>( let ty = drop_place.layout().ty; let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx); - if let ty::InstanceDef::DropGlue(_, None) = drop_instance.def { + if let ty::InstanceDef::DropGlue(_, None) | ty::InstanceDef::AsyncDropGlueCtorShim(_, None) = + drop_instance.def + { // we don't actually need to drop anything } else { match ty.kind() { diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 8874efadec9d..5846689643fd 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -6,6 +6,7 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use cranelift_module::ModuleError; use rustc_ast::InlineAsmOptions; use rustc_index::IndexVec; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -14,6 +15,7 @@ use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphizat use crate::constant::ConstantCx; use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; +use crate::inline_asm::codegen_naked_asm; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -32,7 +34,7 @@ pub(crate) fn codegen_fn<'tcx>( cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, -) -> CodegenedFunction { +) -> Option { debug_assert!(!instance.args.has_infer()); let symbol_name = tcx.symbol_name(instance).name.to_string(); @@ -48,6 +50,37 @@ pub(crate) fn codegen_fn<'tcx>( String::from_utf8_lossy(&buf).into_owned() }); + if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) { + assert_eq!(mir.basic_blocks.len(), 1); + assert!(mir.basic_blocks[START_BLOCK].statements.is_empty()); + + match &mir.basic_blocks[START_BLOCK].terminator().kind { + TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans: _, + targets: _, + unwind: _, + } => { + codegen_naked_asm( + tcx, + cx, + module, + instance, + mir.basic_blocks[START_BLOCK].terminator().source_info.span, + &symbol_name, + template, + operands, + *options, + ); + } + _ => unreachable!(), + } + + return None; + } + // Declare function let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance); let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap(); @@ -128,7 +161,7 @@ pub(crate) fn codegen_fn<'tcx>( // Verify function verify_func(tcx, &clif_comments, &func); - CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx } + Some(CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }) } pub(crate) fn compile_fn( diff --git a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs index 9678969134a8..a73860cf18b2 100644 --- a/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs +++ b/compiler/rustc_codegen_cranelift/src/concurrency_limiter.rs @@ -6,7 +6,7 @@ use rustc_session::Session; // FIXME don't panic when a worker thread panics pub(super) struct ConcurrencyLimiter { - helper_thread: Option, + helper_thread: Option>, state: Arc>, available_token_condvar: Arc, finished: bool, @@ -39,14 +39,14 @@ impl ConcurrencyLimiter { }) .unwrap(); ConcurrencyLimiter { - helper_thread: Some(helper_thread), + helper_thread: Some(Mutex::new(helper_thread)), state, available_token_condvar, finished: false, } } - pub(super) fn acquire(&mut self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { + pub(super) fn acquire(&self, dcx: &rustc_errors::DiagCtxt) -> ConcurrencyLimiterToken { let mut state = self.state.lock().unwrap(); loop { state.assert_invariants(); @@ -73,16 +73,11 @@ impl ConcurrencyLimiter { } } - self.helper_thread.as_mut().unwrap().request_token(); + self.helper_thread.as_ref().unwrap().lock().unwrap().request_token(); state = self.available_token_condvar.wait(state).unwrap(); } } - pub(super) fn job_already_done(&mut self) { - let mut state = self.state.lock().unwrap(); - state.job_already_done(); - } - pub(crate) fn finished(mut self) { self.helper_thread.take(); @@ -190,14 +185,6 @@ mod state { self.assert_invariants(); } - pub(super) fn job_already_done(&mut self) { - self.assert_invariants(); - self.pending_jobs -= 1; - self.assert_invariants(); - self.drop_excess_capacity(); - self.assert_invariants(); - } - pub(super) fn poison(&mut self, error: String) { self.poisoned = true; self.stored_error = Some(error); diff --git a/compiler/rustc_codegen_cranelift/src/config.rs b/compiler/rustc_codegen_cranelift/src/config.rs index 9e92d656c76e..12bce680d9e1 100644 --- a/compiler/rustc_codegen_cranelift/src/config.rs +++ b/compiler/rustc_codegen_cranelift/src/config.rs @@ -64,8 +64,13 @@ impl Default for BackendConfig { BackendConfig { codegen_mode: CodegenMode::Aot, jit_args: { - let args = std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); - args.split(' ').map(|arg| arg.to_string()).collect() + match std::env::var("CG_CLIF_JIT_ARGS") { + Ok(args) => args.split(' ').map(|arg| arg.to_string()).collect(), + Err(std::env::VarError::NotPresent) => vec![], + Err(std::env::VarError::NotUnicode(s)) => { + panic!("CG_CLIF_JIT_ARGS not unicode: {:?}", s); + } + } }, enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"), disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"), diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index cdf499a22f8d..64e83e43d327 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -258,7 +258,7 @@ fn data_id_for_static( ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol_name = tcx.symbol_name(instance).name; if let Some(import_linkage) = attrs.import_linkage { diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index 670384663e83..e7ac084558a5 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -28,16 +28,20 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } => { let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; - let to = if ptr.layout().abi.is_signed() { - ty::ScalarInt::try_from_int( - ptr.layout().size.sign_extend(to) as i128, - ptr.layout().size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(to, ptr.layout().size).unwrap() + let to = match ptr.layout().ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, to as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (to >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(ptr.layout().ty).unwrap(); + let raw_val = ptr.layout().size.truncate(to); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let discr = CValue::const_val(fx, ptr.layout(), to); + let discr = CValue::by_val(to, ptr.layout()); ptr.write_cvalue(fx, discr); } Variants::Multiple { @@ -85,16 +89,21 @@ pub(crate) fn codegen_get_discriminant<'tcx>( .ty .discriminant_for_variant(fx.tcx, *index) .map_or(u128::from(index.as_u32()), |discr| discr.val); - let discr_val = if dest_layout.abi.is_signed() { - ty::ScalarInt::try_from_int( - dest_layout.size.sign_extend(discr_val) as i128, - dest_layout.size, - ) - .unwrap() - } else { - ty::ScalarInt::try_from_uint(discr_val, dest_layout.size).unwrap() + + let val = match dest_layout.ty.kind() { + ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { + let lsb = fx.bcx.ins().iconst(types::I64, discr_val as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (discr_val >> 64) as u64 as i64); + fx.bcx.ins().iconcat(lsb, msb) + } + ty::Uint(_) | ty::Int(_) => { + let clif_ty = fx.clif_type(dest_layout.ty).unwrap(); + let raw_val = dest_layout.size.truncate(discr_val); + fx.bcx.ins().iconst(clif_ty, raw_val as i64) + } + _ => unreachable!(), }; - let res = CValue::const_val(fx, dest_layout, discr_val); + let res = CValue::by_val(val, dest_layout); dest.write_cvalue(fx, res); return; } diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index e8c96486041b..fce4690f97dc 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -15,6 +15,7 @@ use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_data_structures::sync::{par_map, IntoDynSyncSend}; use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -481,15 +482,16 @@ fn module_codegen( for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - let codegened_function = crate::base::codegen_fn( + if let Some(codegened_function) = crate::base::codegen_fn( tcx, &mut cx, &mut type_dbg, Function::new(), &mut module, inst, - ); - codegened_functions.push(codegened_function); + ) { + codegened_functions.push(codegened_function); + } } MonoItem::Static(def_id) => { let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); @@ -604,39 +606,39 @@ pub(crate) fn run_aot( let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx)); - let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len()); + let (todo_cgus, done_cgus) = + cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] { + _ if backend_config.disable_incr_cache => true, + CguReuse::No => true, + CguReuse::PreLto | CguReuse::PostLto => false, + }); + + let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(tcx.sess, todo_cgus.len())); let modules = tcx.sess.time("codegen mono items", || { - cgus.iter() - .enumerate() - .map(|(i, cgu)| { - let cgu_reuse = - if backend_config.disable_incr_cache { CguReuse::No } else { cgu_reuse[i] }; - match cgu_reuse { - CguReuse::No => { - let dep_node = cgu.codegen_dep_node(tcx); - tcx.dep_graph - .with_task( - dep_node, - tcx, - ( - backend_config.clone(), - global_asm_config.clone(), - cgu.name(), - concurrency_limiter.acquire(tcx.dcx()), - ), - module_codegen, - Some(rustc_middle::dep_graph::hash_result), - ) - .0 - } - CguReuse::PreLto | CguReuse::PostLto => { - concurrency_limiter.job_already_done(); - OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu)) - } - } - }) - .collect::>() + let mut modules: Vec<_> = par_map(todo_cgus, |(_, cgu)| { + let dep_node = cgu.codegen_dep_node(tcx); + tcx.dep_graph + .with_task( + dep_node, + tcx, + ( + backend_config.clone(), + global_asm_config.clone(), + cgu.name(), + concurrency_limiter.acquire(tcx.dcx()), + ), + module_codegen, + Some(rustc_middle::dep_graph::hash_result), + ) + .0 + }); + modules.extend( + done_cgus + .into_iter() + .map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))), + ); + modules }); let mut allocator_module = make_module(tcx.sess, &backend_config, "allocator_shim".to_string()); @@ -705,6 +707,6 @@ pub(crate) fn run_aot( metadata_module, metadata, crate_info: CrateInfo::new(tcx, target_cpu), - concurrency_limiter, + concurrency_limiter: concurrency_limiter.0, }) } diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index 929fa92596dc..4b149131b61a 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -83,13 +83,6 @@ fn create_jit_module( ); crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context); - crate::main_shim::maybe_create_entry_wrapper( - tcx, - &mut jit_module, - &mut cx.unwind_context, - true, - true, - ); (jit_module, cx) } @@ -153,6 +146,14 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.dcx().fatal("Inline asm is not supported in JIT mode"); } + crate::main_shim::maybe_create_entry_wrapper( + tcx, + &mut jit_module, + &mut cx.unwind_context, + true, + true, + ); + tcx.dcx().abort_if_errors(); jit_module.finalize_definitions().unwrap(); @@ -231,16 +232,16 @@ pub(crate) fn codegen_and_compile_fn<'tcx>( crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = crate::base::codegen_fn( + if let Some(codegened_func) = crate::base::codegen_fn( tcx, cx, &mut TypeDebugContext::default(), cached_func, module, instance, - ); - - crate::base::compile_fn(cx, cached_context, module, codegened_func); + ) { + crate::base::compile_fn(cx, cached_context, module, codegened_func); + } }); } diff --git a/compiler/rustc_codegen_cranelift/src/driver/mod.rs b/compiler/rustc_codegen_cranelift/src/driver/mod.rs index 12e90b584103..fb0eed07c197 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/mod.rs @@ -5,6 +5,7 @@ //! [`codegen_static`]: crate::constant::codegen_static use rustc_data_structures::profiling::SelfProfilerRef; +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{MonoItem, MonoItemData}; use crate::prelude::*; @@ -33,7 +34,20 @@ fn predefine_mono_items<'tcx>( data.visibility, is_compiler_builtins, ); - module.declare_function(name, linkage, &sig).unwrap(); + let is_naked = tcx + .codegen_fn_attrs(instance.def_id()) + .flags + .contains(CodegenFnAttrFlags::NAKED); + module + .declare_function( + name, + // Naked functions are defined in a separate object + // file from the codegen unit rustc expects them to + // be defined in. + if is_naked { Linkage::Import } else { linkage }, + &sig, + ) + .unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} } diff --git a/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 5a0cd3990f2a..0c99a5ce12f6 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/global_asm.rs @@ -81,7 +81,7 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, ); } - let instance = Instance::mono(tcx, def_id).polymorphize(tcx); + let instance = Instance::mono(tcx, def_id); let symbol = tcx.symbol_name(instance); global_asm.push_str(symbol.name); } diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 28b92f730da3..2de804f5e042 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -127,7 +127,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( } InlineAsmOperand::SymStatic { def_id } => { assert!(fx.tcx.is_static(def_id)); - let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + let instance = Instance::mono(fx.tcx, def_id); CInlineAsmOperand::Symbol { symbol: fx.tcx.symbol_name(instance).name.to_owned() } } InlineAsmOperand::Label { .. } => { @@ -169,6 +169,7 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( stack_slots_input: Vec::new(), stack_slots_output: Vec::new(), stack_slot_size: Size::from_bytes(0), + is_naked: false, }; asm_gen.allocate_registers(); asm_gen.allocate_stack_slots(); @@ -209,6 +210,121 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs); } +pub(crate) fn codegen_naked_asm<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut crate::CodegenCx, + module: &mut dyn Module, + instance: Instance<'tcx>, + span: Span, + symbol_name: &str, + template: &[InlineAsmTemplatePiece], + operands: &[InlineAsmOperand<'tcx>], + options: InlineAsmOptions, +) { + // FIXME add .eh_frame unwind info directives + + let operands = operands + .iter() + .map(|operand| match *operand { + InlineAsmOperand::In { .. } + | InlineAsmOperand::Out { .. } + | InlineAsmOperand::InOut { .. } => { + span_bug!(span, "invalid operand type for naked asm") + } + InlineAsmOperand::Const { ref value } => { + let cv = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + let const_value = cv + .eval(tcx, ty::ParamEnv::reveal_all(), value.span) + .expect("erroneous constant missed by mono item collection"); + + let value = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + span, + const_value, + RevealAllLayoutCx(tcx).layout_of(cv.ty()), + ); + CInlineAsmOperand::Const { value } + } + InlineAsmOperand::SymFn { ref value } => { + if cfg!(not(feature = "inline_asm_sym")) { + tcx.dcx() + .span_err(span, "asm! and global_asm! sym operands are not yet supported"); + } + + let const_ = instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + ty::ParamEnv::reveal_all(), + ty::EarlyBinder::bind(value.const_), + ); + if let ty::FnDef(def_id, args) = *const_.ty().kind() { + let instance = ty::Instance::resolve_for_fn_ptr( + tcx, + ty::ParamEnv::reveal_all(), + def_id, + args, + ) + .unwrap(); + let symbol = tcx.symbol_name(instance); + + // Pass a wrapper rather than the function itself as the function itself may not + // be exported from the main codegen unit and may thus be unreachable from the + // object file created by an external assembler. + let inline_asm_index = cx.inline_asm_index.get(); + cx.inline_asm_index.set(inline_asm_index + 1); + let wrapper_name = format!( + "__inline_asm_{}_wrapper_n{}", + cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + inline_asm_index + ); + let sig = + get_function_sig(tcx, module.target_config().default_call_conv, instance); + create_wrapper_function( + module, + &mut cx.unwind_context, + sig, + &wrapper_name, + symbol.name, + ); + + CInlineAsmOperand::Symbol { symbol: wrapper_name } + } else { + span_bug!(span, "invalid type for asm sym (fn)"); + } + } + InlineAsmOperand::SymStatic { def_id } => { + assert!(tcx.is_static(def_id)); + let instance = Instance::mono(tcx, def_id); + CInlineAsmOperand::Symbol { symbol: tcx.symbol_name(instance).name.to_owned() } + } + InlineAsmOperand::Label { .. } => { + span_bug!(span, "asm! label operands are not yet supported"); + } + }) + .collect::>(); + + let asm_gen = InlineAssemblyGenerator { + tcx, + arch: tcx.sess.asm_arch.unwrap(), + enclosing_def_id: instance.def_id(), + template, + operands: &operands, + options, + registers: Vec::new(), + stack_slots_clobber: Vec::new(), + stack_slots_input: Vec::new(), + stack_slots_output: Vec::new(), + stack_slot_size: Size::from_bytes(0), + is_naked: true, + }; + + let generated_asm = asm_gen.generate_asm_wrapper(symbol_name); + cx.global_asm.push_str(&generated_asm); +} + struct InlineAssemblyGenerator<'a, 'tcx> { tcx: TyCtxt<'tcx>, arch: InlineAsmArch, @@ -221,10 +337,13 @@ struct InlineAssemblyGenerator<'a, 'tcx> { stack_slots_input: Vec>, stack_slots_output: Vec>, stack_slot_size: Size, + is_naked: bool, } impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { fn allocate_registers(&mut self) { + assert!(!self.is_naked); + let sess = self.tcx.sess; let map = allocatable_registers( self.arch, @@ -348,6 +467,8 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { } fn allocate_stack_slots(&mut self) { + assert!(!self.is_naked); + let mut slot_size = Size::from_bytes(0); let mut slots_clobber = vec![None; self.operands.len()]; let mut slots_input = vec![None; self.operands.len()]; @@ -468,30 +589,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { if is_x86 { generated_asm.push_str(".intel_syntax noprefix\n"); } - Self::prologue(&mut generated_asm, self.arch); + if !self.is_naked { + Self::prologue(&mut generated_asm, self.arch); - // Save clobbered registers - if !self.options.contains(InlineAsmOptions::NORETURN) { + // Save clobbered registers + if !self.options.contains(InlineAsmOptions::NORETURN) { + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } + } + + // Write input registers for (reg, slot) in self .registers .iter() - .zip(self.stack_slots_clobber.iter().copied()) + .zip(self.stack_slots_input.iter().copied()) .filter_map(|(r, s)| r.zip(s)) { - Self::save_register(&mut generated_asm, self.arch, reg, slot); + Self::restore_register(&mut generated_asm, self.arch, reg, slot); } } - // Write input registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_input.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } - if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) { generated_asm.push_str(".att_syntax\n"); } @@ -553,30 +676,32 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { generated_asm.push_str(".intel_syntax noprefix\n"); } - if !self.options.contains(InlineAsmOptions::NORETURN) { - // Read output registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_output.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::save_register(&mut generated_asm, self.arch, reg, slot); - } + if !self.is_naked { + if !self.options.contains(InlineAsmOptions::NORETURN) { + // Read output registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_output.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::save_register(&mut generated_asm, self.arch, reg, slot); + } - // Restore clobbered registers - for (reg, slot) in self - .registers - .iter() - .zip(self.stack_slots_clobber.iter().copied()) - .filter_map(|(r, s)| r.zip(s)) - { - Self::restore_register(&mut generated_asm, self.arch, reg, slot); - } + // Restore clobbered registers + for (reg, slot) in self + .registers + .iter() + .zip(self.stack_slots_clobber.iter().copied()) + .filter_map(|(r, s)| r.zip(s)) + { + Self::restore_register(&mut generated_asm, self.arch, reg, slot); + } - Self::epilogue(&mut generated_asm, self.arch); - } else { - Self::epilogue_noreturn(&mut generated_asm, self.arch); + Self::epilogue(&mut generated_asm, self.arch); + } else { + Self::epilogue_noreturn(&mut generated_asm, self.arch); + } } if is_x86 { diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 8df83c706a10..27b55ecc72ee 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -374,6 +374,21 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } } + "llvm.x86.avx2.permd" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_permutevar8x32_epi32 + intrinsic_args!(fx, args => (a, idx); intrinsic); + + for j in 0..=7 { + let index = idx.value_typed_lane(fx, fx.tcx.types.u32, j).load_scalar(fx); + let index = fx.bcx.ins().uextend(fx.pointer_type, index); + let value = a.value_lane_dyn(fx, index).load_scalar(fx); + ret.place_typed_lane(fx, fx.tcx.types.u32, j).to_ptr().store( + fx, + value, + MemFlags::trusted(), + ); + } + } "llvm.x86.avx2.vperm2i128" | "llvm.x86.avx.vperm2f128.ps.256" | "llvm.x86.avx.vperm2f128.pd.256" => { @@ -832,6 +847,43 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( } } + "llvm.x86.sse42.crc32.32.8" + | "llvm.x86.sse42.crc32.32.16" + | "llvm.x86.sse42.crc32.32.32" + | "llvm.x86.sse42.crc32.64.64" => { + // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1419&text=_mm_crc32_u32 + intrinsic_args!(fx, args => (crc, v); intrinsic); + + let crc = crc.load_scalar(fx); + let v = v.load_scalar(fx); + + let asm = match intrinsic { + "llvm.x86.sse42.crc32.32.8" => "crc32 eax, dl", + "llvm.x86.sse42.crc32.32.16" => "crc32 eax, dx", + "llvm.x86.sse42.crc32.32.32" => "crc32 eax, edx", + "llvm.x86.sse42.crc32.64.64" => "crc32 rax, rdx", + _ => unreachable!(), + }; + + codegen_inline_asm_inner( + fx, + &[InlineAsmTemplatePiece::String(asm.to_string())], + &[ + CInlineAsmOperand::InOut { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), + _late: true, + in_value: crc, + out_place: Some(ret), + }, + CInlineAsmOperand::In { + reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), + value: v, + }, + ], + InlineAsmOptions::NOSTACK | InlineAsmOptions::PURE | InlineAsmOptions::NOMEM, + ); + } + "llvm.x86.sse42.pcmpestri128" => { // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_cmpestri&ig_expand=939 intrinsic_args!(fx, args => (a, la, b, lb, _imm8); intrinsic); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index e72951b6f344..39bbad16b0c0 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -331,9 +331,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Arc CValue<'tcx> { let clif_ty = fx.clif_type(layout.ty).unwrap(); - if let ty::Bool = layout.ty.kind() { - assert!( - const_val == ty::ScalarInt::FALSE || const_val == ty::ScalarInt::TRUE, - "Invalid bool 0x{:032X}", - const_val - ); - } - let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.assert_bits(layout.size); diff --git a/compiler/rustc_codegen_cranelift/y.cmd b/compiler/rustc_codegen_cranelift/y.cmd index e9b688645a4d..42106849163b 100644 --- a/compiler/rustc_codegen_cranelift/y.cmd +++ b/compiler/rustc_codegen_cranelift/y.cmd @@ -1,8 +1,6 @@ @echo off echo [BUILD] build system >&2 -mkdir build 2>nul -rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 || goto :error -build\y.exe %* || goto :error +cargo run --manifest-path build_system/Cargo.toml -- %* || goto :error goto :EOF :error diff --git a/compiler/rustc_codegen_cranelift/y.ps1 b/compiler/rustc_codegen_cranelift/y.ps1 old mode 100644 new mode 100755 index 02ef0fcbd50f..821f0ec6e577 --- a/compiler/rustc_codegen_cranelift/y.ps1 +++ b/compiler/rustc_codegen_cranelift/y.ps1 @@ -1,12 +1,7 @@ $ErrorActionPreference = "Stop" $host.ui.WriteErrorLine("[BUILD] build system") -New-Item -ItemType Directory -Force -Path build | Out-Null -& rustc build_system/main.rs -o build\y.exe -Cdebuginfo=1 --edition 2021 -if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE -} -& build\y.exe $args +& cargo run --manifest-path build_system/Cargo.toml -- $args if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } diff --git a/compiler/rustc_codegen_cranelift/y.sh b/compiler/rustc_codegen_cranelift/y.sh index bc925a23e2a8..b9152d2cc6de 100755 --- a/compiler/rustc_codegen_cranelift/y.sh +++ b/compiler/rustc_codegen_cranelift/y.sh @@ -2,5 +2,4 @@ set -e echo "[BUILD] build system" 1>&2 -rustc build_system/main.rs -o y.bin -Cdebuginfo=1 --edition 2021 -exec ./y.bin "$@" +exec cargo run --manifest-path build_system/Cargo.toml -- "$@" diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 358c24bfb823..877e5b75912e 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -283,7 +283,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } if src_f.layout.ty == dst_f.layout.ty { - bx.typed_place_copy(dst_f, src_f); + bx.typed_place_copy(dst_f.val, src_f.val, src_f.layout); } else { coerce_unsized_into(bx, src_f, dst_f); } diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index d36972d0d866..ba6aad51316c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1454,9 +1454,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi), None => arg.layout.align.abi, }; - let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align); - op.val.store(bx, scratch); - (scratch.val.llval, scratch.val.align, true) + let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + op.val.store(bx, scratch.with_type(arg.layout)); + (scratch.llval, scratch.align, true) } PassMode::Cast { .. } => { let scratch = PlaceRef::alloca(bx, arg.layout); @@ -1475,10 +1475,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // For `foo(packed.large_field)`, and types with <4 byte alignment on x86, // alignment requirements may be higher than the type's alignment, so copy // to a higher-aligned alloca. - let scratch = PlaceRef::alloca_aligned(bx, arg.layout, required_align); - let op_place = PlaceRef { val: op_place_val, layout: op.layout }; - bx.typed_place_copy(scratch, op_place); - (scratch.val.llval, scratch.val.align, true) + let scratch = PlaceValue::alloca(bx, arg.layout.size, required_align); + bx.typed_place_copy(scratch, op_place_val, op.layout); + (scratch.llval, scratch.align, true) } else { (op_place_val.llval, op_place_val.align, true) } @@ -1567,7 +1566,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if place_val.llextra.is_some() { bug!("closure arguments must be sized"); } - let tuple_ptr = PlaceRef { val: place_val, layout: tuple.layout }; + let tuple_ptr = place_val.with_type(tuple.layout); for i in 0..tuple.layout.fields.count() { let field_ptr = tuple_ptr.project_field(bx, i); let field = bx.load_operand(field_ptr); diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs index 2e008460798f..f88deaa7abca 100644 --- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs @@ -1,4 +1,4 @@ -use super::operand::{OperandRef, OperandValue}; +use super::operand::OperandRef; use super::place::PlaceRef; use super::FunctionCx; use crate::errors; @@ -93,9 +93,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // into the (unoptimized) direct swapping implementation, so we disable it. || bx.sess().target.arch == "spirv" { - let x_place = PlaceRef::new_sized(args[0].immediate(), pointee_layout); - let y_place = PlaceRef::new_sized(args[1].immediate(), pointee_layout); - bx.typed_place_swap(x_place, y_place); + let align = pointee_layout.align.abi; + let x_place = args[0].val.deref(align); + let y_place = args[1].val.deref(align); + bx.typed_place_swap(x_place, y_place, pointee_layout); return Ok(()); } } @@ -113,15 +114,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { sym::va_end => bx.va_end(args[0].immediate()), sym::size_of_val => { let tp_ty = fn_args.type_at(0); - let meta = - if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (_, meta) = args[0].val.pointer_parts(); let (llsize, _) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); llsize } sym::min_align_of_val => { let tp_ty = fn_args.type_at(0); - let meta = - if let OperandValue::Pair(_, meta) = args[0].val { Some(meta) } else { None }; + let (_, meta) = args[0].val.pointer_parts(); let (_, llalign) = size_of_val::size_and_align_of_dst(bx, tp_ty, meta); llalign } diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 0479dd11ed08..32fd9b657f99 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -61,7 +61,7 @@ pub enum OperandValue { ZeroSized, } -impl OperandValue { +impl OperandValue { /// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values. /// If this is Ref, return the place. #[inline] @@ -86,6 +86,43 @@ impl OperandValue { }; OperandValue::Pair(a, b) } + + /// Treat this value as a pointer and return the data pointer and + /// optional metadata as backend values. + /// + /// If you're making a place, use [`Self::deref`] instead. + pub fn pointer_parts(self) -> (V, Option) { + match self { + OperandValue::Immediate(llptr) => (llptr, None), + OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), + _ => bug!("OperandValue cannot be a pointer: {self:?}"), + } + } + + /// Treat this value as a pointer and return the place to which it points. + /// + /// The pointer immediate doesn't inherently know its alignment, + /// so you need to pass it in. If you want to get it from a type's ABI + /// alignment, then maybe you want [`OperandRef::deref`] instead. + /// + /// This is the inverse of [`PlaceValue::address`]. + pub fn deref(self, align: Align) -> PlaceValue { + let (llval, llextra) = self.pointer_parts(); + PlaceValue { llval, llextra, align } + } + + pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeMethods<'tcx>>( + &self, + cx: &Cx, + ty: TyAndLayout<'tcx>, + ) -> bool { + match self { + OperandValue::ZeroSized => ty.is_zst(), + OperandValue::Immediate(_) => cx.is_backend_immediate(ty), + OperandValue::Pair(_, _) => cx.is_backend_scalar_pair(ty), + OperandValue::Ref(_) => cx.is_backend_ref(ty), + } + } } /// An `OperandRef` is an "SSA" reference to a Rust value, along with @@ -235,6 +272,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } } + /// Asserts that this operand is a pointer (or reference) and returns + /// the place to which it points. (This requires no code to be emitted + /// as we represent places using the pointer to the place.) + /// + /// This uses [`Ty::builtin_deref`] to include the type of the place and + /// assumes the place is aligned to the pointee's usual ABI alignment. + /// + /// If you don't need the type, see [`OperandValue::pointer_parts`] + /// or [`OperandValue::deref`]. pub fn deref>(self, cx: &Cx) -> PlaceRef<'tcx, V> { if self.layout.ty.is_box() { // Derefer should have removed all Box derefs @@ -247,15 +293,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { .builtin_deref(true) .unwrap_or_else(|| bug!("deref of non-pointer {:?}", self)); - let (llptr, llextra) = match self.val { - OperandValue::Immediate(llptr) => (llptr, None), - OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)), - OperandValue::Ref(..) => bug!("Deref of by-Ref operand {:?}", self), - OperandValue::ZeroSized => bug!("Deref of ZST operand {:?}", self), - }; let layout = cx.layout_of(projected_ty); - let val = PlaceValue { llval: llptr, llextra, align: layout.align.abi }; - PlaceRef { val, layout } + self.val.deref(layout.align.abi).with_type(layout) } /// If this operand is a `Pair`, we return an aggregate with the two values. @@ -448,8 +487,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { if val.llextra.is_some() { bug!("cannot directly store unsized values"); } - let source_place = PlaceRef { val, layout: dest.layout }; - bx.typed_place_copy_with_flags(dest, source_place, flags); + bx.typed_place_copy_with_flags(dest.val, val, dest.layout, flags); } OperandValue::Immediate(s) => { let val = bx.from_immediate(s); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index 870a105c61d6..971ac2defdc0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -10,12 +10,15 @@ use rustc_middle::mir; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, Ty}; -use rustc_target::abi::{Align, FieldsShape, Int, Pointer, TagEncoding}; +use rustc_target::abi::{Align, FieldsShape, Int, Pointer, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; /// The location and extra runtime properties of the place. /// /// Typically found in a [`PlaceRef`] or an [`OperandValue::Ref`]. +/// +/// As a location in memory, this has no specific type. If you want to +/// load or store it using a typed operation, use [`Self::with_type`]. #[derive(Copy, Clone, Debug)] pub struct PlaceValue { /// A pointer to the contents of the place. @@ -35,6 +38,41 @@ impl PlaceValue { pub fn new_sized(llval: V, align: Align) -> PlaceValue { PlaceValue { llval, llextra: None, align } } + + /// Allocates a stack slot in the function for a value + /// of the specified size and alignment. + /// + /// The allocation itself is untyped. + pub fn alloca<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx, Value = V>>( + bx: &mut Bx, + size: Size, + align: Align, + ) -> PlaceValue { + let llval = bx.alloca(size, align); + PlaceValue::new_sized(llval, align) + } + + /// Creates a `PlaceRef` to this location with the given type. + pub fn with_type<'tcx>(self, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> { + debug_assert!( + layout.is_unsized() || layout.abi.is_uninhabited() || self.llextra.is_none(), + "Had pointer metadata {:?} for sized type {layout:?}", + self.llextra, + ); + PlaceRef { val: self, layout } + } + + /// Gets the pointer to this place as an [`OperandValue::Immediate`] + /// or, for those needing metadata, an [`OperandValue::Pair`]. + /// + /// This is the inverse of [`OperandValue::deref`]. + pub fn address(self) -> OperandValue { + if let Some(llextra) = self.llextra { + OperandValue::Pair(self.llval, llextra) + } else { + OperandValue::Immediate(self.llval) + } + } } #[derive(Copy, Clone, Debug)] @@ -52,9 +90,7 @@ pub struct PlaceRef<'tcx, V> { impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { pub fn new_sized(llval: V, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> { - assert!(layout.is_sized()); - let val = PlaceValue::new_sized(llval, layout.align.abi); - PlaceRef { val, layout } + PlaceRef::new_sized_aligned(llval, layout, layout.align.abi) } pub fn new_sized_aligned( @@ -63,8 +99,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { align: Align, ) -> PlaceRef<'tcx, V> { assert!(layout.is_sized()); - let val = PlaceValue::new_sized(llval, align); - PlaceRef { val, layout } + PlaceValue::new_sized(llval, align).with_type(layout) } // FIXME(eddyb) pass something else for the name so no work is done @@ -72,18 +107,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { pub fn alloca>( bx: &mut Bx, layout: TyAndLayout<'tcx>, - ) -> Self { - Self::alloca_aligned(bx, layout, layout.align.abi) - } - - pub fn alloca_aligned>( - bx: &mut Bx, - layout: TyAndLayout<'tcx>, - align: Align, ) -> Self { assert!(layout.is_sized(), "tried to statically allocate unsized place"); - let tmp = bx.alloca(layout.size, align); - Self::new_sized_aligned(tmp, layout, align) + PlaceValue::alloca(bx, layout.size, layout.align.abi).with_type(layout) } /// Returns a place for an indirect reference to an unsized place. @@ -132,18 +158,12 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { } else { bx.inbounds_ptradd(self.val.llval, bx.const_usize(offset.bytes())) }; - PlaceRef { - val: PlaceValue { + let val = PlaceValue { llval, - llextra: if bx.cx().type_has_metadata(field.ty) { - self.val.llextra - } else { - None - }, + llextra: if bx.cx().type_has_metadata(field.ty) { self.val.llextra } else { None }, align: effective_field_align, - }, - layout: field, - } + }; + val.with_type(field) }; // Simple cases, which don't need DST adjustment: @@ -198,7 +218,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let ptr = bx.inbounds_ptradd(self.val.llval, offset); let val = PlaceValue { llval: ptr, llextra: self.val.llextra, align: effective_field_align }; - PlaceRef { val, layout: field } + val.with_type(field) } /// Obtain the actual discriminant of a value. @@ -387,18 +407,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout.size }; - PlaceRef { - val: PlaceValue { - llval: bx.inbounds_gep( + let llval = bx.inbounds_gep( bx.cx().backend_type(self.layout), self.val.llval, &[bx.cx().const_usize(0), llindex], - ), - llextra: None, - align: self.val.align.restrict_for_offset(offset), - }, - layout, - } + ); + let align = self.val.align.restrict_for_offset(offset); + PlaceValue::new_sized(llval, align).with_type(layout) } pub fn project_downcast>( diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 2976ca14c924..936ed41a294b 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -74,8 +74,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if val.llextra.is_some() { bug!("unsized coercion on an unsized rvalue"); } - let source = PlaceRef { val, layout: operand.layout }; - base::coerce_unsized_into(bx, source, dest); + base::coerce_unsized_into(bx, val.with_type(operand.layout), dest); } OperandValue::ZeroSized => { bug!("unsized coercion on a ZST rvalue"); @@ -184,10 +183,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Immediate(..) | OperandValue::Pair(..) => { // When we have immediate(s), the alignment of the source is irrelevant, // so we can store them using the destination's alignment. - src.val.store( - bx, - PlaceRef::new_sized_aligned(dst.val.llval, src.layout, dst.val.align), - ); + src.val.store(bx, dst.val.with_type(src.layout)); } } } @@ -225,8 +221,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandValue::Ref(source_place_val) => { debug_assert_eq!(source_place_val.llextra, None); debug_assert!(matches!(operand_kind, OperandValueKind::Ref)); - let fake_place = PlaceRef { val: source_place_val, layout: cast }; - Some(bx.load_operand(fake_place).val) + Some(bx.load_operand(source_place_val.with_type(cast)).val) } OperandValue::ZeroSized => { let OperandValueKind::ZeroSized = operand_kind else { @@ -452,23 +447,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::CastKind::PointerCoercion(PointerCoercion::Unsize) => { assert!(bx.cx().is_backend_scalar_pair(cast)); - let (lldata, llextra) = match operand.val { - OperandValue::Pair(lldata, llextra) => { - // unsize from a fat pointer -- this is a - // "trait-object-to-supertrait" coercion. - (lldata, Some(llextra)) - } - OperandValue::Immediate(lldata) => { - // "standard" unsize - (lldata, None) - } - OperandValue::Ref(..) => { - bug!("by-ref operand {:?} in `codegen_rvalue_operand`", operand); - } - OperandValue::ZeroSized => { - bug!("zero-sized operand {:?} in `codegen_rvalue_operand`", operand); - } - }; + let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::unsize_ptr(bx, lldata, operand.layout.ty, cast.ty, llextra); OperandValue::Pair(lldata, llextra) @@ -489,12 +468,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::CastKind::DynStar => { - let (lldata, llextra) = match operand.val { - OperandValue::Ref(..) => todo!(), - OperandValue::Immediate(v) => (v, None), - OperandValue::Pair(v, l) => (v, Some(l)), - OperandValue::ZeroSized => bug!("ZST -- which is not PointerLike -- in DynStar"), - }; + let (lldata, llextra) = operand.val.pointer_parts(); let (lldata, llextra) = base::cast_to_dyn_star(bx, lldata, operand.layout, cast.ty, llextra); OperandValue::Pair(lldata, llextra) @@ -722,24 +696,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { OperandRef { val: OperandValue::Immediate(static_), layout } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), - mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => { - let ty = rvalue.ty(self.mir, self.cx.tcx()); - let layout = self.cx.layout_of(self.monomorphize(ty)); - let [data, meta] = &*fields.raw else { - bug!("RawPtr fields: {fields:?}"); - }; - let data = self.codegen_operand(bx, data); - let meta = self.codegen_operand(bx, meta); - match (data.val, meta.val) { - (p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => { - OperandRef { val: p, layout } - } - (OperandValue::Immediate(p), OperandValue::Immediate(m)) => { - OperandRef { val: OperandValue::Pair(p, m), layout } - } - _ => bug!("RawPtr operands {data:?} {meta:?}"), - } - } mir::Rvalue::Repeat(..) => bug!("{rvalue:?} in codegen_rvalue_operand"), mir::Rvalue::Aggregate(_, ref fields) => { let ty = rvalue.ty(self.mir, self.cx.tcx()); @@ -774,6 +730,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ); let val = OperandValue::from_immediates(inputs); + debug_assert!( + val.is_expected_variant_for_type(self.cx, layout), + "Made wrong variant {val:?} for type {layout:?}", + ); OperandRef { val, layout } } mir::Rvalue::ShallowInitBox(ref operand, content_ty) => { @@ -812,16 +772,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mk_ptr_ty: impl FnOnce(TyCtxt<'tcx>, Ty<'tcx>) -> Ty<'tcx>, ) -> OperandRef<'tcx, Bx::Value> { let cg_place = self.codegen_place(bx, place.as_ref()); + let val = cg_place.val.address(); let ty = cg_place.layout.ty; + debug_assert!( + if bx.cx().type_has_metadata(ty) { + matches!(val, OperandValue::Pair(..)) + } else { + matches!(val, OperandValue::Immediate(..)) + }, + "Address of place was unexpectedly {val:?} for pointee type {ty:?}", + ); - // Note: places are indirect, so storing the `llval` into the - // destination effectively creates a reference. - let val = if !bx.cx().type_has_metadata(ty) { - OperandValue::Immediate(cg_place.val.llval) - } else { - OperandValue::Pair(cg_place.val.llval, cg_place.val.llextra.unwrap()) - }; OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 51b22bfaf255..fdeccb907008 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -186,6 +186,15 @@ pub trait BuilderMethods<'a, 'tcx>: align: Align, flags: MemFlags, ) -> Self::Value; + fn store_to_place_with_flags( + &mut self, + val: Self::Value, + place: PlaceValue, + flags: MemFlags, + ) -> Self::Value { + debug_assert_eq!(place.llextra, None); + self.store_with_flags(val, place.llval, place.align, flags) + } fn atomic_store( &mut self, val: Self::Value, @@ -286,35 +295,36 @@ pub trait BuilderMethods<'a, 'tcx>: /// (For example, typed load-stores with alias metadata.) fn typed_place_copy( &mut self, - dst: PlaceRef<'tcx, Self::Value>, - src: PlaceRef<'tcx, Self::Value>, + dst: PlaceValue, + src: PlaceValue, + layout: TyAndLayout<'tcx>, ) { - self.typed_place_copy_with_flags(dst, src, MemFlags::empty()); + self.typed_place_copy_with_flags(dst, src, layout, MemFlags::empty()); } fn typed_place_copy_with_flags( &mut self, - dst: PlaceRef<'tcx, Self::Value>, - src: PlaceRef<'tcx, Self::Value>, + dst: PlaceValue, + src: PlaceValue, + layout: TyAndLayout<'tcx>, flags: MemFlags, ) { - debug_assert!(src.val.llextra.is_none(), "cannot directly copy from unsized values"); - debug_assert!(dst.val.llextra.is_none(), "cannot directly copy into unsized values"); - debug_assert_eq!(dst.layout.size, src.layout.size); + debug_assert!(layout.is_sized(), "cannot typed-copy an unsigned type"); + debug_assert!(src.llextra.is_none(), "cannot directly copy from unsized values"); + debug_assert!(dst.llextra.is_none(), "cannot directly copy into unsized values"); if flags.contains(MemFlags::NONTEMPORAL) { // HACK(nox): This is inefficient but there is no nontemporal memcpy. - let ty = self.backend_type(dst.layout); - let val = self.load_from_place(ty, src.val); - self.store_with_flags(val, dst.val.llval, dst.val.align, flags); - } else if self.sess().opts.optimize == OptLevel::No && self.is_backend_immediate(dst.layout) - { + let ty = self.backend_type(layout); + let val = self.load_from_place(ty, src); + self.store_to_place_with_flags(val, dst, flags); + } else if self.sess().opts.optimize == OptLevel::No && self.is_backend_immediate(layout) { // If we're not optimizing, the aliasing information from `memcpy` // isn't useful, so just load-store the value for smaller code. - let temp = self.load_operand(src); - temp.val.store_with_flags(self, dst, flags); - } else if !dst.layout.is_zst() { - let bytes = self.const_usize(dst.layout.size.bytes()); - self.memcpy(dst.val.llval, dst.val.align, src.val.llval, src.val.align, bytes, flags); + let temp = self.load_operand(src.with_type(layout)); + temp.val.store_with_flags(self, dst.with_type(layout), flags); + } else if !layout.is_zst() { + let bytes = self.const_usize(layout.size.bytes()); + self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags); } } @@ -327,18 +337,19 @@ pub trait BuilderMethods<'a, 'tcx>: /// cases (in non-debug), preferring the fallback body instead. fn typed_place_swap( &mut self, - left: PlaceRef<'tcx, Self::Value>, - right: PlaceRef<'tcx, Self::Value>, + left: PlaceValue, + right: PlaceValue, + layout: TyAndLayout<'tcx>, ) { - let mut temp = self.load_operand(left); + let mut temp = self.load_operand(left.with_type(layout)); if let OperandValue::Ref(..) = temp.val { // The SSA value isn't stand-alone, so we need to copy it elsewhere - let alloca = PlaceRef::alloca(self, left.layout); - self.typed_place_copy(alloca, left); + let alloca = PlaceRef::alloca(self, layout); + self.typed_place_copy(alloca.val, left, layout); temp = self.load_operand(alloca); } - self.typed_place_copy(left, right); - temp.val.store(self, right); + self.typed_place_copy(left, right, layout); + temp.val.store(self, right.with_type(layout)); } fn select( diff --git a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs index afc60d33647a..94c9f056b302 100644 --- a/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/dummy_machine.rs @@ -1,9 +1,12 @@ -use crate::interpret::{self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic}; +use crate::interpret::{ + self, throw_machine_stop, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, +}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult}; use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty; use rustc_middle::ty::layout::TyAndLayout; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; /// Macro for machine-specific `InterpError` without allocation. diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 2c9eb393e4a1..08c9609eacfa 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -11,6 +11,7 @@ use rustc_span::{Span, Symbol}; use super::CompileTimeInterpreter; use crate::errors::{self, FrameNote, ReportErrorExt}; +use crate::interpret::{err_inval, err_machine_stop}; use crate::interpret::{ErrorHandled, Frame, InterpError, InterpErrorInfo, MachineStopType}; /// The CTFE machine has some custom error kinds. 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 d9f329c8b0e0..6a9a21bbd8e0 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -3,6 +3,7 @@ use std::sync::atomic::Ordering::Relaxed; use either::{Left, Right}; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo}; use rustc_middle::mir::{self, ConstAlloc, ConstValue}; use rustc_middle::query::TyCtxtAt; @@ -24,7 +25,7 @@ use crate::interpret::{ InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup, }; -use crate::interpret::{eval_nullary_intrinsic, InternResult}; +use crate::interpret::{eval_nullary_intrinsic, throw_exhaust, InternResult}; use crate::CTRL_C_RECEIVED; // Returns a pointer to where the result lives diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 6e6fa70107b7..836e548ae2b7 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -10,6 +10,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::def_id::LocalDefId; use rustc_hir::LangItem; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::AssertMessage; use rustc_middle::query::TyCtxtAt; @@ -24,8 +25,9 @@ use rustc_target::spec::abi::Abi as CallAbi; use crate::errors::{LongRunning, LongRunningWarn}; use crate::fluent_generated as fluent; use crate::interpret::{ - self, compile_time_machine, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, - Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar, + self, compile_time_machine, err_ub, throw_exhaust, throw_inval, throw_ub_custom, + throw_unsup_format, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal, Frame, + ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar, }; use super::error::*; diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 8efc67bcb0c4..a5c8c0bb82ad 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -1,5 +1,6 @@ // Not in interpret to make sure we do not use private implementation details +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::interpret::InterpErrorInfo; use rustc_middle::query::{Key, TyCtxtAt}; diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index dcfce4e35e05..fbf2ca5ab0a6 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -1,4 +1,5 @@ use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 76e59ea90559..799e12f9ac97 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -7,11 +7,13 @@ use rustc_middle::mir::CastKind; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Integer; use rustc_type_ir::TyKind::*; use super::{ - util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, InterpCx, Machine, OpTy, PlaceTy, + err_inval, throw_ub, throw_ub_custom, util::ensure_monomorphic_enough, FnVal, ImmTy, Immediate, + InterpCx, Machine, OpTy, PlaceTy, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index caacc6f57d3c..8ddc741de239 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -1,12 +1,15 @@ //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines). use rustc_middle::mir; +use rustc_middle::span_bug; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt}; use rustc_middle::ty::{self, ScalarInt, Ty}; use rustc_target::abi::{self, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; -use super::{ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable}; +use super::{ + err_ub, throw_ub, ImmTy, InterpCx, InterpResult, Machine, Readable, Scalar, Writeable, +}; impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Writes the discriminant of the given variant. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 126d64329f81..344bb7cd98be 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -17,15 +17,17 @@ use rustc_middle::ty::layout::{ TyAndLayout, }; use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; use rustc_target::abi::{call::FnAbi, Align, HasDataLayout, Size, TargetDataLayout}; use super::{ - GlobalId, Immediate, InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, - Memory, MemoryKind, OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, - Provenance, Scalar, StackPopJump, + err_inval, throw_inval, throw_ub, throw_ub_custom, throw_unsup, GlobalId, Immediate, + InterpErrorInfo, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind, + OpTy, Operand, Place, PlaceTy, Pointer, PointerArithmetic, Projectable, Provenance, Scalar, + StackPopJump, }; use crate::errors; use crate::util; diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index d4168273f29f..3565b4fb5165 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -24,7 +24,7 @@ use rustc_middle::ty::layout::TyAndLayout; use rustc_span::def_id::LocalDefId; use rustc_span::sym; -use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; +use super::{err_ub, AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy}; use crate::const_eval; use crate::errors::NestedStaticInThreadLocal; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 52c31629d547..dce4d56f7e00 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -8,6 +8,7 @@ use rustc_middle::ty::layout::{LayoutOf as _, ValidityRequirement}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{ + bug, mir::{self, BinOp, ConstValue, NonDivergingIntrinsic}, ty::layout::TyAndLayout, }; @@ -15,9 +16,10 @@ use rustc_span::symbol::{sym, Symbol}; use rustc_target::abi::Size; use super::{ - memory::MemoryKind, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, - ConstAllocation, GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, - PointerArithmetic, Scalar, + err_inval, err_ub_custom, err_unsup_format, memory::MemoryKind, throw_inval, throw_ub_custom, + throw_ub_format, util::ensure_monomorphic_enough, Allocation, CheckInAllocMsg, ConstAllocation, + GlobalId, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, Pointer, PointerArithmetic, + Scalar, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 8405d0746dfd..2eaebc1924bc 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -18,9 +18,9 @@ use rustc_target::abi::{Align, Size}; use rustc_target::spec::abi::Abi as CallAbi; use super::{ - AllocBytes, AllocId, AllocKind, AllocRange, Allocation, ConstAllocation, CtfeProvenance, FnArg, - Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, MemoryKind, Misalignment, OpTy, PlaceTy, - Pointer, Provenance, + throw_unsup, throw_unsup_format, AllocBytes, AllocId, AllocKind, AllocRange, Allocation, + ConstAllocation, CtfeProvenance, FnArg, Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, + MemoryKind, Misalignment, OpTy, PlaceTy, Pointer, Provenance, }; /// Data returned by Machine::stack_pop, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 594e3b3212f2..350fd480fbaa 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -16,6 +16,7 @@ use std::ptr; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::display_allocation; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use rustc_target::abi::{Align, HasDataLayout, Size}; @@ -23,9 +24,10 @@ use rustc_target::abi::{Align, HasDataLayout, Size}; use crate::fluent_generated as fluent; use super::{ - alloc_range, AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, - CheckInAllocMsg, CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, - Misalignment, Pointer, PointerArithmetic, Provenance, Scalar, + alloc_range, err_ub, err_ub_custom, throw_ub, throw_ub_custom, throw_unsup, throw_unsup_format, + AllocBytes, AllocId, AllocMap, AllocRange, Allocation, CheckAlignMsg, CheckInAllocMsg, + CtfeProvenance, GlobalAlloc, InterpCx, InterpResult, Machine, MayLeak, Misalignment, Pointer, + PointerArithmetic, Provenance, Scalar, }; #[derive(Debug, PartialEq, Copy, Clone)] diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 718c91b2f767..bad9732f4831 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -10,13 +10,14 @@ use rustc_middle::mir::interpret::ScalarSizeMismatch; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_middle::{mir, ty}; use rustc_target::abi::{self, Abi, HasDataLayout, Size}; use super::{ - alloc_range, from_known_layout, mir_assign_valid_types, CtfeProvenance, InterpCx, InterpResult, - MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, Pointer, Projectable, - Provenance, Scalar, + alloc_range, err_ub, from_known_layout, mir_assign_valid_types, throw_ub, CtfeProvenance, + InterpCx, InterpResult, MPlaceTy, Machine, MemPlace, MemPlaceMeta, OffsetMode, PlaceTy, + Pointer, Projectable, Provenance, Scalar, }; /// An `Immediate` represents a single immediate self-contained Rust value. diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 2d5dbbd58b3b..5f59e3d887e4 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -3,10 +3,11 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, FloatTy, ScalarInt, Ty}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_target::abi::Abi; -use super::{ImmTy, Immediate, InterpCx, Machine, PlaceTy}; +use super::{err_ub, throw_ub, throw_ub_custom, ImmTy, Immediate, InterpCx, Machine, PlaceTy}; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 809aca18990f..9ced825853bd 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -11,12 +11,14 @@ use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Abi, Align, HasDataLayout, Size}; use super::{ - alloc_range, mir_assign_valid_types, AllocRef, AllocRefMut, CheckAlignMsg, CtfeProvenance, - ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, - Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, Scalar, + alloc_range, mir_assign_valid_types, throw_ub, AllocRef, AllocRefMut, CheckAlignMsg, + CtfeProvenance, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemoryKind, Misalignment, + OffsetMode, OpTy, Operand, Pointer, PointerArithmetic, Projectable, Provenance, Readable, + Scalar, }; #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)] diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 5ff78f7b8c90..0a2fedb48401 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -14,10 +14,14 @@ use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::Ty; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Size; use rustc_target::abi::{self, VariantIdx}; -use super::{InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Provenance, Scalar}; +use super::{ + throw_ub, throw_unsup_format, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, + Provenance, Scalar, +}; /// Describes the constraints placed on offset-projections. #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index b29034e991e3..ee415c380de1 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -7,6 +7,7 @@ use either::Either; use rustc_index::IndexSlice; use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use super::{ diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index b474003087ba..b82c18578588 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use either::Either; +use rustc_middle::span_bug; use rustc_middle::{ mir, ty::{ @@ -19,8 +20,9 @@ use rustc_target::abi::{ use rustc_target::spec::abi::Abi; use super::{ - CtfeProvenance, FnVal, ImmTy, InterpCx, InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, - Projectable, Provenance, Scalar, StackPopCleanup, + throw_ub, throw_ub_custom, throw_unsup_format, CtfeProvenance, FnVal, ImmTy, InterpCx, + InterpResult, MPlaceTy, Machine, OpTy, PlaceTy, Projectable, Provenance, Scalar, + StackPopCleanup, }; use crate::fluent_generated as fluent; diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index c83ef14c03fe..e304d1e1cc5e 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,4 @@ use crate::const_eval::{CompileTimeEvalContext, CompileTimeInterpreter, InterpretationResult}; -use crate::interpret::{MemPlaceMeta, MemoryKind}; use rustc_hir::def_id::LocalDefId; use rustc_middle::mir; use rustc_middle::mir::interpret::{Allocation, InterpResult, Pointer}; @@ -9,7 +8,7 @@ use rustc_middle::ty::{ }; use std::ops::ControlFlow; -use super::{InterpCx, MPlaceTy}; +use super::{throw_inval, InterpCx, MPlaceTy, MemPlaceMeta, MemoryKind}; /// Checks whether a type contains generic parameters which must be instantiated. /// diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 14566719ccd7..2bd4d9dc07a5 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -13,6 +13,7 @@ use hir::def::DefKind; use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::mir::interpret::{ ExpectedKind, InterpError, InvalidMetaKind, Misalignment, PointerKind, Provenance, ValidationErrorInfo, ValidationErrorKind, ValidationErrorKind::*, @@ -27,9 +28,9 @@ use rustc_target::abi::{ use std::hash::Hash; use super::{ - format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, - Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, - Scalar, ValueVisitor, + err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, CheckInAllocMsg, + GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, + Pointer, Projectable, Scalar, ValueVisitor, }; // for the validation errors diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 84557b8e2d60..59bcc5174cb2 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -9,7 +9,7 @@ use rustc_target::abi::{FieldsShape, VariantIdx, Variants}; use std::num::NonZero; -use super::{InterpCx, MPlaceTy, Machine, Projectable}; +use super::{throw_inval, InterpCx, MPlaceTy, Machine, Projectable}; /// How to traverse a value and what to do when we are at the leaves. pub trait ValueVisitor<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>: Sized { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index d27d42737cd6..a525b838afa2 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -22,8 +22,6 @@ Rust MIR: a lowered representation of Rust. #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; pub mod const_eval; mod errors; 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 d43dc467c0f0..5edf5bb39dd4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -8,10 +8,11 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::{sym, Span, Symbol, DUMMY_SP}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; @@ -738,7 +739,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { let cause = ObligationCause::new( terminator.source_info.span, self.body.source.def_id().expect_local(), - ObligationCauseCode::WhereClause(callee), + ObligationCauseCode::WhereClause(callee, DUMMY_SP), ); let normalized_predicates = ocx.normalize(&cause, param_env, predicates); ocx.register_obligations(traits::predicates_for_generics( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 12e7ec15e329..308b90cd470d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -8,6 +8,7 @@ use rustc_attr as attr; use rustc_errors::DiagCtxt; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::ty::{self, PolyFnSig, TyCtxt}; use rustc_span::Symbol; 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 247a2889dc58..8775685e8c73 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -8,6 +8,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::{self, CallSource}; +use rustc_middle::span_bug; use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _}; use rustc_middle::ty::{ self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, 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 1847847d9d2a..eae0e2f27dbd 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -5,6 +5,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::LangItem; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::mir::*; use rustc_middle::traits::BuiltinImplSource; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index c95166d84e93..fdc7f6a69cba 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Size, FIRST_VARIANT}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_const_eval/src/util/caller_location.rs b/compiler/rustc_const_eval/src/util/caller_location.rs index af9a4a4271d7..403bc1eca134 100644 --- a/compiler/rustc_const_eval/src/util/caller_location.rs +++ b/compiler/rustc_const_eval/src/util/caller_location.rs @@ -1,4 +1,5 @@ use rustc_hir::LangItem; +use rustc_middle::bug; use rustc_middle::mir; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::LayoutOf; diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 36597507f474..68fb122a765d 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement}; use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants}; diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index e474b952938a..01e517250f77 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -1,6 +1,7 @@ use rustc_data_structures::intern::Interned; use rustc_hir::def_id::CrateNum; use rustc_hir::definitions::DisambiguatedDefPathData; +use rustc_middle::bug; use rustc_middle::ty::{ self, print::{PrettyPrinter, Print, PrintError, Printer}, diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 80b6e72e49ba..2b61e17efa28 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -9,7 +9,7 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "2.4.1" either = "1.0" elsa = "=1.7.1" -ena = "0.14.2" +ena = "0.14.3" indexmap = { version = "2.0.0" } jobserver_crate = { version = "0.1.28", package = "jobserver" } libc = "0.2" diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b2d38a00f0b5..ba6b9ef07846 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -11,6 +11,7 @@ #![allow(internal_features)] #![feature(decl_macro)] #![feature(let_chains)] +#![feature(panic_backtrace_config)] #![feature(panic_update_hook)] #![feature(result_flattening)] @@ -1317,8 +1318,8 @@ pub fn install_ice_hook( // by the user. Compiler developers and other rustc users can // opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE" // (e.g. `RUST_BACKTRACE=1`) - if std::env::var_os("RUST_BACKTRACE").is_none() { - std::env::set_var("RUST_BACKTRACE", "full"); + if env::var_os("RUST_BACKTRACE").is_none() { + panic::set_backtrace_style(panic::BacktraceStyle::Full); } let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default()); diff --git a/compiler/rustc_error_codes/src/error_codes/E0457.md b/compiler/rustc_error_codes/src/error_codes/E0457.md index e2dbf53a0f8c..47bff4bc49f9 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0457.md +++ b/compiler/rustc_error_codes/src/error_codes/E0457.md @@ -1,4 +1,4 @@ -#### Note: this error code is no longer emitted by the compiler` +#### Note: this error code is no longer emitted by the compiler Plugin `..` only found in rlib format, but must be available in dylib format. diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 40560a5ad795..2cc0167dbaa6 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -100,6 +100,12 @@ impl IntoDiagArg for rustc_type_ir::TraitRef { } } +impl IntoDiagArg for rustc_type_ir::ExistentialTraitRef { + fn into_diag_arg(self) -> DiagArgValue { + self.to_string().into_diag_arg() + } +} + into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize); impl IntoDiagArg for bool { diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 897420a11cdf..67a5a9128ccb 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -201,10 +201,17 @@ impl<'a> StripUnconfigured<'a> { inner = self.configure_tokens(&inner); Some(AttrTokenTree::Delimited(sp, spacing, delim, inner)).into_iter() } - AttrTokenTree::Token(ref token, _) - if let TokenKind::Interpolated(nt) = &token.kind => - { - panic!("Nonterminal should have been flattened at {:?}: {:?}", token.span, nt); + AttrTokenTree::Token( + Token { + kind: + TokenKind::NtIdent(..) + | TokenKind::NtLifetime(..) + | TokenKind::Interpolated(..), + .. + }, + _, + ) => { + panic!("Nonterminal should have been flattened: {:?}", tree); } AttrTokenTree::Token(token, spacing) => { Some(AttrTokenTree::Token(token, spacing)).into_iter() diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 464361cb4020..3fee39dd085c 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -73,12 +73,6 @@ pub(super) fn failed_to_match_macro<'cx>( && (matches!(expected_token.kind, TokenKind::Interpolated(_)) || matches!(token.kind, TokenKind::Interpolated(_))) { - if let TokenKind::Interpolated(node) = &expected_token.kind { - err.span_label(node.1, ""); - } - if let TokenKind::Interpolated(node) = &token.kind { - err.span_label(node.1, ""); - } err.note("captured metavariables except for `:tt`, `:ident` and `:lifetime` cannot be compared to other tokens"); err.note("see for more information"); diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index ffb50f4c92e1..27cf6fee702a 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -75,10 +75,9 @@ pub(crate) use ParseResult::*; use crate::mbe::{macro_rules::Tracker, KleeneOp, TokenTree}; -use rustc_ast::token::{self, DocComment, Nonterminal, NonterminalKind, Token}; +use rustc_ast::token::{self, DocComment, NonterminalKind, Token}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sync::Lrc; use rustc_errors::ErrorGuaranteed; use rustc_lint_defs::pluralize; use rustc_parse::parser::{ParseNtResult, Parser}; @@ -392,7 +391,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize { #[derive(Debug, Clone)] pub(crate) enum NamedMatch { MatchedSeq(Vec), - MatchedSingle(ParseNtResult>), + MatchedSingle(ParseNtResult), } /// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison) @@ -686,11 +685,7 @@ impl TtParser { } Ok(nt) => nt, }; - mp.push_match( - next_metavar, - seq_depth, - MatchedSingle(nt.map_nt(|nt| (Lrc::new((nt, span))))), - ); + mp.push_match(next_metavar, seq_depth, MatchedSingle(nt)); mp.idx += 1; } else { unreachable!() diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 011aa95c8a11..e35eba0f859b 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -261,6 +261,16 @@ pub(super) fn transcribe<'a>( // without wrapping them into groups. maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker) } + MatchedSingle(ParseNtResult::Ident(ident, is_raw)) => { + marker.visit_span(&mut sp); + let kind = token::NtIdent(*ident, *is_raw); + TokenTree::token_alone(kind, sp) + } + MatchedSingle(ParseNtResult::Lifetime(ident)) => { + marker.visit_span(&mut sp); + let kind = token::NtLifetime(*ident); + TokenTree::token_alone(kind, sp) + } MatchedSingle(ParseNtResult::Nt(nt)) => { // Other variables are emitted into the output stream as groups with // `Delimiter::Invisible` to maintain parsing priorities. diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 4b5c148cb555..530059e53c21 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -127,7 +127,7 @@ impl MultiItemModifier for DeriveProcMacro { Annotatable::Stmt(stmt) => token::NtStmt(stmt), _ => unreachable!(), }; - TokenStream::token_alone(token::Interpolated(Lrc::new((nt, span))), DUMMY_SP) + TokenStream::token_alone(token::Interpolated(Lrc::new(nt)), DUMMY_SP) } else { item.to_tokens() }; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 5a66b0fbdef1..1f3547c841a9 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -220,6 +220,12 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { trees.push(TokenTree::Ident(Ident { sym, is_raw: is_raw.into(), span })) } + NtIdent(ident, is_raw) => trees.push(TokenTree::Ident(Ident { + sym: ident.name, + is_raw: is_raw.into(), + span: ident.span, + })), + Lifetime(name) => { let ident = symbol::Ident::new(name, span).without_first_quote(); trees.extend([ @@ -227,6 +233,15 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { + let stream = TokenStream::token_alone(token::Lifetime(ident.name), ident.span); + trees.push(TokenTree::Group(Group { + delimiter: pm::Delimiter::None, + stream: Some(stream), + span: DelimSpan::from_single(span), + })) + } + Literal(token::Lit { kind, symbol, suffix }) => { trees.push(TokenTree::Literal(self::Literal { kind: FromInternal::from_internal(kind), @@ -259,23 +274,15 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec { - trees.push(TokenTree::Ident(Ident { - sym: ident.name, - is_raw: matches!(is_raw, IdentIsRaw::Yes), - span: ident.span, - })) - } - Interpolated(nt) => { - let stream = TokenStream::from_nonterminal_ast(&nt.0); + let stream = TokenStream::from_nonterminal_ast(&nt); // A hack used to pass AST fragments to attribute and derive // macros as a single nonterminal token instead of a token // stream. Such token needs to be "unwrapped" and not // represented as a delimited group. // FIXME: It needs to be removed, but there are some // compatibility issues (see #73345). - if crate::base::nt_pretty_printing_compatibility_hack(&nt.0, rustc.ecx.sess) { + if crate::base::nt_pretty_printing_compatibility_hack(&nt, rustc.ecx.sess) { trees.extend(Self::from_internal((stream, rustc))); } else { trees.push(TokenTree::Group(Group { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7d991e21ff3d..6e4cef068c59 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2631,7 +2631,7 @@ pub struct OpaqueTy<'hir> { /// lowered as an associated type. pub in_trait: bool, /// List of arguments captured via `impl use<'a, P, ...> Trait` syntax. - pub precise_capturing_args: Option<&'hir [PreciseCapturingArg<'hir>]>, + pub precise_capturing_args: Option<(&'hir [PreciseCapturingArg<'hir>], Span)>, } #[derive(Debug, Clone, Copy, HashStable_Generic)] @@ -2641,6 +2641,15 @@ pub enum PreciseCapturingArg<'hir> { Param(PreciseCapturingNonLifetimeArg), } +impl PreciseCapturingArg<'_> { + pub fn hir_id(self) -> HirId { + match self { + PreciseCapturingArg::Lifetime(lt) => lt.hir_id, + PreciseCapturingArg::Param(param) => param.hir_id, + } + } +} + /// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param /// resolution to. Lifetimes don't have this problem, and for them, it's actually /// kind of detrimental to use a custom node type versus just using [`Lifetime`], diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 0b095db953b0..664784cd2c60 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -533,7 +533,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_id(item.hir_id())); try_visit!(walk_generics(visitor, generics)); walk_list!(visitor, visit_param_bound, bounds); - if let Some(precise_capturing_args) = precise_capturing_args { + if let Some((precise_capturing_args, _)) = precise_capturing_args { for arg in precise_capturing_args { try_visit!(visitor.visit_precise_capturing_arg(arg)); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index fb9d97ba08b0..b5c067514059 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -14,6 +14,7 @@ use rustc_infer::traits::Obligation; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt}; @@ -485,7 +486,7 @@ fn sanity_check_found_hidden_type<'tcx>( fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { let hir::OpaqueTy { precise_capturing_args, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); - let Some(precise_capturing_args) = precise_capturing_args else { + let Some((precise_capturing_args, _)) = precise_capturing_args else { // No precise capturing args; nothing to validate return; }; 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 b2b82670d8b0..39940c8f0f3e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{ self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::ty::{GenericParamDefKind, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_trait_selection::regions::InferCtxtRegionExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; @@ -819,7 +820,7 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { ObligationCause::new( self.span, self.body_id, - ObligationCauseCode::SpannedWhereClause(proj.def_id, pred_span), + ObligationCauseCode::WhereClause(proj.def_id, pred_span), ), self.param_env, pred, @@ -2011,11 +2012,7 @@ pub(super) fn check_type_bounds<'tcx>( }, ); let mk_cause = |span: Span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(trait_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(trait_ty.def_id, span) - }; + let code = ObligationCauseCode::WhereClause(trait_ty.def_id, span); ObligationCause::new(impl_ty_span, impl_ty_def_id, code) }; @@ -2209,7 +2206,7 @@ fn param_env_with_gat_bounds<'tcx>( _ => predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, trait_ty.def_id, rebased_args), + projection_term: ty::AliasTerm::new(tcx, trait_ty.def_id, rebased_args), term: normalize_impl_ty.into(), }, bound_vars, @@ -2251,8 +2248,7 @@ fn try_report_async_mismatch<'tcx>( }; for error in errors { - if let ObligationCauseCode::SpannedWhereClause(def_id, _) = - *error.root_obligation.cause.code() + if let ObligationCauseCode::WhereClause(def_id, _) = *error.root_obligation.cause.code() && def_id == async_future_def_id && let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred() && let Some(proj) = proj.no_bound_vars() diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index a2a20082bb03..ca08eeea2275 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt}; use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT_REACHABLE}; +use rustc_middle::span_bug; use rustc_middle::traits::{ObligationCause, Reveal}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor, diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs index d5908cf28511..e44e8e67da3e 100644 --- a/compiler/rustc_hir_analysis/src/check/entry.rs +++ b/compiler/rustc_hir_analysis/src/check/entry.rs @@ -1,6 +1,7 @@ use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config::EntryFnType; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index eb1fa1baecca..00ff470a0a7d 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -9,6 +9,7 @@ use crate::errors::{ use rustc_errors::{codes::*, struct_span_code_err, DiagMessage}; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 45ccd0fa2e06..b09de1a4a098 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,6 +1,7 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index eb0ffc19d454..f8b0164b9a59 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -90,6 +90,7 @@ use rustc_middle::query::Providers; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; @@ -343,9 +344,10 @@ fn bounds_from_generic_predicates<'tcx>( let mut projections_str = vec![]; for projection in &projections { let p = projection.skip_binder(); - let alias_ty = p.projection_ty; - if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty { - let name = tcx.item_name(alias_ty.def_id); + if bound == tcx.parent(p.projection_term.def_id) + && p.projection_term.self_ty() == ty + { + let name = tcx.item_name(p.projection_term.def_id); projections_str.push(format!("{} = {}", name, p.term)); } } diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs index d2ea51f65f98..4540310937d0 100644 --- a/compiler/rustc_hir_analysis/src/check/region.rs +++ b/compiler/rustc_hir_analysis/src/check/region.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Block, Expr, LetStmt, Pat, PatKind, Stmt}; use rustc_index::Idx; +use rustc_middle::bug; 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 0578317f9145..b918a8c32d8a 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -24,6 +24,7 @@ use rustc_middle::ty::{ TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_middle::ty::{GenericArgKind, GenericArgs}; +use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; @@ -1550,7 +1551,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let cause = traits::ObligationCause::new( sp, wfcx.body_def_id, - ObligationCauseCode::WhereClause(def_id.to_def_id()), + ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP), ); traits::Obligation::new(tcx, cause, wfcx.param_env, pred) }); diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index 4a85e9983f47..e2d3ff558cf7 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -10,6 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::{simplify_type, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, CrateInherentImpls, Ty, TyCtxt}; use rustc_span::symbol::sym; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 8e1b2e8e65c5..bdac0d9b0b40 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -10,6 +10,7 @@ use rustc_lint_defs::builtin::UNCOVERED_PARAM_IN_PROJECTION; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_trait_selection::traits::{self, IsFirstInputType, UncoveredTyParams}; use rustc_trait_selection::traits::{OrphanCheckErr, OrphanCheckMode}; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 566f818f8995..0b9f7fd41fb9 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -30,6 +30,7 @@ use rustc_middle::hir::nested_filter; use rustc_middle::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 02291cc603e1..dd1d209389dc 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_infer::traits::util; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::Span; @@ -39,7 +40,7 @@ fn associated_type_bounds<'tcx>( let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { match pred.kind().skip_binder() { ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty, - ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty, + ty::ClauseKind::Projection(proj) => proj.projection_term.self_ty() == item_ty, ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty, _ => false, } diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 7e82571d172f..d348d6f789f6 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericPredicates, ImplTraitInTraitData, ToPredicate}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -445,7 +446,9 @@ pub(super) fn explicit_predicates_of<'tcx>( .copied() .filter(|(pred, _)| match pred.kind().skip_binder() { ty::ClauseKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()), - ty::ClauseKind::Projection(proj) => !is_assoc_item_ty(proj.projection_ty.self_ty()), + ty::ClauseKind::Projection(proj) => { + !is_assoc_item_ty(proj.projection_term.self_ty()) + } ty::ClauseKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0), _ => true, }) 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 3ef132a3e8c9..5c7733065c61 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -15,11 +15,11 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node}; use rustc_macros::extension; -use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 24a5349858ad..1475e53c47c2 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -7,6 +7,7 @@ use rustc_middle::query::plumbing::CyclePlaceholder; use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index b5765913cb85..1bec8c496ad1 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -3,6 +3,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, def, Expr, ImplItem, Item, Node, TraitItem}; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 3b8bb0731fbd..620170164f53 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -1,4 +1,5 @@ use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -197,7 +198,7 @@ pub fn setup_constraining_predicates<'tcx>( // Special case: watch out for some kind of sneaky attempt // to project out an associated type defined by this very // trait. - let unbound_trait_ref = projection.projection_ty.trait_ref(tcx); + let unbound_trait_ref = projection.projection_term.trait_ref(tcx); if Some(unbound_trait_ref) == impl_trait_ref { continue; } @@ -207,7 +208,7 @@ pub fn setup_constraining_predicates<'tcx>( // `<::Baz as Iterator>::Output = ::Output` // Then the projection only applies if `T` is known, but it still // does not determine `U`. - let inputs = parameters_for(tcx, projection.projection_ty, true); + let inputs = parameters_for(tcx, projection.projection_term, true); let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(p)); if !relies_only_on_inputs { continue; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index de12475678ca..b0ae73fcc4be 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -5,6 +5,7 @@ use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TyCtxt}; use rustc_span::symbol::Ident; @@ -326,7 +327,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) .or_insert(binding.span); - let projection_ty = if let ty::AssocKind::Fn = assoc_kind { + let projection_term = if let ty::AssocKind::Fn = assoc_kind { let mut emitted_bad_param_err = None; // If we have an method return type bound, then we need to instantiate // the method's early bound params with suitable late-bound params. @@ -380,7 +381,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() && tcx.is_impl_trait_in_trait(alias_ty.def_id) { - alias_ty + alias_ty.into() } else { return Err(tcx.dcx().emit_err(crate::errors::ReturnTypeNotationOnNonRpitit { span: binding.span, @@ -421,10 +422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); debug!(?alias_args); - // Note that we're indeed also using `AliasTy` (alias *type*) for associated - // *constants* to represent *const projections*. Alias *term* would be a more - // appropriate name but alas. - ty::AliasTy::new(tcx, assoc_item.def_id, alias_args) + ty::AliasTerm::new(tcx, assoc_item.def_id, alias_args) }); // Provide the resolved type of the associated constant to `type_of(AnonConst)`. @@ -461,7 +459,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // for<'a> ::Item = &'a str // <-- 'a is bad // for<'a> >::Output = &'a str // <-- 'a is ok let late_bound_in_projection_ty = - tcx.collect_constrained_late_bound_regions(projection_ty); + tcx.collect_constrained_late_bound_regions(projection_term); let late_bound_in_term = tcx.collect_referenced_late_bound_regions(trait_ref.rebind(term)); debug!(?late_bound_in_projection_ty); @@ -490,8 +488,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { bounds.push_projection_bound( tcx, - projection_ty - .map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }), + projection_term.map_bound(|projection_term| ty::ProjectionPredicate { + projection_term, + term, + }), binding.span, ); } @@ -501,6 +501,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // NOTE: If `only_self_bounds` is true, do NOT expand this associated type bound into // a trait predicate, since we only want to add predicates for the `Self` type. if !only_self_bounds.0 { + let projection_ty = projection_term + .map_bound(|projection_term| projection_term.expect_ty(self.tcx())); // Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty` // parameter to have a skipped binder. let param_ty = Ty::new_alias(tcx, ty::Projection, projection_ty.skip_binder()); diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs index 38dfa8d57d34..f19492e00b47 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs @@ -16,6 +16,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::traits::FulfillmentError; +use rustc_middle::bug; use rustc_middle::query::Key; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::GenericParamDefKind; @@ -625,25 +626,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { - let pred = bound_predicate.rebind(pred); // `::Item = String`. - let projection_ty = pred.skip_binder().projection_ty; + let projection_term = pred.projection_term; + let quiet_projection_term = + projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO)); - let args_with_infer_self = tcx.mk_args_from_iter( - std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_ty.args.iter().skip(1)), - ); + let term = pred.term; + let obligation = format!("{projection_term} = {term}"); + let quiet = format!("{quiet_projection_term} = {term}"); - let quiet_projection_ty = - ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self); - - let term = pred.skip_binder().term; - - let obligation = format!("{projection_ty} = {term}"); - let quiet = format!("{quiet_projection_ty} = {term}"); - - bound_span_label(projection_ty.self_ty(), &obligation, &quiet); - Some((obligation, projection_ty.self_ty())) + bound_span_label(projection_term.self_ty(), &obligation, &quiet); + Some((obligation, projection_term.self_ty())) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => { let p = poly_trait_ref.trait_ref; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 591d554d335e..d16648b9e8f6 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -44,6 +44,7 @@ use rustc_middle::ty::{ self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt, TypeVisitableExt, }; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::symbol::{kw, Ident, Symbol}; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs index 297cfe7027ec..30b99a095f3e 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs @@ -6,8 +6,9 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS; +use rustc_middle::span_bug; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_span::{ErrorGuaranteed, Span}; use rustc_trait_selection::traits::error_reporting::report_object_safety_error; @@ -280,11 +281,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let existential_projections = projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|mut b| { - assert_eq!(b.projection_ty.self_ty(), dummy_self); + assert_eq!(b.projection_term.self_ty(), dummy_self); // Like for trait refs, verify that `dummy_self` did not leak inside default type // parameters. - let references_self = b.projection_ty.args.iter().skip(1).any(|arg| { + let references_self = b.projection_term.args.iter().skip(1).any(|arg| { if arg.walk().any(|arg| arg == dummy_self.into()) { return true; } @@ -294,7 +295,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { let guar = tcx .dcx() .span_delayed_bug(span, "trait object projection bounds reference `Self`"); - b.projection_ty = replace_dummy_self_with_error(tcx, b.projection_ty, guar); + b.projection_term = replace_dummy_self_with_error(tcx, b.projection_term, guar); } ty::ExistentialProjection::erase_self_ty(tcx, b) diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index d6ba5fa9b5b0..10101aa046e5 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -4,6 +4,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index de697b04ebf7..6967cb4d9d0b 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -212,7 +212,7 @@ fn get_impl_args( traits::ObligationCause::new( impl1_span, impl1_def_id, - traits::ObligationCauseCode::SpannedWhereClause(impl2_node.def_id(), span), + traits::ObligationCauseCode::WhereClause(impl2_node.def_id(), span), ) }, ); @@ -258,23 +258,20 @@ fn unconstrained_parent_impl_args<'tcx>( // unconstrained parameters. for (clause, _) in impl_generic_predicates.predicates.iter() { if let ty::ClauseKind::Projection(proj) = clause.kind().skip_binder() { - let projection_ty = proj.projection_ty; - let projected_ty = proj.term; - - let unbound_trait_ref = projection_ty.trait_ref(tcx); + let unbound_trait_ref = proj.projection_term.trait_ref(tcx); if Some(unbound_trait_ref) == impl_trait_ref { continue; } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projection_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.projection_term, true)); - for param in cgp::parameters_for(tcx, projected_ty, false) { + for param in cgp::parameters_for(tcx, proj.term, false) { if !unconstrained_parameters.contains(¶m) { constrained_params.insert(param.0); } } - unconstrained_parameters.extend(cgp::parameters_for(tcx, projected_ty, true)); + unconstrained_parameters.extend(cgp::parameters_for(tcx, proj.term, true)); } } @@ -495,11 +492,11 @@ fn check_specialization_on<'tcx>( .emit()) } } - ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => Err(tcx + ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_term, term }) => Err(tcx .dcx() .struct_span_err( span, - format!("cannot specialize on associated type `{projection_ty} == {term}`",), + format!("cannot specialize on associated type `{projection_term} == {term}`",), ) .emit()), ty::ClauseKind::ConstArgHasType(..) => { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index e75740837f8d..654ef4baeb39 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -75,9 +75,6 @@ This API is completely unstable and subject to change. #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; - // These are used by Clippy. pub mod check; diff --git a/compiler/rustc_hir_analysis/src/outlives/test.rs b/compiler/rustc_hir_analysis/src/outlives/test.rs index 60cd8c39fa02..e9b6c679bd5a 100644 --- a/compiler/rustc_hir_analysis/src/outlives/test.rs +++ b/compiler/rustc_hir_analysis/src/outlives/test.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::sym, ErrorGuaranteed}; diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs index d3bb22d715d7..95290bbecf2c 100644 --- a/compiler/rustc_hir_analysis/src/outlives/utils.rs +++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_infer::infer::outlives::components::{push_outlives_components, Component}; use rustc_middle::ty::{self, Region, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use smallvec::smallvec; diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index eeb8b0285052..730e989edaed 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -8,6 +8,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use super::terms::VarianceTerm::*; use super::terms::*; diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 27fdea01c2b2..cefd8fb1ac5f 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -8,6 +8,7 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt}; use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable}; @@ -166,7 +167,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty: ty::AliasTy { args, .. }, + projection_term: ty::AliasTerm { args, .. }, term, }) => { for arg in &args[1..] { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4f5fbd024a99..a47e6af0bf20 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -139,8 +139,12 @@ impl std::ops::DerefMut for State<'_> { } impl<'a> PrintState<'a> for State<'a> { - fn comments(&mut self) -> &mut Option> { - &mut self.comments + fn comments(&self) -> Option<&Comments<'a>> { + self.comments.as_ref() + } + + fn comments_mut(&mut self) -> Option<&mut Comments<'a>> { + self.comments.as_mut() } fn ann_post(&mut self, ident: Ident) { diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 0560d0d902a3..72b95a9603dd 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -46,10 +46,6 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` -hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding - .label = `mut` dereferences the type of this binding - .help = this will change in edition 2024 - hir_typeck_expected_default_return_type = expected `()` because of default return type hir_typeck_expected_return_type = expected `{$expected}` because of return type diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index defb557867b7..502a176845e7 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -574,7 +575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.misc(span), self.param_env, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( self.tcx, fn_once_output_def_id, [arg_ty.into(), fn_sig.inputs()[0].into(), const_param], diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 92f74281ab98..9e9a1f678edd 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -36,6 +36,7 @@ use hir::ExprKind; use rustc_errors::{codes::*, Applicability, Diag, ErrorGuaranteed}; use rustc_hir as hir; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::bug; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; @@ -140,7 +141,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Never | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => { - self.dcx().span_bug(span, format!("`{t:?}` should be sized but is not?")); + let guar = self + .dcx() + .span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); + return Err(guar); } }) } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index f52f95db6d34..aca069d8fb5a 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -10,6 +10,7 @@ use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::infer::{InferOk, InferResult}; use rustc_infer::traits::ObligationCauseCode; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::span_bug; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; @@ -414,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // many viable options, so pick the most restrictive. let trait_def_id = match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { - Some(data.projection_ty.trait_def_id(self.tcx)) + Some(data.projection_term.trait_def_id(self.tcx)) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => Some(data.def_id()), _ => None, @@ -475,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => return None, } - let arg_param_ty = projection.skip_binder().projection_ty.args.type_at(1); + let arg_param_ty = projection.skip_binder().projection_term.args.type_at(1); let arg_param_ty = self.resolve_vars_if_possible(arg_param_ty); debug!(?arg_param_ty); @@ -930,7 +931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; // Check that this is a projection from the `Future` trait. - let trait_def_id = predicate.projection_ty.trait_def_id(self.tcx); + let trait_def_id = predicate.projection_term.trait_def_id(self.tcx); let future_trait = self.tcx.require_lang_item(LangItem::Future, Some(cause_span)); if trait_def_id != future_trait { debug!("deduce_future_output_from_projection: not a future"); @@ -940,11 +941,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The `Future` trait has only one associated item, `Output`, // so check that this is what we see. let output_assoc_item = self.tcx.associated_item_def_ids(future_trait)[0]; - if output_assoc_item != predicate.projection_ty.def_id { + if output_assoc_item != predicate.projection_term.def_id { span_bug!( cause_span, "projecting associated item `{:?}` from future, which is not Output `{:?}`", - predicate.projection_ty.def_id, + predicate.projection_term.def_id, output_assoc_item, ); } diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 88ba937e4b5b..8d93f402f10c 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -45,6 +45,7 @@ use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause}; use rustc_infer::traits::{Obligation, PredicateObligation}; use rustc_middle::lint::in_external_macro; +use rustc_middle::span_bug; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index b21124917332..706f6f875bf6 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::intravisit::Visitor; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index ba8f246fd8d2..f250b909596e 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -651,10 +651,3 @@ pub enum SuggestBoxingForReturnImplTrait { ends: Vec, }, } -#[derive(LintDiagnostic)] -#[diag(hir_typeck_dereferencing_mut_binding)] -pub struct DereferencingMutBinding { - #[label] - #[help] - pub span: Span, -} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index cdf17f3a1131..f283c0138052 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -45,6 +45,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts}; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index cc42e69f5382..1864c7e6ef82 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -2,26 +2,34 @@ //! normal visitor, which just walks the entire body in one shot, the //! `ExprUseVisitor` determines how expressions are being used. +use std::cell::{Ref, RefCell}; +use std::ops::Deref; use std::slice::from_ref; use hir::def::DefKind; +use hir::pat_util::EnumerateAndAdjustIterator as _; use hir::Expr; +use rustc_lint::LateContext; // Export these here so that Clippy can use them. pub use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; -use rustc_hir::def::Res; +use rustc_hir::def::{CtorOf, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, PatKind}; -use rustc_infer::infer::InferCtxt; +use rustc_middle::{bug, span_bug}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt}; -use rustc_target::abi::FIRST_VARIANT; +use rustc_middle::ty::{ + self, adjustment, AdtKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt as _, +}; +use rustc_span::{ErrorGuaranteed, Span}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; +use rustc_trait_selection::infer::InferCtxtExt; use ty::BorrowKind::ImmBorrow; -use crate::mem_categorization as mc; +use crate::fn_ctxt::FnCtxt; /// This trait defines the callbacks you can expect to receive when /// employing the ExprUseVisitor. @@ -80,191 +88,322 @@ pub trait Delegate<'tcx> { ); } -#[derive(Copy, Clone, PartialEq, Debug)] -enum ConsumeMode { - /// reference to x where x has a type that copies - Copy, - /// reference to x where x has a type that moves - Move, +impl<'tcx, D: Delegate<'tcx>> Delegate<'tcx> for &mut D { + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).consume(place_with_id, diag_expr_id) + } + + fn borrow( + &mut self, + place_with_id: &PlaceWithHirId<'tcx>, + diag_expr_id: HirId, + bk: ty::BorrowKind, + ) { + (**self).borrow(place_with_id, diag_expr_id, bk) + } + + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).copy(place_with_id, diag_expr_id) + } + + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).mutate(assignee_place, diag_expr_id) + } + + fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + (**self).bind(binding_place, diag_expr_id) + } + + fn fake_read( + &mut self, + place_with_id: &PlaceWithHirId<'tcx>, + cause: FakeReadCause, + diag_expr_id: HirId, + ) { + (**self).fake_read(place_with_id, cause, diag_expr_id) + } +} + +pub trait TypeInformationCtxt<'tcx> { + type TypeckResults<'a>: Deref> + where + Self: 'a; + + type Error; + + fn typeck_results(&self) -> Self::TypeckResults<'_>; + + fn resolve_vars_if_possible>>(&self, t: T) -> T; + + fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>; + + fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error; + + fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error>; + + fn tainted_by_errors(&self) -> Result<(), Self::Error>; + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool; + + fn body_owner_def_id(&self) -> LocalDefId; + + fn tcx(&self) -> TyCtxt<'tcx>; +} + +impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> { + type TypeckResults<'a> = Ref<'a, ty::TypeckResults<'tcx>> + where + Self: 'a; + + type Error = ErrorGuaranteed; + + fn typeck_results(&self) -> Self::TypeckResults<'_> { + self.typeck_results.borrow() + } + + fn resolve_vars_if_possible>>(&self, t: T) -> T { + self.infcx.resolve_vars_if_possible(t) + } + + fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + (**self).try_structurally_resolve_type(sp, ty) + } + + fn report_error(&self, span: Span, msg: impl ToString) -> Self::Error { + self.tcx.dcx().span_delayed_bug(span, msg.to_string()) + } + + fn error_reported_in_ty(&self, ty: Ty<'tcx>) -> Result<(), Self::Error> { + ty.error_reported() + } + + fn tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> { + if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) } + } + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + self.infcx.type_is_copy_modulo_regions(self.param_env, ty) + } + + fn body_owner_def_id(&self) -> LocalDefId { + self.body_id + } + + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } +} + +impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) { + type TypeckResults<'a> = &'tcx ty::TypeckResults<'tcx> + where + Self: 'a; + + type Error = !; + + fn typeck_results(&self) -> Self::TypeckResults<'_> { + self.0.maybe_typeck_results().expect("expected typeck results") + } + + fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> { + // FIXME: Maybe need to normalize here. + ty + } + + fn resolve_vars_if_possible>>(&self, t: T) -> T { + t + } + + fn report_error(&self, span: Span, msg: impl ToString) -> ! { + span_bug!(span, "{}", msg.to_string()) + } + + fn error_reported_in_ty(&self, _ty: Ty<'tcx>) -> Result<(), !> { + Ok(()) + } + + fn tainted_by_errors(&self) -> Result<(), !> { + Ok(()) + } + + fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { + ty.is_copy_modulo_regions(self.0.tcx, self.0.param_env) + } + + fn body_owner_def_id(&self) -> LocalDefId { + self.1 + } + + fn tcx(&self) -> TyCtxt<'tcx> { + self.0.tcx + } } /// The ExprUseVisitor type /// /// This is the code that actually walks the tree. -pub struct ExprUseVisitor<'a, 'tcx> { - mc: mc::MemCategorizationContext<'a, 'tcx>, - body_owner: LocalDefId, - delegate: &'a mut dyn Delegate<'tcx>, +pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> { + cx: Cx, + /// We use a `RefCell` here so that delegates can mutate themselves, but we can + /// still have calls to our own helper functions. + delegate: RefCell, + upvars: Option<&'tcx FxIndexMap>, } -/// If the MC results in an error, it's because the type check -/// failed (or will fail, when the error is uncovered and reported -/// during writeback). In this case, we just ignore this part of the -/// code. -/// -/// Note that this macro appears similar to try!(), but, unlike try!(), -/// it does not propagate the error. -macro_rules! return_if_err { - ($inp: expr) => { - match $inp { - Ok(v) => v, - Err(()) => { - debug!("mc reported err"); - return; - } - } - }; +impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'tcx, (&'a LateContext<'tcx>, LocalDefId), D> { + pub fn for_clippy(cx: &'a LateContext<'tcx>, body_def_id: LocalDefId, delegate: D) -> Self { + Self::new((cx, body_def_id), delegate) + } } -impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { +impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { /// Creates the ExprUseVisitor, configuring it with the various options provided: /// /// - `delegate` -- who receives the callbacks /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`) /// - `typeck_results` --- typeck results for the code being analyzed - pub fn new( - delegate: &'a mut (dyn Delegate<'tcx> + 'a), - infcx: &'a InferCtxt<'tcx>, - body_owner: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, - ) -> Self { + pub(crate) fn new(cx: Cx, delegate: D) -> Self { ExprUseVisitor { - mc: mc::MemCategorizationContext::new(infcx, param_env, body_owner, typeck_results), - body_owner, - delegate, + delegate: RefCell::new(delegate), + upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()), + cx, } } - #[instrument(skip(self), level = "debug")] - pub fn consume_body(&mut self, body: &hir::Body<'_>) { + pub fn consume_body(&self, body: &hir::Body<'_>) -> Result<(), Cx::Error> { for param in body.params { - let param_ty = return_if_err!(self.mc.pat_ty_adjusted(param.pat)); + let param_ty = self.pat_ty_adjusted(param.pat)?; debug!("consume_body: param_ty = {:?}", param_ty); - let param_place = self.mc.cat_rvalue(param.hir_id, param_ty); + let param_place = self.cat_rvalue(param.hir_id, param_ty); - self.walk_irrefutable_pat(¶m_place, param.pat); + self.walk_irrefutable_pat(¶m_place, param.pat)?; } - self.consume_expr(body.value); + self.consume_expr(body.value)?; + + Ok(()) } - fn tcx(&self) -> TyCtxt<'tcx> { - self.mc.tcx() + fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { + debug!("delegate_consume(place_with_id={:?})", place_with_id); + + if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) { + self.delegate.borrow_mut().copy(place_with_id, diag_expr_id); + } else { + self.delegate.borrow_mut().consume(place_with_id, diag_expr_id); + } } - fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { - delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) - } - - fn consume_exprs(&mut self, exprs: &[hir::Expr<'_>]) { + fn consume_exprs(&self, exprs: &[hir::Expr<'_>]) -> Result<(), Cx::Error> { for expr in exprs { - self.consume_expr(expr); + self.consume_expr(expr)?; } + + Ok(()) } - pub fn consume_expr(&mut self, expr: &hir::Expr<'_>) { + // FIXME: It's suspicious that this is public; clippy should probably use `walk_expr`. + pub fn consume_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { debug!("consume_expr(expr={:?})", expr); - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate_consume(&place_with_id, place_with_id.hir_id); - self.walk_expr(expr); + let place_with_id = self.cat_expr(expr)?; + self.consume_or_copy(&place_with_id, place_with_id.hir_id); + self.walk_expr(expr)?; + Ok(()) } - fn mutate_expr(&mut self, expr: &hir::Expr<'_>) { - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.mutate(&place_with_id, place_with_id.hir_id); - self.walk_expr(expr); + fn mutate_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { + let place_with_id = self.cat_expr(expr)?; + self.delegate.borrow_mut().mutate(&place_with_id, place_with_id.hir_id); + self.walk_expr(expr)?; + Ok(()) } - fn borrow_expr(&mut self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) { + fn borrow_expr(&self, expr: &hir::Expr<'_>, bk: ty::BorrowKind) -> Result<(), Cx::Error> { debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk); - let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); - + let place_with_id = self.cat_expr(expr)?; + self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); self.walk_expr(expr) } - fn select_from_expr(&mut self, expr: &hir::Expr<'_>) { - self.walk_expr(expr) - } - - pub fn walk_expr(&mut self, expr: &hir::Expr<'_>) { + pub fn walk_expr(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { debug!("walk_expr(expr={:?})", expr); - self.walk_adjustment(expr); + self.walk_adjustment(expr)?; match expr.kind { hir::ExprKind::Path(_) => {} - hir::ExprKind::Type(subexpr, _) => self.walk_expr(subexpr), + hir::ExprKind::Type(subexpr, _) => { + self.walk_expr(subexpr)?; + } hir::ExprKind::Unary(hir::UnOp::Deref, base) => { // *base - self.select_from_expr(base); + self.walk_expr(base)?; } hir::ExprKind::Field(base, _) => { // base.f - self.select_from_expr(base); + self.walk_expr(base)?; } hir::ExprKind::Index(lhs, rhs, _) => { // lhs[rhs] - self.select_from_expr(lhs); - self.consume_expr(rhs); + self.walk_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Call(callee, args) => { // callee(args) - self.consume_expr(callee); - self.consume_exprs(args); + self.consume_expr(callee)?; + self.consume_exprs(args)?; } hir::ExprKind::MethodCall(.., receiver, args, _) => { // callee.m(args) - self.consume_expr(receiver); - self.consume_exprs(args); + self.consume_expr(receiver)?; + self.consume_exprs(args)?; } hir::ExprKind::Struct(_, fields, ref opt_with) => { - self.walk_struct_expr(fields, opt_with); + self.walk_struct_expr(fields, opt_with)?; } hir::ExprKind::Tup(exprs) => { - self.consume_exprs(exprs); + self.consume_exprs(exprs)?; } hir::ExprKind::If(cond_expr, then_expr, ref opt_else_expr) => { - self.consume_expr(cond_expr); - self.consume_expr(then_expr); + self.consume_expr(cond_expr)?; + self.consume_expr(then_expr)?; if let Some(else_expr) = *opt_else_expr { - self.consume_expr(else_expr); + self.consume_expr(else_expr)?; } } hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => { - self.walk_local(init, pat, None, |t| t.borrow_expr(init, ty::ImmBorrow)) + self.walk_local(init, pat, None, || self.borrow_expr(init, ty::ImmBorrow))?; } hir::ExprKind::Match(discr, arms, _) => { - let discr_place = return_if_err!(self.mc.cat_expr(discr)); - return_if_err!(self.maybe_read_scrutinee( + let discr_place = self.cat_expr(discr)?; + self.maybe_read_scrutinee( discr, discr_place.clone(), arms.iter().map(|arm| arm.pat), - )); + )?; // treatment of the discriminant is handled while walking the arms. for arm in arms { - self.walk_arm(&discr_place, arm); + self.walk_arm(&discr_place, arm)?; } } hir::ExprKind::Array(exprs) => { - self.consume_exprs(exprs); + self.consume_exprs(exprs)?; } hir::ExprKind::AddrOf(_, m, base) => { @@ -272,21 +411,23 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // make sure that the thing we are pointing out stays valid // for the lifetime `scope_r` of the resulting ptr: let bk = ty::BorrowKind::from_mutbl(m); - self.borrow_expr(base, bk); + self.borrow_expr(base, bk)?; } hir::ExprKind::InlineAsm(asm) => { for (op, _op_sp) in asm.operands { match op { - hir::InlineAsmOperand::In { expr, .. } => self.consume_expr(expr), + hir::InlineAsmOperand::In { expr, .. } => { + self.consume_expr(expr)?; + } hir::InlineAsmOperand::Out { expr: Some(expr), .. } | hir::InlineAsmOperand::InOut { expr, .. } => { - self.mutate_expr(expr); + self.mutate_expr(expr)?; } hir::InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => { - self.consume_expr(in_expr); + self.consume_expr(in_expr)?; if let Some(out_expr) = out_expr { - self.mutate_expr(out_expr); + self.mutate_expr(out_expr)?; } } hir::InlineAsmOperand::Out { expr: None, .. } @@ -294,7 +435,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | hir::InlineAsmOperand::SymFn { .. } | hir::InlineAsmOperand::SymStatic { .. } => {} hir::InlineAsmOperand::Label { block } => { - self.walk_block(block); + self.walk_block(block)?; } } } @@ -307,72 +448,74 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | hir::ExprKind::Err(_) => {} hir::ExprKind::Loop(blk, ..) => { - self.walk_block(blk); + self.walk_block(blk)?; } hir::ExprKind::Unary(_, lhs) => { - self.consume_expr(lhs); + self.consume_expr(lhs)?; } hir::ExprKind::Binary(_, lhs, rhs) => { - self.consume_expr(lhs); - self.consume_expr(rhs); + self.consume_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Block(blk, _) => { - self.walk_block(blk); + self.walk_block(blk)?; } hir::ExprKind::Break(_, ref opt_expr) | hir::ExprKind::Ret(ref opt_expr) => { if let Some(expr) = *opt_expr { - self.consume_expr(expr); + self.consume_expr(expr)?; } } hir::ExprKind::Become(call) => { - self.consume_expr(call); + self.consume_expr(call)?; } hir::ExprKind::Assign(lhs, rhs, _) => { - self.mutate_expr(lhs); - self.consume_expr(rhs); + self.mutate_expr(lhs)?; + self.consume_expr(rhs)?; } hir::ExprKind::Cast(base, _) => { - self.consume_expr(base); + self.consume_expr(base)?; } hir::ExprKind::DropTemps(expr) => { - self.consume_expr(expr); + self.consume_expr(expr)?; } hir::ExprKind::AssignOp(_, lhs, rhs) => { - if self.mc.typeck_results.is_method_call(expr) { - self.consume_expr(lhs); + if self.cx.typeck_results().is_method_call(expr) { + self.consume_expr(lhs)?; } else { - self.mutate_expr(lhs); + self.mutate_expr(lhs)?; } - self.consume_expr(rhs); + self.consume_expr(rhs)?; } hir::ExprKind::Repeat(base, _) => { - self.consume_expr(base); + self.consume_expr(base)?; } hir::ExprKind::Closure(closure) => { - self.walk_captures(closure); + self.walk_captures(closure)?; } hir::ExprKind::Yield(value, _) => { - self.consume_expr(value); + self.consume_expr(value)?; } } + + Ok(()) } - fn walk_stmt(&mut self, stmt: &hir::Stmt<'_>) { + fn walk_stmt(&self, stmt: &hir::Stmt<'_>) -> Result<(), Cx::Error> { match stmt.kind { hir::StmtKind::Let(hir::LetStmt { pat, init: Some(expr), els, .. }) => { - self.walk_local(expr, pat, *els, |_| {}) + self.walk_local(expr, pat, *els, || Ok(()))?; } hir::StmtKind::Let(_) => {} @@ -383,25 +526,26 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) => { - self.consume_expr(expr); + self.consume_expr(expr)?; } } + + Ok(()) } fn maybe_read_scrutinee<'t>( - &mut self, + &self, discr: &Expr<'_>, discr_place: PlaceWithHirId<'tcx>, pats: impl Iterator>, - ) -> Result<(), ()> { + ) -> Result<(), Cx::Error> { // Matching should not always be considered a use of the place, hence // discr does not necessarily need to be borrowed. // We only want to borrow discr if the pattern contain something other // than wildcards. - let ExprUseVisitor { ref mc, body_owner: _, delegate: _ } = *self; let mut needs_to_be_read = false; for pat in pats { - mc.cat_pattern(discr_place.clone(), pat, |place, pat| { + self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { match &pat.kind { PatKind::Binding(.., opt_sub_pat) => { // If the opt_sub_pat is None, then the binding does not count as @@ -419,7 +563,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // A `Path` pattern is just a name like `Foo`. This is either a // named constant or else it refers to an ADT variant - let res = self.mc.typeck_results.qpath_res(qpath, pat.hir_id); + let res = self.cx.typeck_results().qpath_res(qpath, pat.hir_id); match res { Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => { // Named constants have to be equated with the value @@ -431,7 +575,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { _ => { // Otherwise, this is a struct/enum variant, and so it's // only a read if we need to read the discriminant. - needs_to_be_read |= is_multivariant_adt(place.place.ty()); + needs_to_be_read |= + self.is_multivariant_adt(place.place.ty(), pat.span); } } } @@ -443,7 +588,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // perform some reads). let place_ty = place.place.ty(); - needs_to_be_read |= is_multivariant_adt(place_ty); + needs_to_be_read |= self.is_multivariant_adt(place_ty, pat.span); } PatKind::Lit(_) | PatKind::Range(..) => { // If the PatKind is a Lit or a Range then we want @@ -473,18 +618,20 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // being examined } } + + Ok(()) })? } if needs_to_be_read { - self.borrow_expr(discr, ty::ImmBorrow); + self.borrow_expr(discr, ty::ImmBorrow)?; } else { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( &discr_place, FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, @@ -492,90 +639,93 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // We always want to walk the discriminant. We want to make sure, for instance, // that the discriminant has been initialized. - self.walk_expr(discr); + self.walk_expr(discr)?; } Ok(()) } fn walk_local( - &mut self, + &self, expr: &hir::Expr<'_>, pat: &hir::Pat<'_>, els: Option<&hir::Block<'_>>, mut f: F, - ) where - F: FnMut(&mut Self), + ) -> Result<(), Cx::Error> + where + F: FnMut() -> Result<(), Cx::Error>, { - self.walk_expr(expr); - let expr_place = return_if_err!(self.mc.cat_expr(expr)); - f(self); + self.walk_expr(expr)?; + let expr_place = self.cat_expr(expr)?; + f()?; if let Some(els) = els { // borrowing because we need to test the discriminant - return_if_err!(self.maybe_read_scrutinee( - expr, - expr_place.clone(), - from_ref(pat).iter() - )); - self.walk_block(els) + self.maybe_read_scrutinee(expr, expr_place.clone(), from_ref(pat).iter())?; + self.walk_block(els)?; } - self.walk_irrefutable_pat(&expr_place, pat); + self.walk_irrefutable_pat(&expr_place, pat)?; + Ok(()) } /// Indicates that the value of `blk` will be consumed, meaning either copied or moved /// depending on its type. - fn walk_block(&mut self, blk: &hir::Block<'_>) { + fn walk_block(&self, blk: &hir::Block<'_>) -> Result<(), Cx::Error> { debug!("walk_block(blk.hir_id={})", blk.hir_id); for stmt in blk.stmts { - self.walk_stmt(stmt); + self.walk_stmt(stmt)?; } if let Some(tail_expr) = blk.expr { - self.consume_expr(tail_expr); + self.consume_expr(tail_expr)?; } + + Ok(()) } fn walk_struct_expr<'hir>( - &mut self, + &self, fields: &[hir::ExprField<'_>], opt_with: &Option<&'hir hir::Expr<'_>>, - ) { + ) -> Result<(), Cx::Error> { // Consume the expressions supplying values for each field. for field in fields { - self.consume_expr(field.expr); + self.consume_expr(field.expr)?; // The struct path probably didn't resolve - if self.mc.typeck_results.opt_field_index(field.hir_id).is_none() { - self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field"); + if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() { + self.cx + .tcx() + .dcx() + .span_delayed_bug(field.span, "couldn't resolve index for field"); } } let with_expr = match *opt_with { Some(w) => &*w, None => { - return; + return Ok(()); } }; - let with_place = return_if_err!(self.mc.cat_expr(with_expr)); + let with_place = self.cat_expr(with_expr)?; // Select just those fields of the `with` // expression that will actually be used - match with_place.place.ty().kind() { + match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() { ty::Adt(adt, args) if adt.is_struct() => { // Consume those fields of the with expression that are needed. for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { - let is_mentioned = fields - .iter() - .any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); + let is_mentioned = fields.iter().any(|f| { + self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index) + }); if !is_mentioned { - let field_place = self.mc.cat_projection( - &*with_expr, + let field_place = self.cat_projection( + with_expr.hir_id, with_place.clone(), - with_field.ty(self.tcx(), args), + with_field.ty(self.cx.tcx(), args), ProjectionKind::Field(f_index, FIRST_VARIANT), ); - self.delegate_consume(&field_place, field_place.hir_id); + self.consume_or_copy(&field_place, field_place.hir_id); } } } @@ -584,7 +734,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if self.tcx().dcx().has_errors().is_none() { + if self.cx.tcx().dcx().has_errors().is_none() { span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } @@ -592,15 +742,18 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // walk the with expression so that complex expressions // are properly handled. - self.walk_expr(with_expr); + self.walk_expr(with_expr)?; + + Ok(()) } /// Invoke the appropriate delegate calls for anything that gets /// consumed or borrowed as part of the automatic adjustment /// process. - fn walk_adjustment(&mut self, expr: &hir::Expr<'_>) { - let adjustments = self.mc.typeck_results.expr_adjustments(expr); - let mut place_with_id = return_if_err!(self.mc.cat_expr_unadjusted(expr)); + fn walk_adjustment(&self, expr: &hir::Expr<'_>) -> Result<(), Cx::Error> { + let typeck_results = self.cx.typeck_results(); + let adjustments = typeck_results.expr_adjustments(expr); + let mut place_with_id = self.cat_expr_unadjusted(expr)?; for adjustment in adjustments { debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment); match adjustment.kind { @@ -609,7 +762,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { | adjustment::Adjust::DynStar => { // Creating a closure/fn-pointer or unsizing consumes // the input and stores it into the resulting rvalue. - self.delegate_consume(&place_with_id, place_with_id.hir_id); + self.consume_or_copy(&place_with_id, place_with_id.hir_id); } adjustment::Adjust::Deref(None) => {} @@ -621,23 +774,24 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // this is an autoref of `x`. adjustment::Adjust::Deref(Some(ref deref)) => { let bk = ty::BorrowKind::from_mutbl(deref.mutbl); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); + self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk); } adjustment::Adjust::Borrow(ref autoref) => { self.walk_autoref(expr, &place_with_id, autoref); } } - place_with_id = - return_if_err!(self.mc.cat_expr_adjusted(expr, place_with_id, adjustment)); + place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?; } + + Ok(()) } /// Walks the autoref `autoref` applied to the autoderef'd /// `expr`. `base_place` is the mem-categorized form of `expr` /// after all relevant autoderefs have occurred. fn walk_autoref( - &mut self, + &self, expr: &hir::Expr<'_>, base_place: &PlaceWithHirId<'tcx>, autoref: &adjustment::AutoBorrow<'tcx>, @@ -649,7 +803,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match *autoref { adjustment::AutoBorrow::Ref(_, m) => { - self.delegate.borrow( + self.delegate.borrow_mut().borrow( base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m.into()), @@ -659,80 +813,93 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); - self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m)); + self.delegate.borrow_mut().borrow( + base_place, + base_place.hir_id, + ty::BorrowKind::from_mutbl(m), + ); } } } - fn walk_arm(&mut self, discr_place: &PlaceWithHirId<'tcx>, arm: &hir::Arm<'_>) { + fn walk_arm( + &self, + discr_place: &PlaceWithHirId<'tcx>, + arm: &hir::Arm<'_>, + ) -> Result<(), Cx::Error> { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( discr_place, FakeReadCause::ForMatchedPlace(closure_def_id), discr_place.hir_id, ); - self.walk_pat(discr_place, arm.pat, arm.guard.is_some()); + self.walk_pat(discr_place, arm.pat, arm.guard.is_some())?; if let Some(ref e) = arm.guard { - self.consume_expr(e) + self.consume_expr(e)?; } - self.consume_expr(arm.body); + self.consume_expr(arm.body)?; + Ok(()) } /// Walks a pat that occurs in isolation (i.e., top-level of fn argument or /// let binding, and *not* a match arm or nested pat.) - fn walk_irrefutable_pat(&mut self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>) { + fn walk_irrefutable_pat( + &self, + discr_place: &PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + ) -> Result<(), Cx::Error> { let closure_def_id = match discr_place.place.base { PlaceBase::Upvar(upvar_id) => Some(upvar_id.closure_expr_id), _ => None, }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( discr_place, FakeReadCause::ForLet(closure_def_id), discr_place.hir_id, ); - self.walk_pat(discr_place, pat, false); + self.walk_pat(discr_place, pat, false)?; + Ok(()) } /// The core driver for walking a pattern fn walk_pat( - &mut self, + &self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, has_guard: bool, - ) { + ) -> Result<(), Cx::Error> { debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard); - let tcx = self.tcx(); - let ExprUseVisitor { ref mc, body_owner: _, ref mut delegate } = *self; - return_if_err!(mc.cat_pattern(discr_place.clone(), pat, |place, pat| { + let tcx = self.cx.tcx(); + self.cat_pattern(discr_place.clone(), pat, &mut |place, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.kind { debug!("walk_pat: binding place={:?} pat={:?}", place, pat); if let Some(bm) = - mc.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span) + self.cx.typeck_results().extract_binding_mode(tcx.sess, pat.hir_id, pat.span) { debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); // pat_ty: the type of the binding being produced. - let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); + let pat_ty = self.node_ty(pat.hir_id)?; debug!("walk_pat: pat_ty={:?}", pat_ty); let def = Res::Local(canonical_id); - if let Ok(ref binding_place) = mc.cat_res(pat.hir_id, pat.span, pat_ty, def) { - delegate.bind(binding_place, binding_place.hir_id); + if let Ok(ref binding_place) = self.cat_res(pat.hir_id, pat.span, pat_ty, def) { + self.delegate.borrow_mut().bind(binding_place, binding_place.hir_id); } // Subtle: MIR desugaring introduces immutable borrows for each pattern // binding when lowering pattern guards to ensure that the guard does not // modify the scrutinee. if has_guard { - delegate.borrow(place, discr_place.hir_id, ImmBorrow); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, ImmBorrow); } // It is also a borrow or copy/move of the value being matched. @@ -742,11 +909,11 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match bm.0 { hir::ByRef::Yes(m) => { let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(place, discr_place.hir_id, bk); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } hir::ByRef::No => { debug!("walk_pat binding consuming pat"); - delegate_consume(mc, *delegate, place, discr_place.hir_id); + self.consume_or_copy(place, discr_place.hir_id); } } } @@ -755,12 +922,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // determines whether to borrow *at the level of the deref pattern* rather than // borrowing the bound place (since that inner place is inside the temporary that // stores the result of calling `deref()`/`deref_mut()` so can't be captured). - let mutable = mc.typeck_results.pat_has_ref_mut_binding(subpattern); + let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpattern); let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; let bk = ty::BorrowKind::from_mutbl(mutability); - delegate.borrow(place, discr_place.hir_id, bk); + self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk); } - })); + + Ok(()) + }) } /// Handle the case where the current body contains a closure. @@ -782,7 +951,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// /// - When reporting the Place back to the Delegate, ensure that the UpvarId uses the enclosing /// closure as the DefId. - fn walk_captures(&mut self, closure_expr: &hir::Closure<'_>) { + fn walk_captures(&self, closure_expr: &hir::Closure<'_>) -> Result<(), Cx::Error> { fn upvar_is_local_variable( upvars: Option<&FxIndexMap>, upvar_id: HirId, @@ -793,21 +962,21 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { debug!("walk_captures({:?})", closure_expr); - let tcx = self.tcx(); + let tcx = self.cx.tcx(); let closure_def_id = closure_expr.def_id; - let upvars = tcx.upvars_mentioned(self.body_owner); - // For purposes of this function, coroutine and closures are equivalent. - let body_owner_is_closure = - matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,); + let body_owner_is_closure = matches!( + tcx.hir().body_owner_kind(self.cx.body_owner_def_id()), + hir::BodyOwnerKind::Closure + ); // If we have a nested closure, we want to include the fake reads present in the nested closure. - if let Some(fake_reads) = self.mc.typeck_results.closure_fake_reads.get(&closure_def_id) { + if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) { for (fake_read, cause, hir_id) in fake_reads.iter() { match fake_read.base { PlaceBase::Upvar(upvar_id) => { if upvar_is_local_variable( - upvars, + self.upvars, upvar_id.var_path.hir_id, body_owner_is_closure, ) { @@ -837,7 +1006,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { ); } }; - self.delegate.fake_read( + self.delegate.borrow_mut().fake_read( &PlaceWithHirId { place: fake_read.clone(), hir_id: *hir_id }, *cause, *hir_id, @@ -845,10 +1014,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - if let Some(min_captures) = self.mc.typeck_results.closure_min_captures.get(&closure_def_id) + if let Some(min_captures) = + self.cx.typeck_results().closure_min_captures.get(&closure_def_id) { for (var_hir_id, min_list) in min_captures.iter() { - if upvars.map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) { + if self + .upvars + .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) + { // The nested closure might be capturing the current (enclosing) closure's local variables. // We check if the root variable is ever mentioned within the enclosing closure, if not // then for the current body (if it's a closure) these aren't captures, we will ignore them. @@ -860,7 +1033,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { let place_base = if body_owner_is_closure { // Mark the place to be captured by the enclosing closure - PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner)) + PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id())) } else { // If the body owner isn't a closure then the variable must // be a local variable @@ -878,10 +1051,10 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match capture_info.capture_kind { ty::UpvarCapture::ByValue => { - self.delegate_consume(&place_with_id, place_with_id.hir_id); + self.consume_or_copy(&place_with_id, place_with_id.hir_id); } ty::UpvarCapture::ByRef(upvar_borrow) => { - self.delegate.borrow( + self.delegate.borrow_mut().borrow( &place_with_id, place_with_id.hir_id, upvar_borrow, @@ -891,53 +1064,733 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } } + + Ok(()) } } -fn copy_or_move<'a, 'tcx>( - mc: &mc::MemCategorizationContext<'a, 'tcx>, - place_with_id: &PlaceWithHirId<'tcx>, -) -> ConsumeMode { - if !mc.type_is_copy_modulo_regions(place_with_id.place.ty()) { - ConsumeMode::Move - } else { - ConsumeMode::Copy - } -} - -// - If a place is used in a `ByValue` context then move it if it's not a `Copy` type. -// - If the place that is a `Copy` type consider it an `ImmBorrow`. -fn delegate_consume<'a, 'tcx>( - mc: &mc::MemCategorizationContext<'a, 'tcx>, - delegate: &mut (dyn Delegate<'tcx> + 'a), - place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: HirId, -) { - debug!("delegate_consume(place_with_id={:?})", place_with_id); - - let mode = copy_or_move(mc, place_with_id); - - match mode { - ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), - ConsumeMode::Copy => delegate.copy(place_with_id, diag_expr_id), - } -} - -fn is_multivariant_adt(ty: Ty<'_>) -> bool { - if let ty::Adt(def, _) = ty.kind() { - // Note that if a non-exhaustive SingleVariant is defined in another crate, we need - // to assume that more cases will be added to the variant in the future. This mean - // that we should handle non-exhaustive SingleVariant the same way we would handle - // a MultiVariant. - // If the variant is not local it must be defined in another crate. - let is_non_exhaustive = match def.adt_kind() { - AdtKind::Struct | AdtKind::Union => { - def.non_enum_variant().is_field_list_non_exhaustive() +/// The job of the categorization methods is to analyze an expression to +/// determine what kind of memory is used in evaluating it (for example, +/// where dereferences occur and what kind of pointer is dereferenced; +/// whether the memory is mutable, etc.). +/// +/// Categorization effectively transforms all of our expressions into +/// expressions of the following forms (the actual enum has many more +/// possibilities, naturally, but they are all variants of these base +/// forms): +/// ```ignore (not-rust) +/// E = rvalue // some computed rvalue +/// | x // address of a local variable or argument +/// | *E // deref of a ptr +/// | E.comp // access to an interior component +/// ``` +/// Imagine a routine ToAddr(Expr) that evaluates an expression and returns an +/// address where the result is to be found. If Expr is a place, then this +/// is the address of the place. If `Expr` is an rvalue, this is the address of +/// some temporary spot in memory where the result is stored. +/// +/// Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)` +/// as follows: +/// +/// - `cat`: what kind of expression was this? This is a subset of the +/// full expression forms which only includes those that we care about +/// for the purpose of the analysis. +/// - `mutbl`: mutability of the address `A`. +/// - `ty`: the type of data found at the address `A`. +/// +/// The resulting categorization tree differs somewhat from the expressions +/// themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is +/// decomposed into two operations: a dereference to reach the array data and +/// then an index to jump forward to the relevant item. +/// +/// ## By-reference upvars +/// +/// One part of the codegen which may be non-obvious is that we translate +/// closure upvars into the dereference of a borrowed pointer; this more closely +/// resembles the runtime codegen. So, for example, if we had: +/// +/// let mut x = 3; +/// let y = 5; +/// let inc = || x += y; +/// +/// Then when we categorize `x` (*within* the closure) we would yield a +/// result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference +/// tied to `x`. The type of `x'` will be a borrowed pointer. +impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> { + fn resolve_type_vars_or_error( + &self, + id: HirId, + ty: Option>, + ) -> Result, Cx::Error> { + match ty { + Some(ty) => { + let ty = self.cx.resolve_vars_if_possible(ty); + self.cx.error_reported_in_ty(ty)?; + if ty.is_ty_var() { + debug!("resolve_type_vars_or_error: infer var from {:?}", ty); + Err(self + .cx + .report_error(self.cx.tcx().hir().span(id), "encountered type variable")) + } else { + Ok(ty) + } } - AdtKind::Enum => def.is_variant_list_non_exhaustive(), + None => { + // FIXME: We shouldn't be relying on the infcx being tainted. + self.cx.tainted_by_errors()?; + bug!( + "no type for node {} in mem_categorization", + self.cx.tcx().hir().node_to_string(id) + ); + } + } + } + + fn node_ty(&self, hir_id: HirId) -> Result, Cx::Error> { + self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id)) + } + + fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { + self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr)) + } + + fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { + self.resolve_type_vars_or_error( + expr.hir_id, + self.cx.typeck_results().expr_ty_adjusted_opt(expr), + ) + } + + /// Returns the type of value that this pattern matches against. + /// Some non-obvious cases: + /// + /// - a `ref x` binding matches against a value of type `T` and gives + /// `x` the type `&T`; we return `T`. + /// - a pattern with implicit derefs (thanks to default binding + /// modes #42640) may look like `Some(x)` but in fact have + /// implicit deref patterns attached (e.g., it is really + /// `&Some(x)`). In that case, we return the "outermost" type + /// (e.g., `&Option`). + fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> Result, Cx::Error> { + // Check for implicit `&` types wrapping the pattern; note + // that these are never attached to binding patterns, so + // actually this is somewhat "disjoint" from the code below + // that aims to account for `ref x`. + if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) { + if let Some(first_ty) = vec.first() { + debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); + return Ok(*first_ty); + } + } + + self.pat_ty_unadjusted(pat) + } + + /// Like `TypeckResults::pat_ty`, but ignores implicit `&` patterns. + fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> Result, Cx::Error> { + let base_ty = self.node_ty(pat.hir_id)?; + trace!(?base_ty); + + // This code detects whether we are looking at a `ref x`, + // and if so, figures out what the type *being borrowed* is. + match pat.kind { + PatKind::Binding(..) => { + let bm = *self + .cx + .typeck_results() + .pat_binding_modes() + .get(pat.hir_id) + .expect("missing binding mode"); + + if matches!(bm.0, hir::ByRef::Yes(_)) { + // a bind-by-ref means that the base_ty will be the type of the ident itself, + // but what we want here is the type of the underlying value being borrowed. + // So peel off one-level, turning the &T into T. + match self + .cx + .try_structurally_resolve_type(pat.span, base_ty) + .builtin_deref(false) + { + Some(ty) => Ok(ty), + None => { + debug!("By-ref binding of non-derefable type"); + Err(self + .cx + .report_error(pat.span, "by-ref binding of non-derefable type")) + } + } + } else { + Ok(base_ty) + } + } + _ => Ok(base_ty), + } + } + + fn cat_expr(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { + self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr)) + } + + /// This recursion helper avoids going through *too many* + /// adjustments, since *only* non-overloaded deref recurses. + fn cat_expr_( + &self, + expr: &hir::Expr<'_>, + adjustments: &[adjustment::Adjustment<'tcx>], + ) -> Result, Cx::Error> { + match adjustments.split_last() { + None => self.cat_expr_unadjusted(expr), + Some((adjustment, previous)) => { + self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment) + } + } + } + + fn cat_expr_adjusted( + &self, + expr: &hir::Expr<'_>, + previous: PlaceWithHirId<'tcx>, + adjustment: &adjustment::Adjustment<'tcx>, + ) -> Result, Cx::Error> { + self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) + } + + fn cat_expr_adjusted_with( + &self, + expr: &hir::Expr<'_>, + previous: F, + adjustment: &adjustment::Adjustment<'tcx>, + ) -> Result, Cx::Error> + where + F: FnOnce() -> Result, Cx::Error>, + { + let target = self.cx.resolve_vars_if_possible(adjustment.target); + match adjustment.kind { + adjustment::Adjust::Deref(overloaded) => { + // Equivalent to *expr or something similar. + let base = if let Some(deref) = overloaded { + let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl); + self.cat_rvalue(expr.hir_id, ref_ty) + } else { + previous()? + }; + self.cat_deref(expr.hir_id, base) + } + + adjustment::Adjust::NeverToAny + | adjustment::Adjust::Pointer(_) + | adjustment::Adjust::Borrow(_) + | adjustment::Adjust::DynStar => { + // Result is an rvalue. + Ok(self.cat_rvalue(expr.hir_id, target)) + } + } + } + + fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> Result, Cx::Error> { + let expr_ty = self.expr_ty(expr)?; + match expr.kind { + hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { + if self.cx.typeck_results().is_method_call(expr) { + self.cat_overloaded_place(expr, e_base) + } else { + let base = self.cat_expr(e_base)?; + self.cat_deref(expr.hir_id, base) + } + } + + hir::ExprKind::Field(base, _) => { + let base = self.cat_expr(base)?; + debug!(?base); + + let field_idx = self + .cx + .typeck_results() + .field_indices() + .get(expr.hir_id) + .cloned() + .expect("Field index not found"); + + Ok(self.cat_projection( + expr.hir_id, + base, + expr_ty, + ProjectionKind::Field(field_idx, FIRST_VARIANT), + )) + } + + hir::ExprKind::Index(base, _, _) => { + if self.cx.typeck_results().is_method_call(expr) { + // If this is an index implemented by a method call, then it + // will include an implicit deref of the result. + // The call to index() returns a `&T` value, which + // is an rvalue. That is what we will be + // dereferencing. + self.cat_overloaded_place(expr, base) + } else { + let base = self.cat_expr(base)?; + Ok(self.cat_projection(expr.hir_id, base, expr_ty, ProjectionKind::Index)) + } + } + + hir::ExprKind::Path(ref qpath) => { + let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id); + self.cat_res(expr.hir_id, expr.span, expr_ty, res) + } + + hir::ExprKind::Type(e, _) => self.cat_expr(e), + + hir::ExprKind::AddrOf(..) + | hir::ExprKind::Call(..) + | hir::ExprKind::Assign(..) + | hir::ExprKind::AssignOp(..) + | hir::ExprKind::Closure { .. } + | hir::ExprKind::Ret(..) + | hir::ExprKind::Become(..) + | hir::ExprKind::Unary(..) + | hir::ExprKind::Yield(..) + | hir::ExprKind::MethodCall(..) + | hir::ExprKind::Cast(..) + | hir::ExprKind::DropTemps(..) + | hir::ExprKind::Array(..) + | hir::ExprKind::If(..) + | hir::ExprKind::Tup(..) + | hir::ExprKind::Binary(..) + | hir::ExprKind::Block(..) + | hir::ExprKind::Let(..) + | hir::ExprKind::Loop(..) + | hir::ExprKind::Match(..) + | hir::ExprKind::Lit(..) + | hir::ExprKind::ConstBlock(..) + | hir::ExprKind::Break(..) + | hir::ExprKind::Continue(..) + | hir::ExprKind::Struct(..) + | hir::ExprKind::Repeat(..) + | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) + | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)), + } + } + + fn cat_res( + &self, + hir_id: HirId, + span: Span, + expr_ty: Ty<'tcx>, + res: Res, + ) -> Result, Cx::Error> { + match res { + Res::Def( + DefKind::Ctor(..) + | DefKind::Const + | DefKind::ConstParam + | DefKind::AssocConst + | DefKind::Fn + | DefKind::AssocFn, + _, + ) + | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)), + + Res::Def(DefKind::Static { .. }, _) => { + Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new())) + } + + Res::Local(var_id) => { + if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) { + self.cat_upvar(hir_id, var_id) + } else { + Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new())) + } + } + + def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def), + } + } + + /// Categorize an upvar. + /// + /// Note: the actual upvar access contains invisible derefs of closure + /// environment and upvar reference as appropriate. Only regionck cares + /// about these dereferences, so we let it compute them as needed. + fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> Result, Cx::Error> { + let closure_expr_def_id = self.cx.body_owner_def_id(); + + let upvar_id = ty::UpvarId { + var_path: ty::UpvarPath { hir_id: var_id }, + closure_expr_id: closure_expr_def_id, }; - def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive) - } else { - false + let var_ty = self.node_ty(var_id)?; + + Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new())) + } + + fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { + PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) + } + + fn cat_projection( + &self, + node: HirId, + base_place: PlaceWithHirId<'tcx>, + ty: Ty<'tcx>, + kind: ProjectionKind, + ) -> PlaceWithHirId<'tcx> { + let place_ty = base_place.place.ty(); + let mut projections = base_place.place.projections; + + let node_ty = self.cx.typeck_results().node_type(node); + // Opaque types can't have field projections, but we can instead convert + // the current place in-place (heh) to the hidden type, and then apply all + // follow up projections on that. + if node_ty != place_ty + && self + .cx + .try_structurally_resolve_type( + self.cx.tcx().hir().span(base_place.hir_id), + place_ty, + ) + .is_impl_trait() + { + projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); + } + projections.push(Projection { kind, ty }); + PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections) + } + + fn cat_overloaded_place( + &self, + expr: &hir::Expr<'_>, + base: &hir::Expr<'_>, + ) -> Result, Cx::Error> { + // Reconstruct the output assuming it's a reference with the + // same region and mutability as the receiver. This holds for + // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. + let place_ty = self.expr_ty(expr)?; + let base_ty = self.expr_ty_adjusted(base)?; + + let ty::Ref(region, _, mutbl) = + *self.cx.try_structurally_resolve_type(base.span, base_ty).kind() + else { + span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); + }; + let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl); + + let base = self.cat_rvalue(expr.hir_id, ref_ty); + self.cat_deref(expr.hir_id, base) + } + + fn cat_deref( + &self, + node: HirId, + base_place: PlaceWithHirId<'tcx>, + ) -> Result, Cx::Error> { + let base_curr_ty = base_place.place.ty(); + let deref_ty = match self + .cx + .try_structurally_resolve_type( + self.cx.tcx().hir().span(base_place.hir_id), + base_curr_ty, + ) + .builtin_deref(true) + { + Some(ty) => ty, + None => { + debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); + return Err(self.cx.report_error( + self.cx.tcx().hir().span(node), + "explicit deref of non-derefable type", + )); + } + }; + let mut projections = base_place.place.projections; + projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); + + Ok(PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)) + } + + /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn variant_index_for_adt( + &self, + qpath: &hir::QPath<'_>, + pat_hir_id: HirId, + span: Span, + ) -> Result { + let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id); + let ty = self.cx.typeck_results().node_type(pat_hir_id); + let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else { + return Err(self + .cx + .report_error(span, "struct or tuple struct pattern not applied to an ADT")); + }; + + match res { + Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)), + Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { + Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id)) + } + Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) + | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) + | Res::SelfCtor(..) + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => { + // Structs and Unions have only have one variant. + Ok(FIRST_VARIANT) + } + _ => bug!("expected ADT path, found={:?}", res), + } + } + + /// Returns the total number of fields in an ADT variant used within a pattern. + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn total_fields_in_adt_variant( + &self, + pat_hir_id: HirId, + variant_index: VariantIdx, + span: Span, + ) -> Result { + let ty = self.cx.typeck_results().node_type(pat_hir_id); + match self.cx.try_structurally_resolve_type(span, ty).kind() { + ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), + _ => { + self.cx + .tcx() + .dcx() + .span_bug(span, "struct or tuple struct pattern not applied to an ADT"); + } + } + } + + /// Returns the total number of fields in a tuple used within a Tuple pattern. + /// Here `pat_hir_id` is the HirId of the pattern itself. + fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result { + let ty = self.cx.typeck_results().node_type(pat_hir_id); + match self.cx.try_structurally_resolve_type(span, ty).kind() { + ty::Tuple(args) => Ok(args.len()), + _ => Err(self.cx.report_error(span, "tuple pattern not applied to a tuple")), + } + } + + /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it + /// is being matched against. + /// + /// In general, the way that this works is that we walk down the pattern, + /// constructing a `PlaceWithHirId` that represents the path that will be taken + /// to reach the value being matched. + fn cat_pattern( + &self, + mut place_with_id: PlaceWithHirId<'tcx>, + pat: &hir::Pat<'_>, + op: &mut F, + ) -> Result<(), Cx::Error> + where + F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>) -> Result<(), Cx::Error>, + { + // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly. + // `PlaceWithHirId`s are constructed differently from patterns. For example, in + // + // ``` + // match foo { + // &&Some(x, ) => { ... }, + // _ => { ... }, + // } + // ``` + // + // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the + // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the + // pattern, try to answer the question: given the address of `foo`, how is `x` reached? + // + // `&&Some(x,)` `place_foo` + // `&Some(x,)` `deref { place_foo}` + // `Some(x,)` `deref { deref { place_foo }}` + // `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place + // + // The above example has no adjustments. If the code were instead the (after adjustments, + // equivalent) version + // + // ``` + // match foo { + // Some(x, ) => { ... }, + // _ => { ... }, + // } + // ``` + // + // Then we see that to get the same result, we must start with + // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` + // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. + for _ in + 0..self.cx.typeck_results().pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) + { + debug!("applying adjustment to place_with_id={:?}", place_with_id); + place_with_id = self.cat_deref(pat.hir_id, place_with_id)?; + } + let place_with_id = place_with_id; // lose mutability + debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id); + + // Invoke the callback, but only now, after the `place_with_id` has adjusted. + // + // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that + // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We + // don't want to call `op` with these incompatible values. As written, what happens instead + // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern + // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)` + // result in the place `Downcast(*&Some(3)).0` associated to `x` and invoke `op` with + // that (where the `ref` on `x` is implied). + op(&place_with_id, pat)?; + + match pat.kind { + PatKind::Tuple(subpats, dots_pos) => { + // (p1, ..., pN) + let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?; + + for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { + let subpat_ty = self.pat_ty_adjusted(subpat)?; + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT); + let sub_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + subpat_ty, + projection_kind, + ); + self.cat_pattern(sub_place, subpat, op)?; + } + } + + PatKind::TupleStruct(ref qpath, subpats, dots_pos) => { + // S(p1, ..., pN) + let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; + let total_fields = + self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?; + + for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { + let subpat_ty = self.pat_ty_adjusted(subpat)?; + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), variant_index); + let sub_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + subpat_ty, + projection_kind, + ); + self.cat_pattern(sub_place, subpat, op)?; + } + } + + PatKind::Struct(ref qpath, field_pats, _) => { + // S { f1: p1, ..., fN: pN } + + let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; + + for fp in field_pats { + let field_ty = self.pat_ty_adjusted(fp.pat)?; + let field_index = self + .cx + .typeck_results() + .field_indices() + .get(fp.hir_id) + .cloned() + .expect("no index for a field"); + + let field_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + field_ty, + ProjectionKind::Field(field_index, variant_index), + ); + self.cat_pattern(field_place, fp.pat, op)?; + } + } + + PatKind::Or(pats) => { + for pat in pats { + self.cat_pattern(place_with_id.clone(), pat, op)?; + } + } + + PatKind::Binding(.., Some(subpat)) => { + self.cat_pattern(place_with_id, subpat, op)?; + } + + PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { + // box p1, &p1, &mut p1. we can ignore the mutability of + // PatKind::Ref since that information is already contained + // in the type. + let subplace = self.cat_deref(pat.hir_id, place_with_id)?; + self.cat_pattern(subplace, subpat, op)?; + } + PatKind::Deref(subpat) => { + let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpat); + let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; + let re_erased = self.cx.tcx().lifetimes.re_erased; + let ty = self.pat_ty_adjusted(subpat)?; + let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability); + // A deref pattern generates a temporary. + let place = self.cat_rvalue(pat.hir_id, ty); + self.cat_pattern(place, subpat, op)?; + } + + PatKind::Slice(before, ref slice, after) => { + let Some(element_ty) = place_with_id.place.ty().builtin_index() else { + debug!("explicit index of non-indexable type {:?}", place_with_id); + return Err(self + .cx + .report_error(pat.span, "explicit index of non-indexable type")); + }; + let elt_place = self.cat_projection( + pat.hir_id, + place_with_id.clone(), + element_ty, + ProjectionKind::Index, + ); + for before_pat in before { + self.cat_pattern(elt_place.clone(), before_pat, op)?; + } + if let Some(slice_pat) = *slice { + let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?; + let slice_place = self.cat_projection( + pat.hir_id, + place_with_id, + slice_pat_ty, + ProjectionKind::Subslice, + ); + self.cat_pattern(slice_place, slice_pat, op)?; + } + for after_pat in after { + self.cat_pattern(elt_place.clone(), after_pat, op)?; + } + } + + PatKind::Path(_) + | PatKind::Binding(.., None) + | PatKind::Lit(..) + | PatKind::Range(..) + | PatKind::Never + | PatKind::Wild + | PatKind::Err(_) => { + // always ok + } + } + + Ok(()) + } + + fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool { + if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() { + // Note that if a non-exhaustive SingleVariant is defined in another crate, we need + // to assume that more cases will be added to the variant in the future. This mean + // that we should handle non-exhaustive SingleVariant the same way we would handle + // a MultiVariant. + // If the variant is not local it must be defined in another crate. + let is_non_exhaustive = match def.adt_kind() { + AdtKind::Struct | AdtKind::Union => { + def.non_enum_variant().is_field_list_non_exhaustive() + } + AdtKind::Enum => def.is_variant_list_non_exhaustive(), + }; + def.variants().len() > 1 || (!def.did().is_local() && is_non_exhaustive) + } else { + false + } } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index f240a53a6797..c79b6be65606 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::HirId; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; use rustc_span::DUMMY_SP; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 881f726e1da8..6e8ef0444521 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -29,6 +29,7 @@ use rustc_middle::ty::{ self, AdtKind, CanonicalUserType, GenericParamDefKind, IsIdentity, Ty, TyCtxt, UserType, }; use rustc_middle::ty::{GenericArgKind, GenericArgsRef, UserArgs, UserSelfTy}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; @@ -1409,11 +1410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir_id: HirId, ) { self.add_required_obligations_with_code(span, def_id, args, |idx, span| { - if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, hir_id, idx) - } + ObligationCauseCode::WhereClauseInExpr(def_id, span, hir_id, idx) }) } 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 26996397659e..4edc11d7ab15 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 @@ -14,8 +14,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, error: &mut traits::FulfillmentError<'tcx>, ) -> bool { - let (ObligationCauseCode::WhereClauseInExpr(def_id, hir_id, idx) - | ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, hir_id, idx)) = + let ObligationCauseCode::WhereClauseInExpr(def_id, _, hir_id, idx) = *error.obligation.cause.code().peel_derives() else { return false; @@ -38,7 +37,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::ClauseKind::Trait(pred) => { (pred.trait_ref.args.to_vec(), Some(pred.self_ty().into())) } - ty::ClauseKind::Projection(pred) => (pred.projection_ty.args.to_vec(), None), + ty::ClauseKind::Projection(pred) => (pred.projection_term.args.to_vec(), None), ty::ClauseKind::ConstArgHasType(arg, ty) => (vec![ty.into(), arg.into()], None), ty::ClauseKind::ConstEvaluatable(e) => (vec![e.into()], None), _ => return false, @@ -512,7 +511,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, ) -> Result<&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>> { match obligation_cause_code { - traits::ObligationCauseCode::SpannedWhereClauseInExpr(_, _, _, _) => { + traits::ObligationCauseCode::WhereClauseInExpr(_, _, _, _) => { // This is the "root"; we assume that the `expr` is already pointing here. // Therefore, we return `Ok` so that this `expr` can be refined further. Ok(expr) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 4bf82355b622..aea34407a2d5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -36,6 +36,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; use rustc_span::{sym, BytePos, Span, DUMMY_SP}; @@ -2013,8 +2014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (span, code) in errors_causecode { self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| { if let Some(fn_sig) = self.body_fn_sig() - && let ObligationCauseCode::SpannedWhereClauseInExpr(_, _, binding_hir_id, ..) = - code + && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code && !fn_sig.output().is_unit() { let mut block_num = 0; @@ -2103,7 +2103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // This is because due to normalization, we often register duplicate // obligations with misc obligations that are basically impossible to - // line back up with a useful SpannedWhereClauseInExpr. + // line back up with a useful WhereClauseInExpr. for error in not_adjusted { for (span, predicate, cause) in &remap_cause { if *predicate == error.obligation.predicate diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 2ef254f644f7..ac1e26df8707 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -38,7 +38,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.type_matches_expected_vid(expected_vid, data.self_ty()) } ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { - self.type_matches_expected_vid(expected_vid, data.projection_ty.self_ty()) + self.type_matches_expected_vid(expected_vid, data.projection_term.self_ty()) } ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) | ty::PredicateKind::Subtype(..) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f1b719f24c7a..11f288391c3b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -25,6 +25,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits; use rustc_middle::lint::in_external_macro; use rustc_middle::middle::stability::EvalResult; +use rustc_middle::span_bug; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, suggest_constraining_type_params, Article, Binder, IsSuggestable, ToPredicate, Ty, diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 62711e40049a..fb8863c143f7 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -2,6 +2,7 @@ use hir::HirId; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_target::abi::{Pointer, VariantIdx}; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index e270e5895054..6892da7a5e23 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -10,9 +10,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; - mod _match; mod autoderef; mod callee; @@ -32,7 +29,6 @@ mod fallback; mod fn_ctxt; mod gather_locals; mod intrinsicck; -mod mem_categorization; mod method; mod op; mod pat; @@ -63,6 +59,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::config; use rustc_span::def_id::LocalDefId; use rustc_span::Span; diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs deleted file mode 100644 index ae71c484f7b0..000000000000 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ /dev/null @@ -1,774 +0,0 @@ -//! # Categorization -//! -//! The job of the categorization module is to analyze an expression to -//! determine what kind of memory is used in evaluating it (for example, -//! where dereferences occur and what kind of pointer is dereferenced; -//! whether the memory is mutable, etc.). -//! -//! Categorization effectively transforms all of our expressions into -//! expressions of the following forms (the actual enum has many more -//! possibilities, naturally, but they are all variants of these base -//! forms): -//! ```ignore (not-rust) -//! E = rvalue // some computed rvalue -//! | x // address of a local variable or argument -//! | *E // deref of a ptr -//! | E.comp // access to an interior component -//! ``` -//! Imagine a routine ToAddr(Expr) that evaluates an expression and returns an -//! address where the result is to be found. If Expr is a place, then this -//! is the address of the place. If `Expr` is an rvalue, this is the address of -//! some temporary spot in memory where the result is stored. -//! -//! Now, `cat_expr()` classifies the expression `Expr` and the address `A = ToAddr(Expr)` -//! as follows: -//! -//! - `cat`: what kind of expression was this? This is a subset of the -//! full expression forms which only includes those that we care about -//! for the purpose of the analysis. -//! - `mutbl`: mutability of the address `A`. -//! - `ty`: the type of data found at the address `A`. -//! -//! The resulting categorization tree differs somewhat from the expressions -//! themselves. For example, auto-derefs are explicit. Also, an index `a[b]` is -//! decomposed into two operations: a dereference to reach the array data and -//! then an index to jump forward to the relevant item. -//! -//! ## By-reference upvars -//! -//! One part of the codegen which may be non-obvious is that we translate -//! closure upvars into the dereference of a borrowed pointer; this more closely -//! resembles the runtime codegen. So, for example, if we had: -//! -//! let mut x = 3; -//! let y = 5; -//! let inc = || x += y; -//! -//! Then when we categorize `x` (*within* the closure) we would yield a -//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference -//! tied to `x`. The type of `x'` will be a borrowed pointer. - -use rustc_middle::hir::place::*; -use rustc_middle::ty::adjustment; -use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; - -use rustc_data_structures::fx::FxIndexMap; -use rustc_hir as hir; -use rustc_hir::def::{CtorOf, DefKind, Res}; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{HirId, PatKind}; -use rustc_infer::infer::InferCtxt; -use rustc_span::Span; -use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; -use rustc_trait_selection::infer::InferCtxtExt; - -pub(crate) trait HirNode { - fn hir_id(&self) -> HirId; -} - -impl HirNode for hir::Expr<'_> { - fn hir_id(&self) -> HirId { - self.hir_id - } -} - -impl HirNode for hir::Pat<'_> { - fn hir_id(&self) -> HirId { - self.hir_id - } -} - -#[derive(Clone)] -pub(crate) struct MemCategorizationContext<'a, 'tcx> { - pub(crate) typeck_results: &'a ty::TypeckResults<'tcx>, - infcx: &'a InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - body_owner: LocalDefId, - upvars: Option<&'tcx FxIndexMap>, -} - -pub(crate) type McResult = Result; - -impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { - /// Creates a `MemCategorizationContext`. - pub(crate) fn new( - infcx: &'a InferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - body_owner: LocalDefId, - typeck_results: &'a ty::TypeckResults<'tcx>, - ) -> MemCategorizationContext<'a, 'tcx> { - MemCategorizationContext { - typeck_results, - infcx, - param_env, - body_owner, - upvars: infcx.tcx.upvars_mentioned(body_owner), - } - } - - pub(crate) fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - pub(crate) fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool { - self.infcx.type_is_copy_modulo_regions(self.param_env, ty) - } - - fn resolve_vars_if_possible(&self, value: T) -> T - where - T: TypeFoldable>, - { - self.infcx.resolve_vars_if_possible(value) - } - - fn is_tainted_by_errors(&self) -> bool { - self.infcx.tainted_by_errors().is_some() - } - - fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { - match ty { - Some(ty) => { - let ty = self.resolve_vars_if_possible(ty); - if ty.references_error() || ty.is_ty_var() { - debug!("resolve_type_vars_or_error: error from {:?}", ty); - Err(()) - } else { - Ok(ty) - } - } - // FIXME - None if self.is_tainted_by_errors() => Err(()), - None => { - bug!( - "no type for node {} in mem_categorization", - self.tcx().hir().node_to_string(id) - ); - } - } - } - - pub(crate) fn node_ty(&self, hir_id: HirId) -> McResult> { - self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) - } - - fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr)) - } - - pub(crate) fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult> { - self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr)) - } - - /// Returns the type of value that this pattern matches against. - /// Some non-obvious cases: - /// - /// - a `ref x` binding matches against a value of type `T` and gives - /// `x` the type `&T`; we return `T`. - /// - a pattern with implicit derefs (thanks to default binding - /// modes #42640) may look like `Some(x)` but in fact have - /// implicit deref patterns attached (e.g., it is really - /// `&Some(x)`). In that case, we return the "outermost" type - /// (e.g., `&Option`). - pub(crate) fn pat_ty_adjusted(&self, pat: &hir::Pat<'_>) -> McResult> { - // Check for implicit `&` types wrapping the pattern; note - // that these are never attached to binding patterns, so - // actually this is somewhat "disjoint" from the code below - // that aims to account for `ref x`. - if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) { - if let Some(first_ty) = vec.first() { - debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty); - return Ok(*first_ty); - } - } - - self.pat_ty_unadjusted(pat) - } - - /// Like `pat_ty`, but ignores implicit `&` patterns. - #[instrument(level = "debug", skip(self), ret)] - fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult> { - let base_ty = self.node_ty(pat.hir_id)?; - trace!(?base_ty); - - // This code detects whether we are looking at a `ref x`, - // and if so, figures out what the type *being borrowed* is. - match pat.kind { - PatKind::Binding(..) => { - let bm = *self - .typeck_results - .pat_binding_modes() - .get(pat.hir_id) - .expect("missing binding mode"); - - if matches!(bm.0, hir::ByRef::Yes(_)) { - // a bind-by-ref means that the base_ty will be the type of the ident itself, - // but what we want here is the type of the underlying value being borrowed. - // So peel off one-level, turning the &T into T. - match base_ty.builtin_deref(false) { - Some(ty) => Ok(ty), - None => { - debug!("By-ref binding of non-derefable type"); - Err(()) - } - } - } else { - Ok(base_ty) - } - } - _ => Ok(base_ty), - } - } - - pub(crate) fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult> { - // This recursion helper avoids going through *too many* - // adjustments, since *only* non-overloaded deref recurses. - fn helper<'a, 'tcx>( - mc: &MemCategorizationContext<'a, 'tcx>, - expr: &hir::Expr<'_>, - adjustments: &[adjustment::Adjustment<'tcx>], - ) -> McResult> { - match adjustments.split_last() { - None => mc.cat_expr_unadjusted(expr), - Some((adjustment, previous)) => { - mc.cat_expr_adjusted_with(expr, || helper(mc, expr, previous), adjustment) - } - } - } - - helper(self, expr, self.typeck_results.expr_adjustments(expr)) - } - - pub(crate) fn cat_expr_adjusted( - &self, - expr: &hir::Expr<'_>, - previous: PlaceWithHirId<'tcx>, - adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> { - self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment) - } - - #[instrument(level = "debug", skip(self, previous))] - fn cat_expr_adjusted_with( - &self, - expr: &hir::Expr<'_>, - previous: F, - adjustment: &adjustment::Adjustment<'tcx>, - ) -> McResult> - where - F: FnOnce() -> McResult>, - { - let target = self.resolve_vars_if_possible(adjustment.target); - match adjustment.kind { - adjustment::Adjust::Deref(overloaded) => { - // Equivalent to *expr or something similar. - let base = if let Some(deref) = overloaded { - let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl); - self.cat_rvalue(expr.hir_id, ref_ty) - } else { - previous()? - }; - self.cat_deref(expr, base) - } - - adjustment::Adjust::NeverToAny - | adjustment::Adjust::Pointer(_) - | adjustment::Adjust::Borrow(_) - | adjustment::Adjust::DynStar => { - // Result is an rvalue. - Ok(self.cat_rvalue(expr.hir_id, target)) - } - } - } - - #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_expr_unadjusted( - &self, - expr: &hir::Expr<'_>, - ) -> McResult> { - let expr_ty = self.expr_ty(expr)?; - match expr.kind { - hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => { - if self.typeck_results.is_method_call(expr) { - self.cat_overloaded_place(expr, e_base) - } else { - let base = self.cat_expr(e_base)?; - self.cat_deref(expr, base) - } - } - - hir::ExprKind::Field(base, _) => { - let base = self.cat_expr(base)?; - debug!(?base); - - let field_idx = self - .typeck_results - .field_indices() - .get(expr.hir_id) - .cloned() - .expect("Field index not found"); - - Ok(self.cat_projection( - expr, - base, - expr_ty, - ProjectionKind::Field(field_idx, FIRST_VARIANT), - )) - } - - hir::ExprKind::Index(base, _, _) => { - if self.typeck_results.is_method_call(expr) { - // If this is an index implemented by a method call, then it - // will include an implicit deref of the result. - // The call to index() returns a `&T` value, which - // is an rvalue. That is what we will be - // dereferencing. - self.cat_overloaded_place(expr, base) - } else { - let base = self.cat_expr(base)?; - Ok(self.cat_projection(expr, base, expr_ty, ProjectionKind::Index)) - } - } - - hir::ExprKind::Path(ref qpath) => { - let res = self.typeck_results.qpath_res(qpath, expr.hir_id); - self.cat_res(expr.hir_id, expr.span, expr_ty, res) - } - - hir::ExprKind::Type(e, _) => self.cat_expr(e), - - hir::ExprKind::AddrOf(..) - | hir::ExprKind::Call(..) - | hir::ExprKind::Assign(..) - | hir::ExprKind::AssignOp(..) - | hir::ExprKind::Closure { .. } - | hir::ExprKind::Ret(..) - | hir::ExprKind::Become(..) - | hir::ExprKind::Unary(..) - | hir::ExprKind::Yield(..) - | hir::ExprKind::MethodCall(..) - | hir::ExprKind::Cast(..) - | hir::ExprKind::DropTemps(..) - | hir::ExprKind::Array(..) - | hir::ExprKind::If(..) - | hir::ExprKind::Tup(..) - | hir::ExprKind::Binary(..) - | hir::ExprKind::Block(..) - | hir::ExprKind::Let(..) - | hir::ExprKind::Loop(..) - | hir::ExprKind::Match(..) - | hir::ExprKind::Lit(..) - | hir::ExprKind::ConstBlock(..) - | hir::ExprKind::Break(..) - | hir::ExprKind::Continue(..) - | hir::ExprKind::Struct(..) - | hir::ExprKind::Repeat(..) - | hir::ExprKind::InlineAsm(..) - | hir::ExprKind::OffsetOf(..) - | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)), - } - } - - #[instrument(level = "debug", skip(self, span), ret)] - pub(crate) fn cat_res( - &self, - hir_id: HirId, - span: Span, - expr_ty: Ty<'tcx>, - res: Res, - ) -> McResult> { - match res { - Res::Def( - DefKind::Ctor(..) - | DefKind::Const - | DefKind::ConstParam - | DefKind::AssocConst - | DefKind::Fn - | DefKind::AssocFn, - _, - ) - | Res::SelfCtor(..) => Ok(self.cat_rvalue(hir_id, expr_ty)), - - Res::Def(DefKind::Static { .. }, _) => { - Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::StaticItem, Vec::new())) - } - - Res::Local(var_id) => { - if self.upvars.is_some_and(|upvars| upvars.contains_key(&var_id)) { - self.cat_upvar(hir_id, var_id) - } else { - Ok(PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Local(var_id), Vec::new())) - } - } - - def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def), - } - } - - /// Categorize an upvar. - /// - /// Note: the actual upvar access contains invisible derefs of closure - /// environment and upvar reference as appropriate. Only regionck cares - /// about these dereferences, so we let it compute them as needed. - #[instrument(level = "debug", skip(self), ret)] - fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { - let closure_expr_def_id = self.body_owner; - - let upvar_id = ty::UpvarId { - var_path: ty::UpvarPath { hir_id: var_id }, - closure_expr_id: closure_expr_def_id, - }; - let var_ty = self.node_ty(var_id)?; - - Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new())) - } - - #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { - PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) - } - - #[instrument(level = "debug", skip(self, node), ret)] - pub(crate) fn cat_projection( - &self, - node: &N, - base_place: PlaceWithHirId<'tcx>, - ty: Ty<'tcx>, - kind: ProjectionKind, - ) -> PlaceWithHirId<'tcx> { - let place_ty = base_place.place.ty(); - let mut projections = base_place.place.projections; - - let node_ty = self.typeck_results.node_type(node.hir_id()); - // Opaque types can't have field projections, but we can instead convert - // the current place in-place (heh) to the hidden type, and then apply all - // follow up projections on that. - if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) { - projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty }); - } - projections.push(Projection { kind, ty }); - PlaceWithHirId::new( - node.hir_id(), - base_place.place.base_ty, - base_place.place.base, - projections, - ) - } - - #[instrument(level = "debug", skip(self))] - fn cat_overloaded_place( - &self, - expr: &hir::Expr<'_>, - base: &hir::Expr<'_>, - ) -> McResult> { - // Reconstruct the output assuming it's a reference with the - // same region and mutability as the receiver. This holds for - // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`. - let place_ty = self.expr_ty(expr)?; - let base_ty = self.expr_ty_adjusted(base)?; - - let ty::Ref(region, _, mutbl) = *base_ty.kind() else { - span_bug!(expr.span, "cat_overloaded_place: base is not a reference"); - }; - let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl); - - let base = self.cat_rvalue(expr.hir_id, ref_ty); - self.cat_deref(expr, base) - } - - #[instrument(level = "debug", skip(self, node), ret)] - fn cat_deref( - &self, - node: &impl HirNode, - base_place: PlaceWithHirId<'tcx>, - ) -> McResult> { - let base_curr_ty = base_place.place.ty(); - let deref_ty = match base_curr_ty.builtin_deref(true) { - Some(pointee_ty) => pointee_ty, - None => { - debug!("explicit deref of non-derefable type: {:?}", base_curr_ty); - return Err(()); - } - }; - let mut projections = base_place.place.projections; - projections.push(Projection { kind: ProjectionKind::Deref, ty: deref_ty }); - - Ok(PlaceWithHirId::new( - node.hir_id(), - base_place.place.base_ty, - base_place.place.base, - projections, - )) - } - - pub(crate) fn cat_pattern( - &self, - place: PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - mut op: F, - ) -> McResult<()> - where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), - { - self.cat_pattern_(place, pat, &mut op) - } - - /// Returns the variant index for an ADT used within a Struct or TupleStruct pattern - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn variant_index_for_adt( - &self, - qpath: &hir::QPath<'_>, - pat_hir_id: HirId, - span: Span, - ) -> McResult { - let res = self.typeck_results.qpath_res(qpath, pat_hir_id); - let ty = self.typeck_results.node_type(pat_hir_id); - let ty::Adt(adt_def, _) = ty.kind() else { - self.tcx() - .dcx() - .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"); - return Err(()); - }; - - match res { - Res::Def(DefKind::Variant, variant_id) => Ok(adt_def.variant_index_with_id(variant_id)), - Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { - Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id)) - } - Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) - | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) - | Res::SelfCtor(..) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } => { - // Structs and Unions have only have one variant. - Ok(FIRST_VARIANT) - } - _ => bug!("expected ADT path, found={:?}", res), - } - } - - /// Returns the total number of fields in an ADT variant used within a pattern. - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_adt_variant( - &self, - pat_hir_id: HirId, - variant_index: VariantIdx, - span: Span, - ) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); - match ty.kind() { - ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), - _ => { - self.tcx() - .dcx() - .span_bug(span, "struct or tuple struct pattern not applied to an ADT"); - } - } - } - - /// Returns the total number of fields in a tuple used within a Tuple pattern. - /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { - let ty = self.typeck_results.node_type(pat_hir_id); - match ty.kind() { - ty::Tuple(args) => Ok(args.len()), - _ => { - self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple"); - Err(()) - } - } - } - - /// Here, `place` is the `PlaceWithHirId` being matched and pat is the pattern it - /// is being matched against. - /// - /// In general, the way that this works is that we walk down the pattern, - /// constructing a `PlaceWithHirId` that represents the path that will be taken - /// to reach the value being matched. - #[instrument(skip(self, op), ret, level = "debug")] - fn cat_pattern_( - &self, - mut place_with_id: PlaceWithHirId<'tcx>, - pat: &hir::Pat<'_>, - op: &mut F, - ) -> McResult<()> - where - F: FnMut(&PlaceWithHirId<'tcx>, &hir::Pat<'_>), - { - // If (pattern) adjustments are active for this pattern, adjust the `PlaceWithHirId` correspondingly. - // `PlaceWithHirId`s are constructed differently from patterns. For example, in - // - // ``` - // match foo { - // &&Some(x, ) => { ... }, - // _ => { ... }, - // } - // ``` - // - // the pattern `&&Some(x,)` is represented as `Ref { Ref { TupleStruct }}`. To build the - // corresponding `PlaceWithHirId` we start with the `PlaceWithHirId` for `foo`, and then, by traversing the - // pattern, try to answer the question: given the address of `foo`, how is `x` reached? - // - // `&&Some(x,)` `place_foo` - // `&Some(x,)` `deref { place_foo}` - // `Some(x,)` `deref { deref { place_foo }}` - // `(x,)` `field0 { deref { deref { place_foo }}}` <- resulting place - // - // The above example has no adjustments. If the code were instead the (after adjustments, - // equivalent) version - // - // ``` - // match foo { - // Some(x, ) => { ... }, - // _ => { ... }, - // } - // ``` - // - // Then we see that to get the same result, we must start with - // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)` - // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`. - for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) { - debug!("applying adjustment to place_with_id={:?}", place_with_id); - place_with_id = self.cat_deref(pat, place_with_id)?; - } - let place_with_id = place_with_id; // lose mutability - debug!("applied adjustment derefs to get place_with_id={:?}", place_with_id); - - // Invoke the callback, but only now, after the `place_with_id` has adjusted. - // - // To see that this makes sense, consider `match &Some(3) { Some(x) => { ... }}`. In that - // case, the initial `place_with_id` will be that for `&Some(3)` and the pattern is `Some(x)`. We - // don't want to call `op` with these incompatible values. As written, what happens instead - // is that `op` is called with the adjusted place (that for `*&Some(3)`) and the pattern - // `Some(x)` (which matches). Recursing once more, `*&Some(3)` and the pattern `Some(x)` - // result in the place `Downcast(*&Some(3)).0` associated to `x` and invoke `op` with - // that (where the `ref` on `x` is implied). - op(&place_with_id, pat); - - match pat.kind { - PatKind::Tuple(subpats, dots_pos) => { - // (p1, ..., pN) - let total_fields = self.total_fields_in_tuple(pat.hir_id, pat.span)?; - - for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { - let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = - ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT); - let sub_place = - self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); - self.cat_pattern_(sub_place, subpat, op)?; - } - } - - PatKind::TupleStruct(ref qpath, subpats, dots_pos) => { - // S(p1, ..., pN) - let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; - let total_fields = - self.total_fields_in_adt_variant(pat.hir_id, variant_index, pat.span)?; - - for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { - let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = - ProjectionKind::Field(FieldIdx::from_usize(i), variant_index); - let sub_place = - self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); - self.cat_pattern_(sub_place, subpat, op)?; - } - } - - PatKind::Struct(ref qpath, field_pats, _) => { - // S { f1: p1, ..., fN: pN } - - let variant_index = self.variant_index_for_adt(qpath, pat.hir_id, pat.span)?; - - for fp in field_pats { - let field_ty = self.pat_ty_adjusted(fp.pat)?; - let field_index = self - .typeck_results - .field_indices() - .get(fp.hir_id) - .cloned() - .expect("no index for a field"); - - let field_place = self.cat_projection( - pat, - place_with_id.clone(), - field_ty, - ProjectionKind::Field(field_index, variant_index), - ); - self.cat_pattern_(field_place, fp.pat, op)?; - } - } - - PatKind::Or(pats) => { - for pat in pats { - self.cat_pattern_(place_with_id.clone(), pat, op)?; - } - } - - PatKind::Binding(.., Some(subpat)) => { - self.cat_pattern_(place_with_id, subpat, op)?; - } - - PatKind::Box(subpat) | PatKind::Ref(subpat, _) => { - // box p1, &p1, &mut p1. we can ignore the mutability of - // PatKind::Ref since that information is already contained - // in the type. - let subplace = self.cat_deref(pat, place_with_id)?; - self.cat_pattern_(subplace, subpat, op)?; - } - PatKind::Deref(subpat) => { - let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat); - let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not }; - let re_erased = self.tcx().lifetimes.re_erased; - let ty = self.pat_ty_adjusted(subpat)?; - let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability); - // A deref pattern generates a temporary. - let place = self.cat_rvalue(pat.hir_id, ty); - self.cat_pattern_(place, subpat, op)?; - } - - PatKind::Slice(before, ref slice, after) => { - let Some(element_ty) = place_with_id.place.ty().builtin_index() else { - debug!("explicit index of non-indexable type {:?}", place_with_id); - return Err(()); - }; - let elt_place = self.cat_projection( - pat, - place_with_id.clone(), - element_ty, - ProjectionKind::Index, - ); - for before_pat in before { - self.cat_pattern_(elt_place.clone(), before_pat, op)?; - } - if let Some(slice_pat) = *slice { - let slice_pat_ty = self.pat_ty_adjusted(slice_pat)?; - let slice_place = self.cat_projection( - pat, - place_with_id, - slice_pat_ty, - ProjectionKind::Subslice, - ); - self.cat_pattern_(slice_place, slice_pat, op)?; - } - for after_pat in after { - self.cat_pattern_(elt_place.clone(), after_pat, op)?; - } - } - - PatKind::Path(_) - | PatKind::Binding(.., None) - | PatKind::Lit(..) - | PatKind::Range(..) - | PatKind::Never - | PatKind::Wild - | PatKind::Err(_) => { - // always ok - } - } - - Ok(()) - } -} diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 56c296fc1c00..742540585348 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt, UserArgs, UserType, }; +use rustc_middle::{bug, span_bug}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits; @@ -564,16 +565,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { // `self.add_required_obligations(self.span, def_id, &all_args);` for obligation in traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr(def_id, self.call_expr.hir_id, idx) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - def_id, - span, - self.call_expr.hir_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + def_id, + span, + self.call_expr.hir_id, + idx, + ); traits::ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index ec613f3d14e7..f82182fa0583 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 305aaf3b8ddd..a305461344d4 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -7,6 +7,7 @@ use hir::HirId; use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_middle::span_bug; use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 434bd9574986..81e179c90900 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -24,6 +24,7 @@ use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::def_id::DefId; use rustc_span::def_id::LocalDefId; @@ -1401,20 +1402,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // Convert the bounds into obligations. ocx.register_obligations(traits::predicates_for_generics( |idx, span| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClauseInExpr( - impl_def_id, - self.scope_expr_id, - idx, - ) - } else { - ObligationCauseCode::SpannedWhereClauseInExpr( - impl_def_id, - span, - self.scope_expr_id, - idx, - ) - }; + let code = ObligationCauseCode::WhereClauseInExpr( + impl_def_id, + span, + self.scope_expr_id, + idx, + ); ObligationCause::new(self.span, self.body_id, code) }, self.param_env, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index d1891a032e10..d50e99433842 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -23,6 +23,7 @@ use rustc_hir::PatKind::Binding; use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{self, RegionVariableOrigin}; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{ @@ -46,7 +47,6 @@ use std::borrow::Cow; use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; use rustc_hir::intravisit::Visitor; -use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool { @@ -172,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => { + ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::Opaque, _) => { for unsatisfied in unsatisfied_predicates.iter() { if is_iterator_predicate(unsatisfied.0, self.tcx) { return true; @@ -787,26 +787,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => { let pred = bound_predicate.rebind(pred); // `::Item = String`. - let projection_ty = pred.skip_binder().projection_ty; - - let args_with_infer_self = tcx.mk_args_from_iter( - iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into()) - .chain(projection_ty.args.iter().skip(1)), - ); - - let quiet_projection_ty = - ty::AliasTy::new(tcx, projection_ty.def_id, args_with_infer_self); + let projection_term = pred.skip_binder().projection_term; + let quiet_projection_term = + projection_term.with_self_ty(tcx, Ty::new_var(tcx, ty::TyVid::ZERO)); let term = pred.skip_binder().term; - let obligation = format!("{projection_ty} = {term}"); + let obligation = format!("{projection_term} = {term}"); let quiet = with_forced_trimmed_paths!(format!( "{} = {}", - quiet_projection_ty, term + quiet_projection_term, term )); - bound_span_label(projection_ty.self_ty(), &obligation, &quiet); - Some((obligation, projection_ty.self_ty())) + bound_span_label(projection_term.self_ty(), &obligation, &quiet); + Some((obligation, projection_term.self_ty())) } ty::PredicateKind::Clause(ty::ClauseKind::Trait(poly_trait_ref)) => { let p = poly_trait_ref.trait_ref; @@ -832,9 +826,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (data.impl_or_alias_def_id, data.span) } Some( - ObligationCauseCode::SpannedWhereClauseInExpr(def_id, span, _, _) - | ObligationCauseCode::SpannedWhereClause(def_id, span), - ) => (*def_id, *span), + ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _) + | ObligationCauseCode::WhereClause(def_id, span), + ) if !span.is_dummy() => (*def_id, *span), _ => continue, }; diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index dca1cda06940..e371775be0aa 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index b1a0aa689cff..b9b220d5af8e 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -11,6 +11,7 @@ use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind use rustc_infer::infer; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; @@ -73,21 +74,23 @@ struct TopInfo<'tcx> { /// found type `std::result::Result<_, _>` /// ``` span: Option, + /// The [`HirId`] of the top-level pattern. + hir_id: HirId, } #[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: ByRef, - max_ref_mutbl: Mutability, - top_info: TopInfo<'tcx>, - decl_origin: Option>, + max_ref_mutbl: MutblCap, + top_info: &'a TopInfo<'tcx>, + decl_origin: Option>, /// The depth of current pattern current_depth: u32, } impl<'tcx> FnCtxt<'_, 'tcx> { - fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { + fn pattern_cause(&self, ti: &TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> { let code = ObligationCauseCode::Pattern { span: ti.span, root_ty: ti.expected, @@ -101,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Option> { let mut diag = self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?; @@ -118,7 +121,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { cause_span: Span, expected: Ty<'tcx>, actual: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) { if let Some(err) = self.demand_eqtype_pat_diag(cause_span, expected, actual, ti) { err.emit(); @@ -127,22 +130,61 @@ impl<'tcx> FnCtxt<'_, 'tcx> { } /// Mode for adjusting the expected type and binding mode. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] enum AdjustMode { /// Peel off all immediate reference types. Peel, /// Reset binding mode to the initial mode. /// Used for destructuring assignment, where we don't want any match ergonomics. Reset, - /// Produced by ref patterns. - /// Reset the binding mode to the initial mode, - /// and if the old biding mode was by-reference - /// with mutability matching the pattern, - /// mark the pattern as having consumed this reference. - ResetAndConsumeRef(Mutability), /// Pass on the input binding mode and expected type. Pass, } +/// `ref mut` patterns (explicit or match-ergonomics) +/// are not allowed behind an `&` reference. +/// +/// This includes explicit `ref mut` behind `&` patterns +/// that match against `&mut` references, +/// where the code would have compiled +/// had the pattern been written as `&mut`. +/// However, the borrow checker will not catch +/// this last case, so we need to throw an error ourselves. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +enum MutblCap { + /// Mutability restricted to immutable. + Not, + + /// Mutability restricted to immutable, but only because of the pattern + /// (not the scrutinee type). + /// + /// The contained span, if present, points to an `&` pattern + /// that is the reason for the restriction, + /// and which will be reported in a diagnostic. + WeaklyNot(Option), + + /// No restriction on mutability + Mut, +} + +impl MutblCap { + #[must_use] + fn cap_to_weakly_not(self, span: Option) -> Self { + match self { + MutblCap::Not => MutblCap::Not, + _ => MutblCap::WeaklyNot(span), + } + } + + #[must_use] + fn as_mutbl(self) -> Mutability { + match self { + MutblCap::Not | MutblCap::WeaklyNot(_) => Mutability::Not, + MutblCap::Mut => Mutability::Mut, + } + } +} + impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Type check the given top level pattern against the `expected` type. /// @@ -160,11 +202,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { origin_expr: Option<&'tcx hir::Expr<'tcx>>, decl_origin: Option>, ) { - let info = TopInfo { expected, origin_expr, span }; + let info = TopInfo { expected, origin_expr, span, hir_id: pat.hir_id }; let pat_info = PatInfo { binding_mode: ByRef::No, - max_ref_mutbl: Mutability::Mut, - top_info: info, + max_ref_mutbl: MutblCap::Mut, + top_info: &info, decl_origin, current_depth: 0, }; @@ -172,14 +214,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Type check the given `pat` against the `expected` type - /// with the provided `def_bm` (default binding mode). + /// with the provided `binding_mode` (default binding mode). /// /// Outside of this module, `check_pat_top` should always be used. /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { - let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } = - pat_info; + let PatInfo { binding_mode, max_ref_mutbl, top_info: ti, current_depth, .. } = pat_info; let path_res = match &pat.kind { PatKind::Path(qpath) => Some( @@ -188,10 +229,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); - let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) = - self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl); + let (expected, binding_mode, max_ref_mutbl) = + self.calc_default_binding_mode(pat, expected, binding_mode, adjust_mode, max_ref_mutbl); let pat_info = PatInfo { - binding_mode: def_bm, + binding_mode, max_ref_mutbl, top_info: ti, decl_origin: pat_info.decl_origin, @@ -204,8 +245,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::Never => expected, PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, ti), PatKind::Range(lhs, rhs, _) => self.check_pat_range(pat.span, lhs, rhs, expected, ti), - PatKind::Binding(ba, var_id, _, sub) => { - self.check_pat_ident(pat, ba, var_id, sub, expected, pat_info) + PatKind::Binding(ba, var_id, ident, sub) => { + self.check_pat_ident(pat, ba, var_id, ident, sub, expected, pat_info) } PatKind::TupleStruct(ref qpath, subpats, ddpos) => { self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, pat_info) @@ -227,14 +268,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info), PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info), - PatKind::Ref(inner, mutbl) => self.check_pat_ref( - pat, - inner, - mutbl, - expected, - pat_info, - ref_pattern_already_consumed, - ), + PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info), PatKind::Slice(before, slice, after) => { self.check_pat_slice(pat.span, before, slice, after, expected, pat_info) } @@ -287,52 +321,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Compute the new expected type and default binding mode from the old ones /// as well as the pattern form we are currently checking. - /// - /// Last entry is only relevant for ref patterns (`&` and `&mut`); - /// if `true`, then the ref pattern consumed a match ergonomics inserted reference - /// and so does no need to match against a reference in the scrutinee type. fn calc_default_binding_mode( &self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, def_br: ByRef, adjust_mode: AdjustMode, - max_ref_mutbl: Mutability, - ) -> (Ty<'tcx>, ByRef, Mutability, bool) { - if let ByRef::Yes(mutbl) = def_br { - debug_assert!(mutbl <= max_ref_mutbl); + max_ref_mutbl: MutblCap, + ) -> (Ty<'tcx>, ByRef, MutblCap) { + if let ByRef::Yes(Mutability::Mut) = def_br { + debug_assert!(max_ref_mutbl == MutblCap::Mut); } match adjust_mode { - AdjustMode::Pass => (expected, def_br, max_ref_mutbl, false), - AdjustMode::Reset => (expected, ByRef::No, Mutability::Mut, false), - AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { - let mutbls_match = def_br == ByRef::Yes(ref_pat_mutbl); - if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - if mutbls_match { - debug!("consuming inherited reference"); - (expected, ByRef::No, cmp::min(max_ref_mutbl, ref_pat_mutbl), true) - } else { - let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { - self.peel_off_references( - pat, - expected, - def_br, - Mutability::Not, - max_ref_mutbl, - ) - } else { - (expected, def_br.cap_ref_mutability(Mutability::Not), Mutability::Not) - }; - (new_ty, new_bm, max_ref_mutbl, false) - } - } else { - (expected, ByRef::No, max_ref_mutbl, mutbls_match) - } - } + AdjustMode::Pass => (expected, def_br, max_ref_mutbl), + AdjustMode::Reset => (expected, ByRef::No, MutblCap::Mut), AdjustMode::Peel => { - let peeled = - self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl); - (peeled.0, peeled.1, peeled.2, false) + self.peel_off_references(pat, expected, def_br, Mutability::Mut, max_ref_mutbl) } } } @@ -378,17 +382,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // a reference type wherefore peeling doesn't give up any expressiveness. _ => AdjustMode::Peel, }, - // When encountering a `& mut? pat` pattern, reset to "by value". - // This is so that `x` and `y` here are by value, as they appear to be: - // - // ``` - // match &(&22, &44) { - // (&x, &y) => ... - // } - // ``` - // - // See issue #46688. - PatKind::Ref(_, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl), + // Ref patterns are complicated, we handle them in `check_pat_ref`. + PatKind::Ref(..) => AdjustMode::Pass, // A `_` pattern works with any expected type, so there's no need to do anything. PatKind::Wild // A malformed pattern doesn't have an expected type, so let's just accept any type. @@ -414,8 +409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, mut def_br: ByRef, max_peelable_mutability: Mutability, - mut max_ref_mutability: Mutability, - ) -> (Ty<'tcx>, ByRef, Mutability) { + mut max_ref_mutability: MutblCap, + ) -> (Ty<'tcx>, ByRef, MutblCap) { let mut expected = self.try_structurally_resolve_type(pat.span, expected); // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches @@ -449,9 +444,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - def_br = def_br.cap_ref_mutability(max_ref_mutability); + def_br = def_br.cap_ref_mutability(max_ref_mutability.as_mutbl()); if def_br == ByRef::Yes(Mutability::Not) { - max_ref_mutability = Mutability::Not; + max_ref_mutability = MutblCap::Not; } } @@ -471,7 +466,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, lt: &hir::Expr<'tcx>, expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { // We've already computed the type above (when checking for a non-ref pat), // so avoid computing it again. @@ -541,7 +536,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lhs: Option<&'tcx hir::Expr<'tcx>>, rhs: Option<&'tcx hir::Expr<'tcx>>, expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { let calc_side = |opt_expr: Option<&'tcx hir::Expr<'tcx>>| match opt_expr { None => None, @@ -668,8 +663,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn check_pat_ident( &self, pat: &'tcx Pat<'tcx>, - ba: BindingMode, + user_bind_annot: BindingMode, var_id: HirId, + ident: Ident, sub: Option<&'tcx Pat<'tcx>>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, @@ -677,24 +673,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let PatInfo { binding_mode: def_br, top_info: ti, .. } = pat_info; // Determine the binding mode... - let bm = match ba { + let bm = match user_bind_annot { + // `mut` resets binding mode on edition <= 2021 BindingMode(ByRef::No, Mutability::Mut) if !(pat.span.at_least_rust_2024() && self.tcx.features().mut_preserve_binding_mode_2024) && matches!(def_br, ByRef::Yes(_)) => { - // `mut x` resets the binding mode in edition <= 2021. - self.tcx.emit_node_span_lint( - rustc_lint::builtin::DEREFERENCING_MUT_BINDING, - pat.hir_id, - pat.span, - errors::DereferencingMutBinding { span: pat.span }, - ); + self.typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .insert(pat_info.top_info.hir_id); BindingMode(ByRef::No, Mutability::Mut) } BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl), - BindingMode(ByRef::Yes(_), _) => ba, + BindingMode(ByRef::Yes(_), _) => user_bind_annot, }; + + if bm.0 == ByRef::Yes(Mutability::Mut) + && let MutblCap::WeaklyNot(and_pat_span) = pat_info.max_ref_mutbl + { + let mut err = struct_span_code_err!( + self.tcx.dcx(), + ident.span, + E0596, + "cannot borrow as mutable inside an `&` pattern" + ); + + if let Some(span) = and_pat_span { + err.span_suggestion( + span, + "replace this `&` with `&mut`", + "&mut ", + Applicability::MachineApplicable, + ); + } + err.emit(); + } + // ...and store it in a side table: self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); @@ -720,7 +736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be. if var_id != pat.hir_id { - self.check_binding_alt_eq_ty(ba, pat.span, var_id, local_ty, ti); + self.check_binding_alt_eq_ty(user_bind_annot, pat.span, var_id, local_ty, ti); } if let Some(p) = sub { @@ -739,7 +755,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, var_id: HirId, ty: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) { let var_ty = self.local_ty(span, var_id); if let Some(mut err) = self.demand_eqtype_pat_diag(span, var_ty, ty, ti) { @@ -981,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { qpath: &hir::QPath<'_>, path_resolution: (Res, Option>, &'tcx [hir::PathSegment<'tcx>]), expected: Ty<'tcx>, - ti: TopInfo<'tcx>, + ti: &TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; @@ -2105,72 +2121,145 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &'tcx Pat<'tcx>, inner: &'tcx Pat<'tcx>, - mutbl: Mutability, - expected: Ty<'tcx>, - pat_info: PatInfo<'tcx, '_>, - consumed_inherited_ref: bool, + pat_mutbl: Mutability, + mut expected: Ty<'tcx>, + mut pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - if consumed_inherited_ref - && pat.span.at_least_rust_2024() - && self.tcx.features().ref_pat_eat_one_layer_2024 - { - self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); - self.check_pat(inner, expected, pat_info); - expected + // FIXME: repace with `bool` once final decision on 1 vs 2 layers is made + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + enum MatchErgonomicsMode { + EatOneLayer, + EatTwoLayers, + Legacy, + } + + let match_ergonomics_mode = + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + MatchErgonomicsMode::EatOneLayer + } else if self.tcx.features().ref_pat_everywhere { + MatchErgonomicsMode::EatTwoLayers + } else { + MatchErgonomicsMode::Legacy + }; + + let mut inherited_ref_mutbl_match = false; + if match_ergonomics_mode != MatchErgonomicsMode::Legacy { + if pat_mutbl == Mutability::Not { + // Prevent the inner pattern from binding with `ref mut`. + pat_info.max_ref_mutbl = pat_info.max_ref_mutbl.cap_to_weakly_not( + inner.span.find_ancestor_inside(pat.span).map(|end| pat.span.until(end)), + ); + } + + if let ByRef::Yes(inh_mut) = pat_info.binding_mode { + inherited_ref_mutbl_match = pat_mutbl <= inh_mut; + } + + if inherited_ref_mutbl_match { + pat_info.binding_mode = ByRef::No; + if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer { + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + return expected; + } + } else if match_ergonomics_mode == MatchErgonomicsMode::EatOneLayer + && pat_mutbl == Mutability::Mut + { + // `&mut` patterns pell off `&` references + let (new_expected, new_bm, max_ref_mutbl) = self.peel_off_references( + pat, + expected, + pat_info.binding_mode, + Mutability::Not, + pat_info.max_ref_mutbl, + ); + expected = new_expected; + pat_info.binding_mode = new_bm; + pat_info.max_ref_mutbl = max_ref_mutbl; + } } else { - let tcx = self.tcx; - let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { - Ok(()) => { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. + // Reset binding mode on old editions - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), - _ => { - if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { - // We already matched against a match-ergonmics inserted reference, - // so we don't need to match against a reference from the original type. - // Save this infor for use in lowering later - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - (expected, expected) - } else { - let inner_ty = self.next_ty_var(inner.span); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag( - pat.span, - expected, - ref_ty, - pat_info.top_info, - ); + if pat_info.binding_mode != ByRef::No { + pat_info.binding_mode = ByRef::No; - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); - } - (ref_ty, inner_ty) - } + self.typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .insert(pat_info.top_info.hir_id); + } + + pat_info.max_ref_mutbl = MutblCap::Mut; + } + + let tcx = self.tcx; + expected = self.try_structurally_resolve_type(pat.span, expected); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. + + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == pat_mutbl => { + if r_mutbl == Mutability::Not + && match_ergonomics_mode != MatchErgonomicsMode::Legacy + { + pat_info.max_ref_mutbl = MutblCap::Not; } + + (expected, r_ty) + } + + // `&` pattern eats `&mut` reference + ty::Ref(_, r_ty, Mutability::Mut) + if pat_mutbl == Mutability::Not + && match_ergonomics_mode != MatchErgonomicsMode::Legacy => + { + (expected, r_ty) + } + + _ if inherited_ref_mutbl_match + && match_ergonomics_mode == MatchErgonomicsMode::EatTwoLayers => + { + // We already matched against a match-ergonmics inserted reference, + // so we don't need to match against a reference from the original type. + // Save this info for use in lowering later + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + (expected, expected) + } + + _ => { + let inner_ty = self.next_ty_var(inner.span); + let ref_ty = self.new_ref_ty(pat.span, pat_mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag( + pat.span, + expected, + ref_ty, + pat_info.top_info, + ); + + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); + } + (ref_ty, inner_ty) } } - Err(guar) => { - let err = Ty::new_error(tcx, guar); - (err, err) - } - }; - self.check_pat(inner, inner_ty, pat_info); - ref_ty - } + } + Err(guar) => { + let err = Ty::new_error(tcx, guar); + (err, err) + } + }; + self.check_pat(inner, inner_ty, pat_info); + ref_ty } /// Create a reference type with a fresh region variable. diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index 374279722ba2..515e1b5ed0e0 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -5,6 +5,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::autoderef::Autoderef; use rustc_infer::infer::InferOk; +use rustc_middle::span_bug; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{self, Ty}; diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs index 34ce0ab1f8b9..805f36d9b97a 100644 --- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs +++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs @@ -2,6 +2,7 @@ use super::FnCtxt; use hir::def_id::DefId; use hir::Node; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::middle::region::{RvalueCandidateType, Scope, ScopeTree}; use rustc_middle::ty::RvalueScopes; diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 31ce271a5fc4..19d6481cc1b8 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -5,6 +5,7 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::{HirId, HirIdMap}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; +use rustc_middle::span_bug; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 2bf4f51a8038..d313c0eafe10 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -47,6 +47,7 @@ use rustc_middle::ty::{ self, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, UpvarArgs, UpvarCapture, }; +use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::sym; use rustc_span::{BytePos, Pos, Span, Symbol}; @@ -252,12 +253,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - euv::ExprUseVisitor::new( + let _ = euv::ExprUseVisitor::new( + &FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id), &mut delegate, - &self.infcx, - closure_def_id, - self.param_env, - &self.typeck_results.borrow(), ) .consume_body(body); diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 0a40ffb0d5aa..f798deea207a 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -9,6 +9,7 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; +use rustc_middle::span_bug; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; @@ -346,6 +347,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { _ => {} }; + self.visit_rust_2024_migration_desugared_pats(p.hir_id); self.visit_skipped_ref_pats(p.hir_id); self.visit_pat_adjustments(p.span, p.hir_id); @@ -655,6 +657,22 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } + #[instrument(skip(self), level = "debug")] + fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) { + if self + .fcx + .typeck_results + .borrow_mut() + .rust_2024_migration_desugared_pats_mut() + .remove(hir_id) + { + debug!( + "node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint" + ); + self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id); + } + } + #[instrument(skip(self, span), level = "debug")] fn visit_pat_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().pat_adjustments_mut().remove(hir_id); diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index c7f07ebed973..f0b336ca0461 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,6 +1,7 @@ use crate::fluent_generated as fluent; use crate::infer::error_reporting::nice_region_error::find_anon_type; use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, SubdiagMessageOp, Subdiagnostic}; +use rustc_middle::bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 0f21d3966c40..eaef715fe5dc 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -27,6 +27,7 @@ use super::*; +use rustc_middle::bug; use rustc_middle::ty::relate::{Relate, TypeRelation}; use rustc_middle::ty::{Const, ImplSubject}; @@ -430,6 +431,20 @@ impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { } impl<'tcx> ToTrace<'tcx> for ty::AliasTy<'tcx> { + fn to_trace( + cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self, + ) -> TypeTrace<'tcx> { + TypeTrace { + cause: cause.clone(), + values: Aliases(ExpectedFound::new(a_is_expected, a.into(), b.into())), + } + } +} + +impl<'tcx> ToTrace<'tcx> for ty::AliasTerm<'tcx> { fn to_trace( cause: &ObligationCause<'tcx>, a_is_expected: bool, diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 4d712e9ffd37..27b06c4b73e9 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -9,6 +9,7 @@ use crate::infer::canonical::{ Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, OriginalQueryValues, }; use crate::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; diff --git a/compiler/rustc_infer/src/infer/canonical/instantiate.rs b/compiler/rustc_infer/src/infer/canonical/instantiate.rs index f95cc13623cd..de0e15ef3def 100644 --- a/compiler/rustc_infer/src/infer/canonical/instantiate.rs +++ b/compiler/rustc_infer/src/infer/canonical/instantiate.rs @@ -8,6 +8,7 @@ use crate::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index b948067e750e..1732913e1915 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -25,6 +25,7 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, BoundVar, Ty, TyCtxt}; use rustc_middle::ty::{GenericArg, GenericArgKind}; +use rustc_middle::{bug, span_bug}; use std::fmt::Debug; use std::iter; diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 46310941113d..d0687dfc6fd2 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -69,6 +69,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError, PrintTraitRefExt as _}; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; @@ -410,7 +411,7 @@ impl<'tcx> InferCtxt<'tcx> { .kind() .map_bound(|kind| match kind { ty::ClauseKind::Projection(projection_predicate) - if projection_predicate.projection_ty.def_id == item_def_id => + if projection_predicate.projection_term.def_id == item_def_id => { projection_predicate.term.ty() } @@ -883,9 +884,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help("...or use `match` instead of `let...else`"); } _ => { - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = cause.code().peel_derives() + && !span.is_dummy() && let TypeError::RegionsPlaceholderMismatch = terr { err.span_note(*span, "the lifetime requirement is introduced here"); 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 415f0eee8c51..b4decbf14a23 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 @@ -11,6 +11,7 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; +use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index b6c38739e9af..45dce0a0e330 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -13,6 +13,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; +use rustc_middle::bug; use rustc_middle::ty::TypeVisitor; impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { @@ -38,11 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let ObligationCauseCode::MatchImpl(parent, impl_def_id) = code else { return None; }; - let (ObligationCauseCode::SpannedWhereClause(_, binding_span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, binding_span, ..)) = *parent.code() + let (ObligationCauseCode::WhereClause(_, binding_span) + | ObligationCauseCode::WhereClauseInExpr(_, binding_span, ..)) = *parent.code() else { return None; }; + if binding_span.is_dummy() { + return None; + } // FIXME: we should point at the lifetime let multi_span: MultiSpan = vec![binding_span].into(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index dbd165c093aa..8859772848fa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -10,7 +10,8 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::intern::Interned; use rustc_errors::{Diag, IntoDiagArg}; use rustc_hir::def::Namespace; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; +use rustc_middle::bug; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::print::{FmtPrinter, Print, PrintTraitRefExt as _, RegionHighlightMode}; use rustc_middle::ty::GenericArgsRef; @@ -240,8 +241,9 @@ impl<'tcx> NiceRegionError<'_, 'tcx> { let span = cause.span(); let (leading_ellipsis, satisfy_span, where_span, dup_span, def_id) = - if let ObligationCauseCode::WhereClause(def_id) - | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *cause.code() + if let ObligationCauseCode::WhereClause(def_id, span) + | ObligationCauseCode::WhereClauseInExpr(def_id, span, ..) = *cause.code() + && def_id != CRATE_DEF_ID.to_def_id() { ( true, 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 e5950a7c9350..8a1e3a7ac71b 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 @@ -214,7 +214,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _ => cause.code(), } && let ( - &ObligationCauseCode::WhereClause(item_def_id) + &ObligationCauseCode::WhereClause(item_def_id, _) | &ObligationCauseCode::WhereClauseInExpr(item_def_id, ..), None, ) = (code, override_error_code) diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index ecbe65fe9261..00dd20a2cc27 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -357,21 +357,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::Subtype(box ref trace) if matches!( &trace.cause.code().peel_derives(), - ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) ) => { // Hack to get around the borrow checker because trace.cause has an `Rc`. - if let ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) = + if let ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) = &trace.cause.code().peel_derives() + && !span.is_dummy() { let span = *span; self.report_concrete_failure(placeholder_origin, sub, sup) .with_span_note(span, "the lifetime requirement is introduced here") } else { unreachable!( - "control flow ensures we have a `BindingObligation` or `SpannedWhereClauseInExpr` here..." + "control flow ensures we have a `BindingObligation` or `WhereClauseInExpr` here..." ) } } diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index ef9c407acef5..b2d89523ea84 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -32,6 +32,7 @@ //! inferencer knows "so far". use super::InferCtxt; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::bug; use rustc_middle::infer::unify_key::ToType; use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; 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 5ae7f8bf5048..72944c9c7de6 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReBound, RePlaceholder, ReVar}; use rustc_middle::ty::{ReEarlyParam, ReErased, ReError, ReLateParam, ReStatic}; use rustc_middle::ty::{Region, RegionVid}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use std::fmt; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index ce82296a8aad..723f4c81ca52 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -44,6 +44,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid}; use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::Symbol; use rustc_span::Span; use snapshot::undo_log::InferCtxtUndoLogs; @@ -403,7 +404,7 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> { pub enum ValuePairs<'tcx> { Regions(ExpectedFound>), Terms(ExpectedFound>), - Aliases(ExpectedFound>), + Aliases(ExpectedFound>), TraitRefs(ExpectedFound>), PolySigs(ExpectedFound>), ExistentialTraitRef(ExpectedFound>), diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 703bd5ae90b7..8eb3185673b4 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -588,7 +588,7 @@ impl<'tcx> InferCtxt<'tcx> { && !tcx.is_impl_trait_in_trait(projection_ty.def_id) && !self.next_trait_solver() => { - self.infer_projection( + self.projection_ty_to_infer( param_env, projection_ty, cause.clone(), diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs index a7ddf4754362..e07d181e4e0a 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/table.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs @@ -1,4 +1,5 @@ use rustc_data_structures::undo_log::UndoLogs; +use rustc_middle::bug; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}; use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog}; diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index f8dbfdde30c5..c44a5082f68b 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -3,6 +3,7 @@ use crate::infer::GenericKind; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; +use rustc_middle::bug; use rustc_middle::ty::{self, Region}; use super::explicit_outlives_bounds; diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 94f8a2664f9c..32c790523b64 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -67,6 +67,7 @@ use crate::infer::snapshot::undo_log::UndoLog; use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound}; use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::undo_log::UndoLogs; +use rustc_middle::bug; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ @@ -103,8 +104,12 @@ impl<'tcx> InferCtxt<'tcx> { cause.span, sup_type, match cause.code().peel_derives() { - ObligationCauseCode::SpannedWhereClause(_, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(_, span, ..) => Some(*span), + ObligationCauseCode::WhereClause(_, span) + | ObligationCauseCode::WhereClauseInExpr(_, span, ..) + if !span.is_dummy() => + { + Some(*span) + } _ => None, }, ) diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 041838ffc169..167863479806 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -12,7 +12,7 @@ impl<'tcx> InferCtxt<'tcx> { /// of the given projection. This allows us to proceed with projections /// while they cannot be resolved yet due to missing information or /// simply due to the lack of access to the trait resolution machinery. - pub fn infer_projection( + pub fn projection_ty_to_infer( &self, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, @@ -24,7 +24,7 @@ impl<'tcx> InferCtxt<'tcx> { let def_id = projection_ty.def_id; let ty_var = self.next_ty_var(self.tcx.def_span(def_id)); let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection( - ty::ProjectionPredicate { projection_ty, term: ty_var.into() }, + ty::ProjectionPredicate { projection_term: projection_ty.into(), term: ty_var.into() }, ))); let obligation = Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection); 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 6e8efa3e7c18..255ca52d3e98 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -3,6 +3,7 @@ use crate::infer::snapshot::CombinedSnapshot; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::graph::{scc::Sccs, vec_graph::VecGraph}; use rustc_index::Idx; +use rustc_middle::span_bug; 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 223e6e3d3441..6f755e07ff17 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::ReStatic; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReBound, ReVar}; use rustc_middle::ty::{Region, RegionVid}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use std::ops::Range; diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 8a3125f9dedf..c1baadfa8df7 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -24,6 +24,7 @@ use super::type_relating::TypeRelating; use super::StructurallyRelateAliases; use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; +use rustc_middle::bug; use rustc_middle::infer::canonical::OriginalQueryValues; use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::error::{ExpectedFound, TypeError}; diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5880ca788bce..d4c7d752c953 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -6,6 +6,7 @@ use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; @@ -101,7 +102,7 @@ impl<'tcx> InferCtxt<'tcx> { // instead create a new inference variable `?normalized_source`, emitting // `Projection(normalized_source, ?ty_normalized)` and `?normalized_source <: generalized_ty`. relation.register_predicates([ty::ProjectionPredicate { - projection_ty: data, + projection_term: data.into(), term: generalized_ty.into(), }]); } diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 758aac004dcf..61b13dd9a54f 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,4 +1,5 @@ use super::{FixupError, FixupResult, InferCtxt}; +use rustc_middle::bug; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 96afa257ebba..b56b39e61f0c 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -1,6 +1,7 @@ use rustc_data_structures::undo_log::Rollback; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyVid}; use rustc_span::Span; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 0299af61d45c..28d908abf83e 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -31,8 +31,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; mod errors; pub mod infer; diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index 85510cf2dcce..f77a92bf9bc3 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -27,7 +27,7 @@ pub use self::engine::{TraitEngine, TraitEngineExt}; pub use self::project::MismatchedProjectionTypes; pub(crate) use self::project::UndoLog; pub use self::project::{ - Normalized, NormalizedTy, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey, + Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry, ProjectionCacheKey, ProjectionCacheStorage, Reveal, }; pub use rustc_middle::traits::*; diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs index c6ffba59638e..b696264aab03 100644 --- a/compiler/rustc_infer/src/traits/project.rs +++ b/compiler/rustc_infer/src/traits/project.rs @@ -8,7 +8,7 @@ use rustc_data_structures::{ snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage}, undo_log::Rollback, }; -use rustc_middle::ty::{self, Ty}; +use rustc_middle::ty; pub use rustc_middle::traits::{EvaluationResult, Reveal}; @@ -26,7 +26,7 @@ pub struct Normalized<'tcx, T> { pub obligations: Vec>, } -pub type NormalizedTy<'tcx> = Normalized<'tcx, Ty<'tcx>>; +pub type NormalizedTerm<'tcx> = Normalized<'tcx, ty::Term<'tcx>>; impl<'tcx, T> Normalized<'tcx, T> { pub fn with(self, value: U) -> Normalized<'tcx, U> { @@ -77,13 +77,13 @@ pub struct ProjectionCacheStorage<'tcx> { #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] pub struct ProjectionCacheKey<'tcx> { - ty: ty::AliasTy<'tcx>, + term: ty::AliasTerm<'tcx>, param_env: ty::ParamEnv<'tcx>, } impl<'tcx> ProjectionCacheKey<'tcx> { - pub fn new(ty: ty::AliasTy<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { - Self { ty, param_env } + pub fn new(term: ty::AliasTerm<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self { + Self { term, param_env } } } @@ -93,8 +93,8 @@ pub enum ProjectionCacheEntry<'tcx> { Ambiguous, Recur, Error, - NormalizedTy { - ty: Normalized<'tcx, ty::Term<'tcx>>, + NormalizedTerm { + ty: NormalizedTerm<'tcx>, /// If we were able to successfully evaluate the /// corresponding cache entry key during predicate /// evaluation, then this field stores the final @@ -175,11 +175,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { } /// Indicates that `key` was normalized to `value`. - pub fn insert_term( - &mut self, - key: ProjectionCacheKey<'tcx>, - value: Normalized<'tcx, ty::Term<'tcx>>, - ) { + pub fn insert_term(&mut self, key: ProjectionCacheKey<'tcx>, value: NormalizedTerm<'tcx>) { debug!( "ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}", key, value @@ -190,7 +186,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { return; } let fresh_key = - map.insert(key, ProjectionCacheEntry::NormalizedTy { ty: value, complete: None }); + map.insert(key, ProjectionCacheEntry::NormalizedTerm { ty: value, complete: None }); assert!(!fresh_key, "never started projecting `{key:?}`"); } @@ -201,13 +197,16 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>, result: EvaluationResult) { let mut map = self.map(); match map.get(&key) { - Some(ProjectionCacheEntry::NormalizedTy { ty, complete: _ }) => { + Some(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => { info!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty); let mut ty = ty.clone(); if result.must_apply_considering_regions() { ty.obligations = vec![]; } - map.insert(key, ProjectionCacheEntry::NormalizedTy { ty, complete: Some(result) }); + map.insert( + key, + ProjectionCacheEntry::NormalizedTerm { ty, complete: Some(result) }, + ); } ref value => { // Type inference could "strand behind" old cache entries. Leave @@ -219,7 +218,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> { pub fn is_complete(&mut self, key: ProjectionCacheKey<'tcx>) -> Option { self.map().get(&key).and_then(|res| match res { - ProjectionCacheEntry::NormalizedTy { ty: _, complete } => *complete, + ProjectionCacheEntry::NormalizedTerm { ty: _, complete } => *complete, _ => None, }) } diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 676a7c21841a..5180fce2eb37 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -269,6 +269,17 @@ lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len -> lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level +lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than possibly intended in edition 2024 + .note = specifically, {$num_captured -> + [one] this lifetime is + *[other] these lifetimes are + } in scope but not mentioned in the type's bounds + .note2 = all lifetimes in scope will be captured by `impl Trait`s in edition 2024 + .suggestion = use the precise capturing `use<...>` syntax to make the captures explicit + +lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + .suggestion = remove the `use<...>` syntax + lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe .label = not FFI-safe .note = the type is defined here diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs new file mode 100644 index 000000000000..30bf80b915b8 --- /dev/null +++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs @@ -0,0 +1,425 @@ +use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::unord::UnordSet; +use rustc_errors::{Applicability, LintDiagnostic}; +use rustc_hir as hir; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_macros::LintDiagnostic; +use rustc_middle::middle::resolve_bound_vars::ResolvedArg; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; +use rustc_middle::{bug, span_bug}; +use rustc_session::{declare_lint, declare_lint_pass}; +use rustc_span::{sym, BytePos, Span}; + +use crate::fluent_generated as fluent; +use crate::{LateContext, LateLintPass}; + +declare_lint! { + /// The `impl_trait_overcaptures` lint warns against cases where lifetime + /// capture behavior will differ in edition 2024. + /// + /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope, + /// rather than just the lifetimes that are mentioned in the bounds of the type. + /// Often these sets are equal, but if not, it means that the `impl Trait` may + /// cause erroneous borrow-checker errors. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![feature(precise_capturing)] + /// # #![allow(incomplete_features)] + /// # #![deny(impl_trait_overcaptures)] + /// # use std::fmt::Display; + /// let mut x = vec![]; + /// x.push(1); + /// + /// fn test(x: &Vec) -> impl Display { + /// x[0] + /// } + /// + /// let element = test(&x); + /// x.push(2); + /// println!("{element}"); + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// In edition < 2024, the returned `impl Display` doesn't capture the + /// lifetime from the `&Vec`, so the vector can be mutably borrowed + /// while the `impl Display` is live. + /// + /// To fix this, we can explicitly state that the `impl Display` doesn't + /// capture any lifetimes, using `impl use<> Display`. + pub IMPL_TRAIT_OVERCAPTURES, + Allow, + "`impl Trait` will capture more lifetimes than possibly intended in edition 2024", + @feature_gate = sym::precise_capturing; + //@future_incompatible = FutureIncompatibleInfo { + // reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + // reference: "", + //}; +} + +declare_lint! { + /// The `impl_trait_redundant_captures` lint warns against cases where use of the + /// precise capturing `use<...>` syntax is not needed. + /// + /// In the 2024 edition, `impl Trait`s will capture all lifetimes in scope. + /// If precise-capturing `use<...>` syntax is used, and the set of parameters + /// that are captures are *equal* to the set of parameters in scope, then + /// the syntax is redundant, and can be removed. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// # #![feature(precise_capturing, lifetime_capture_rules_2024)] + /// # #![allow(incomplete_features)] + /// # #![deny(impl_trait_redundant_captures)] + /// fn test<'a>(x: &'a i32) -> impl use<'a> Sized { x } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// To fix this, remove the `use<'a>`, since the lifetime is already captured + /// since it is in scope. + pub IMPL_TRAIT_REDUNDANT_CAPTURES, + Warn, + "redundant precise-capturing `use<...>` syntax on an `impl Trait`", + @feature_gate = sym::precise_capturing; +} + +declare_lint_pass!( + /// Lint for opaque types that will begin capturing in-scope but unmentioned lifetimes + /// in edition 2024. + ImplTraitOvercaptures => [IMPL_TRAIT_OVERCAPTURES, IMPL_TRAIT_REDUNDANT_CAPTURES] +); + +impl<'tcx> LateLintPass<'tcx> for ImplTraitOvercaptures { + fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'tcx>) { + match &it.kind { + hir::ItemKind::Fn(..) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} + } + } + + fn check_impl_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::ImplItem<'tcx>) { + match &it.kind { + hir::ImplItemKind::Fn(_, _) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} + } + } + + fn check_trait_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::TraitItem<'tcx>) { + match &it.kind { + hir::TraitItemKind::Fn(_, _) => check_fn(cx.tcx, it.owner_id.def_id), + _ => {} + } + } +} + +fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) { + let sig = tcx.fn_sig(parent_def_id).instantiate_identity(); + + let mut in_scope_parameters = FxIndexSet::default(); + // Populate the in_scope_parameters list first with all of the generics in scope + let mut current_def_id = Some(parent_def_id.to_def_id()); + while let Some(def_id) = current_def_id { + let generics = tcx.generics_of(def_id); + for param in &generics.own_params { + in_scope_parameters.insert(param.def_id); + } + current_def_id = generics.parent; + } + + // Then visit the signature to walk through all the binders (incl. the late-bound + // vars on the function itself, which we need to count too). + sig.visit_with(&mut VisitOpaqueTypes { + tcx, + parent_def_id, + in_scope_parameters, + seen: Default::default(), + }); +} + +struct VisitOpaqueTypes<'tcx> { + tcx: TyCtxt<'tcx>, + parent_def_id: LocalDefId, + in_scope_parameters: FxIndexSet, + seen: FxIndexSet, +} + +impl<'tcx> TypeVisitor> for VisitOpaqueTypes<'tcx> { + fn visit_binder>>( + &mut self, + t: &ty::Binder<'tcx, T>, + ) -> Self::Result { + // When we get into a binder, we need to add its own bound vars to the scope. + let mut added = vec![]; + for arg in t.bound_vars() { + let arg: ty::BoundVariableKind = arg; + match arg { + ty::BoundVariableKind::Region(ty::BoundRegionKind::BrNamed(def_id, ..)) + | ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(def_id, _)) => { + added.push(def_id); + let unique = self.in_scope_parameters.insert(def_id); + assert!(unique); + } + _ => { + self.tcx.dcx().span_delayed_bug( + self.tcx.def_span(self.parent_def_id), + format!("unsupported bound variable kind: {arg:?}"), + ); + } + } + } + + t.super_visit_with(self); + + // And remove them. The `shift_remove` should be `O(1)` since we're popping + // them off from the end. + for arg in added.into_iter().rev() { + self.in_scope_parameters.shift_remove(&arg); + } + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result { + if !t.has_aliases() { + return; + } + + if let ty::Alias(ty::Projection, opaque_ty) = *t.kind() + && self.tcx.is_impl_trait_in_trait(opaque_ty.def_id) + { + // visit the opaque of the RPITIT + self.tcx + .type_of(opaque_ty.def_id) + .instantiate(self.tcx, opaque_ty.args) + .visit_with(self) + } else if let ty::Alias(ty::Opaque, opaque_ty) = *t.kind() + && let Some(opaque_def_id) = opaque_ty.def_id.as_local() + // Don't recurse infinitely on an opaque + && self.seen.insert(opaque_def_id) + // If it's owned by this function + && let opaque = + self.tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty() + && let hir::OpaqueTyOrigin::FnReturn(parent_def_id) = opaque.origin + && parent_def_id == self.parent_def_id + { + // Compute the set of args that are captured by the opaque... + let mut captured = FxIndexSet::default(); + let variances = self.tcx.variances_of(opaque_def_id); + let mut current_def_id = Some(opaque_def_id.to_def_id()); + while let Some(def_id) = current_def_id { + let generics = self.tcx.generics_of(def_id); + for param in &generics.own_params { + // A param is captured if it's invariant. + if variances[param.index as usize] != ty::Invariant { + continue; + } + // We need to turn all `ty::Param`/`ConstKind::Param` and + // `ReEarlyParam`/`ReBound` into def ids. + captured.insert(extract_def_id_from_arg( + self.tcx, + generics, + opaque_ty.args[param.index as usize], + )); + } + current_def_id = generics.parent; + } + + // Compute the set of in scope params that are not captured. Get their spans, + // since that's all we really care about them for emitting the diagnostic. + let uncaptured_spans: Vec<_> = self + .in_scope_parameters + .iter() + .filter(|def_id| !captured.contains(*def_id)) + .map(|def_id| self.tcx.def_span(def_id)) + .collect(); + + let opaque_span = self.tcx.def_span(opaque_def_id); + let new_capture_rules = + opaque_span.at_least_rust_2024() || self.tcx.features().lifetime_capture_rules_2024; + + // If we have uncaptured args, and if the opaque doesn't already have + // `use<>` syntax on it, and we're < edition 2024, then warn the user. + if !new_capture_rules + && opaque.precise_capturing_args.is_none() + && !uncaptured_spans.is_empty() + { + let suggestion = if let Ok(snippet) = + self.tcx.sess.source_map().span_to_snippet(opaque_span) + && snippet.starts_with("impl ") + { + let (lifetimes, others): (Vec<_>, Vec<_>) = captured + .into_iter() + .partition(|def_id| self.tcx.def_kind(*def_id) == DefKind::LifetimeParam); + // Take all lifetime params first, then all others (ty/ct). + let generics: Vec<_> = lifetimes + .into_iter() + .chain(others) + .map(|def_id| self.tcx.item_name(def_id).to_string()) + .collect(); + // Make sure that we're not trying to name any APITs + if generics.iter().all(|name| !name.starts_with("impl ")) { + Some(( + format!(" use<{}>", generics.join(", ")), + opaque_span.with_lo(opaque_span.lo() + BytePos(4)).shrink_to_lo(), + )) + } else { + None + } + } else { + None + }; + + self.tcx.emit_node_span_lint( + IMPL_TRAIT_OVERCAPTURES, + self.tcx.local_def_id_to_hir_id(opaque_def_id), + opaque_span, + ImplTraitOvercapturesLint { + self_ty: t, + num_captured: uncaptured_spans.len(), + uncaptured_spans, + suggestion, + }, + ); + } + // Otherwise, if we are edition 2024, have `use<>` syntax, and + // have no uncaptured args, then we should warn to the user that + // it's redundant to capture all args explicitly. + else if new_capture_rules + && let Some((captured_args, capturing_span)) = opaque.precise_capturing_args + { + let mut explicitly_captured = UnordSet::default(); + for arg in captured_args { + match self.tcx.named_bound_var(arg.hir_id()) { + Some( + ResolvedArg::EarlyBound(def_id) | ResolvedArg::LateBound(_, _, def_id), + ) => { + if self.tcx.def_kind(self.tcx.parent(def_id)) == DefKind::OpaqueTy { + let (ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) + | ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + })) = self + .tcx + .map_opaque_lifetime_to_parent_lifetime(def_id.expect_local()) + .kind() + else { + span_bug!( + self.tcx.def_span(def_id), + "variable should have been duplicated from a parent" + ); + }; + explicitly_captured.insert(def_id); + } else { + explicitly_captured.insert(def_id); + } + } + _ => { + self.tcx.dcx().span_delayed_bug( + self.tcx.hir().span(arg.hir_id()), + "no valid for captured arg", + ); + } + } + } + + if self + .in_scope_parameters + .iter() + .all(|def_id| explicitly_captured.contains(def_id)) + { + self.tcx.emit_node_span_lint( + IMPL_TRAIT_REDUNDANT_CAPTURES, + self.tcx.local_def_id_to_hir_id(opaque_def_id), + opaque_span, + ImplTraitRedundantCapturesLint { capturing_span }, + ); + } + } + + // Walk into the bounds of the opaque, too, since we want to get nested opaques + // in this lint as well. Interestingly, one place that I expect this lint to fire + // is for `impl for<'a> Bound`, since `impl Other` will begin + // to capture `'a` in e2024 (even though late-bound vars in opaques are not allowed). + for clause in + self.tcx.item_bounds(opaque_ty.def_id).iter_instantiated(self.tcx, opaque_ty.args) + { + clause.visit_with(self) + } + } + + t.super_visit_with(self); + } +} + +struct ImplTraitOvercapturesLint<'tcx> { + uncaptured_spans: Vec, + self_ty: Ty<'tcx>, + num_captured: usize, + suggestion: Option<(String, Span)>, +} + +impl<'a> LintDiagnostic<'a, ()> for ImplTraitOvercapturesLint<'_> { + fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) { + diag.arg("self_ty", self.self_ty.to_string()) + .arg("num_captured", self.num_captured) + .span_note(self.uncaptured_spans, fluent::lint_note) + .note(fluent::lint_note2); + if let Some((suggestion, span)) = self.suggestion { + diag.span_suggestion( + span, + fluent::lint_suggestion, + suggestion, + Applicability::MachineApplicable, + ); + } + } + + fn msg(&self) -> rustc_errors::DiagMessage { + fluent::lint_impl_trait_overcaptures + } +} + +#[derive(LintDiagnostic)] +#[diag(lint_impl_trait_redundant_captures)] +struct ImplTraitRedundantCapturesLint { + #[suggestion(lint_suggestion, code = "", applicability = "machine-applicable")] + capturing_span: Span, +} + +fn extract_def_id_from_arg<'tcx>( + tcx: TyCtxt<'tcx>, + generics: &'tcx ty::Generics, + arg: ty::GenericArg<'tcx>, +) -> DefId { + match arg.unpack() { + ty::GenericArgKind::Lifetime(re) => match *re { + ty::ReEarlyParam(ebr) => generics.region_param(ebr, tcx).def_id, + ty::ReBound( + _, + ty::BoundRegion { kind: ty::BoundRegionKind::BrNamed(def_id, ..), .. }, + ) => def_id, + _ => unreachable!(), + }, + ty::GenericArgKind::Type(ty) => { + let ty::Param(param_ty) = *ty.kind() else { + bug!(); + }; + generics.type_param(param_ty, tcx).def_id + } + ty::GenericArgKind::Const(ct) => { + let ty::ConstKind::Param(param_ct) = ct.kind() else { + bug!(); + }; + generics.const_param(param_ct, tcx).def_id + } + } +} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index a78b410f500c..d93edadcfbcc 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -55,6 +55,7 @@ mod expect; mod for_loops_over_fallibles; mod foreign_modules; pub mod hidden_unicode_codepoints; +mod impl_trait_overcaptures; mod internal; mod invalid_from_utf8; mod late; @@ -94,6 +95,7 @@ use drop_forget_useless::*; use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums; use for_loops_over_fallibles::*; use hidden_unicode_codepoints::*; +use impl_trait_overcaptures::ImplTraitOvercaptures; use internal::*; use invalid_from_utf8::*; use let_underscore::*; @@ -228,6 +230,7 @@ late_lint_methods!( MissingDoc: MissingDoc, AsyncFnInTrait: AsyncFnInTrait, NonLocalDefinitions: NonLocalDefinitions::default(), + ImplTraitOvercaptures: ImplTraitOvercaptures, ] ] ); diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 1ea1f496e508..eda40e4a011a 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -1,9 +1,8 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{ - self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable, -}; +use rustc_middle::ty::print::{PrintTraitPredicateExt as _, TraitPredPrintModifiersAndPath}; +use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; @@ -108,8 +107,11 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { return; } - let proj_ty = - Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args); + let proj_ty = Ty::new_projection( + cx.tcx, + proj.projection_term.def_id, + proj.projection_term.args, + ); // For every instance of the projection type in the bounds, // replace them with the term we're assigning to the associated // type in our opaque type. @@ -124,8 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // with `impl Send: OtherTrait`. for (assoc_pred, assoc_pred_span) in cx .tcx - .explicit_item_bounds(proj.projection_ty.def_id) - .iter_instantiated_copied(cx.tcx, proj.projection_ty.args) + .explicit_item_bounds(proj.projection_term.def_id) + .iter_instantiated_copied(cx.tcx, proj.projection_term.args) { let assoc_pred = assoc_pred.fold_with(proj_replacer); let Ok(assoc_pred) = traits::fully_normalize( diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs index b80e90c25a33..34153e3a220d 100644 --- a/compiler/rustc_lint/src/reference_casting.rs +++ b/compiler/rustc_lint/src/reference_casting.rs @@ -202,8 +202,10 @@ fn is_cast_to_bigger_memory_layout<'tcx>( // if the current expr looks like this `&mut expr[index]` then just looking // at `expr[index]` won't give us the underlying allocation, so we just skip it - // the same logic applies field access like `&mut expr.field` - if let ExprKind::Index(..) | ExprKind::Field(..) = e_alloc.kind { + // the same logic applies field access `&mut expr.field` and reborrows `&mut *expr`. + if let ExprKind::Index(..) | ExprKind::Field(..) | ExprKind::Unary(UnOp::Deref, ..) = + e_alloc.kind + { return None; } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 2b147e052ae0..8866b2be0784 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -677,6 +677,33 @@ trait UnusedDelimLint { } // Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`. + // + // FIXME: https://github.com/rust-lang/rust/issues/119426 + // The syntax tree in this code is from after macro expansion, so the + // current implementation has both false negatives and false positives + // related to expressions containing macros. + // + // macro_rules! m1 { + // () => { + // 1 + // }; + // } + // + // fn f1() -> u8 { + // // Lint says parens are not needed, but they are. + // (m1! {} + 1) + // } + // + // macro_rules! m2 { + // () => { + // loop { break 1; } + // }; + // } + // + // fn f2() -> u8 { + // // Lint says parens are needed, but they are not. + // (m2!() + 1) + // } { let mut innermost = inner; loop { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index eea3ca44c48b..536945457724 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -38,7 +38,6 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DEPRECATED_IN_FUTURE, DEPRECATED_WHERE_CLAUSE_LOCATION, - DEREFERENCING_MUT_BINDING, DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, @@ -90,6 +89,7 @@ declare_lint_pass! { RUST_2021_INCOMPATIBLE_OR_PATTERNS, RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, RUST_2021_PRELUDE_COLLISIONS, + RUST_2024_INCOMPATIBLE_PAT, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SINGLE_USE_LIFETIMES, SOFT_UNSTABLE, @@ -1630,34 +1630,34 @@ declare_lint! { } declare_lint! { - /// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode, - /// as this behavior will change in rust 2024. + /// The `rust_2024_incompatible_pat` lint + /// detects patterns whose meaning will change in the Rust 2024 edition. /// /// ### Example /// - /// ```rust - /// # #![warn(dereferencing_mut_binding)] - /// let x = Some(123u32); - /// let _y = match &x { - /// Some(mut x) => { - /// x += 1; - /// x - /// } - /// None => 0, - /// }; + /// ```rust,edition2021 + /// #![feature(ref_pat_eat_one_layer_2024)] + /// #![warn(rust_2024_incompatible_pat)] + /// + /// if let Some(&a) = &Some(&0u8) { + /// let _: u8 = a; + /// } + /// if let Some(mut _a) = &mut Some(0u8) { + /// _a = 7u8; + /// } /// ``` /// /// {{produces}} /// /// ### Explanation /// - /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type - /// `u32`, which was deemed surprising. After edition 2024, adding `mut` will not change the - /// type of `x`. This lint warns users of editions before 2024 to update their code. - pub DEREFERENCING_MUT_BINDING, + /// In Rust 2024 and above, the `mut` keyword does not reset the pattern binding mode, + /// and nor do `&` or `&mut` patterns. The lint will suggest code that + /// has the same meaning in all editions. + pub RUST_2024_INCOMPATIBLE_PAT, Allow, - "detects `mut x` bindings that change the type of `x`", - @feature_gate = sym::mut_preserve_binding_mode_2024; + "detects patterns whose meaning will change in Rust 2024", + @feature_gate = sym::ref_pat_eat_one_layer_2024; // FIXME uncomment below upon stabilization /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 888c2427d8f4..e3205fc1d30e 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -16,6 +16,7 @@ use rustc_fs_util::try_canonicalize; use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_session::config::{self, CrateType, ExternLocation}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; diff --git a/compiler/rustc_metadata/src/dependency_format.rs b/compiler/rustc_metadata/src/dependency_format.rs index 4d1bd4554123..99181f9c8605 100644 --- a/compiler/rustc_metadata/src/dependency_format.rs +++ b/compiler/rustc_metadata/src/dependency_format.rs @@ -59,6 +59,7 @@ use crate::errors::{ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::CrateNum; +use rustc_middle::bug; use rustc_middle::middle::dependency_format::{Dependencies, DependencyList, Linkage}; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index c8162a1f0eea..99584845e49a 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -19,9 +19,6 @@ extern crate proc_macro; -#[macro_use] -extern crate rustc_middle; - #[macro_use] extern crate tracing; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2a33088513b7..bb68c6eaf092 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -21,6 +21,7 @@ use rustc_middle::middle::lib_features::LibFeatures; use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc_middle::ty::codec::TyDecoder; use rustc_middle::ty::Visibility; +use rustc_middle::{bug, implement_ty_decoder}; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; use rustc_session::cstore::{CrateSource, ExternCrate}; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 531b2e05411a..c783149a6951 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -11,6 +11,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; +use rustc_middle::bug; use rustc_middle::metadata::ModChild; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7c96a6fa9a97..db0dc6d9064b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -20,6 +20,7 @@ use rustc_middle::ty::codec::TyEncoder; use rustc_middle::ty::fast_reject::{self, TreatParams}; use rustc_middle::ty::{AssocItemContainer, SymbolName}; use rustc_middle::util::common::to_readable_str; +use rustc_middle::{bug, span_bug}; use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder}; use rustc_session::config::{CrateType, OptLevel}; use rustc_span::hygiene::HygieneEncodeContext; diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c9cb2f5a2405..79e4ff81093b 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -24,6 +24,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::mir; +use rustc_middle::trivially_parameterized_over_tcx; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams}; use rustc_middle::ty::{DeducedParamAttrs, ParameterizedOverTcx, TyCtxt}; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 383241465c3d..6e152cbcb657 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -188,8 +188,9 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { } /// Error information for when the program we executed turned out not to actually be a valid -/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp -/// where we work on generic code or execution does not have all information available. +/// program. This cannot happen in stand-alone Miri (except for layout errors that are only detect +/// during monomorphization), but it can happen during CTFE/ConstProp where we work on generic code +/// or execution does not have all information available. #[derive(Debug)] pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. @@ -507,7 +508,7 @@ pub enum ValidationErrorKind<'tcx> { /// Miri engine, e.g., CTFE does not support dereferencing pointers at integral addresses. #[derive(Debug)] pub enum UnsupportedOpInfo { - /// Free-form case. Only for errors that are never caught! + /// Free-form case. Only for errors that are never caught! Used by Miri. // FIXME still use translatable diagnostics Unsupported(String), /// Unsized local variables. @@ -592,3 +593,117 @@ impl InterpError<'_> { ) } } + +// Macros for constructing / throwing `InterpError` +#[macro_export] +macro_rules! err_unsup { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_unsup_format { + ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_inval { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::UndefinedBehavior( + $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_ub_format { + ($($tt:tt)*) => { $crate::err_ub!(Ub(format!($($tt)*))) }; +} + +#[macro_export] +macro_rules! err_ub_custom { + ($msg:expr $(, $($name:ident = $value:expr),* $(,)?)?) => {{ + $( + let ($($name,)*) = ($($value,)*); + )? + $crate::err_ub!(Custom( + $crate::error::CustomSubdiagnostic { + msg: || $msg, + add_args: Box::new(move |mut set_arg| { + $($( + set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); + )*)? + }) + } + )) + }}; +} + +#[macro_export] +macro_rules! err_exhaust { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_machine_stop { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) + }; +} + +// In the `throw_*` macros, avoid `return` to make them work with `try {}`. +#[macro_export] +macro_rules! throw_unsup { + ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_unsup_format { + ($($tt:tt)*) => { do yeet $crate::err_unsup_format!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_inval { + ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub { + ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub_format { + ($($tt:tt)*) => { do yeet $crate::err_ub_format!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_ub_custom { + ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_exhaust { + ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) }; +} + +#[macro_export] +macro_rules! throw_machine_stop { + ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) }; +} diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index 38cb1d5f9a07..739b1410e6db 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -1,120 +1,9 @@ //! An interpreter for MIR used in CTFE and by miri. -#[macro_export] -macro_rules! err_unsup { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedOpInfo::$($tt)* - ) - }; -} - -#[macro_export] -macro_rules! err_unsup_format { - ($($tt:tt)*) => { err_unsup!(Unsupported(format!($($tt)*))) }; -} - -#[macro_export] -macro_rules! err_inval { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::InvalidProgram( - $crate::mir::interpret::InvalidProgramInfo::$($tt)* - ) - }; -} - -#[macro_export] -macro_rules! err_ub { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::UndefinedBehavior( - $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)* - ) - }; -} - -#[macro_export] -macro_rules! err_ub_format { - ($($tt:tt)*) => { err_ub!(Ub(format!($($tt)*))) }; -} - -#[macro_export] -macro_rules! err_exhaust { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::ResourceExhaustion( - $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* - ) - }; -} - -#[macro_export] -macro_rules! err_machine_stop { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::MachineStop(Box::new($($tt)*)) - }; -} - -// In the `throw_*` macros, avoid `return` to make them work with `try {}`. -#[macro_export] -macro_rules! throw_unsup { - ($($tt:tt)*) => { do yeet err_unsup!($($tt)*) }; -} - -#[macro_export] -macro_rules! throw_unsup_format { - ($($tt:tt)*) => { throw_unsup!(Unsupported(format!($($tt)*))) }; -} - -#[macro_export] -macro_rules! throw_inval { - ($($tt:tt)*) => { do yeet err_inval!($($tt)*) }; -} - -#[macro_export] -macro_rules! throw_ub { - ($($tt:tt)*) => { do yeet err_ub!($($tt)*) }; -} - -#[macro_export] -macro_rules! throw_ub_format { - ($($tt:tt)*) => { throw_ub!(Ub(format!($($tt)*))) }; -} - -#[macro_export] -macro_rules! throw_exhaust { - ($($tt:tt)*) => { do yeet err_exhaust!($($tt)*) }; -} - -#[macro_export] -macro_rules! throw_machine_stop { - ($($tt:tt)*) => { do yeet err_machine_stop!($($tt)*) }; -} - -#[macro_export] -macro_rules! err_ub_custom { - ($msg:expr $(, $($name:ident = $value:expr),* $(,)?)?) => {{ - $( - let ($($name,)*) = ($($value,)*); - )? - err_ub!(Custom( - rustc_middle::error::CustomSubdiagnostic { - msg: || $msg, - add_args: Box::new(move |mut set_arg| { - $($( - set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name)); - )*)? - }) - } - )) - }}; -} - -#[macro_export] -macro_rules! throw_ub_custom { - ($($tt:tt)*) => { do yeet err_ub_custom!($($tt)*) }; -} +#[macro_use] +mod error; mod allocation; -mod error; mod pointer; mod queries; mod value; @@ -150,6 +39,12 @@ pub use self::error::{ ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind, }; +// Also make the error macros available from this module. +pub use { + err_exhaust, err_inval, err_machine_stop, err_ub, err_ub_custom, err_ub_format, err_unsup, + err_unsup_format, throw_exhaust, throw_inval, throw_machine_stop, throw_ub, throw_ub_custom, + throw_ub_format, throw_unsup, throw_unsup_format, +}; pub use self::value::Scalar; diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 6c33a29ea812..fb796bf87a1d 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -247,22 +247,15 @@ pub enum ObligationCauseCode<'tcx> { /// A tuple is WF only if its middle elements are `Sized`. TupleElem, - /// Must satisfy all of the where-clause predicates of the - /// given item. - WhereClause(DefId), + /// Represents a clause that comes from a specific item. + /// The span corresponds to the clause. + WhereClause(DefId, Span), - /// Like `WhereClause`, but carries the span of the - /// predicate when it can be identified. - SpannedWhereClause(DefId, Span), - - /// Like `WhereClause`, but carries the `HirId` of the - /// expression that caused the obligation, and the `usize` - /// indicates exactly which predicate it is in the list of - /// instantiated predicates. - WhereClauseInExpr(DefId, HirId, usize), - - /// Combines `SpannedWhereClause` and `WhereClauseInExpr`. - SpannedWhereClauseInExpr(DefId, Span, HirId, usize), + /// Like `WhereClause`, but also identifies the expression + /// which requires the `where` clause to be proven, and also + /// identifies the index of the predicate in the `predicates_of` + /// list of the item. + WhereClauseInExpr(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 0464be2df066..e831db1a41bf 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -26,6 +26,7 @@ use crate::traits::solve; use crate::traits::solve::{ ExternalConstraints, ExternalConstraintsData, PredefinedOpaques, PredefinedOpaquesData, }; +use crate::ty::predicate::ExistentialPredicateStableCmpExt as _; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, ConstData, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst, ParamTy, Pattern, @@ -99,17 +100,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type CanonicalVars = CanonicalVarInfos<'tcx>; type Ty = Ty<'tcx>; - type Pat = Pattern<'tcx>; type Tys = &'tcx List>; type AliasTy = ty::AliasTy<'tcx>; type ParamTy = ParamTy; type BoundTy = ty::BoundTy; type PlaceholderTy = ty::PlaceholderType; - type ErrorGuaranteed = ErrorGuaranteed; + type BoundExistentialPredicates = &'tcx List>; type PolyFnSig = PolyFnSig<'tcx>; type AllocId = crate::mir::interpret::AllocId; + type Pat = Pattern<'tcx>; type Const = ty::Const<'tcx>; type AliasConst = ty::UnevaluatedConst<'tcx>; @@ -121,8 +122,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Region = Region<'tcx>; type EarlyParamRegion = ty::EarlyParamRegion; - type BoundRegion = ty::BoundRegion; type LateParamRegion = ty::LateParamRegion; + type BoundRegion = ty::BoundRegion; type InferRegion = ty::RegionVid; type PlaceholderRegion = ty::PlaceholderRegion; @@ -131,6 +132,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>; type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>; type ProjectionPredicate = ty::ProjectionPredicate<'tcx>; + type AliasTerm = ty::AliasTerm<'tcx>; type NormalizesTo = ty::NormalizesTo<'tcx>; type SubtypePredicate = ty::SubtypePredicate<'tcx>; type CoercePredicate = ty::CoercePredicate<'tcx>; @@ -146,6 +148,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { self.generics_of(def_id) } + fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs { + self.mk_args(args) + } + fn check_and_mk_args( self, def_id: DefId, @@ -153,6 +159,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> { ) -> ty::GenericArgsRef<'tcx> { self.check_and_mk_args(def_id, args) } + + fn parent(self, def_id: Self::DefId) -> Self::DefId { + self.parent(def_id) + } } type InternedSet<'tcx, T> = ShardedHashMap, ()>; diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 0dc835671d56..4de7d532c967 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -294,10 +294,10 @@ impl FlagComputation { self.add_ty(b); } ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty, + projection_term, term, })) => { - self.add_alias_ty(projection_ty); + self.add_alias_term(projection_term); self.add_term(term); } ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { @@ -313,7 +313,7 @@ impl FlagComputation { } ty::PredicateKind::Ambiguous => {} ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => { - self.add_alias_ty(alias); + self.add_alias_term(alias); self.add_term(term); } ty::PredicateKind::AliasRelate(t1, t2, _) => { @@ -410,6 +410,10 @@ impl FlagComputation { self.add_args(alias_ty.args); } + fn add_alias_term(&mut self, alias_term: ty::AliasTerm<'_>) { + self.add_args(alias_term.args); + } + fn add_args(&mut self, args: &[GenericArg<'_>]) { for kind in args { match kind.unpack() { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 12cefc23233c..dc5e881843a5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -96,13 +96,13 @@ pub use self::list::{List, ListWithCachedTypeInfo}; pub use self::parameterized::ParameterizedOverTcx; pub use self::pattern::{Pattern, PatternKind}; pub use self::predicate::{ - Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialProjection, - ExistentialTraitRef, NormalizesTo, OutlivesPredicate, PolyCoercePredicate, - PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef, - PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate, - PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate, - RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitPredicate, - TraitRef, TypeOutlivesPredicate, + Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialPredicateStableCmpExt, + ExistentialProjection, ExistentialTraitRef, NormalizesTo, OutlivesPredicate, + PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection, + PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate, + PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, + PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, + ToPredicate, TraitPredicate, TraitRef, TypeOutlivesPredicate, }; pub use self::region::{ BoundRegion, BoundRegionKind, BoundRegionKind::*, EarlyParamRegion, LateParamRegion, Region, @@ -110,11 +110,11 @@ pub use self::region::{ }; pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::{ - AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, - ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs, - CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs, - InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs, - VarianceDiagInfo, + AliasTerm, AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, + CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, + CoroutineClosureArgs, CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, + InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, + UpvarArgs, VarianceDiagInfo, }; pub use self::trait_def::TraitDef; pub use self::typeck_results::{ @@ -275,61 +275,6 @@ pub enum ImplSubject<'tcx> { Inherent(Ty<'tcx>), } -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum ImplPolarity { - /// `impl Trait for Type` - Positive, - /// `impl !Trait for Type` - Negative, - /// `#[rustc_reservation_impl] impl Trait for Type` - /// - /// This is a "stability hack", not a real Rust feature. - /// See #64631 for details. - Reservation, -} - -impl fmt::Display for ImplPolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - Self::Reservation => f.write_str("reservation"), - } - } -} - -/// Polarity for a trait predicate. May either be negative or positive. -/// Distinguished from [`ImplPolarity`] since we never compute goals with -/// "reservation" level. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum PredicatePolarity { - /// `Type: Trait` - Positive, - /// `Type: !Trait` - Negative, -} - -impl PredicatePolarity { - /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. - pub fn flip(&self) -> PredicatePolarity { - match self { - PredicatePolarity::Positive => PredicatePolarity::Negative, - PredicatePolarity::Negative => PredicatePolarity::Positive, - } - } -} - -impl fmt::Display for PredicatePolarity { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Positive => f.write_str("positive"), - Self::Negative => f.write_str("negative"), - } - } -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)] #[derive(TypeFoldable, TypeVisitable)] pub enum Asyncness { @@ -684,15 +629,14 @@ impl<'tcx> Term<'tcx> { } } - /// This function returns the inner `AliasTy` for a `ty::Alias` or `ConstKind::Unevaluated`. - pub fn to_alias_ty(&self, tcx: TyCtxt<'tcx>) -> Option> { + pub fn to_alias_term(self) -> Option> { match self.unpack() { TermKind::Ty(ty) => match *ty.kind() { - ty::Alias(_kind, alias_ty) => Some(alias_ty), + ty::Alias(_kind, alias_ty) => Some(alias_ty.into()), _ => None, }, TermKind::Const(ct) => match ct.kind() { - ConstKind::Unevaluated(uv) => Some(AliasTy::new(tcx, uv.def, uv.args)), + ConstKind::Unevaluated(uv) => Some(uv.into()), _ => None, }, } diff --git a/compiler/rustc_middle/src/ty/predicate.rs b/compiler/rustc_middle/src/ty/predicate.rs index 5387036d4091..e78856517b21 100644 --- a/compiler/rustc_middle/src/ty/predicate.rs +++ b/compiler/rustc_middle/src/ty/predicate.rs @@ -1,22 +1,28 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; -use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir::def_id::DefId; -use rustc_macros::{HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; -use rustc_type_ir::ClauseKind as IrClauseKind; -use rustc_type_ir::PredicateKind as IrPredicateKind; -use rustc_type_ir::TraitRef as IrTraitRef; +use rustc_macros::{ + extension, HashStable, Lift, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable, +}; +use rustc_type_ir as ir; use std::cmp::Ordering; -use crate::ty::visit::TypeVisitableExt; use crate::ty::{ - self, AliasTy, Binder, DebruijnIndex, DebugWithInfcx, EarlyBinder, GenericArgsRef, - PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, WithCachedTypeInfo, + self, Binder, DebruijnIndex, EarlyBinder, PredicatePolarity, Term, Ty, TyCtxt, TypeFlags, + WithCachedTypeInfo, }; -pub type TraitRef<'tcx> = IrTraitRef>; -pub type ClauseKind<'tcx> = IrClauseKind>; -pub type PredicateKind<'tcx> = IrPredicateKind>; +pub type TraitRef<'tcx> = ir::TraitRef>; +pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate>; +pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate>; +pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef>; +pub type ExistentialProjection<'tcx> = ir::ExistentialProjection>; +pub type TraitPredicate<'tcx> = ir::TraitPredicate>; +pub type ClauseKind<'tcx> = ir::ClauseKind>; +pub type PredicateKind<'tcx> = ir::PredicateKind>; +pub type NormalizesTo<'tcx> = ir::NormalizesTo>; +pub type CoercePredicate<'tcx> = ir::CoercePredicate>; +pub type SubtypePredicate<'tcx> = ir::SubtypePredicate>; /// A statement that can be proven by a trait solver. This includes things that may /// show up in where clauses, such as trait predicates and projection predicates, @@ -195,43 +201,25 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub enum ExistentialPredicate<'tcx> { - /// E.g., `Iterator`. - Trait(ExistentialTraitRef<'tcx>), - /// E.g., `Iterator::Item = T`. - Projection(ExistentialProjection<'tcx>), - /// E.g., `Send`. - AutoTrait(DefId), -} - -impl<'tcx> DebugWithInfcx> for ExistentialPredicate<'tcx> { - fn fmt>>( - this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - std::fmt::Debug::fmt(&this.data, f) - } -} - +#[extension(pub trait ExistentialPredicateStableCmpExt<'tcx>)] impl<'tcx> ExistentialPredicate<'tcx> { /// Compares via an ordering that will not change if modules are reordered or other changes are /// made to the tree. In particular, this ordering is preserved across incremental compilations. - pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { - use self::ExistentialPredicate::*; + fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering { match (*self, *other) { - (Trait(_), Trait(_)) => Ordering::Equal, - (Projection(ref a), Projection(ref b)) => { + (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => Ordering::Equal, + (ExistentialPredicate::Projection(ref a), ExistentialPredicate::Projection(ref b)) => { tcx.def_path_hash(a.def_id).cmp(&tcx.def_path_hash(b.def_id)) } - (AutoTrait(ref a), AutoTrait(ref b)) => { + (ExistentialPredicate::AutoTrait(ref a), ExistentialPredicate::AutoTrait(ref b)) => { tcx.def_path_hash(*a).cmp(&tcx.def_path_hash(*b)) } - (Trait(_), _) => Ordering::Less, - (Projection(_), Trait(_)) => Ordering::Greater, - (Projection(_), _) => Ordering::Less, - (AutoTrait(_), _) => Ordering::Greater, + (ExistentialPredicate::Trait(_), _) => Ordering::Less, + (ExistentialPredicate::Projection(_), ExistentialPredicate::Trait(_)) => { + Ordering::Greater + } + (ExistentialPredicate::Projection(_), _) => Ordering::Less, + (ExistentialPredicate::AutoTrait(_), _) => Ordering::Greater, } } } @@ -340,52 +328,6 @@ impl<'tcx> PolyTraitRef<'tcx> { } } -/// An existential reference to a trait, where `Self` is erased. -/// For example, the trait object `Trait<'a, 'b, X, Y>` is: -/// ```ignore (illustrative) -/// exists T. T: Trait<'a, 'b, X, Y> -/// ``` -/// The generic parameters don't include the erased `Self`, only trait -/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialTraitRef<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, -} - -impl<'tcx> ExistentialTraitRef<'tcx> { - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - trait_ref: ty::TraitRef<'tcx>, - ) -> ty::ExistentialTraitRef<'tcx> { - // Assert there is a Self. - trait_ref.args.type_at(0); - - ty::ExistentialTraitRef { - def_id: trait_ref.def_id, - args: tcx.mk_args(&trait_ref.args[1..]), - } - } - - /// Object types don't have a self type specified. Therefore, when - /// we convert the principal trait-ref into a normal trait-ref, - /// you must give *some* self type. A common choice is `mk_err()` - /// or some placeholder type. - pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> { - // otherwise the escaping vars would be captured by the binder - // debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::TraitRef::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter())) - } -} - -impl<'tcx> IntoDiagArg for ExistentialTraitRef<'tcx> { - fn into_diag_arg(self) -> DiagArgValue { - self.to_string().into_diag_arg() - } -} - pub type PolyExistentialTraitRef<'tcx> = ty::Binder<'tcx, ExistentialTraitRef<'tcx>>; impl<'tcx> PolyExistentialTraitRef<'tcx> { @@ -402,62 +344,8 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { } } -/// A `ProjectionPredicate` for an `ExistentialTraitRef`. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ExistentialProjection<'tcx> { - pub def_id: DefId, - pub args: GenericArgsRef<'tcx>, - pub term: Term<'tcx>, -} - pub type PolyExistentialProjection<'tcx> = ty::Binder<'tcx, ExistentialProjection<'tcx>>; -impl<'tcx> ExistentialProjection<'tcx> { - /// Extracts the underlying existential trait reference from this projection. - /// For example, if this is a projection of `exists T. ::Item == X`, - /// then this function would return an `exists T. T: Iterator` existential trait - /// reference. - pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { - let def_id = tcx.parent(self.def_id); - let args_count = tcx.generics_of(def_id).count() - 1; - let args = tcx.mk_args(&self.args[..args_count]); - ty::ExistentialTraitRef { def_id, args } - } - - pub fn with_self_ty( - &self, - tcx: TyCtxt<'tcx>, - self_ty: Ty<'tcx>, - ) -> ty::ProjectionPredicate<'tcx> { - // otherwise the escaping regions would be captured by the binders - debug_assert!(!self_ty.has_escaping_bound_vars()); - - ty::ProjectionPredicate { - projection_ty: AliasTy::new( - tcx, - self.def_id, - [self_ty.into()].into_iter().chain(self.args), - ), - term: self.term, - } - } - - pub fn erase_self_ty( - tcx: TyCtxt<'tcx>, - projection_predicate: ty::ProjectionPredicate<'tcx>, - ) -> Self { - // Assert there is a Self. - projection_predicate.projection_ty.args.type_at(0); - - Self { - def_id: projection_predicate.projection_ty.def_id, - args: tcx.mk_args(&projection_predicate.projection_ty.args[1..]), - term: projection_predicate.term, - } - } -} - impl<'tcx> PolyExistentialProjection<'tcx> { pub fn with_self_ty( &self, @@ -578,37 +466,8 @@ impl<'tcx> Clause<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx>, - - /// If polarity is Positive: we are proving that the trait is implemented. - /// - /// If polarity is Negative: we are proving that a negative impl of this trait - /// exists. (Note that coherence also checks whether negative impls of supertraits - /// exist via a series of predicates.) - /// - /// If polarity is Reserved: that's a bug. - pub polarity: PredicatePolarity, -} - pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>; -impl<'tcx> TraitPredicate<'tcx> { - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { - Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self } - } - - pub fn def_id(self) -> DefId { - self.trait_ref.def_id - } - - pub fn self_ty(self) -> Ty<'tcx> { - self.trait_ref.self_ty() - } -} - impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. @@ -634,71 +493,17 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'t pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<'tcx, RegionOutlivesPredicate<'tcx>>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder<'tcx, TypeOutlivesPredicate<'tcx>>; -/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates -/// whether the `a` type is the type that we should label as "expected" when -/// presenting user diagnostics. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct SubtypePredicate<'tcx> { - pub a_is_expected: bool, - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolySubtypePredicate<'tcx> = ty::Binder<'tcx, SubtypePredicate<'tcx>>; -/// Encodes that we have to coerce *from* the `a` type to the `b` type. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct CoercePredicate<'tcx> { - pub a: Ty<'tcx>, - pub b: Ty<'tcx>, -} pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>; -/// This kind of predicate has no *direct* correspondent in the -/// syntax, but it roughly corresponds to the syntactic forms: -/// -/// 1. `T: TraitRef<..., Item = Type>` -/// 2. `>::Item == Type` (NYI) -/// -/// In particular, form #1 is "desugared" to the combination of a -/// normal trait predicate (`T: TraitRef<...>`) and one of these -/// predicates. Form #2 is a broader form in that it also permits -/// equality between arbitrary types. Processing an instance of -/// Form #2 eventually yields one of these `ProjectionPredicate` -/// instances to normalize the LHS. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct ProjectionPredicate<'tcx> { - pub projection_ty: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> ProjectionPredicate<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.projection_ty.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ProjectionPredicate<'tcx> { - Self { projection_ty: self.projection_ty.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.projection_ty.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.projection_ty.def_id - } -} - pub type PolyProjectionPredicate<'tcx> = Binder<'tcx, ProjectionPredicate<'tcx>>; impl<'tcx> PolyProjectionPredicate<'tcx> { /// Returns the `DefId` of the trait of the associated item being projected. #[inline] pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { - self.skip_binder().projection_ty.trait_def_id(tcx) + self.skip_binder().projection_term.trait_def_id(tcx) } /// Get the [PolyTraitRef] required for this projection to be well formed. @@ -711,7 +516,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { // This is because here `self` has a `Binder` and so does our // return value, so we are preserving the number of binding // levels. - self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx)) + self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx)) } pub fn term(&self) -> Binder<'tcx, Term<'tcx>> { @@ -724,34 +529,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { // Ok to skip binder since trait `DefId` does not care about regions. - self.skip_binder().projection_ty.def_id - } -} - -/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be -/// proven by actually normalizing `alias`. -#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] -#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct NormalizesTo<'tcx> { - pub alias: AliasTy<'tcx>, - pub term: Term<'tcx>, -} - -impl<'tcx> NormalizesTo<'tcx> { - pub fn self_ty(self) -> Ty<'tcx> { - self.alias.self_ty() - } - - pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> NormalizesTo<'tcx> { - Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self } - } - - pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { - self.alias.trait_def_id(tcx) - } - - pub fn def_id(self) -> DefId { - self.alias.def_id + self.skip_binder().projection_term.def_id } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 14a628ab064e..8d8ed70a7574 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1277,7 +1277,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { fn pretty_print_inherent_projection( &mut self, - alias_ty: ty::AliasTy<'tcx>, + alias_ty: ty::AliasTerm<'tcx>, ) -> Result<(), PrintError> { let def_key = self.tcx().def_key(alias_ty.def_id); self.path_generic_args( @@ -2953,8 +2953,9 @@ impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> { } } +#[extension(pub trait PrintTraitPredicateExt<'tcx>)] impl<'tcx> ty::TraitPredicate<'tcx> { - pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { + fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> { TraitPredPrintModifiersAndPath(self) } } @@ -3037,6 +3038,15 @@ define_print! { p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path())) } + ty::TraitPredicate<'tcx> { + p!(print(self.trait_ref.self_ty()), ": "); + p!(pretty_print_bound_constness(self.trait_ref)); + if let ty::PredicatePolarity::Negative = self.polarity { + p!("!"); + } + p!(print(self.trait_ref.print_trait_sugared())) + } + ty::TypeAndMut<'tcx> { p!(write("{}", self.mutbl.prefix_str()), print(self.ty)) } @@ -3077,13 +3087,15 @@ define_print! { ty::PredicateKind::AliasRelate(t1, t2, dir) => p!(print(t1), write(" {} ", dir), print(t2)), } } -} -define_print_and_forward_display! { - (self, cx): - - &'tcx ty::List> { - p!("{{", comma_sep(self.iter()), "}}") + ty::ExistentialPredicate<'tcx> { + match *self { + ty::ExistentialPredicate::Trait(x) => p!(print(x)), + ty::ExistentialPredicate::Projection(x) => p!(print(x)), + ty::ExistentialPredicate::AutoTrait(def_id) => { + p!(print_def_path(def_id, &[])); + } + } } ty::ExistentialTraitRef<'tcx> { @@ -3098,14 +3110,36 @@ define_print_and_forward_display! { p!(write("{} = ", name), print(self.term)) } - ty::ExistentialPredicate<'tcx> { - match *self { - ty::ExistentialPredicate::Trait(x) => p!(print(x)), - ty::ExistentialPredicate::Projection(x) => p!(print(x)), - ty::ExistentialPredicate::AutoTrait(def_id) => { - p!(print_def_path(def_id, &[])); - } - } + ty::ProjectionPredicate<'tcx> { + p!(print(self.projection_term), " == "); + cx.reset_type_limit(); + p!(print(self.term)) + } + + ty::SubtypePredicate<'tcx> { + p!(print(self.a), " <: "); + cx.reset_type_limit(); + p!(print(self.b)) + } + + ty::CoercePredicate<'tcx> { + p!(print(self.a), " -> "); + cx.reset_type_limit(); + p!(print(self.b)) + } + + ty::NormalizesTo<'tcx> { + p!(print(self.alias), " normalizes-to "); + cx.reset_type_limit(); + p!(print(self.term)) + } +} + +define_print_and_forward_display! { + (self, cx): + + &'tcx ty::List> { + p!("{{", comma_sep(self.iter()), "}}") } ty::FnSig<'tcx> { @@ -3164,39 +3198,6 @@ define_print_and_forward_display! { p!(write("{}", self.name)) } - ty::SubtypePredicate<'tcx> { - p!(print(self.a), " <: "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::CoercePredicate<'tcx> { - p!(print(self.a), " -> "); - cx.reset_type_limit(); - p!(print(self.b)) - } - - ty::TraitPredicate<'tcx> { - p!(print(self.trait_ref.self_ty()), ": "); - p!(pretty_print_bound_constness(self.trait_ref)); - if let ty::PredicatePolarity::Negative = self.polarity { - p!("!"); - } - p!(print(self.trait_ref.print_trait_sugared())) - } - - ty::ProjectionPredicate<'tcx> { - p!(print(self.projection_ty), " == "); - cx.reset_type_limit(); - p!(print(self.term)) - } - - ty::NormalizesTo<'tcx> { - p!(print(self.alias), " normalizes-to "); - cx.reset_type_limit(); - p!(print(self.term)) - } - ty::Term<'tcx> { match self.unpack() { ty::TermKind::Ty(ty) => p!(print(ty)), @@ -3205,20 +3206,29 @@ define_print_and_forward_display! { } ty::AliasTy<'tcx> { - if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) { - p!(pretty_print_inherent_projection(*self)) - } else { - // If we're printing verbosely, or don't want to invoke queries - // (`is_impl_trait_in_trait`), then fall back to printing the def path. - // This is likely what you want if you're debugging the compiler anyways. - if !(cx.should_print_verbose() || with_reduced_queries()) - && cx.tcx().is_impl_trait_in_trait(self.def_id) - { - return cx.pretty_print_opaque_impl_type(self.def_id, self.args); - } else { - p!(print_def_path(self.def_id, self.args)); - } + let alias_term: ty::AliasTerm<'tcx> = (*self).into(); + p!(print(alias_term)) + } + ty::AliasTerm<'tcx> { + match self.kind(cx.tcx()) { + ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)), + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { + // If we're printing verbosely, or don't want to invoke queries + // (`is_impl_trait_in_trait`), then fall back to printing the def path. + // This is likely what you want if you're debugging the compiler anyways. + if !(cx.should_print_verbose() || with_reduced_queries()) + && cx.tcx().is_impl_trait_in_trait(self.def_id) + { + return cx.pretty_print_opaque_impl_type(self.def_id, self.args); + } else { + p!(print_def_path(self.def_id, self.args)); + } + } } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 7063ef07201b..eaf5fdf57109 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -5,10 +5,11 @@ //! subtyping, type equality, etc. use crate::ty::error::{ExpectedFound, TypeError}; -use crate::ty::{self, Expr, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable}; -use crate::ty::{GenericArg, GenericArgKind, GenericArgsRef}; +use crate::ty::{ + self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg, + GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, +}; use rustc_hir as hir; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_macros::TypeVisitable; use rustc_target::spec::abi; @@ -225,8 +226,8 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { if a.def_id != b.def_id { Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) } else { - let args = match relation.tcx().def_kind(a.def_id) { - DefKind::OpaqueTy => relate_args_with_variances( + let args = match a.kind(relation.tcx()) { + ty::Opaque => relate_args_with_variances( relation, a.def_id, relation.tcx().variances_of(a.def_id), @@ -234,16 +235,46 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> { b.args, false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle )?, - DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => { + ty::Projection | ty::Weak | ty::Inherent => { relate_args_invariantly(relation, a.args, b.args)? } - def => bug!("unknown alias DefKind: {def:?}"), }; Ok(ty::AliasTy::new(relation.tcx(), a.def_id, args)) } } } +impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> { + fn relate>( + relation: &mut R, + a: ty::AliasTerm<'tcx>, + b: ty::AliasTerm<'tcx>, + ) -> RelateResult<'tcx, ty::AliasTerm<'tcx>> { + if a.def_id != b.def_id { + Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id))) + } else { + let args = match a.kind(relation.tcx()) { + ty::AliasTermKind::OpaqueTy => relate_args_with_variances( + relation, + a.def_id, + relation.tcx().variances_of(a.def_id), + a.args, + b.args, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )?, + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::WeakTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::UnevaluatedConst + | ty::AliasTermKind::ProjectionConst => { + relate_args_invariantly(relation, a.args, b.args)? + } + }; + Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args)) + } + } +} + impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> { fn relate>( relation: &mut R, @@ -702,14 +733,21 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List> { } let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| { - use crate::ty::ExistentialPredicate::*; match (ep_a.skip_binder(), ep_b.skip_binder()) { - (Trait(a), Trait(b)) => Ok(ep_a - .rebind(Trait(relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder()))), - (Projection(a), Projection(b)) => Ok(ep_a.rebind(Projection( - relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), - ))), - (AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))), + (ExistentialPredicate::Trait(a), ExistentialPredicate::Trait(b)) => Ok(ep_a + .rebind(ExistentialPredicate::Trait( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))), + (ExistentialPredicate::Projection(a), ExistentialPredicate::Projection(b)) => { + Ok(ep_a.rebind(ExistentialPredicate::Projection( + relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(), + ))) + } + (ExistentialPredicate::AutoTrait(a), ExistentialPredicate::AutoTrait(b)) + if a == b => + { + Ok(ep_a.rebind(ExistentialPredicate::AutoTrait(a))) + } _ => Err(TypeError::ExistentialMismatch(expected_found(a, b))), } }); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index a7770f719260..6abd685343b3 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -55,12 +55,6 @@ impl fmt::Debug for ty::UpvarId { } } -impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - with_no_trimmed_paths!(fmt::Display::fmt(self, f)) - } -} - impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?} -> {}", self.kind, self.target) @@ -158,25 +152,6 @@ impl fmt::Debug for ty::ParamConst { } } -impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // FIXME(effects) printing? - write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) - } -} - -impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_ty, self.term) - } -} - -impl<'tcx> fmt::Debug for ty::NormalizesTo<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) - } -} - impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}", self.kind()) @@ -435,7 +410,7 @@ TrivialTypeTraversalImpls! { crate::ty::BoundRegionKind, crate::ty::AssocItem, crate::ty::AssocKind, - crate::ty::AliasKind, + crate::ty::AliasTyKind, crate::ty::Placeholder, crate::ty::Placeholder, crate::ty::Placeholder, diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index a97244dda9a8..163016332475 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1105,14 +1105,14 @@ where } } -/// Represents the projection of an associated type. +/// Represents the unprojected term of a projection goal. /// /// * For a projection, this would be `>::N<...>`. /// * For an inherent projection, this would be `Ty::N<...>`. /// * For an opaque type, there is no explicit syntax. #[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] -pub struct AliasTy<'tcx> { +pub struct AliasTerm<'tcx> { /// The parameters of the associated or opaque item. /// /// For a projection, these are the generic parameters for the trait and the @@ -1137,7 +1137,232 @@ pub struct AliasTy<'tcx> { /// aka. `tcx.parent(def_id)`. pub def_id: DefId, - /// This field exists to prevent the creation of `AliasTy` without using + /// This field exists to prevent the creation of `AliasTerm` without using + /// [AliasTerm::new]. + _use_alias_term_new_instead: (), +} + +// FIXME: Remove these when we uplift `AliasTerm` +use crate::ty::{DebugWithInfcx, InferCtxtLike, WithInfcx}; +impl<'tcx> std::fmt::Debug for AliasTerm<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + WithInfcx::with_no_infcx(self).fmt(f) + } +} +impl<'tcx> DebugWithInfcx> for AliasTerm<'tcx> { + fn fmt>>( + this: WithInfcx<'_, Infcx, &Self>, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result { + f.debug_struct("AliasTerm") + .field("args", &this.map(|data| data.args)) + .field("def_id", &this.data.def_id) + .finish() + } +} + +impl<'tcx> rustc_type_ir::inherent::AliasTerm> for AliasTerm<'tcx> { + fn new( + interner: TyCtxt<'tcx>, + trait_def_id: DefId, + args: impl IntoIterator>>, + ) -> Self { + AliasTerm::new(interner, trait_def_id, args) + } + + fn def_id(self) -> DefId { + self.def_id + } + + fn args(self) -> ty::GenericArgsRef<'tcx> { + self.args + } + + fn trait_def_id(self, interner: TyCtxt<'tcx>) -> DefId { + self.trait_def_id(interner) + } + + fn self_ty(self) -> Ty<'tcx> { + self.self_ty() + } + + fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + self.with_self_ty(tcx, self_ty) + } +} + +impl<'tcx> AliasTerm<'tcx> { + pub fn new( + tcx: TyCtxt<'tcx>, + def_id: DefId, + args: impl IntoIterator>>, + ) -> AliasTerm<'tcx> { + let args = tcx.check_and_mk_args(def_id, args); + AliasTerm { def_id, args, _use_alias_term_new_instead: () } + } + + pub fn expect_ty(self, tcx: TyCtxt<'tcx>) -> AliasTy<'tcx> { + match self.kind(tcx) { + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::WeakTy => {} + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { + bug!("Cannot turn `UnevaluatedConst` into `AliasTy`") + } + } + ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () } + } + + pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTermKind { + match tcx.def_kind(self.def_id) { + DefKind::AssocTy => { + if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) { + ty::AliasTermKind::InherentTy + } else { + ty::AliasTermKind::ProjectionTy + } + } + DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy, + DefKind::TyAlias => ty::AliasTermKind::WeakTy, + DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst, + DefKind::AssocConst => ty::AliasTermKind::ProjectionConst, + kind => bug!("unexpected DefKind in AliasTy: {kind:?}"), + } + } +} + +/// The following methods work only with (trait) associated item projections. +impl<'tcx> AliasTerm<'tcx> { + pub fn self_ty(self) -> Ty<'tcx> { + self.args.type_at(0) + } + + pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + AliasTerm::new( + tcx, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.iter().skip(1)), + ) + } + + pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { + match tcx.def_kind(self.def_id) { + DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), + kind => bug!("expected a projection AliasTy; found {kind:?}"), + } + } + + /// Extracts the underlying trait reference from this projection. + /// For example, if this is a projection of `::Item`, + /// then this function would return a `T: Iterator` trait reference. + /// + /// NOTE: This will drop the args for generic associated types + /// consider calling [Self::trait_ref_and_own_args] to get those + /// as well. + pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { + let def_id = self.trait_def_id(tcx); + ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id))) + } + + /// Extracts the underlying trait reference and own args from this projection. + /// For example, if this is a projection of `::Item<'a>`, + /// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args + pub fn trait_ref_and_own_args( + self, + tcx: TyCtxt<'tcx>, + ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { + let trait_def_id = self.trait_def_id(tcx); + let trait_generics = tcx.generics_of(trait_def_id); + ( + ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)), + &self.args[trait_generics.count()..], + ) + } + + pub fn to_term(self, tcx: TyCtxt<'tcx>) -> ty::Term<'tcx> { + match self.kind(tcx) { + ty::AliasTermKind::ProjectionTy => Ty::new_alias( + tcx, + ty::Projection, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::InherentTy => Ty::new_alias( + tcx, + ty::Inherent, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::OpaqueTy => Ty::new_alias( + tcx, + ty::Opaque, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::WeakTy => Ty::new_alias( + tcx, + ty::Weak, + AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }, + ) + .into(), + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => { + ty::Const::new_unevaluated( + tcx, + ty::UnevaluatedConst::new(self.def_id, self.args), + tcx.type_of(self.def_id).instantiate(tcx, self.args), + ) + .into() + } + } + } +} + +impl<'tcx> From> for AliasTerm<'tcx> { + fn from(ty: AliasTy<'tcx>) -> Self { + AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () } + } +} + +impl<'tcx> From> for AliasTerm<'tcx> { + fn from(ct: ty::UnevaluatedConst<'tcx>) -> Self { + AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () } + } +} + +/// Represents the projection of an associated, opaque, or lazy-type-alias type. +/// +/// * For a projection, this would be `>::N<...>`. +/// * For an inherent projection, this would be `Ty::N<...>`. +/// * For an opaque type, there is no explicit syntax. +#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] +pub struct AliasTy<'tcx> { + /// The parameters of the associated or opaque type. + /// + /// For a projection, these are the generic parameters for the trait and the + /// GAT parameters, if there are any. + /// + /// For an inherent projection, they consist of the self type and the GAT parameters, + /// if there are any. + /// + /// For RPIT the generic parameters are for the generics of the function, + /// while for TAIT it is used for the generic parameters of the alias. + pub args: GenericArgsRef<'tcx>, + + /// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether + /// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if + /// this is an opaque. + /// + /// During codegen, `tcx.type_of(def_id)` can be used to get the type of the + /// underlying type if the type is an opaque. + /// + /// Note that if this is an associated type, this is not the `DefId` of the + /// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`, + /// aka. `tcx.parent(def_id)`. + pub def_id: DefId, + + /// This field exists to prevent the creation of `AliasT` without using /// [AliasTy::new]. _use_alias_ty_new_instead: (), } @@ -1152,7 +1377,7 @@ impl<'tcx> AliasTy<'tcx> { ty::AliasTy { def_id, args, _use_alias_ty_new_instead: () } } - pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind { + pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTyKind { match tcx.def_kind(self.def_id) { DefKind::AssocTy if let DefKind::Impl { of_trait: false } = @@ -1169,24 +1394,7 @@ impl<'tcx> AliasTy<'tcx> { /// Whether this alias type is an opaque. pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool { - matches!(self.opt_kind(tcx), Some(ty::Opaque)) - } - - /// FIXME: rename `AliasTy` to `AliasTerm` and always handle - /// constants. This function can then be removed. - pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option { - match tcx.def_kind(self.def_id) { - DefKind::AssocTy - if let DefKind::Impl { of_trait: false } = - tcx.def_kind(tcx.parent(self.def_id)) => - { - Some(ty::Inherent) - } - DefKind::AssocTy => Some(ty::Projection), - DefKind::OpaqueTy => Some(ty::Opaque), - DefKind::TyAlias => Some(ty::Weak), - _ => None, - } + matches!(self.kind(tcx), ty::Opaque) } pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { @@ -1194,7 +1402,7 @@ impl<'tcx> AliasTy<'tcx> { } } -/// The following methods work only with associated type projections. +/// The following methods work only with (trait) associated type projections. impl<'tcx> AliasTy<'tcx> { pub fn self_ty(self) -> Ty<'tcx> { self.args.type_at(0) @@ -1203,10 +1411,7 @@ impl<'tcx> AliasTy<'tcx> { pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { AliasTy::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1))) } -} -/// The following methods work only with trait associated type projections. -impl<'tcx> AliasTy<'tcx> { pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId { match tcx.def_kind(self.def_id) { DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id), @@ -1221,7 +1426,6 @@ impl<'tcx> AliasTy<'tcx> { self, tcx: TyCtxt<'tcx>, ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { - debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst)); let trait_def_id = self.trait_def_id(tcx); let trait_generics = tcx.generics_of(trait_def_id); ( @@ -1511,7 +1715,7 @@ impl<'tcx> Ty<'tcx> { #[inline] pub fn new_alias( tcx: TyCtxt<'tcx>, - kind: ty::AliasKind, + kind: ty::AliasTyKind, alias_ty: ty::AliasTy<'tcx>, ) -> Ty<'tcx> { debug_assert_matches!( diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 41f417dfd4b1..24e3e623ff27 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -79,6 +79,10 @@ pub struct TypeckResults<'tcx> { /// Stores the actual binding mode for all instances of [`BindingMode`]. pat_binding_modes: ItemLocalMap, + /// Top-level patterns whose match ergonomics need to be desugared + /// by the Rust 2021 -> 2024 migration lint. + rust_2024_migration_desugared_pats: ItemLocalSet, + /// Stores the types which were implicitly dereferenced in pattern binding modes /// for later usage in THIR lowering. For example, /// @@ -229,6 +233,7 @@ impl<'tcx> TypeckResults<'tcx> { adjustments: Default::default(), pat_binding_modes: Default::default(), pat_adjustments: Default::default(), + rust_2024_migration_desugared_pats: Default::default(), skipped_ref_pats: Default::default(), closure_kind_origins: Default::default(), liberated_fn_sigs: Default::default(), @@ -432,6 +437,20 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } + pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> { + LocalSetInContext { + hir_owner: self.hir_owner, + data: &self.rust_2024_migration_desugared_pats, + } + } + + pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> { + LocalSetInContextMut { + hir_owner: self.hir_owner, + data: &mut self.rust_2024_migration_desugared_pats, + } + } + pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> { LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 6ad4f492f742..04ce3de88744 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1086,7 +1086,7 @@ impl<'tcx> TypeFolder> for OpaqueTypeExpander<'tcx> { { p.kind() .rebind(ty::ProjectionPredicate { - projection_ty: projection_pred.projection_ty.fold_with(self), + projection_term: projection_pred.projection_term.fold_with(self), // Don't fold the term on the RHS of the projection predicate. // This is because for default trait methods with RPITITs, we // install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))` diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 6618e4f5a002..77f27236437d 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -16,6 +16,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } +rustc_lint = { path = "../rustc_lint" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 34440c60cf37..0bb44dbb8706 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -267,6 +267,8 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future +mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024 + mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly .attributes = no other attributes may be applied .not_box = `#[rustc_box]` may only be applied to a `Box::new()` call diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 00e99f330f72..6ae98e15946d 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,6 +1,7 @@ use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; +use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::{mir::*, ty}; use rustc_span::Span; diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index 566dba460d43..9cfb25e663d1 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -1,5 +1,6 @@ use std::collections::VecDeque; +use rustc_middle::bug; use rustc_middle::mir::coverage::{ BlockMarkerId, ConditionId, ConditionInfo, MCDCBranchSpan, MCDCDecisionSpan, }; diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 30877e38318d..a0a512a2effc 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -24,6 +24,7 @@ use rustc_hir::HirId; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::{ mir::*, + span_bug, thir::*, ty::{ParamEnv, Ty, TyCtxt}, }; 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 a557f61b016b..817f5f787b1b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -9,6 +9,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, TyCtxt, UserTypeAnnotationIndex, }; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { 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 060b328ef48a..9963629fc52f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -4,6 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; 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 260ab058e600..0b2248d049af 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -9,6 +9,7 @@ use crate::build::expr::as_place::PlaceBase; use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; use rustc_hir::lang_items::LangItem; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index c8360b6a5fdd..f8c910730456 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -7,6 +7,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::thir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_span::source_map::Spanned; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7cf4fac731b4..3fc719394bf9 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -12,6 +12,7 @@ use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::build::{GuardFrame, GuardFrameLocal, LocalsForNode}; use rustc_data_structures::{fx::FxIndexMap, stack::ensure_sufficient_stack}; use rustc_hir::{BindingMode, ByRef}; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::mir::{self, *}; use rustc_middle::thir::{self, *}; diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 7f65697fa4b2..f3faeb4158ee 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -13,6 +13,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 794e7ebb7b43..92cd7f75d628 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -20,6 +20,7 @@ use rustc_middle::mir::*; use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::{self, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::Symbol; diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 2d31e84aba7d..be32363fec52 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -90,6 +90,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{ExprId, LintLevel}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::Level; use rustc_span::source_map::Spanned; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 227d19c3e43c..b9990d65ec77 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -4,6 +4,7 @@ use crate::errors::*; use rustc_errors::DiagArgValue; use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability}; use rustc_middle::mir::BorrowKind; +use rustc_middle::span_bug; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index f67113afd6d9..e2a28467b845 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -950,3 +950,30 @@ pub enum RustcBoxAttrReason { #[note(mir_build_missing_box)] MissingBox, } + +#[derive(LintDiagnostic)] +#[diag(mir_build_rust_2024_incompatible_pat)] +pub struct Rust2024IncompatiblePat { + #[subdiagnostic] + pub sugg: Rust2024IncompatiblePatSugg, +} + +pub struct Rust2024IncompatiblePatSugg { + pub suggestion: Vec<(Span, String)>, +} + +impl Subdiagnostic for Rust2024IncompatiblePatSugg { + fn add_to_diag_with>( + self, + diag: &mut Diag<'_, G>, + _f: &F, + ) { + let applicability = + if self.suggestion.iter().all(|(span, _)| span.can_be_used_for_suggestions()) { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + diag.multipart_suggestion("desugar the match ergonomics", self.suggestion, applicability); + } +} diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index e79e3b887fb4..2e1cb0e1b5e0 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -12,8 +12,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; mod build; mod check_unsafety; diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 65cc13286afc..03c7c1fd6ec6 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -1,4 +1,5 @@ use rustc_ast as ast; +use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt}; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c697e16217bd..b77666669605 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -21,6 +21,7 @@ use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{ self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType, }; +use rustc_middle::{bug, span_bug}; use rustc_span::source_map::Spanned; use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 79738b540354..d1d21f88aef6 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::HirId; use rustc_hir::Node; +use rustc_middle::bug; use rustc_middle::middle::region; use rustc_middle::thir::*; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; 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 25ab90467061..592f0dcf4ef5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1,9 +1,3 @@ -use rustc_pattern_analysis::errors::Uncovered; -use rustc_pattern_analysis::rustc::{ - Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport, - WitnessPat, -}; - use crate::errors::*; use rustc_arena::{DroplessArena, TypedArena}; @@ -14,11 +8,17 @@ use rustc_errors::{codes::*, struct_span_code_err, Applicability, ErrorGuarantee use rustc_hir::def::*; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, BindingMode, ByRef, HirId}; +use rustc_middle::bug; use rustc_middle::middle::limits::get_limit_size; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; +use rustc_pattern_analysis::errors::Uncovered; +use rustc_pattern_analysis::rustc::{ + Constructor, DeconstructedPat, MatchArm, RustcPatCtxt as PatCtxt, Usefulness, UsefulnessReport, + WitnessPat, +}; use rustc_session::lint::builtin::{ BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS, }; 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 65c53be8ddd9..c6f81c3cb997 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 @@ -4,6 +4,7 @@ use rustc_index::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::mir; +use rustc_middle::span_bug; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, ValTree}; use rustc_session::lint; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 5c016682d8d2..dc845b3d4acc 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -11,8 +11,9 @@ use crate::thir::util::UserAnnotatedTyHelpers; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::{self as hir, RangeEnd}; +use rustc_hir::{self as hir, ByRef, Mutability, RangeEnd}; use rustc_index::Idx; +use rustc_lint as lint; use rustc_middle::mir::interpret::{ErrorHandled, GlobalId, LitToConstError, LitToConstInput}; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{ @@ -20,6 +21,7 @@ use rustc_middle::thir::{ }; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; use rustc_target::abi::{FieldIdx, Integer}; @@ -30,6 +32,9 @@ struct PatCtxt<'a, 'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, typeck_results: &'a ty::TypeckResults<'tcx>, + + /// Used by the Rust 2024 migration lint. + rust_2024_migration_suggestion: Option, } pub(super) fn pat_from_hir<'a, 'tcx>( @@ -38,9 +43,25 @@ pub(super) fn pat_from_hir<'a, 'tcx>( typeck_results: &'a ty::TypeckResults<'tcx>, pat: &'tcx hir::Pat<'tcx>, ) -> Box> { - let mut pcx = PatCtxt { tcx, param_env, typeck_results }; + let mut pcx = PatCtxt { + tcx, + param_env, + typeck_results, + rust_2024_migration_suggestion: typeck_results + .rust_2024_migration_desugared_pats() + .contains(pat.hir_id) + .then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }), + }; let result = pcx.lower_pattern(pat); debug!("pat_from_hir({:?}) = {:?}", pat, result); + if let Some(sugg) = pcx.rust_2024_migration_suggestion { + tcx.emit_node_span_lint( + lint::builtin::RUST_2024_INCOMPATIBLE_PAT, + pat.hir_id, + pat.span, + Rust2024IncompatiblePat { sugg }, + ); + } result } @@ -73,17 +94,38 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } _ => self.lower_pattern_unadjusted(pat), }; - self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold( - unadjusted_pat, - |pat: Box<_>, ref_ty| { - debug!("{:?}: wrapping pattern with type {:?}", pat, ref_ty); - Box::new(Pat { - span: pat.span, - ty: *ref_ty, - kind: PatKind::Deref { subpattern: pat }, + + let adjustments: &[Ty<'tcx>] = + self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(&[], |v| &**v); + let adjusted_pat = adjustments.iter().rev().fold(unadjusted_pat, |thir_pat, ref_ty| { + debug!("{:?}: wrapping pattern with type {:?}", thir_pat, ref_ty); + Box::new(Pat { + span: thir_pat.span, + ty: *ref_ty, + kind: PatKind::Deref { subpattern: thir_pat }, + }) + }); + + if let Some(s) = &mut self.rust_2024_migration_suggestion + && !adjustments.is_empty() + { + let suggestion_str: String = adjustments + .iter() + .map(|ref_ty| { + let &ty::Ref(_, _, mutbl) = ref_ty.kind() else { + span_bug!(pat.span, "pattern implicitly dereferences a non-ref type"); + }; + + match mutbl { + ty::Mutability::Not => "&", + ty::Mutability::Mut => "&mut ", + } }) - }, - ) + .collect(); + s.suggestion.push((pat.span.shrink_to_lo(), suggestion_str)); + }; + + adjusted_pat } fn lower_pattern_range_endpoint( @@ -272,7 +314,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Deref { subpattern: self.lower_pattern(subpattern) } } - hir::PatKind::Slice(prefix, ref slice, suffix) => { + hir::PatKind::Slice(prefix, slice, suffix) => { self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) } @@ -284,7 +326,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::Leaf { subpatterns } } - hir::PatKind::Binding(_, id, ident, ref sub) => { + hir::PatKind::Binding(explicit_ba, id, ident, sub) => { if let Some(ident_span) = ident.span.find_ancestor_inside(span) { span = span.with_hi(ident_span.hi()); } @@ -295,6 +337,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { .get(pat.hir_id) .expect("missing binding mode"); + if let Some(s) = &mut self.rust_2024_migration_suggestion + && explicit_ba.0 == ByRef::No + && let ByRef::Yes(mutbl) = mode.0 + { + let sugg_str = match mutbl { + Mutability::Not => "ref ", + Mutability::Mut => "ref mut ", + }; + s.suggestion.push(( + pat.span.with_lo(ident.span.lo()).shrink_to_lo(), + sugg_str.to_owned(), + )) + } + // A ref x pattern is the same node used for x, and as such it has // x's type, which is &T, where we want T (the type being matched). let var_ty = ty; @@ -366,10 +422,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pats.iter().map(|p| self.lower_pattern(p)).collect() } - fn lower_opt_pattern( - &mut self, - pat: &'tcx Option<&'tcx hir::Pat<'tcx>>, - ) -> Option>> { + fn lower_opt_pattern(&mut self, pat: Option<&'tcx hir::Pat<'tcx>>) -> Option>> { pat.map(|p| self.lower_pattern(p)) } @@ -378,7 +431,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span: Span, ty: Ty<'tcx>, prefix: &'tcx [hir::Pat<'tcx>], - slice: &'tcx Option<&'tcx hir::Pat<'tcx>>, + slice: Option<&'tcx hir::Pat<'tcx>>, suffix: &'tcx [hir::Pat<'tcx>], ) -> PatKind<'tcx> { let prefix = self.lower_patterns(prefix); diff --git a/compiler/rustc_mir_build/src/thir/util.rs b/compiler/rustc_mir_build/src/thir/util.rs index 52c9cf14ac87..340eb3c2eea0 100644 --- a/compiler/rustc_mir_build/src/thir/util.rs +++ b/compiler/rustc_mir_build/src/thir/util.rs @@ -1,4 +1,5 @@ use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, CanonicalUserType, TyCtxt, UserType}; pub(crate) trait UserAnnotatedTyHelpers<'tcx> { diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index ba70a4453d65..d43fca3dc7ef 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -1,5 +1,6 @@ use rustc_ast::InlineAsmOptions; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::layout; use rustc_middle::ty::{self, TyCtxt}; use rustc_target::spec::abi::Abi; diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index a405ed6088d8..5f67bd75c48a 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -1,5 +1,6 @@ use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{self, TyCtxt}; use crate::MirLint; diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 3008016863e4..a3e6e5a5a915 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -70,6 +70,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::CoroutineArgs; use rustc_middle::ty::InstanceDef; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, }; diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 3d6c1a952041..10c0567eb4b7 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -71,6 +71,7 @@ use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::hir::place::{Projection, ProjectionKind}; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir, MirPass}; diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 6e73a476421f..b98554ec00fa 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -4,6 +4,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::DirectedGraph; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op}; use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops}; diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 1895735ab352..fd74a2a97e2c 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -4,6 +4,7 @@ use rustc_data_structures::graph::dominators::{self, Dominators}; use rustc_data_structures::graph::{self, DirectedGraph, StartNode}; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::{self, BasicBlock, Terminator, TerminatorKind}; use std::cmp::Ordering; diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index a0570c45f963..f2f76ac70c20 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::mir; use rustc_span::{BytePos, Span}; diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 4ce37b5defce..d1727a94a35e 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -1,5 +1,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::{ self, AggregateKind, FakeReadCause, Rvalue, Statement, StatementKind, Terminator, diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index cf1a2b399f95..ca64688e6b87 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -30,6 +30,7 @@ use super::graph::{self, BasicCoverageBlock}; use itertools::Itertools; use rustc_data_structures::graph::{DirectedGraph, Successors}; use rustc_index::{Idx, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty; use rustc_span::{BytePos, Pos, Span, DUMMY_SP}; diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 3019b275fb26..a42d64f86be1 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -6,6 +6,7 @@ use rustc_const_eval::const_eval::{throw_machine_stop_str, DummyMachine}; use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, PlaceTy, Projectable}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::DefKind; +use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index e6317e5469ce..08dba1de500c 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -13,6 +13,7 @@ //! use crate::util::is_within_packed; +use rustc_middle::bug; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 10fea09531a6..1bc383fccc72 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -135,6 +135,7 @@ use crate::MirPass; use rustc_data_structures::fx::{FxIndexMap, IndexEntry, IndexOccupiedEntry}; use rustc_index::bit_set::BitSet; use rustc_index::interval::SparseIntervalMatrix; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::HasLocalDecls; use rustc_middle::mir::{dump_mir, PassWhere}; diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 318674f24e7a..d955b96d06af 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -6,6 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; +use rustc_middle::span_bug; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_target::abi::FieldIdx; diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 0970c4de19fd..5e3cd8536750 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -4,6 +4,7 @@ use rustc_middle::query::LocalCrate; use rustc_middle::query::Providers; use rustc_middle::ty::layout; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::lint::builtin::FFI_UNWIND_CALLS; use rustc_target::spec::abi::Abi; use rustc_target::spec::PanicStrategy; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 342d1a1cd5bb..123166a764d8 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -91,6 +91,7 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; use rustc_index::newtype_index; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 7a3b08f82f61..401056cd4960 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -6,6 +6,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index fd768cc96ae3..f1adeab3f884 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -2,6 +2,7 @@ use crate::simplify::simplify_duplicate_switch_targets; use rustc_ast::attr; +use rustc_middle::bug; use rustc_middle::mir::*; use rustc_middle::ty::layout; use rustc_middle::ty::layout::ValidityRequirement; diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index a458297210db..ae807655b68d 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -41,6 +41,7 @@ use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable} use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 90c1c7ba63b4..d0a5a6cada8f 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -14,6 +14,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_hir::HirId; use rustc_index::{bit_set::BitSet, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e69c5da757ed..9af48f0bad25 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -16,8 +16,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; use hir::ConstContext; use required_consts::RequiredConstsVisitor; @@ -38,6 +36,7 @@ use rustc_middle::mir::{ use rustc_middle::query; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::util::Providers; +use rustc_middle::{bug, span_bug}; use rustc_span::{source_map::Spanned, sym, DUMMY_SP}; use rustc_trait_selection::traits; diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index da63fcf23d9e..43d8c45bb2dd 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -2,6 +2,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; pub struct LowerIntrinsics; diff --git a/compiler/rustc_mir_transform/src/nrvo.rs b/compiler/rustc_mir_transform/src/nrvo.rs index 232c290e0fb2..885dbd5f3393 100644 --- a/compiler/rustc_mir_transform/src/nrvo.rs +++ b/compiler/rustc_mir_transform/src/nrvo.rs @@ -2,6 +2,7 @@ use rustc_hir::Mutability; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, BasicBlock, Local, Location}; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 689a547689a2..b3116c002d3c 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -20,6 +20,7 @@ use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Vis use rustc_middle::mir::*; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, List, Ty, TyCtxt, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use rustc_index::{Idx, IndexSlice, IndexVec}; diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs index 044ae32c1d40..801ef14c9cd9 100644 --- a/compiler/rustc_mir_transform/src/ref_prop.rs +++ b/compiler/rustc_mir_transform/src/ref_prop.rs @@ -1,6 +1,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; +use rustc_middle::bug; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 1c85a604053c..cd8a43d6e6c2 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -5,6 +5,7 @@ use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_index::{Idx, IndexVec}; diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index 80eadb9abdcf..f4481c22fc1f 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -14,6 +14,7 @@ use rustc_middle::mir::{ use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::Discr; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::source_map::respan; use rustc_span::{Span, Symbol}; use rustc_target::abi::{FieldIdx, VariantIdx}; @@ -534,8 +535,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { } // If projection of Discriminant then compare with `Ty::discriminant_ty` - if let ty::Alias(ty::AliasKind::Projection, ty::AliasTy { args, def_id, .. }) = - expected_ty.kind() + if let ty::Alias(ty::Projection, ty::AliasTy { args, def_id, .. }) = expected_ty.kind() && Some(*def_id) == self.tcx.lang_items().discriminant_type() && args.first().unwrap().as_type().unwrap().discriminant_ty(self.tcx) == operand_ty { diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 1a8cfc411784..03907babf2b0 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -2,6 +2,7 @@ use std::iter; use super::MirPass; use rustc_middle::{ + bug, mir::{ interpret::Scalar, BasicBlock, BinOp, Body, Operand, Place, Rvalue, Statement, StatementKind, SwitchTargets, TerminatorKind, diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 06d5e17fdd6c..cdf3305b5609 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -1,6 +1,7 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_index::bit_set::{BitSet, GrowableBitSet}; use rustc_index::IndexVec; +use rustc_middle::bug; 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 55fed7d9da28..fb870425f6ef 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -9,6 +9,7 @@ use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; +use rustc_middle::bug; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs index 66b6235eb938..1404a45f4d2d 100644 --- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs @@ -2,6 +2,7 @@ use crate::MirPass; use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::{ BasicBlock, BasicBlockData, BasicBlocks, Body, Local, Operand, Rvalue, StatementKind, diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs index 8ad7bc394c5a..a6c3c3b189ed 100644 --- a/compiler/rustc_mir_transform/src/unreachable_prop.rs +++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs @@ -3,6 +3,7 @@ //! post-order traversal of the blocks. use rustc_data_structures::fx::FxHashSet; +use rustc_middle::bug; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::*; diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 2f68a299f26b..3f08a830b0c9 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -83,7 +83,7 @@ pub(crate) struct IncorrectSemicolon<'a> { #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, #[help] - pub opt_help: Option<()>, + pub show_help: bool, pub name: &'a str, } diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index b5a5a2a90ee1..eabe0226b2fb 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -241,7 +241,7 @@ impl<'psess, 'src> TokenTreesReader<'psess, 'src> { // we have no way of tracking this in the lexer itself, so we piggyback on the parser let mut in_cond = false; while parser.token != token::Eof { - if let Err(diff_err) = parser.err_diff_marker() { + if let Err(diff_err) = parser.err_vcs_conflict_marker() { diff_errs.push(diff_err); } else if parser.is_keyword_ahead(0, &[kw::If, kw::While]) { in_cond = true; diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index d5d8060d909a..a57eb70c7053 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -363,7 +363,7 @@ impl<'a> Parser<'a> { // We can't use `maybe_whole` here because it would bump in the `None` // case, which we don't want. if let token::Interpolated(nt) = &self.token.kind - && let token::NtMeta(attr_item) = &nt.0 + && let token::NtMeta(attr_item) = &**nt { match attr_item.meta(attr_item.path.span) { Some(meta) => { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 50698dbf9c17..ac12787f2ef0 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1817,34 +1817,31 @@ impl<'a> Parser<'a> { Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path))) } - pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { - if self.token.kind == TokenKind::Semi { - self.bump(); + /// This function gets called in places where a semicolon is NOT expected and if there's a + /// semicolon it emits the appropriate error and returns true. + pub fn maybe_consume_incorrect_semicolon(&mut self, previous_item: Option<&Item>) -> bool { + if self.token.kind != TokenKind::Semi { + return false; + } - let mut err = - IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" }; - - if !items.is_empty() { - let previous_item = &items[items.len() - 1]; - let previous_item_kind_name = match previous_item.kind { + // Check previous item to add it to the diagnostic, for example to say + // `enum declarations are not followed by a semicolon` + let err = match previous_item { + Some(previous_item) => { + let name = match previous_item.kind { // Say "braced struct" because tuple-structs and // braceless-empty-struct declarations do take a semicolon. - ItemKind::Struct(..) => Some("braced struct"), - ItemKind::Enum(..) => Some("enum"), - ItemKind::Trait(..) => Some("trait"), - ItemKind::Union(..) => Some("union"), - _ => None, + ItemKind::Struct(..) => "braced struct", + _ => previous_item.kind.descr(), }; - if let Some(name) = previous_item_kind_name { - err.opt_help = Some(()); - err.name = name; - } + IncorrectSemicolon { span: self.token.span, name, show_help: true } } - self.dcx().emit_err(err); - true - } else { - false - } + None => IncorrectSemicolon { span: self.token.span, name: "", show_help: false }, + }; + self.dcx().emit_err(err); + + self.bump(); + true } /// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a @@ -2372,9 +2369,9 @@ impl<'a> Parser<'a> { // in a subsequent macro invocation (#71039). let mut tok = self.token.clone(); let mut labels = vec![]; - while let TokenKind::Interpolated(node) = &tok.kind { - let tokens = node.0.tokens(); - labels.push(node.clone()); + while let TokenKind::Interpolated(nt) = &tok.kind { + let tokens = nt.tokens(); + labels.push(nt.clone()); if let Some(tokens) = tokens && let tokens = tokens.to_attr_token_stream() && let tokens = tokens.0.deref() @@ -2387,27 +2384,20 @@ impl<'a> Parser<'a> { } let mut iter = labels.into_iter().peekable(); let mut show_link = false; - while let Some(node) = iter.next() { - let descr = node.0.descr(); + while let Some(nt) = iter.next() { + let descr = nt.descr(); if let Some(next) = iter.peek() { - let next_descr = next.0.descr(); + let next_descr = next.descr(); if next_descr != descr { - err.span_label(next.1, format!("this macro fragment matcher is {next_descr}")); - err.span_label(node.1, format!("this macro fragment matcher is {descr}")); + err.span_label(next.use_span(), format!("this is expected to be {next_descr}")); err.span_label( - next.0.use_span(), - format!("this is expected to be {next_descr}"), - ); - err.span_label( - node.0.use_span(), + nt.use_span(), format!( "this is interpreted as {}, but it is expected to be {}", next_descr, descr, ), ); show_link = true; - } else { - err.span_label(node.1, ""); } } } @@ -2964,13 +2954,23 @@ impl<'a> Parser<'a> { err } - pub fn is_diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> bool { + /// This checks if this is a conflict marker, depending of the parameter passed. + /// + /// * `>>>>>` + /// * `=====` + /// * `<<<<<` + /// + pub fn is_vcs_conflict_marker( + &mut self, + long_kind: &TokenKind, + short_kind: &TokenKind, + ) -> bool { (0..3).all(|i| self.look_ahead(i, |tok| tok == long_kind)) && self.look_ahead(3, |tok| tok == short_kind) } - fn diff_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> Option { - if self.is_diff_marker(long_kind, short_kind) { + fn conflict_marker(&mut self, long_kind: &TokenKind, short_kind: &TokenKind) -> Option { + if self.is_vcs_conflict_marker(long_kind, short_kind) { let lo = self.token.span; for _ in 0..4 { self.bump(); @@ -2980,15 +2980,16 @@ impl<'a> Parser<'a> { None } - pub fn recover_diff_marker(&mut self) { - if let Err(err) = self.err_diff_marker() { + pub fn recover_vcs_conflict_marker(&mut self) { + if let Err(err) = self.err_vcs_conflict_marker() { err.emit(); FatalError.raise(); } } - pub fn err_diff_marker(&mut self) -> PResult<'a, ()> { - let Some(start) = self.diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) else { + pub fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { + let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) + else { return Ok(()); }; let mut spans = Vec::with_capacity(3); @@ -3000,13 +3001,15 @@ impl<'a> Parser<'a> { if self.token.kind == TokenKind::Eof { break; } - if let Some(span) = self.diff_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or)) { + if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or)) + { middlediff3 = Some(span); } - if let Some(span) = self.diff_marker(&TokenKind::EqEq, &TokenKind::Eq) { + if let Some(span) = self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq) { middle = Some(span); } - if let Some(span) = self.diff_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt) { + if let Some(span) = self.conflict_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt) + { spans.push(span); end = Some(span); break; diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 577003e94fb2..d2d21624150b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -45,7 +45,7 @@ use thin_vec::{thin_vec, ThinVec}; macro_rules! maybe_whole_expr { ($p:expr) => { if let token::Interpolated(nt) = &$p.token.kind { - match &nt.0 { + match &**nt { token::NtExpr(e) | token::NtLiteral(e) => { let e = e.clone(); $p.bump(); @@ -497,8 +497,7 @@ impl<'a> Parser<'a> { /// Checks if this expression is a successfully parsed statement. fn expr_is_complete(&self, e: &Expr) -> bool { - self.restrictions.contains(Restrictions::STMT_EXPR) - && !classify::expr_requires_semi_to_be_stmt(e) + self.restrictions.contains(Restrictions::STMT_EXPR) && classify::expr_is_complete(e) } /// Parses `x..y`, `x..=y`, and `x..`/`x..=`. @@ -725,7 +724,9 @@ impl<'a> Parser<'a> { /// Returns the span of expr if it was not interpolated, or the span of the interpolated token. fn interpolated_or_expr_span(&self, expr: &Expr) -> Span { match self.prev_token.kind { - TokenKind::Interpolated(..) => self.prev_token.span, + TokenKind::NtIdent(..) | TokenKind::NtLifetime(..) | TokenKind::Interpolated(..) => { + self.prev_token.span + } _ => expr.span, } } @@ -2691,8 +2692,33 @@ impl<'a> Parser<'a> { let first_tok_span = self.token.span; match self.parse_expr() { Ok(cond) - // If it's not a free-standing expression, and is followed by a block, - // then it's very likely the condition to an `else if`. + // Try to guess the difference between a "condition-like" vs + // "statement-like" expression. + // + // We are seeing the following code, in which $cond is neither + // ExprKind::Block nor ExprKind::If (the 2 cases wherein this + // would be valid syntax). + // + // if ... { + // } else $cond + // + // If $cond is "condition-like" such as ExprKind::Binary, we + // want to suggest inserting `if`. + // + // if ... { + // } else if a == b { + // ^^ + // } + // + // If $cond is "statement-like" such as ExprKind::While then we + // want to suggest wrapping in braces. + // + // if ... { + // } else { + // ^ + // while true {} + // } + // ^ if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) && classify::expr_requires_semi_to_be_stmt(&cond) => { @@ -3136,7 +3162,7 @@ impl<'a> Parser<'a> { err })?; - let require_comma = classify::expr_requires_semi_to_be_stmt(&expr) + let require_comma = !classify::expr_is_complete(&expr) && this.token != token::CloseDelim(Delimiter::Brace); if !require_comma { @@ -3708,7 +3734,7 @@ impl<'a> Parser<'a> { /// Parses `ident (COLON expr)?`. fn parse_expr_field(&mut self) -> PResult<'a, ExprField> { let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index df6996dbc458..34cdf8a9b5f8 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -49,6 +49,7 @@ impl<'a> Parser<'a> { } /// Parses the contents of a module (inner attributes followed by module items). + /// We exit once we hit `term` pub fn parse_mod( &mut self, term: &TokenKind, @@ -59,13 +60,13 @@ impl<'a> Parser<'a> { let post_attr_lo = self.token.span; let mut items = ThinVec::new(); while let Some(item) = self.parse_item(ForceCollect::No)? { + self.maybe_consume_incorrect_semicolon(Some(&item)); items.push(item); - self.maybe_consume_incorrect_semicolon(&items); } if !self.eat(term) { let token_str = super::token_descr(&self.token); - if !self.maybe_consume_incorrect_semicolon(&items) { + if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) { let msg = format!("expected item, found {token_str}"); let mut err = self.dcx().struct_span_err(self.token.span, msg); let span = self.token.span; @@ -101,9 +102,9 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, force_collect: ForceCollect, ) -> PResult<'a, Option> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.parse_item_common(attrs, true, false, fn_parse_mode, force_collect) } @@ -194,12 +195,12 @@ impl<'a> Parser<'a> { fn_parse_mode: FnParseMode, case: Case, ) -> PResult<'a, Option> { - let def_final = def == &Defaultness::Final; + let check_pub = def == &Defaultness::Final; let mut def_ = || mem::replace(def, Defaultness::Final); let info = if self.eat_keyword_case(kw::Use, case) { self.parse_use_item()? - } else if self.check_fn_front_matter(def_final, case) { + } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM let (ident, sig, generics, body) = self.parse_fn(attrs, fn_parse_mode, lo, vis, case)?; @@ -310,7 +311,7 @@ impl<'a> Parser<'a> { Ok(Some(info)) } - fn recover_import_as_use(&mut self) -> PResult<'a, Option<(Ident, ItemKind)>> { + fn recover_import_as_use(&mut self) -> PResult<'a, Option> { let span = self.token.span; let token_name = super::token_descr(&self.token); let snapshot = self.create_snapshot_for_diagnostic(); @@ -328,7 +329,7 @@ impl<'a> Parser<'a> { } } - fn parse_use_item(&mut self) -> PResult<'a, (Ident, ItemKind)> { + fn parse_use_item(&mut self) -> PResult<'a, ItemInfo> { let tree = self.parse_use_tree()?; if let Err(mut e) = self.expect_semi() { match tree.kind { @@ -723,7 +724,7 @@ impl<'a> Parser<'a> { if self.recover_doc_comment_before_brace() { continue; } - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); match parse_item(self) { Ok(None) => { let mut is_unnecessary_semicolon = !items.is_empty() @@ -1070,7 +1071,7 @@ impl<'a> Parser<'a> { /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> { self.parse_delim_comma_seq(Delimiter::Brace, |p| { - p.recover_diff_marker(); + p.recover_vcs_conflict_marker(); Ok((p.parse_use_tree()?, DUMMY_NODE_ID)) }) .map(|(r, _)| r) @@ -1497,9 +1498,9 @@ impl<'a> Parser<'a> { } fn parse_enum_variant(&mut self, span: Span) -> PResult<'a, Option> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let variant_attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let help = "enum variants can be `Variant`, `Variant = `, \ `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`"; self.collect_tokens_trailing_token( @@ -1688,6 +1689,10 @@ impl<'a> Parser<'a> { Ok((class_name, ItemKind::Union(vdata, generics))) } + /// This function parses the fields of record structs: + /// + /// - `struct S { ... }` + /// - `enum E { Variant { ... } }` pub(crate) fn parse_record_struct_body( &mut self, adt_ty: &str, @@ -1714,19 +1719,10 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(Delimiter::Brace)); } else { let token_str = super::token_descr(&self.token); - let msg = format!( - "expected {}`{{` after struct name, found {}", - if parsed_where { "" } else { "`where`, or " }, - token_str - ); + let where_str = if parsed_where { "" } else { "`where`, or " }; + let msg = format!("expected {where_str}`{{` after struct name, found {token_str}"); let mut err = self.dcx().struct_span_err(self.token.span, msg); - err.span_label( - self.token.span, - format!( - "expected {}`{{` after struct name", - if parsed_where { "" } else { "`where`, or " } - ), - ); + err.span_label(self.token.span, format!("expected {where_str}`{{` after struct name",)); return Err(err); } @@ -1740,7 +1736,7 @@ impl<'a> Parser<'a> { let attrs = p.parse_outer_attributes()?; p.collect_tokens_trailing_token(attrs, ForceCollect::No, |p, attrs| { let mut snapshot = None; - if p.is_diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if p.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid type start, so we snapshot and reparse only we've // encountered another parse error. @@ -1751,7 +1747,7 @@ impl<'a> Parser<'a> { Ok(vis) => vis, Err(err) => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } return Err(err); } @@ -1760,7 +1756,7 @@ impl<'a> Parser<'a> { Ok(ty) => ty, Err(err) => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } return Err(err); } @@ -1785,9 +1781,9 @@ impl<'a> Parser<'a> { /// Parses an element of a struct declaration. fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> { - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); let attrs = self.parse_outer_attributes()?; - self.recover_diff_marker(); + self.recover_vcs_conflict_marker(); self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { let lo = this.token.span; let vis = this.parse_visibility(FollowedByType::No)?; @@ -2647,7 +2643,7 @@ impl<'a> Parser<'a> { } let (mut params, _) = self.parse_paren_comma_seq(|p| { - p.recover_diff_marker(); + p.recover_vcs_conflict_marker(); let snapshot = p.create_snapshot_for_diagnostic(); let param = p.parse_param_general(req_name, first_param).or_else(|e| { let guar = e.emit(); @@ -2841,7 +2837,7 @@ impl<'a> Parser<'a> { fn is_named_param(&self) -> bool { let offset = match &self.token.kind { - token::Interpolated(nt) => match &nt.0 { + token::Interpolated(nt) => match &**nt { token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), _ => 0, }, diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index bfb6c4a38858..3e0a98a55ae9 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -11,7 +11,6 @@ mod stmt; mod ty; use crate::lexer::UnmatchedDelim; -use ast::token::IdentIsRaw; pub use attr_wrapper::AttrWrapper; pub use diagnostics::AttemptLocalParseRecovery; pub(crate) use expr::ForbiddenLetReason; @@ -21,7 +20,7 @@ pub use path::PathStyle; use core::fmt; use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Token, TokenKind}; +use rustc_ast::token::{self, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{AttributesData, DelimSpacing, DelimSpan, Spacing}; use rustc_ast::tokenstream::{TokenStream, TokenTree, TokenTreeCursor}; use rustc_ast::util::case::Case; @@ -32,6 +31,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diag, FatalError, MultiSpan, PResult}; use rustc_session::parse::ParseSess; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -107,7 +107,7 @@ pub enum TrailingToken { macro_rules! maybe_whole { ($p:expr, $constructor:ident, |$x:ident| $e:expr) => { if let token::Interpolated(nt) = &$p.token.kind - && let token::$constructor(x) = &nt.0 + && let token::$constructor(x) = &**nt { #[allow(unused_mut)] let mut $x = x.clone(); @@ -125,7 +125,7 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { && $self.may_recover() && $self.look_ahead(1, |t| t == &token::PathSep) && let token::Interpolated(nt) = &$self.token.kind - && let token::NtTy(ty) = &nt.0 + && let token::NtTy(ty) = &**nt { let ty = ty.clone(); $self.bump(); @@ -407,7 +407,9 @@ pub(super) fn token_descr(token: &Token) -> String { (Some(TokenDescription::Keyword), _) => Some("keyword"), (Some(TokenDescription::ReservedKeyword), _) => Some("reserved keyword"), (Some(TokenDescription::DocComment), _) => Some("doc comment"), - (None, TokenKind::Interpolated(node)) => Some(node.0.descr()), + (None, TokenKind::NtIdent(..)) => Some("identifier"), + (None, TokenKind::NtLifetime(..)) => Some("lifetime"), + (None, TokenKind::Interpolated(node)) => Some(node.descr()), (None, _) => None, }; @@ -708,7 +710,7 @@ impl<'a> Parser<'a> { fn check_inline_const(&self, dist: usize) -> bool { self.is_keyword_ahead(dist, &[kw::Const]) && self.look_ahead(dist + 1, |t| match &t.kind { - token::Interpolated(nt) => matches!(&nt.0, token::NtBlock(..)), + token::Interpolated(nt) => matches!(&**nt, token::NtBlock(..)), token::OpenDelim(Delimiter::Brace) => true, _ => false, }) @@ -1631,19 +1633,11 @@ pub enum FlatToken { // Metavar captures of various kinds. #[derive(Clone, Debug)] -pub enum ParseNtResult { +pub enum ParseNtResult { Tt(TokenTree), - Nt(NtType), -} + Ident(Ident, IdentIsRaw), + Lifetime(Ident), -impl ParseNtResult { - pub fn map_nt(self, mut f: F) -> ParseNtResult - where - F: FnMut(T) -> U, - { - match self { - ParseNtResult::Tt(tt) => ParseNtResult::Tt(tt), - ParseNtResult::Nt(nt) => ParseNtResult::Nt(f(nt)), - } - } + /// This case will eventually be removed, along with `Token::Interpolate`. + Nt(Lrc), } diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 73b17353ac90..a6f0ab78b5c2 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -1,7 +1,8 @@ use rustc_ast::ptr::P; -use rustc_ast::token::{self, Delimiter, Nonterminal, Nonterminal::*, NonterminalKind, Token}; +use rustc_ast::token::{self, Delimiter, Nonterminal::*, NonterminalKind, Token}; use rustc_ast::HasTokens; use rustc_ast_pretty::pprust; +use rustc_data_structures::sync::Lrc; use rustc_errors::PResult; use rustc_span::symbol::{kw, Ident}; @@ -24,15 +25,13 @@ impl<'a> Parser<'a> { | NtPat(_) | NtExpr(_) | NtTy(_) - | NtIdent(..) | NtLiteral(_) // `true`, `false` | NtMeta(_) | NtPath(_) => true, NtItem(_) | NtBlock(_) - | NtVis(_) - | NtLifetime(_) => false, + | NtVis(_) => false, } } @@ -49,25 +48,30 @@ impl<'a> Parser<'a> { NonterminalKind::Literal => token.can_begin_literal_maybe_minus(), NonterminalKind::Vis => match token.kind { // The follow-set of :vis + "priv" keyword + interpolated - token::Comma | token::Ident(..) | token::Interpolated(_) => true, + token::Comma + | token::Ident(..) + | token::NtIdent(..) + | token::NtLifetime(..) + | token::Interpolated(_) => true, _ => token.can_begin_type(), }, NonterminalKind::Block => match &token.kind { token::OpenDelim(Delimiter::Brace) => true, - token::Interpolated(nt) => match &nt.0 { - NtBlock(_) | NtLifetime(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, - NtItem(_) | NtPat(_) | NtTy(_) | NtIdent(..) | NtMeta(_) | NtPath(_) - | NtVis(_) => false, + token::NtLifetime(..) => true, + token::Interpolated(nt) => match &**nt { + NtBlock(_) | NtStmt(_) | NtExpr(_) | NtLiteral(_) => true, + NtItem(_) | NtPat(_) | NtTy(_) | NtMeta(_) | NtPath(_) | NtVis(_) => false, }, _ => false, }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { - token::PathSep | token::Ident(..) => true, - token::Interpolated(nt) => may_be_ident(&nt.0), + token::PathSep | token::Ident(..) | token::NtIdent(..) => true, + token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::PatParam { .. } | NonterminalKind::PatWithOr => match &token.kind { - token::Ident(..) | // box, ref, mut, and other identifiers (can stricten) + // box, ref, mut, and other identifiers (can stricten) + token::Ident(..) | token::NtIdent(..) | token::OpenDelim(Delimiter::Parenthesis) | // tuple pattern token::OpenDelim(Delimiter::Bracket) | // slice pattern token::BinOp(token::And) | // reference @@ -81,14 +85,11 @@ impl<'a> Parser<'a> { token::BinOp(token::Shl) => true, // path (double UFCS) // leading vert `|` or-pattern token::BinOp(token::Or) => matches!(kind, NonterminalKind::PatWithOr), - token::Interpolated(nt) => may_be_ident(&nt.0), + token::Interpolated(nt) => may_be_ident(nt), _ => false, }, NonterminalKind::Lifetime => match &token.kind { - token::Lifetime(_) => true, - token::Interpolated(nt) => { - matches!(&nt.0, NtLifetime(_)) - } + token::Lifetime(_) | token::NtLifetime(..) => true, _ => false, }, NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => { @@ -100,10 +101,7 @@ impl<'a> Parser<'a> { /// Parse a non-terminal (e.g. MBE `:pat` or `:ident`). Inlined because there is only one call /// site. #[inline] - pub fn parse_nonterminal( - &mut self, - kind: NonterminalKind, - ) -> PResult<'a, ParseNtResult> { + pub fn parse_nonterminal(&mut self, kind: NonterminalKind) -> PResult<'a, ParseNtResult> { // A `macro_rules!` invocation may pass a captured item/expr to a proc-macro, // which requires having captured tokens available. Since we cannot determine // in advance whether or not a proc-macro will be (transitively) invoked, @@ -156,15 +154,16 @@ impl<'a> Parser<'a> { } // this could be handled like a token, since it is one - NonterminalKind::Ident if let Some((ident, is_raw)) = get_macro_ident(&self.token) => { - self.bump(); - NtIdent(ident, is_raw) - } NonterminalKind::Ident => { - return Err(self.dcx().create_err(UnexpectedNonterminal::Ident { - span: self.token.span, - token: self.token.clone(), - })); + return if let Some((ident, is_raw)) = get_macro_ident(&self.token) { + self.bump(); + Ok(ParseNtResult::Ident(ident, is_raw)) + } else { + Err(self.dcx().create_err(UnexpectedNonterminal::Ident { + span: self.token.span, + token: self.token.clone(), + })) + }; } NonterminalKind::Path => { NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?)) @@ -175,14 +174,14 @@ impl<'a> Parser<'a> { .collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?)) } NonterminalKind::Lifetime => { - if self.check_lifetime() { - NtLifetime(self.expect_lifetime().ident) + return if self.check_lifetime() { + Ok(ParseNtResult::Lifetime(self.expect_lifetime().ident)) } else { - return Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime { + Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime { span: self.token.span, token: self.token.clone(), - })); - } + })) + }; } }; @@ -196,7 +195,7 @@ impl<'a> Parser<'a> { ); } - Ok(ParseNtResult::Nt(nt)) + Ok(ParseNtResult::Nt(Lrc::new(nt))) } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 78d3d019bf4d..8af415f7c9dd 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -757,7 +757,7 @@ impl<'a> Parser<'a> { // Make sure we don't allow e.g. `let mut $p;` where `$p:pat`. if let token::Interpolated(nt) = &self.token.kind { - if let token::NtPat(..) = &nt.0 { + if let token::NtPat(..) = &**nt { self.expected_ident_found_err().emit(); } } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 3636a3579781..c37d3f0441d0 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -193,7 +193,7 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtPath, |path| reject_generics_if_mod_style(self, path.into_inner())); if let token::Interpolated(nt) = &self.token.kind { - if let token::NtTy(ty) = &nt.0 { + if let token::NtTy(ty) = &**nt { if let ast::TyKind::Path(None, path) = &ty.kind { let path = path.clone(); self.bump(); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index d70afebf1b2d..7424fbea9b05 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -567,7 +567,7 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } - if self.is_diff_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { + if self.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) { // Account for `<<<<<<<` diff markers. We can't proactively error here because // that can be a valid path start, so we snapshot and reparse only we've // encountered another parse error. @@ -576,7 +576,7 @@ impl<'a> Parser<'a> { let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { if let Some(ref mut snapshot) = snapshot { - snapshot.recover_diff_marker(); + snapshot.recover_vcs_conflict_marker(); } if self.token == token::Colon { // if a previous and next token of the current one is diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 7096b201f847..2f08a48c7bcd 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -675,8 +675,8 @@ impl<'a> Parser<'a> { let precise_capturing = if self.eat_keyword(kw::Use) { let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); - let args = self.parse_precise_capturing_args()?; - Some(P((args, use_span))) + let (args, args_span) = self.parse_precise_capturing_args()?; + Some(P((args, use_span.to(args_span)))) } else { None }; @@ -689,32 +689,34 @@ impl<'a> Parser<'a> { Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) } - fn parse_precise_capturing_args(&mut self) -> PResult<'a, ThinVec> { - Ok(self - .parse_unspanned_seq( - &TokenKind::Lt, - &TokenKind::Gt, - SeqSep::trailing_allowed(token::Comma), - |self_| { - if self_.check_keyword(kw::SelfUpper) { - self_.bump(); - Ok(PreciseCapturingArg::Arg( - ast::Path::from_ident(self_.prev_token.ident().unwrap().0), - DUMMY_NODE_ID, - )) - } else if self_.check_ident() { - Ok(PreciseCapturingArg::Arg( - ast::Path::from_ident(self_.parse_ident()?), - DUMMY_NODE_ID, - )) - } else if self_.check_lifetime() { - Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) - } else { - self_.unexpected_any() - } - }, - )? - .0) + fn parse_precise_capturing_args( + &mut self, + ) -> PResult<'a, (ThinVec, Span)> { + let lo = self.token.span; + let (args, _) = self.parse_unspanned_seq( + &TokenKind::Lt, + &TokenKind::Gt, + SeqSep::trailing_allowed(token::Comma), + |self_| { + if self_.check_keyword(kw::SelfUpper) { + self_.bump(); + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.prev_token.ident().unwrap().0), + DUMMY_NODE_ID, + )) + } else if self_.check_ident() { + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.parse_ident()?), + DUMMY_NODE_ID, + )) + } else if self_.check_lifetime() { + Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) + } else { + self_.unexpected_any() + } + }, + )?; + Ok((args, lo.to(self.prev_token.span))) } /// Is a `dyn B0 + ... + Bn` type allowed here? diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index c8143015583e..f631ae76de50 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -117,7 +117,7 @@ where if V::SHALLOW { V::Result::output() } else { args.visit_with(self) } } - fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> V::Result { + fn visit_projection_term(&mut self, projection: ty::AliasTerm<'tcx>) -> V::Result { let tcx = self.def_id_visitor.tcx(); let (trait_ref, assoc_args) = projection.trait_ref_and_own_args(tcx); try_visit!(self.visit_trait(trait_ref)); @@ -135,9 +135,12 @@ where ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => { self.visit_trait(trait_ref) } - ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => { + ty::ClauseKind::Projection(ty::ProjectionPredicate { + projection_term: projection_ty, + term, + }) => { try_visit!(term.visit_with(self)); - self.visit_projection_ty(projection_ty) + self.visit_projection_term(projection_ty) } ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => ty.visit_with(self), ty::ClauseKind::RegionOutlives(..) => V::Result::output(), @@ -226,7 +229,7 @@ where return if V::SHALLOW { V::Result::output() } else if kind == ty::Projection { - self.visit_projection_ty(data) + self.visit_projection_term(data.into()) } else { V::Result::from_branch( data.args.iter().try_for_each(|arg| arg.visit_with(self).branch()), diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 914481d712e8..85f55553af39 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -8,9 +8,6 @@ #![allow(rustc::potential_query_instability, unused_parens)] #![allow(internal_features)] -#[macro_use] -extern crate rustc_middle; - use crate::plumbing::{__rust_begin_short_backtrace, encode_all_query_results, try_mark_green}; use crate::profiling_support::QueryKeyStringCache; use field_offset::offset_of; @@ -222,4 +219,4 @@ pub fn query_system<'tcx>( } } -rustc_query_append! { define_queries! } +rustc_middle::rustc_query_append! { define_queries! } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a7696b1fbaff..86531bd95900 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -7,8 +7,8 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher}; use rustc_data_structures::sync::Lock; use rustc_data_structures::unord::UnordMap; use rustc_errors::DiagInner; - use rustc_index::Idx; +use rustc_middle::bug; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::{ self, DepContext, DepKind, DepKindStruct, DepNode, DepNodeIndex, SerializedDepNodeIndex, @@ -781,6 +781,7 @@ macro_rules! define_queries { #[allow(nonstandard_style)] mod query_callbacks { use super::*; + use rustc_middle::bug; use rustc_query_system::dep_graph::FingerprintStyle; // We use this for most things when incr. comp. is turned off. @@ -849,7 +850,7 @@ macro_rules! define_queries { } pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { - arena.alloc_from_iter(make_dep_kind_array!(query_callbacks)) + arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(query_callbacks)) } } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index 7141c6c9bb0c..21433cfdb613 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -8,7 +8,8 @@ use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{ - self, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, UintTy, + self, ExistentialPredicateStableCmpExt as _, Instance, IntTy, List, Ty, TyCtxt, TypeFoldable, + TypeVisitableExt, UintTy, }; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index c442d33cf866..44737e6ce405 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -9,7 +9,7 @@ use stable_mir::ty::{ use crate::rustc_smir::{alloc, Stable, Tables}; -impl<'tcx> Stable<'tcx> for ty::AliasKind { +impl<'tcx> Stable<'tcx> for ty::AliasTyKind { type T = stable_mir::ty::AliasKind; fn stable(&self, _: &mut Tables<'_>) -> Self::T { match self { @@ -29,6 +29,14 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { } } +impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { + type T = stable_mir::ty::AliasTerm; + fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + let ty::AliasTerm { args, def_id, .. } = self; + stable_mir::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables) } + } +} + impl<'tcx> Stable<'tcx> for ty::DynKind { type T = stable_mir::ty::DynKind; @@ -715,9 +723,9 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { type T = stable_mir::ty::ProjectionPredicate; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let ty::ProjectionPredicate { projection_ty, term } = self; + let ty::ProjectionPredicate { projection_term, term } = self; stable_mir::ty::ProjectionPredicate { - projection_ty: projection_ty.stable(tables), + projection_term: projection_term.stable(tables), term: term.unpack().stable(tables), } } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 1de2ecbb7006..9fb217d2f843 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -319,11 +319,10 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { ty::Uint(UintTy::U64) => "y", ty::Uint(UintTy::U128) => "o", ty::Uint(UintTy::Usize) => "j", - // FIXME(f16_f128): update these once `rustc-demangle` supports the new types - ty::Float(FloatTy::F16) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F16) => "C3f16", ty::Float(FloatTy::F32) => "f", ty::Float(FloatTy::F64) => "d", - ty::Float(FloatTy::F128) => unimplemented!("f16_f128"), + ty::Float(FloatTy::F128) => "C4f128", ty::Never => "z", // Placeholders (should be demangled as `_`). diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index d667bad44e3b..c5b2065080b2 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -17,14 +17,9 @@ pub enum Arch { Arm64e, Arm64_32, I386, - I386_sim, I686, X86_64, X86_64h, - X86_64_sim, - X86_64_macabi, - Arm64_macabi, - Arm64_sim, } impl Arch { @@ -32,12 +27,12 @@ impl Arch { match self { Armv7k => "armv7k", Armv7s => "armv7s", - Arm64 | Arm64_macabi | Arm64_sim => "arm64", + Arm64 => "arm64", Arm64e => "arm64e", Arm64_32 => "arm64_32", - I386 | I386_sim => "i386", + I386 => "i386", I686 => "i686", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64 => "x86_64", X86_64h => "x86_64h", } } @@ -45,61 +40,70 @@ impl Arch { pub fn target_arch(self) -> Cow<'static, str> { Cow::Borrowed(match self { Armv7k | Armv7s => "arm", - Arm64 | Arm64e | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", - I386 | I386_sim | I686 => "x86", - X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", + Arm64 | Arm64e | Arm64_32 => "aarch64", + I386 | I686 => "x86", + X86_64 | X86_64h => "x86_64", }) } - fn target_abi(self) -> &'static str { - match self { - Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", - X86_64_macabi | Arm64_macabi => "macabi", - I386_sim | Arm64_sim | X86_64_sim => "sim", - } - } - - fn target_cpu(self) -> &'static str { + fn target_cpu(self, abi: TargetAbi) -> &'static str { match self { Armv7k => "cortex-a8", Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher. - Arm64 => "apple-a7", + Arm64 => match abi { + TargetAbi::Normal => "apple-a7", + TargetAbi::Simulator => "apple-a12", + TargetAbi::MacCatalyst => "apple-a12", + }, Arm64e => "apple-a12", Arm64_32 => "apple-s4", // Only macOS 10.12+ is supported, which means // all x86_64/x86 CPUs must be running at least penryn // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82 - I386 | I386_sim | I686 => "penryn", - X86_64 | X86_64_sim => "penryn", - X86_64_macabi => "penryn", + I386 | I686 => "penryn", + X86_64 => "penryn", // Note: `core-avx2` is slightly more advanced than `x86_64h`, see // comments (and disabled features) in `x86_64h_apple_darwin` for // details. It is a higher baseline then `penryn` however. X86_64h => "core-avx2", - Arm64_macabi => "apple-a12", - Arm64_sim => "apple-a12", } } fn stack_probes(self) -> StackProbeType { match self { Armv7k | Armv7s => StackProbeType::None, - Arm64 | Arm64e | Arm64_32 | I386 | I386_sim | I686 | X86_64 | X86_64h | X86_64_sim - | X86_64_macabi | Arm64_macabi | Arm64_sim => StackProbeType::Inline, + Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => StackProbeType::Inline, } } } -fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { +#[derive(Copy, Clone, PartialEq)] +pub enum TargetAbi { + Normal, + Simulator, + MacCatalyst, +} + +impl TargetAbi { + fn target_abi(self) -> &'static str { + match self { + Self::Normal => "", + Self::MacCatalyst => "macabi", + Self::Simulator => "sim", + } + } +} + +fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { let platform_name: StaticCow = match abi { - "sim" => format!("{os}-simulator").into(), - "macabi" => "mac-catalyst".into(), - _ => os.into(), + TargetAbi::Normal => os.into(), + TargetAbi::Simulator => format!("{os}-simulator").into(), + TargetAbi::MacCatalyst => "mac-catalyst".into(), }; let min_version: StaticCow = { let (major, minor) = match os { - "ios" => ios_deployment_target(arch, abi), + "ios" => ios_deployment_target(arch, abi.target_abi()), "tvos" => tvos_deployment_target(), "watchos" => watchos_deployment_target(), "visionos" => visionos_deployment_target(), @@ -119,7 +123,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { LinkerFlavor::Darwin(Cc::No, Lld::No), [platform_name, min_version, sdk_version].into_iter(), ); - if abi != "macabi" { + if abi != TargetAbi::MacCatalyst { add_link_args( &mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), @@ -136,13 +140,11 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { args } -pub fn opts(os: &'static str, arch: Arch) -> TargetOptions { - let abi = arch.target_abi(); - +pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions { TargetOptions { - abi: abi.into(), + abi: abi.target_abi().into(), os: os.into(), - cpu: arch.target_cpu().into(), + cpu: arch.target_cpu(abi).into(), link_env_remove: link_env_remove(os), vendor: "apple".into(), linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No), @@ -263,8 +265,7 @@ fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> { fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { match arch { - // Note: Arm64_sim is not included since macOS has no simulator. - Arm64 | Arm64e | Arm64_macabi => (11, 0), + Arm64 | Arm64e => (11, 0), _ => (10, 12), } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 8307803676e1..8ba945e193c1 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1774,6 +1774,9 @@ supported_targets! { ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), ("x86_64-unknown-linux-ohos", x86_64_unknown_linux_ohos), + + ("x86_64-unknown-linux-none", x86_64_unknown_linux_none), + } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index c59c0ee8f7af..4e2964174f92 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index 4bbd96277385..20655689772d 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs index af413e892ce4..4c008f7985e6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch}; +use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_macabi; - let mut base = opts("ios", arch); + let arch = Arch::Arm64; + let mut base = opts("ios", arch, TargetAbi::MacCatalyst); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index 2c1dd4151509..4a63abdf5419 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; - let mut base = opts("ios", arch); + let arch = Arch::Arm64; + let mut base = opts("ios", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index b5623c898356..3310e6c9e8a4 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{opts, tvos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { @@ -18,7 +18,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch) + ..opts("tvos", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs index cf4bbb1082ce..b901c663afae 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; + let arch = Arch::Arm64; Target { llvm_target: tvos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -18,7 +18,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch) + ..opts("tvos", arch, TargetAbi::Simulator) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs index bacc4671f33b..b0798e5e4f58 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, visionos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64; - let mut base = opts("visionos", arch); + let mut base = opts("visionos", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs index 99df73cb9df5..7b2d2b6a8e44 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; - let mut base = opts("visionos", arch); + let arch = Arch::Arm64; + let mut base = opts("visionos", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs index 3fbb7803f8c3..a00a97a133f6 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, Arch}; +use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::Arm64); + let base = opts("watchos", Arch::Arm64, TargetAbi::Normal); Target { llvm_target: "aarch64-apple-watchos".into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs index c13615b8b2a5..e2f80b7b7a88 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{FramePointer, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_sim; + let arch = Arch::Arm64; Target { // Clang automatically chooses a more specific target based on // WATCHOS_DEPLOYMENT_TARGET. @@ -22,7 +22,7 @@ pub fn target() -> Target { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("watchos", arch) + ..opts("watchos", arch, TargetAbi::Simulator) }, } } diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs index 38166a88ff33..3ca8c9969c2d 100644 --- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{opts, watchos_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64_32; - let base = opts("watchos", arch); + let base = opts("watchos", arch, TargetAbi::Normal); Target { llvm_target: watchos_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs index cf69309e1c04..90be518638e9 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64e; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs index bff407455451..56470d29eae0 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::Arm64e; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Normal); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs index 42ad9e0a35e6..5c675c22ef51 100644 --- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{opts, Arch}; +use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -19,7 +19,7 @@ pub fn target() -> Target { max_atomic_width: Some(64), dynamic_linking: false, position_independent_executables: true, - ..opts("watchos", arch) + ..opts("watchos", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs index 40e5fc3f20da..4dd475e3a82d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs @@ -1,4 +1,4 @@ -use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { @@ -17,7 +17,7 @@ pub fn target() -> Target { options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), - ..opts("ios", arch) + ..opts("ios", arch, TargetAbi::Normal) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index afa92ba99c61..c03a0974bc1c 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -1,10 +1,11 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::I386; // i386-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::I386_sim; + let abi = TargetAbi::Simulator; Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. @@ -22,6 +23,6 @@ pub fn target() -> Target { i128:128-f64:32:64-f80:128-n8:16:32-S128" .into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch) }, + options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index 34a447a97efb..aea6a1ac4ece 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understands i386 and not i686 let arch = Arch::I386; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); base.frame_pointer = FramePointer::Always; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index 1716c590aa50..21acd750df2d 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index fa22c2907d27..ec61b7967646 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -1,11 +1,11 @@ -use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch}; +use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::X86_64; // x86_64-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::X86_64_sim; - let mut base = opts("ios", arch); + let mut base = opts("ios", arch, TargetAbi::Simulator); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs index 9b479de81652..bd967ee972b3 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs @@ -1,9 +1,9 @@ -use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch}; +use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64_macabi; - let mut base = opts("ios", arch); + let arch = Arch::X86_64; + let mut base = opts("ios", arch, TargetAbi::MacCatalyst); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index f62d31c51662..55b2e1afcd39 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -1,10 +1,11 @@ -use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { + let arch = Arch::X86_64; // x86_64-apple-tvos is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let arch = Arch::X86_64_sim; + let abi = TargetAbi::Simulator; Target { llvm_target: tvos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -17,6 +18,6 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch) }, + options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs index 371aab8b5080..a783eff15b26 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs @@ -1,8 +1,8 @@ -use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch}; +use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64_sim; + let arch = Arch::X86_64; Target { llvm_target: watchos_sim_llvm_target(arch).into(), metadata: crate::spec::TargetMetadata { @@ -15,6 +15,9 @@ pub fn target() -> Target { data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(128), ..opts("watchos", arch) }, + options: TargetOptions { + max_atomic_width: Some(128), + ..opts("watchos", arch, TargetAbi::Simulator) + }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs new file mode 100644 index 000000000000..b6e331bd8545 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_none.rs @@ -0,0 +1,25 @@ +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; + +pub fn target() -> Target { + let mut base = base::linux::opts(); + base.cpu = "x86-64".into(); + base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; + base.linker_flavor = LinkerFlavor::Gnu(Cc::No, Lld::Yes); + base.linker = Some("rust-lld".into()); + + Target { + llvm_target: "x86_64-unknown-linux-none".into(), + metadata: crate::spec::TargetMetadata { + description: None, + tier: None, + host_tools: None, + std: None, + }, + pointer_width: 64, + data_layout: + "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), + arch: "x86_64".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs index b17e21e5d120..fe6cbca32c74 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs @@ -1,10 +1,10 @@ -use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let arch = Arch::X86_64h; - let mut base = opts("macos", arch); + let mut base = opts("macos", arch, TargetAbi::Normal); base.max_atomic_width = Some(128); base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index f1f03b810a96..521e4ef0c9ed 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -30,8 +30,6 @@ #[macro_use] extern crate tracing; -#[macro_use] -extern crate rustc_middle; pub mod errors; pub mod infer; diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs index f2c441dcbeda..65cc0a458573 100644 --- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs +++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs @@ -20,7 +20,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_alias_relate_goal( &mut self, goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, @@ -29,7 +29,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; // Structurally normalize the lhs. - let lhs = if let Some(alias) = lhs.to_alias_ty(self.tcx()) { + let lhs = if let Some(alias) = lhs.to_alias_term() { let term = self.next_term_infer_of_kind(lhs); self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); term @@ -38,7 +38,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; // Structurally normalize the rhs. - let rhs = if let Some(alias) = rhs.to_alias_ty(self.tcx()) { + let rhs = if let Some(alias) = rhs.to_alias_term() { let term = self.next_term_infer_of_kind(rhs); self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term })); term @@ -50,13 +50,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.try_evaluate_added_goals()?; let lhs = self.resolve_vars_if_possible(lhs); let rhs = self.resolve_vars_if_possible(rhs); - debug!(?lhs, ?rhs); + trace!(?lhs, ?rhs); let variance = match direction { ty::AliasRelationDirection::Equate => ty::Variance::Invariant, ty::AliasRelationDirection::Subtype => ty::Variance::Covariant, }; - match (lhs.to_alias_ty(tcx), rhs.to_alias_ty(tcx)) { + match (lhs.to_alias_term(), rhs.to_alias_term()) { (None, None) => { self.relate(param_env, lhs, variance, rhs)?; self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index f2ca42a0be91..9a027d7f937e 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -4,6 +4,7 @@ use crate::solve::GoalSource; use crate::solve::{inspect, EvalCtxt, SolverMode}; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; +use rustc_middle::bug; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{ CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult, @@ -331,7 +332,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { .enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty)) } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_non_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -447,7 +448,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_blanket_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -470,7 +471,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_builtin_impl_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -544,7 +545,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_param_env_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -561,7 +562,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_alias_bound_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -665,7 +666,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_object_bound_candidates>( &mut self, goal: Goal<'tcx, G>, @@ -756,7 +757,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// /// To do so we add an ambiguous candidate in case such an unknown impl could /// apply to the current goal. - #[instrument(level = "debug", skip_all)] + #[instrument(level = "trace", skip_all)] fn assemble_coherence_unknowable_candidates>( &mut self, goal: Goal<'tcx, G>, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index a8b1a182d3c2..9e844d78702d 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -5,6 +5,7 @@ use rustc_hir::LangItem; use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_infer::traits::query::NoSolution; use rustc_macros::{TypeFoldable, TypeVisitable}; +use rustc_middle::bug; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{ self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -17,7 +18,7 @@ use crate::solve::EvalCtxt; // // For types with an "existential" binder, i.e. coroutine witnesses, we also // instantiate the binder with placeholders eagerly. -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -96,7 +97,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } } -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -160,7 +161,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>( } } -#[instrument(level = "debug", skip(ecx), ret)] +#[instrument(level = "trace", skip(ecx), ret)] pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -698,7 +699,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>( old_ty, None, "{} has two generic parameters: {} and {}", - proj.projection_ty, + proj.projection_term, proj.term, old_ty.unwrap() ); @@ -739,7 +740,11 @@ impl<'tcx> TypeFolder> for ReplaceProjectionWith<'_, 'tcx> { // FIXME: Technically this equate could be fallible... self.nested.extend( self.ecx - .eq_and_get_goals(self.param_env, alias_ty, proj.projection_ty) + .eq_and_get_goals( + self.param_env, + alias_ty, + proj.projection_term.expect_ty(self.ecx.tcx()), + ) .expect("expected to be able to unify goal projection with dyn's projection"), ); proj.term.ty().unwrap() 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 d6010242e4ce..2058650f288f 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -22,6 +22,7 @@ use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::solve::NestedNormalizationGoals; +use rustc_middle::bug; use rustc_middle::infer::canonical::Canonical; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ @@ -83,7 +84,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// the values inferred while solving the instantiated goal. /// - `external_constraints`: additional constraints which aren't expressible /// using simple unification of inference variables. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( &mut self, certainty: Certainty, @@ -166,7 +167,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// external constraints do not need to record that opaque, since if it is /// further constrained by inference, that will be passed back in the var /// values. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn compute_external_query_constraints( &self, normalization_nested_goals: NestedNormalizationGoals<'tcx>, @@ -174,7 +175,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // We only check for leaks from universes which were entered inside // of the query. self.infcx.leak_check(self.max_input_universe, None).map_err(|e| { - debug!(?e, "failed the leak check"); + trace!(?e, "failed the leak check"); NoSolution })?; @@ -334,7 +335,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// whether an alias is rigid by using the trait solver. When instantiating a response /// from the solver we assume that the solver correctly handled aliases and therefore /// always relate them structurally here. - #[instrument(level = "debug", skip(infcx))] + #[instrument(level = "trace", skip(infcx))] fn unify_query_var_values( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -407,7 +408,7 @@ pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable> /// This currently assumes that unifying the var values trivially succeeds. /// Adding any inference constraints which weren't present when originally /// computing the canonical query can result in bugs. -#[instrument(level = "debug", skip(infcx, span, param_env))] +#[instrument(level = "trace", skip(infcx, span, param_env))] pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable>>( infcx: &InferCtxt<'tcx>, span: Span, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 9cd1841051dd..e5d26e530ee5 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -9,6 +9,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; use rustc_infer::traits::ObligationCause; use rustc_macros::{extension, HashStable}; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::inspect; use rustc_middle::traits::solve::{ @@ -458,7 +459,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn add_normalizes_to_goal(&mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>) { self.inspect.add_normalizes_to_goal(self.infcx, self.max_input_universe, goal); self.nested_goals.normalizes_to_goals.push(goal); @@ -472,7 +473,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // Recursively evaluates all the goals added to this `EvalCtxt` to completion, returning // the certainty of all the goals. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn try_evaluate_added_goals(&mut self) -> Result { self.inspect.start_evaluate_added_goals(); let mut response = Ok(Certainty::overflow(false)); @@ -526,7 +527,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { unconstrained_goal, )?; // Add the nested goals from normalization to our own nested goals. - debug!(?nested_goals); + trace!(?nested_goals); goals.goals.extend(nested_goals); // Finally, equate the goal's RHS with the unconstrained var. @@ -622,7 +623,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// /// This is the case if the `term` does not occur in any other part of the predicate /// and is able to name all other placeholder and inference variables. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn term_is_fully_unconstrained( &self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, @@ -718,7 +719,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { && goal.param_env.visit_with(&mut visitor).is_continue() } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn eq>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -733,7 +734,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to equate"); + trace!(?e, "failed to equate"); NoSolution }) } @@ -743,11 +744,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// Normally we emit a nested `AliasRelate` when equating an inference /// variable and an alias. This causes us to instead constrain the inference /// variable to the alias without emitting a nested alias relate goals. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn relate_rigid_alias_non_alias( &mut self, param_env: ty::ParamEnv<'tcx>, - alias: ty::AliasTy<'tcx>, + alias: ty::AliasTerm<'tcx>, variance: ty::Variance, term: ty::Term<'tcx>, ) -> Result<(), NoSolution> { @@ -764,13 +765,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // Alternatively we could modify `Equate` for this case by adding another // variant to `StructurallyRelateAliases`. let identity_args = self.fresh_args_for_item(alias.def_id); - let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args); - let ctor_ty = rigid_ctor.to_ty(tcx); + let rigid_ctor = ty::AliasTerm::new(tcx, alias.def_id, identity_args); + let ctor_term = rigid_ctor.to_term(tcx); let InferOk { value: (), obligations } = self .infcx .at(&ObligationCause::dummy(), param_env) - .trace(term, ctor_ty.into()) - .eq_structurally_relating_aliases(term, ctor_ty.into())?; + .trace(term, ctor_term) + .eq_structurally_relating_aliases(term, ctor_term)?; debug_assert!(obligations.is_empty()); self.relate(param_env, alias, variance, rigid_ctor) } else { @@ -781,7 +782,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// This sohuld only be used when we're either instantiating a previously /// unconstrained "return value" or when we're sure that all aliases in /// the types are rigid. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn eq_structurally_relating_aliases>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -798,7 +799,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(()) } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn sub>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -813,12 +814,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to subtype"); + trace!(?e, "failed to subtype"); NoSolution }) } - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] pub(super) fn relate>( &mut self, param_env: ty::ParamEnv<'tcx>, @@ -834,7 +835,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into())); }) .map_err(|e| { - debug!(?e, "failed to relate"); + trace!(?e, "failed to relate"); NoSolution }) } @@ -859,7 +860,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { obligations.into_iter().map(|o| o.into()).collect() }) .map_err(|e| { - debug!(?e, "failed to equate"); + trace!(?e, "failed to equate"); NoSolution }) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs index ee23f49939b7..47109c8ad5d2 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/probe.rs @@ -58,6 +58,7 @@ impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F> where F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<'tcx>, { + #[instrument(level = "debug", skip_all, fields(source = ?self.source))] pub(in crate::solve) fn enter( self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 7efc951135b7..6fda5f4af25e 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -8,6 +8,7 @@ use rustc_infer::traits::{ PolyTraitObligation, Selection, SelectionError, SelectionResult, }; use rustc_macros::extension; +use rustc_middle::{bug, span_bug}; use rustc_span::Span; use crate::solve::inspect::{self, ProofTreeInferCtxtExt}; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 4cc041fca8ce..3323f1bbf399 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -9,6 +9,7 @@ use rustc_infer::traits::{ self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, SelectionError, TraitEngine, }; +use rustc_middle::bug; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::sym; @@ -119,7 +120,7 @@ impl<'tcx> FulfillmentCtxt<'tcx> { } impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> { - #[instrument(level = "debug", skip(self, infcx))] + #[instrument(level = "trace", skip(self, infcx))] fn register_predicate_obligation( &mut self, infcx: &InferCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs index 3c5505055a44..9dd681f09e76 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs @@ -6,6 +6,7 @@ use std::mem; use rustc_infer::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarValues; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{ diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index b2b076e28e64..6c912db975a0 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -17,6 +17,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::traits::solve::{ CanonicalResponse, Certainty, ExternalConstraintsData, Goal, GoalSource, QueryResult, Response, @@ -82,7 +83,7 @@ impl<'tcx> Canonical<'tcx, Response<'tcx>> { } impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_type_outlives_goal( &mut self, goal: Goal<'tcx, TypeOutlivesPredicate<'tcx>>, @@ -92,7 +93,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_region_outlives_goal( &mut self, goal: Goal<'tcx, RegionOutlivesPredicate<'tcx>>, @@ -102,7 +103,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_coerce_goal( &mut self, goal: Goal<'tcx, CoercePredicate<'tcx>>, @@ -117,7 +118,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_subtype_goal( &mut self, goal: Goal<'tcx, SubtypePredicate<'tcx>>, @@ -138,7 +139,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_well_formed_goal( &mut self, goal: Goal<'tcx, ty::GenericArg<'tcx>>, @@ -152,7 +153,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn compute_const_evaluatable_goal( &mut self, Goal { param_env, predicate: ct }: Goal<'tcx, ty::Const<'tcx>>, @@ -189,7 +190,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn compute_const_arg_has_type_goal( &mut self, goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>, @@ -201,7 +202,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { } impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self, goals))] + #[instrument(level = "trace", skip(self, goals))] fn add_goals( &mut self, source: GoalSource, @@ -215,7 +216,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// Try to merge multiple possible ways to prove a goal, if that is not possible returns `None`. /// /// In this case we tend to flounder and return ambiguity by calling `[EvalCtxt::flounder]`. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_merge_responses( &mut self, responses: &[CanonicalResponse<'tcx>], @@ -241,7 +242,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } /// If we fail to merge responses we flounder and return overflow or ambiguity. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn flounder(&mut self, responses: &[CanonicalResponse<'tcx>]) -> QueryResult<'tcx> { if responses.is_empty() { return Err(NoSolution); @@ -263,7 +264,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// This function is necessary in nearly all cases before matching on a type. /// Not doing so is likely to be incomplete and therefore unsound during /// coherence. - #[instrument(level = "debug", skip(self, param_env), ret)] + #[instrument(level = "trace", skip(self, param_env), ret)] fn structurally_normalize_ty( &mut self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index cd1add9e0fa0..5d5161e092e3 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::InferCtxt; use rustc_infer::traits::TraitEngineExt; use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex}; +use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{TypeFoldable, TypeVisitableExt}; @@ -63,7 +63,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { }; self.at.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.at.cause.span, true, |_| {}, @@ -108,7 +108,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { let recursion_limit = tcx.recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.at.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)), + OverflowCause::DeeplyNormalize(uv.into()), self.at.cause.span, true, |_| {}, @@ -122,10 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { tcx, self.at.cause.clone(), self.at.param_env, - ty::NormalizesTo { - alias: AliasTy::new(tcx, uv.def, uv.args), - term: new_infer_ct.into(), - }, + ty::NormalizesTo { alias: uv.into(), term: new_infer_ct.into() }, ); let result = if infcx.predicate_may_hold(&obligation) { @@ -162,7 +159,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { Ok(t) } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; debug_assert_eq!(ty, infcx.shallow_resolve(ty)); @@ -189,7 +186,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; debug_assert_eq!(ct, infcx.shallow_resolve_const(ct)); diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs index 37d564528939..94e078f56159 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/anon_const.rs @@ -3,7 +3,7 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn normalize_anon_const( &mut self, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs index 439f9eec831f..353bdb9caff8 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/inherent.rs @@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - let inherent = goal.predicate.alias; + let inherent = goal.predicate.alias.expect_ty(tcx); let impl_def_id = tcx.parent(inherent.def_id); let impl_args = self.fresh_args_for_item(impl_def_id); diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 454c7a5f00f8..6ec0ad9d29a0 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::NormalizesTo; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use rustc_span::{sym, ErrorGuaranteed, DUMMY_SP}; mod anon_const; @@ -25,7 +26,7 @@ mod opaque_types; mod weak_types; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_normalizes_to_goal( &mut self, goal: Goal<'tcx, NormalizesTo<'tcx>>, @@ -40,26 +41,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(res) => Ok(res), Err(NoSolution) => { let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal; - if alias.opt_kind(self.tcx()).is_some() { - self.relate_rigid_alias_non_alias( - param_env, - alias, - ty::Variance::Invariant, - term, - )?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } else { - // FIXME(generic_const_exprs): we currently do not support rigid - // unevaluated constants. - Err(NoSolution) - } + self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?; + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } } /// Normalize the given alias by at least one step. If the alias is rigid, this /// returns `NoSolution`. - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] fn normalize_at_least_one_step( &mut self, goal: Goal<'tcx, NormalizesTo<'tcx>>, @@ -132,7 +122,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ecx.eq( goal.param_env, goal.predicate.alias, - assumption_projection_pred.projection_ty, + assumption_projection_pred.projection_term, )?; ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term); @@ -373,7 +363,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { let pred = tupled_inputs_and_output .map_bound(|(inputs, output)| ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs], @@ -425,9 +415,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty, coroutine_return_ty, }| { - let (projection_ty, term) = match tcx.item_name(goal.predicate.def_id()) { + let (projection_term, term) = match tcx.item_name(goal.predicate.def_id()) { sym::CallOnceFuture => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), tupled_inputs_ty], @@ -435,7 +425,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty.into(), ), sym::CallRefFuture => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [ @@ -447,7 +437,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty.into(), ), sym::Output => ( - ty::AliasTy::new( + ty::AliasTerm::new( tcx, goal.predicate.def_id(), [ @@ -459,7 +449,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ), name => bug!("no such associated type: {name}"), }; - ty::ProjectionPredicate { projection_ty, term } + ty::ProjectionPredicate { projection_term, term } }, ) .to_predicate(tcx); @@ -636,7 +626,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), term, } .to_predicate(tcx), @@ -668,7 +658,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), + projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), term, } .to_predicate(tcx), @@ -752,7 +742,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), goal, ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( ecx.tcx(), goal.predicate.def_id(), [self_ty, coroutine.resume_ty()], @@ -897,7 +887,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { /// /// FIXME: We should merge these 3 implementations as it's likely that they otherwise /// diverge. -#[instrument(level = "debug", skip(ecx, param_env), ret)] +#[instrument(level = "trace", skip(ecx, param_env), ret)] fn fetch_eligible_assoc_item_def<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -920,7 +910,7 @@ fn fetch_eligible_assoc_item_def<'tcx>( let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref); !poly_trait_ref.still_further_specializable() } else { - debug!(?node_item.item.def_id, "not eligible due to default"); + trace!(?node_item.item.def_id, "not eligible due to default"); false } }; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 30ae385a8a0b..0f1be1072a8f 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -5,25 +5,13 @@ use rustc_middle::traits::solve::{Certainty, Goal, QueryResult}; use rustc_middle::ty::{self, ProjectionPredicate}; impl<'tcx> EvalCtxt<'_, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "trace", skip(self), ret)] pub(super) fn compute_projection_goal( &mut self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, ) -> QueryResult<'tcx> { let tcx = self.tcx(); - let projection_term = match goal.predicate.term.unpack() { - ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(), - ty::TermKind::Const(_) => ty::Const::new_unevaluated( - tcx, - ty::UnevaluatedConst::new( - goal.predicate.projection_ty.def_id, - goal.predicate.projection_ty.args, - ), - tcx.type_of(goal.predicate.projection_ty.def_id) - .instantiate(tcx, goal.predicate.projection_ty.args), - ) - .into(), - }; + let projection_term = goal.predicate.projection_term.to_term(tcx); let goal = goal.with( tcx, ty::PredicateKind::AliasRelate( diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index a48b2f2478b0..60362aa01da8 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -130,7 +130,7 @@ impl<'tcx> SearchGraph<'tcx> { } /// Update the stack and reached depths on cache hits. - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) { let reached_depth = self.stack.next_index().plus(additional_depth); if let Some(last) = self.stack.raw.last_mut() { @@ -296,6 +296,7 @@ impl<'tcx> SearchGraph<'tcx> { } self.on_cache_hit(reached_depth, encountered_overflow); + debug!("global cache hit"); return result; } @@ -315,6 +316,7 @@ impl<'tcx> SearchGraph<'tcx> { .filter(|p| !Self::stack_coinductive_from(tcx, &self.stack, p.head)) }) { + debug!("provisional cache hit"); // We have a nested goal which is already in the provisional cache, use // its result. We do not provide any usage kind as that should have been // already set correctly while computing the cache entry. diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 083cc0aa3c21..1cafa970b68e 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -10,6 +10,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{LangItem, Movability}; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::MaybeCause; +use rustc_middle::bug; use rustc_middle::traits::solve::inspect::ProbeKind; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult}; use rustc_middle::traits::{BuiltinImplSource, Reveal}; @@ -1130,7 +1131,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }, ); if let Some(def_id) = disqualifying_impl { - debug!(?def_id, ?goal, "disqualified auto-trait implementation"); + trace!(?def_id, ?goal, "disqualified auto-trait implementation"); // No need to actually consider the candidate here, // since we do that in `consider_impl_candidate`. return Some(Err(NoSolution)); @@ -1171,7 +1172,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }) } - #[instrument(level = "debug", skip(self))] + #[instrument(level = "trace", skip(self))] pub(super) fn compute_trait_goal( &mut self, goal: Goal<'tcx, TraitPredicate<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 053de2c673b8..60562acfe93f 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -540,11 +540,11 @@ impl<'tcx> AutoTraitFinder<'tcx> { finished_map } - fn is_param_no_infer(&self, args: GenericArgsRef<'_>) -> bool { + fn is_param_no_infer(&self, args: GenericArgsRef<'tcx>) -> bool { self.is_of_param(args.type_at(0)) && !args.types().any(|t| t.has_infer_types()) } - pub fn is_of_param(&self, ty: Ty<'_>) -> bool { + pub fn is_of_param(&self, ty: Ty<'tcx>) -> bool { match ty.kind() { ty::Param(_) => true, ty::Alias(ty::Projection, p) => self.is_of_param(p.self_ty()), @@ -552,9 +552,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { } } - fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool { + fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'tcx>) -> bool { if let Some(ty) = p.term().skip_binder().ty() { - matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_ty) + matches!(ty.kind(), ty::Alias(ty::Projection, proj) if proj == &p.skip_binder().projection_term.expect_ty(self.tcx)) } else { false } @@ -612,7 +612,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // an inference variable. // Additionally, we check if we've seen this predicate before, // to avoid rendering duplicate bounds to the user. - if self.is_param_no_infer(p.skip_binder().projection_ty.args) + if self.is_param_no_infer(p.skip_binder().projection_term.args) && !p.term().skip_binder().has_infer_types() && is_new_pred { @@ -684,7 +684,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { // and turn them into an explicit negative impl for our type. debug!("Projecting and unifying projection predicate {:?}", predicate); - match project::poly_project_and_unify_type(selcx, &obligation.with(self.tcx, p)) + match project::poly_project_and_unify_term(selcx, &obligation.with(self.tcx, p)) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { debug!( diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 59725ce9de09..ebdb032dc0e2 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -20,6 +20,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, FulfillmentErrorCode}; +use rustc_middle::bug; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; @@ -1095,11 +1096,11 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> { Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref, Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))) if matches!( - infcx.tcx.def_kind(proj.projection_ty.def_id), + infcx.tcx.def_kind(proj.projection_term.def_id), DefKind::AssocTy | DefKind::AssocConst ) => { - proj.projection_ty.trait_ref(infcx.tcx) + proj.projection_term.trait_ref(infcx.tcx) } _ => return, }; diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index a8be5627fed8..8348482386f7 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -11,6 +11,7 @@ use rustc_hir::def::DefKind; use rustc_infer::infer::InferCtxt; +use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; 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 040ce450aaf9..7fc94b31b3b5 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 @@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{extension, LintDiagnostic}; +use rustc_middle::bug; use rustc_middle::ty::print::PrintTraitRefExt as _; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; 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 597effcbbf0e..866108554416 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -34,6 +34,7 @@ use rustc_middle::ty::{ InferTy, IsSuggestable, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, TypeckResults, }; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP}; @@ -45,7 +46,9 @@ use std::iter; use crate::infer::InferCtxtExt as _; use crate::traits::error_reporting::type_err_ctxt_ext::InferCtxtPrivExt; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::print::{ + with_forced_trimmed_paths, with_no_trimmed_paths, PrintTraitPredicateExt as _, +}; use itertools::EitherOrBoth; use itertools::Itertools; @@ -1102,9 +1105,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .iter() .find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() + && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() // args tuple will always be args[1] - && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() + && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() { Some(( DefIdOrName::DefId(def_id), @@ -1146,10 +1149,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; param_env.caller_bounds().iter().find_map(|pred| { if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder() - && Some(proj.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() - && proj.projection_ty.self_ty() == found + && Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output() + && proj.projection_term.self_ty() == found // args tuple will always be args[1] - && let ty::Tuple(args) = proj.projection_ty.args.type_at(1).kind() + && let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind() { Some(( name, @@ -1205,8 +1208,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = match obligation.cause.code() { ObligationCauseCode::FunctionArg { parent_code, .. } => parent_code, - c @ ObligationCauseCode::WhereClause(_) - | c @ ObligationCauseCode::WhereClauseInExpr(..) => c, + // FIXME(compiler-errors): This is kind of a mess, but required for obligations + // that come from a path expr to affect the *call* expr. + c @ ObligationCauseCode::WhereClauseInExpr(_, _, hir_id, _) + if self.tcx.hir().span(*hir_id).lo() == span.lo() => + { + c + } c if matches!( span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(DesugaringKind::ForLoop) @@ -1262,8 +1270,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut_ref_self_ty_satisfies_pred = mk_result(trait_pred_and_mut_ref); let (ref_inner_ty_satisfies_pred, ref_inner_ty_mut) = - if let ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() + if let ObligationCauseCode::WhereClauseInExpr(..) = obligation.cause.code() && let ty::Ref(_, ty, mutability) = old_pred.self_ty().skip_binder().kind() { ( @@ -1403,10 +1410,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ObligationCauseCode::ImplDerived(cause) = &*code { try_borrowing(cause.derived.parent_trait_pred, &[]) - } else if let ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) = code + } else if let ObligationCauseCode::WhereClause(..) + | ObligationCauseCode::WhereClauseInExpr(..) = code { try_borrowing(poly_trait_pred, &never_suggest_borrow) } else { @@ -2102,10 +2107,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { cause: &ObligationCauseCode<'tcx>, err: &mut Diag<'tcx>, ) { - // First, look for an `SpannedWhereClauseInExpr`, which means we can get + // First, look for an `WhereClauseInExpr`, which means we can get // the uninstantiated predicate list of the called function. And check // that the predicate that we failed to satisfy is a `Fn`-like trait. - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = cause + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = cause && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx) && let Some(pred) = predicates.predicates.get(*idx) && let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() @@ -2746,12 +2751,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::TupleElem => { err.note("only the last element of a tuple may have a dynamically sized type"); } - ObligationCauseCode::WhereClause(_) | ObligationCauseCode::WhereClauseInExpr(..) => { - // We hold the `DefId` of the item introducing the obligation, but displaying it - // doesn't add user usable information. It always point at an associated item. - } - ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..) => { + ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..) + if !span.is_dummy() => + { let item_name = tcx.def_path_str(item_def_id); let short_item_name = with_forced_trimmed_paths!(tcx.def_path_str(item_def_id)); let mut multispan = MultiSpan::from(span); @@ -2882,6 +2885,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.help(help); } } + ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) => { + // We hold the `DefId` of the item introducing the obligation, but displaying it + // doesn't add user usable information. It always point at an associated item. + } ObligationCauseCode::Coercion { source, target } => { let source = tcx.short_ty_string(self.resolve_vars_if_possible(source), &mut long_ty_file); @@ -3802,7 +3809,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // to an associated type (as seen from `trait_pred`) in the predicate. Like in // trait_pred `S: Sum<::Item>` and predicate `i32: Sum<&()>` let mut type_diffs = vec![]; - if let ObligationCauseCode::SpannedWhereClauseInExpr(def_id, _, _, idx) = parent_code + if let ObligationCauseCode::WhereClauseInExpr(def_id, _, _, idx) = parent_code && let Some(node_args) = typeck_results.node_args_opt(call_hir_id) && let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_args) @@ -3839,11 +3846,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { && let Some(found) = failed_pred.skip_binder().term.ty() { type_diffs = vec![Sorts(ty::error::ExpectedFound { - expected: Ty::new_alias( - self.tcx, - ty::Projection, - where_pred.skip_binder().projection_ty, - ), + expected: where_pred + .skip_binder() + .projection_term + .expect_ty(self.tcx) + .to_ty(self.tcx), found, })]; } @@ -4268,7 +4275,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // This corresponds to `::Item = _`. let projection = ty::Binder::dummy(ty::PredicateKind::Clause( ty::ClauseKind::Projection(ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(self.tcx, proj.def_id, args), + projection_term: ty::AliasTerm::new(self.tcx, proj.def_id, args), term: ty.into(), }), )); @@ -4965,7 +4972,7 @@ fn point_at_assoc_type_restriction( let ty::ClauseKind::Projection(proj) = clause else { return; }; - let name = tcx.item_name(proj.projection_ty.def_id); + let name = tcx.item_name(proj.projection_term.def_id); let mut predicates = generics.predicates.iter().peekable(); let mut prev: Option<&hir::WhereBoundPredicate<'_>> = None; while let Some(pred) = predicates.next() { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index cdde12af8ea1..f9824acdae07 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -38,12 +38,14 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{ - with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitRefExt as _, + with_forced_trimmed_paths, FmtPrinter, Print, PrintTraitPredicateExt as _, + PrintTraitRefExt as _, }; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, TypeVisitableExt, }; +use rustc_middle::{bug, span_bug}; use rustc_session::config::DumpSolverProofTree; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; @@ -61,7 +63,7 @@ use super::{ pub use rustc_infer::traits::error_reporting::*; pub enum OverflowCause<'tcx> { - DeeplyNormalize(ty::AliasTy<'tcx>), + DeeplyNormalize(ty::AliasTerm<'tcx>), TraitSolver(ty::Predicate<'tcx>), } @@ -245,10 +247,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } let mut err = match cause { - OverflowCause::DeeplyNormalize(alias_ty) => { - let alias_ty = self.resolve_vars_if_possible(alias_ty); - let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr()); - let alias_str = with_short_path(self.tcx, alias_ty); + OverflowCause::DeeplyNormalize(alias_term) => { + let alias_term = self.resolve_vars_if_possible(alias_term); + let kind = alias_term.kind(self.tcx).descr(); + let alias_str = with_short_path(self.tcx, alias_term); struct_span_code_err!( self.dcx(), span, @@ -1467,7 +1469,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ); let param_env = ty::ParamEnv::empty(); - self.can_eq(param_env, goal.projection_ty, assumption.projection_ty) + self.can_eq(param_env, goal.projection_term, assumption.projection_term) && self.can_eq(param_env, goal.term, assumption.term) } @@ -1535,9 +1537,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { *err, ); let code = error.obligation.cause.code().peel_derives().peel_match_impls(); - if let ObligationCauseCode::SpannedWhereClause(..) - | ObligationCauseCode::WhereClause(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) + if let ObligationCauseCode::WhereClause(..) | ObligationCauseCode::WhereClauseInExpr(..) = code { self.note_obligation_cause_code( @@ -1584,23 +1584,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { infer::BoundRegionConversionTime::HigherRankedType, bound_predicate.rebind(data), ); - let unnormalized_term = match data.term.unpack() { - ty::TermKind::Ty(_) => Ty::new_projection( - self.tcx, - data.projection_ty.def_id, - data.projection_ty.args, - ) - .into(), - ty::TermKind::Const(ct) => ty::Const::new_unevaluated( - self.tcx, - ty::UnevaluatedConst { - def: data.projection_ty.def_id, - args: data.projection_ty.args, - }, - ct.ty(), - ) - .into(), - }; + let unnormalized_term = data.projection_term.to_term(self.tcx); // FIXME(-Znext-solver): For diagnostic purposes, it would be nice // to deeply normalize this type. let normalized_term = @@ -1612,11 +1596,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let is_normalized_term_expected = !matches!( obligation.cause.code().peel_derives(), - ObligationCauseCode::WhereClause(_) - | ObligationCauseCode::SpannedWhereClause(_, _) - | ObligationCauseCode::WhereClauseInExpr(..) - | ObligationCauseCode::SpannedWhereClauseInExpr(..) - | ObligationCauseCode::Coercion { .. } + |ObligationCauseCode::WhereClause(..)| ObligationCauseCode::WhereClauseInExpr( + .. + ) | ObligationCauseCode::Coercion { .. } ); let (expected, actual) = if is_normalized_term_expected { @@ -1667,13 +1649,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { return None; }; - let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?; + let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_term.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(), + self.tcx.trait_of_item(proj.projection_term.def_id)?, + proj.projection_term.self_ty(), |impl_def_id| { associated_items.extend( self.tcx @@ -1742,11 +1724,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { normalized_ty: ty::Term<'tcx>, expected_ty: ty::Term<'tcx>, ) -> Option { - let trait_def_id = pred.projection_ty.trait_def_id(self.tcx); - let self_ty = pred.projection_ty.self_ty(); + let trait_def_id = pred.projection_term.trait_def_id(self.tcx); + let self_ty = pred.projection_term.self_ty(); with_forced_trimmed_paths! { - if Some(pred.projection_ty.def_id) == self.tcx.lang_items().fn_once_output() { + if Some(pred.projection_term.def_id) == self.tcx.lang_items().fn_once_output() { let fn_kind = self_ty.prefix_string(self.tcx); let item = match self_ty.kind() { ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(), @@ -2447,7 +2429,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - if let ObligationCauseCode::WhereClause(def_id) + if let ObligationCauseCode::WhereClause(def_id, _) | ObligationCauseCode::WhereClauseInExpr(def_id, ..) = *obligation.cause.code() { self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); @@ -2625,14 +2607,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } if let Err(guar) = - self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id)) + self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_term.def_id)) { // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. return guar; } let arg = data - .projection_ty + .projection_term .args .iter() .chain(Some(data.term.into_arg())) @@ -2883,12 +2865,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { else { return; }; - let (ObligationCauseCode::SpannedWhereClause(item_def_id, span) - | ObligationCauseCode::SpannedWhereClauseInExpr(item_def_id, span, ..)) = + let (ObligationCauseCode::WhereClause(item_def_id, span) + | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)) = *obligation.cause.code().peel_derives() else { return; }; + if span.is_dummy() { + return; + } debug!(?pred, ?item_def_id, ?span); let (Some(node), true) = ( @@ -3181,10 +3166,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ObligationCauseCode::RustCall => { err.primary_message("functions with the \"rust-call\" ABI must take a single non-self tuple argument"); } - ObligationCauseCode::SpannedWhereClause(def_id, _) - | ObligationCauseCode::WhereClause(def_id) - if self.tcx.is_fn_trait(*def_id) => - { + ObligationCauseCode::WhereClause(def_id, _) if self.tcx.is_fn_trait(*def_id) => { err.code(E0059); err.primary_message(format!( "type parameter to bare `{}` trait must be a tuple", diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e3497c646dbd..07fcf109fdaa 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -8,6 +8,7 @@ use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProce use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::{PolyTraitObligation, SelectionError, TraitEngine}; +use rustc_middle::bug; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -770,13 +771,13 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { } } - match project::poly_project_and_unify_type(&mut self.selcx, &project_obligation) { + match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) { ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)), ProjectAndUnifyResult::FailedNormalization => { stalled_on.clear(); stalled_on.extend(args_infer_vars( &self.selcx, - project_obligation.predicate.map_bound(|pred| pred.projection_ty.args), + project_obligation.predicate.map_bound(|pred| pred.projection_term.args), )); ProcessResult::Unchanged } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 56f8b4b9cdb8..61f47bc1f23d 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -31,6 +31,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::query::Providers; +use rustc_middle::span_bug; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFolder, TypeSuperVisitable}; @@ -51,7 +52,7 @@ pub use self::object_safety::hir_ty_lowering_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::object_safety_violations_for_assoc_item; pub use self::object_safety::ObjectSafetyViolation; -pub use self::project::{normalize_inherent_projection, normalize_projection_type}; +pub use self::project::{normalize_inherent_projection, normalize_projection_ty}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::specialization_graph::FutureCompatOverlapError; diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 43f4fa8e81ca..d10aee2d4e29 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -213,7 +213,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, true, |_| {}, @@ -238,7 +238,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx // register an obligation to *later* project, since we know // there won't be bound vars there. let data = data.fold_with(self); - let normalized_ty = project::normalize_projection_type( + let normalized_ty = project::normalize_projection_ty( self.selcx, self.param_env, data, @@ -273,10 +273,10 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let (data, mapped_regions, mapped_types, mapped_consts) = BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data); let data = data.fold_with(self); - let normalized_ty = project::opt_normalize_projection_type( + let normalized_ty = project::opt_normalize_projection_term( self.selcx, self.param_env, - data, + data.into(), self.cause.clone(), self.depth, self.obligations, @@ -309,7 +309,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx let recursion_limit = self.interner().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, false, |diag| { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5cb61dff8314..41080b3d9d35 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -18,7 +18,8 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, EarlyBinder, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeSuperVisitable, + TypeVisitable, TypeVisitor, }; use rustc_middle::ty::{GenericArg, GenericArgs}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; @@ -304,7 +305,7 @@ fn predicate_references_self<'tcx>( // // This is ALT2 in issue #56288, see that for discussion of the // possible alternatives. - data.projection_ty.args[1..].iter().any(has_self_ty).then_some(sp) + data.projection_term.args[1..].iter().any(has_self_ty).then_some(sp) } ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp), diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 1dd2ada3356f..1dc2ebfaa7a3 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -5,6 +5,7 @@ use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::infer::InferOk; use rustc_macros::extension; use rustc_middle::infer::canonical::{OriginalQueryValues, QueryRegionConstraints}; +use rustc_middle::span_bug; use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 1e78484f3054..2e7d2790dc36 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -12,11 +12,12 @@ use super::PredicateObligation; use super::Selection; use super::SelectionContext; use super::SelectionError; -use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey}; +use super::{Normalized, NormalizedTerm, ProjectionCacheEntry, ProjectionCacheKey}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::traits::ImplSource; use rustc_middle::traits::ImplSourceUserDefinedData; +use rustc_middle::{bug, span_bug}; use crate::errors::InherentProjectionNormalizationOverflow; use crate::infer::{BoundRegionConversionTime, InferOk}; @@ -43,7 +44,7 @@ pub type PolyProjectionObligation<'tcx> = Obligation<'tcx, ty::PolyProjectionPre pub type ProjectionObligation<'tcx> = Obligation<'tcx, ty::ProjectionPredicate<'tcx>>; -pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::AliasTy<'tcx>>; +pub type ProjectionTermObligation<'tcx> = Obligation<'tcx, ty::AliasTerm<'tcx>>; pub(super) struct InProgress; @@ -181,7 +182,7 @@ pub(super) enum ProjectAndUnifyResult<'tcx> { /// If successful, this may result in additional obligations. Also returns /// the projection cache key used to track these additional obligations. #[instrument(level = "debug", skip(selcx))] -pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( +pub(super) fn poly_project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &PolyProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { @@ -192,7 +193,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( let new_universe = infcx.universe(); let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate); - match project_and_unify_type(selcx, &placeholder_obligation) { + match project_and_unify_term(selcx, &placeholder_obligation) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e), ProjectAndUnifyResult::Holds(obligations) if old_universe != new_universe @@ -232,19 +233,19 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( /// ``` /// If successful, this may result in additional obligations. /// -/// See [poly_project_and_unify_type] for an explanation of the return value. +/// See [poly_project_and_unify_term] for an explanation of the return value. #[instrument(level = "debug", skip(selcx))] -fn project_and_unify_type<'cx, 'tcx>( +fn project_and_unify_term<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, obligation: &ProjectionObligation<'tcx>, ) -> ProjectAndUnifyResult<'tcx> { let mut obligations = vec![]; let infcx = selcx.infcx; - let normalized = match opt_normalize_projection_type( + let normalized = match opt_normalize_projection_term( selcx, obligation.param_env, - obligation.predicate.projection_ty, + obligation.predicate.projection_term, obligation.cause.clone(), obligation.recursion_depth, &mut obligations, @@ -290,7 +291,7 @@ fn project_and_unify_type<'cx, 'tcx>( /// there are unresolved type variables in the projection, we will /// instantiate it with a fresh type variable `$X` and generate a new /// obligation `::Item == $X` for later. -pub fn normalize_projection_type<'a, 'b, 'tcx>( +pub fn normalize_projection_ty<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::AliasTy<'tcx>, @@ -298,10 +299,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( depth: usize, obligations: &mut Vec>, ) -> Term<'tcx> { - opt_normalize_projection_type( + opt_normalize_projection_term( selcx, param_env, - projection_ty, + projection_ty.into(), cause.clone(), depth, obligations, @@ -313,7 +314,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( // and a deferred predicate to resolve this when more type // information is available. - selcx.infcx.infer_projection(param_env, projection_ty, cause, depth + 1, obligations).into() + selcx + .infcx + .projection_ty_to_infer(param_env, projection_ty, cause, depth + 1, obligations) + .into() }) } @@ -328,10 +332,10 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>( /// function takes an obligations vector and appends to it directly, which is /// slightly uglier but avoids the need for an extra short-lived allocation. #[instrument(level = "debug", skip(selcx, param_env, cause, obligations))] -pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( +pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, obligations: &mut Vec>, @@ -343,8 +347,8 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( // mode, which could lead to using incorrect cache results. let use_cache = !selcx.is_intercrate(); - let projection_ty = infcx.resolve_vars_if_possible(projection_ty); - let cache_key = ProjectionCacheKey::new(projection_ty, param_env); + let projection_term = infcx.resolve_vars_if_possible(projection_term); + let cache_key = ProjectionCacheKey::new(projection_term, param_env); // FIXME(#20304) For now, I am caching here, which is good, but it // means we don't capture the type variables that are created in @@ -392,7 +396,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( debug!("recur cache"); return Err(InProgress); } - Err(ProjectionCacheEntry::NormalizedTy { ty, complete: _ }) => { + Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => { // This is the hottest path in this function. // // If we find the value in the cache, then return it along @@ -410,14 +414,14 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( } Err(ProjectionCacheEntry::Error) => { debug!("opt_normalize_projection_type: found error"); - let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); + let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); return Ok(Some(result.value.into())); } } let obligation = - Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty); + Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_term); match project(selcx, &obligation) { Ok(Projected::Progress(Progress { @@ -480,7 +484,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( if use_cache { infcx.inner.borrow_mut().projection_cache().error(cache_key); } - let result = normalize_to_error(selcx, param_env, projection_ty, cause, depth); + let result = normalize_to_error(selcx, param_env, projection_term, cause, depth); obligations.extend(result.obligations); Ok(Some(result.value.into())) } @@ -509,19 +513,33 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>( fn normalize_to_error<'a, 'tcx>( selcx: &SelectionContext<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, - projection_ty: ty::AliasTy<'tcx>, + projection_term: ty::AliasTerm<'tcx>, cause: ObligationCause<'tcx>, depth: usize, -) -> NormalizedTy<'tcx> { - let trait_ref = ty::Binder::dummy(projection_ty.trait_ref(selcx.tcx())); +) -> NormalizedTerm<'tcx> { + let trait_ref = ty::Binder::dummy(projection_term.trait_ref(selcx.tcx())); + let new_value = match projection_term.kind(selcx.tcx()) { + ty::AliasTermKind::ProjectionTy + | ty::AliasTermKind::InherentTy + | ty::AliasTermKind::OpaqueTy + | ty::AliasTermKind::WeakTy => selcx.infcx.next_ty_var(cause.span).into(), + ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => selcx + .infcx + .next_const_var( + selcx + .tcx() + .type_of(projection_term.def_id) + .instantiate(selcx.tcx(), projection_term.args), + cause.span, + ) + .into(), + }; let trait_obligation = Obligation { cause, recursion_depth: depth, param_env, predicate: trait_ref.to_predicate(selcx.tcx()), }; - let tcx = selcx.infcx.tcx; - let new_value = selcx.infcx.next_ty_var(tcx.def_span(projection_ty.def_id)); Normalized { value: new_value, obligations: vec![trait_obligation] } } @@ -573,11 +591,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>( // cause code, inherent projections will be printed with identity instantiation in // diagnostics which is not ideal. // Consider creating separate cause codes for this specific situation. - if span.is_dummy() { - ObligationCauseCode::WhereClause(alias_ty.def_id) - } else { - ObligationCauseCode::SpannedWhereClause(alias_ty.def_id, span) - }, + ObligationCauseCode::WhereClause(alias_ty.def_id, span), ); obligations.push(Obligation::with_depth( @@ -679,7 +693,7 @@ impl<'tcx> Progress<'tcx> { #[instrument(level = "info", skip(selcx))] fn project<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, ) -> Result, ProjectionError<'tcx>> { if !selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth) { // This should really be an immediate error, but some existing code @@ -754,7 +768,7 @@ fn project<'cx, 'tcx>( /// there that can answer this question. fn assemble_candidates_from_param_env<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { assemble_candidates_from_predicates( @@ -779,7 +793,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>( /// Here, for example, we could conclude that the result is `i32`. fn assemble_candidates_from_trait_def<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { debug!("assemble_candidates_from_trait_def(..)"); @@ -837,7 +851,7 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>( /// `dyn Iterator: Iterator` again. fn assemble_candidates_from_object_ty<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { debug!("assemble_candidates_from_object_ty(..)"); @@ -881,7 +895,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( )] fn assemble_candidates_from_predicates<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ctor: fn(ty::PolyProjectionPredicate<'tcx>) -> ProjectionCandidate<'tcx>, env_predicates: impl Iterator>, @@ -929,7 +943,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( #[instrument(level = "debug", skip(selcx, obligation, candidate_set))] fn assemble_candidates_from_impls<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate_set: &mut ProjectionCandidateSet<'tcx>, ) { // If we are resolving `>::Item == Type`, @@ -1257,7 +1271,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( fn confirm_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, candidate: ProjectionCandidate<'tcx>, ) -> Progress<'tcx> { debug!(?obligation, ?candidate, "confirm_candidate"); @@ -1289,7 +1303,7 @@ fn confirm_candidate<'cx, 'tcx>( fn confirm_select_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, impl_source: Selection<'tcx>, ) -> Progress<'tcx> { match impl_source { @@ -1337,7 +1351,7 @@ fn confirm_select_candidate<'cx, 'tcx>( fn confirm_coroutine_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1381,7 +1395,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: ty.into(), }; @@ -1392,7 +1406,7 @@ fn confirm_coroutine_candidate<'cx, 'tcx>( fn confirm_future_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1425,7 +1439,7 @@ fn confirm_future_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: return_ty.into(), }; @@ -1436,7 +1450,7 @@ fn confirm_future_candidate<'cx, 'tcx>( fn confirm_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()); @@ -1467,7 +1481,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: yield_ty.into(), }; @@ -1478,7 +1492,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>( fn confirm_async_iterator_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let ty::Coroutine(_, args) = selcx.infcx.shallow_resolve(obligation.predicate.self_ty()).kind() @@ -1517,7 +1531,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( let item_ty = args.type_at(0); let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, obligation.predicate.def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, obligation.predicate.def_id, trait_ref.args), term: item_ty.into(), }; @@ -1528,7 +1542,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>( fn confirm_builtin_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, data: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1586,8 +1600,10 @@ fn confirm_builtin_candidate<'cx, 'tcx>( bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate); }; - let predicate = - ty::ProjectionPredicate { projection_ty: ty::AliasTy::new(tcx, item_def_id, args), term }; + let predicate = ty::ProjectionPredicate { + projection_term: ty::AliasTerm::new(tcx, item_def_id, args), + term, + }; confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false) .with_addl_obligations(obligations) @@ -1596,7 +1612,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( fn confirm_fn_pointer_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1632,7 +1648,7 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>( fn confirm_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1731,7 +1747,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( fn confirm_callable_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, fn_sig: ty::PolyFnSig<'tcx>, flag: util::TupleArgumentsFlag, fn_host_effect: ty::Const<'tcx>, @@ -1752,7 +1768,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn_host_effect, ) .map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new(tcx, fn_once_output_def_id, trait_ref.args), + projection_term: ty::AliasTerm::new(tcx, fn_once_output_def_id, trait_ref.args), term: ret_type.into(), }); @@ -1761,7 +1777,7 @@ fn confirm_callable_candidate<'cx, 'tcx>( fn confirm_async_closure_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -1840,13 +1856,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( sym::Output => sig.return_ty, name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { - sym::CallOnceFuture | sym::Output => ty::AliasTy::new( + let projection_term = match item_name { + sym::CallOnceFuture | sym::Output => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [self_ty, sig.tupled_inputs_ty], ), - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.tupled_inputs_ty.into(), env_region.into()], @@ -1855,7 +1871,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( }; args.coroutine_closure_sig() - .rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + .rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } ty::FnDef(..) | ty::FnPtr(..) => { let bound_sig = self_ty.fn_sig(tcx); @@ -1875,13 +1891,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( } name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { - sym::CallOnceFuture | sym::Output => ty::AliasTy::new( + let projection_term = match item_name { + sym::CallOnceFuture | sym::Output => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [self_ty, Ty::new_tup(tcx, sig.inputs())], ), - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ @@ -1893,7 +1909,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( name => bug!("no such associated type: {name}"), }; - bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } ty::Closure(_, args) => { let args = args.as_closure(); @@ -1914,11 +1930,11 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( } name => bug!("no such associated type: {name}"), }; - let projection_ty = match item_name { + let projection_term = match item_name { sym::CallOnceFuture | sym::Output => { - ty::AliasTy::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]]) + ty::AliasTerm::new(tcx, obligation.predicate.def_id, [self_ty, sig.inputs()[0]]) } - sym::CallRefFuture => ty::AliasTy::new( + sym::CallRefFuture => ty::AliasTerm::new( tcx, obligation.predicate.def_id, [ty::GenericArg::from(self_ty), sig.inputs()[0].into(), env_region.into()], @@ -1926,7 +1942,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( name => bug!("no such associated type: {name}"), }; - bound_sig.rebind(ty::ProjectionPredicate { projection_ty, term: term.into() }) + bound_sig.rebind(ty::ProjectionPredicate { projection_term, term: term.into() }) } _ => bug!("expected callable type for AsyncFn candidate"), }; @@ -1937,7 +1953,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: Vec>, ) -> Progress<'tcx> { let [ @@ -1954,7 +1970,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( }; let predicate = ty::ProjectionPredicate { - projection_ty: ty::AliasTy::new( + projection_term: ty::AliasTerm::new( selcx.tcx(), obligation.predicate.def_id, obligation.predicate.args, @@ -1976,7 +1992,7 @@ fn confirm_async_fn_kind_helper_candidate<'cx, 'tcx>( fn confirm_param_env_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, poly_cache_entry: ty::PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidate: bool, ) -> Progress<'tcx> { @@ -1990,7 +2006,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( poly_cache_entry, ); - let cache_projection = cache_entry.projection_ty; + let cache_projection = cache_entry.projection_term; let mut nested_obligations = Vec::new(); let obligation_projection = obligation.predicate; let obligation_projection = ensure_sufficient_stack(|| { @@ -2045,7 +2061,7 @@ fn confirm_param_env_candidate<'cx, 'tcx>( fn confirm_impl_candidate<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, impl_impl_source: ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); @@ -2106,7 +2122,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( // associated type itself. fn assoc_ty_own_obligations<'cx, 'tcx>( selcx: &mut SelectionContext<'cx, 'tcx>, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, nested: &mut Vec>, ) { let tcx = selcx.tcx(); @@ -2130,17 +2146,11 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( | ObligationCauseCode::AscribeUserTypeProvePredicate(..) ) { obligation.cause.clone() - } else if span.is_dummy() { - ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - ObligationCauseCode::WhereClause(obligation.predicate.def_id), - ) } else { ObligationCause::new( obligation.cause.span, obligation.cause.body_id, - ObligationCauseCode::SpannedWhereClause(obligation.predicate.def_id, span), + ObligationCauseCode::WhereClause(obligation.predicate.def_id, span), ) }; nested.push(Obligation::with_depth( @@ -2174,7 +2184,7 @@ impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> { // from a specific call to `opt_normalize_projection_type` - if // there's no precise match, the original cache entry is "stranded" // anyway. - infcx.resolve_vars_if_possible(predicate.projection_ty), + infcx.resolve_vars_if_possible(predicate.projection_term), obligation.param_env, ) }) diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 87d240cf8ac7..692feee73951 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,4 +1,5 @@ use rustc_macros::extension; +use rustc_middle::span_bug; use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 8b39c23da56b..1b5ffeebc01f 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -222,7 +222,7 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> .infcx .err_ctxt() .build_overflow_error( - OverflowCause::DeeplyNormalize(data), + OverflowCause::DeeplyNormalize(data.into()), self.cause.span, true, ) 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 40d206b92b8d..b9e853a06787 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -16,6 +16,7 @@ use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError}; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt}; +use rustc_middle::{bug, span_bug}; use crate::traits; use crate::traits::query::evaluate_obligation::InferCtxtExt; @@ -944,7 +945,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } self.infcx.probe(|_| { - let ty = traits::normalize_projection_type( + let ty = traits::normalize_projection_ty( self, param_env, ty::AliasTy::new(tcx, tcx.lang_items().deref_target()?, trait_ref.args), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 69d11b45e604..24c6951a014f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate, TraitPredicate, Ty, TyCtxt, }; +use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to}; diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 7aa2aabed7f7..5b25c62689fb 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -8,7 +8,7 @@ use self::SelectionCandidate::*; use super::coherence::{self, Conflict}; use super::const_evaluatable; use super::project; -use super::project::ProjectionTyObligation; +use super::project::ProjectionTermObligation; use super::util; use super::util::closure_trait_ref_and_return_type; use super::wf; @@ -36,6 +36,7 @@ use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::traits::TraitObligation; +use rustc_middle::bug; use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::mir::interpret::ErrorHandled; @@ -808,7 +809,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => { let data = bound_predicate.rebind(data); let project_obligation = obligation.with(self.tcx(), data); - match project::poly_project_and_unify_type(self, &project_obligation) { + match project::poly_project_and_unify_term(self, &project_obligation) { ProjectAndUnifyResult::Holds(mut subobligations) => { 'compute_res: { // If we've previously marked this projection as 'complete', then @@ -1733,7 +1734,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// in cases like #91762. pub(super) fn match_projection_projections( &mut self, - obligation: &ProjectionTyObligation<'tcx>, + obligation: &ProjectionTermObligation<'tcx>, env_predicate: PolyProjectionPredicate<'tcx>, potentially_unnormalized_candidates: bool, ) -> ProjectionMatchesProjection { @@ -1752,12 +1753,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, - infer_predicate.projection_ty, + infer_predicate.projection_term, &mut nested_obligations, ) }) } else { - infer_predicate.projection_ty + infer_predicate.projection_term }; let is_match = self diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index fe3f66f3a3ff..826bb706f48b 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -23,6 +23,7 @@ use crate::traits::{ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{codes::*, DelayDm, Diag, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_middle::bug; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index b6c2fcb46eb8..90f2c7ad213b 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -4,6 +4,7 @@ use crate::traits; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_macros::extension; +use rustc_middle::bug; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 6778ac81aeae..d4535db951e2 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_middle::bug; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use std::ops::ControlFlow; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b2ba7854f188..83edddb9a962 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -6,6 +6,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Diag; use rustc_hir::def_id::DefId; use rustc_infer::infer::{InferCtxt, InferOk}; +use rustc_middle::bug; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{TypeFoldable, TypeFolder, TypeSuperFoldable}; diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 3f1ba80acd3d..8fd9889b4eab 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -4,6 +4,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::util::PredicateSet; use rustc_infer::traits::ImplSource; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::BuiltinImplSource; use rustc_middle::ty::visit::TypeVisitableExt; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 2c2b84d4a875..6d84523da8a6 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -3,6 +3,7 @@ use crate::traits; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::ObligationCauseCode; +use rustc_middle::bug; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; @@ -165,11 +166,8 @@ pub fn clause_obligations<'tcx>( wf.compute(ty.into()); } ty::ClauseKind::Projection(t) => { - wf.compute_alias(t.projection_ty); - wf.compute(match t.term.unpack() { - ty::TermKind::Ty(ty) => ty.into(), - ty::TermKind::Const(c) => c.into(), - }) + wf.compute_alias_term(t.projection_term); + wf.compute(t.term.into_arg()); } ty::ClauseKind::ConstArgHasType(ct, ty) => { wf.compute(ct.into()); @@ -439,7 +437,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. - fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) { + fn compute_alias_ty(&mut self, data: ty::AliasTy<'tcx>) { + self.compute_alias_term(data.into()); + } + + /// Pushes the obligations required for an alias (except inherent) to be WF + /// into `self.out`. + fn compute_alias_term(&mut self, data: ty::AliasTerm<'tcx>) { // A projection is well-formed if // // (a) its predicates hold (*) @@ -568,11 +572,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { iter::zip(predicates, origins.into_iter().rev()) .map(|((pred, span), origin_def_id)| { - let code = if span.is_dummy() { - ObligationCauseCode::WhereClause(origin_def_id) - } else { - ObligationCauseCode::SpannedWhereClause(origin_def_id, span) - }; + let code = ObligationCauseCode::WhereClause(origin_def_id, span); let cause = self.cause(code); traits::Obligation::with_depth( self.tcx(), @@ -702,7 +702,7 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { } ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { - self.compute_alias(data); + self.compute_alias_ty(data); return; // Subtree handled by compute_projection. } ty::Alias(ty::Inherent, data) => { diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 559c05eb3e78..fee13078250f 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -34,14 +34,8 @@ fn normalize_canonicalized_projection_ty<'tcx>( let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = vec![]; - let answer = traits::normalize_projection_type( - selcx, - param_env, - goal, - cause, - 0, - &mut obligations, - ); + let answer = + traits::normalize_projection_ty(selcx, param_env, goal, cause, 0, &mut obligations); ocx.register_obligations(obligations); // #112047: With projections and opaques, we are able to create opaques that // are recursive (given some generic parameters of the opaque's type variables). diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index c6b836285066..fd7e2fec3892 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -1,5 +1,6 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index d3fe8291e03c..4395eb57cd6d 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -5,6 +5,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_span::symbol::kw; pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index acbcc3918b2f..fec02f515caf 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::query::Providers; use rustc_middle::thir::visit; diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 862fb2e16639..e87058f9ba48 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index d0aa4eb2e714..41f482d8a706 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,6 +1,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::traits::{BuiltinImplSource, CodegenObligationError}; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index f78a28d16fdf..1ef22497a8fc 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -2,6 +2,7 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::{IndexSlice, IndexVec}; +use rustc_middle::bug; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 6332c614a90b..ab7d1be226b3 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -1,3 +1,4 @@ +use rustc_middle::bug; use rustc_middle::ty::{ layout::{LayoutCx, TyAndLayout}, TyCtxt, diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index fd392d11e831..e8c5c54d3a09 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -16,8 +16,6 @@ #![feature(let_chains)] #![feature(never_type)] -#[macro_use] -extern crate rustc_middle; #[macro_use] extern crate tracing; diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index ee930a78e77c..4e23fb303836 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop}; use rustc_middle::ty::GenericArgsRef; diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index d7d31a88c9b5..be227ec8b9aa 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -2,6 +2,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::intravisit::Visitor; use rustc_hir::{def::DefKind, def_id::LocalDefId}; use rustc_hir::{intravisit, CRATE_HIR_ID}; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::util::{CheckRegions, NotUniqueParam}; use rustc_middle::ty::{self, Ty, TyCtxt}; diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 446f16b41254..0ffb7f624965 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -1,5 +1,6 @@ use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, Representability, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 19c092c5ddf3..2d8c78267d9f 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -4,6 +4,7 @@ use rustc_ast_ir::try_visit; use rustc_ast_ir::visit::VisitorResult; use rustc_hir::{def::DefKind, def_id::LocalDefId}; +use rustc_middle::span_bug; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index fa1085c7cd79..492cc1d55cb0 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::LangItem; use rustc_index::bit_set::BitSet; +use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt, TypeVisitableExt, TypeVisitor}; use rustc_middle::ty::{ToPredicate, TypeSuperVisitable, TypeVisitable}; @@ -214,7 +215,7 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { self.predicates.push( ty::Binder::bind_with_vars( ty::ProjectionPredicate { - projection_ty: shifted_alias_ty, + projection_term: shifted_alias_ty.into(), term: default_ty.into(), }, self.bound_vars, diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 79ff60802d28..cef3f4e8ce05 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -13,7 +13,8 @@ rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } -smallvec = { version = "1.8.1" } +rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } +smallvec = { version = "1.8.1", default-features = false } # tidy-alphabetical-end [features] diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index f7c7ec242c10..efefd174cd6f 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -1,20 +1,25 @@ -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; use std::hash::Hash; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::inherent::*; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::{Interner, UniverseIndex}; /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are /// numbered starting from 0 in order of first appearance. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))] +#[derivative( + Clone(bound = "V: Clone"), + Hash(bound = "V: Hash"), + PartialEq(bound = "V: PartialEq"), + Eq(bound = "V: Eq"), + Debug(bound = "V: fmt::Debug"), + Copy(bound = "V: Copy") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub struct Canonical { pub value: V, @@ -64,18 +69,6 @@ impl Canonical { } } -impl Eq for Canonical {} - -impl PartialEq for Canonical { - fn eq(&self, other: &Self) -> bool { - let Self { value, max_universe, variables, defining_opaque_types } = self; - *value == other.value - && *max_universe == other.max_universe - && *variables == other.variables - && *defining_opaque_types == other.defining_opaque_types - } -} - impl fmt::Display for Canonical { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self { value, max_universe, variables, defining_opaque_types } = self; @@ -86,84 +79,25 @@ impl fmt::Display for Canonical { } } -impl fmt::Debug for Canonical { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; - f.debug_struct("Canonical") - .field("value", &value) - .field("max_universe", &max_universe) - .field("variables", &variables) - .field("defining_opaque_types", &defining_opaque_types) - .finish() - } -} - -impl Copy for Canonical where I::CanonicalVars: Copy {} - -impl> TypeFoldable for Canonical -where - I::CanonicalVars: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(Canonical { - value: self.value.try_fold_with(folder)?, - max_universe: self.max_universe.try_fold_with(folder)?, - variables: self.variables.try_fold_with(folder)?, - defining_opaque_types: self.defining_opaque_types, - }) - } -} - -impl> TypeVisitable for Canonical -where - I::CanonicalVars: TypeVisitable, -{ - fn visit_with>(&self, folder: &mut F) -> F::Result { - let Self { value, max_universe, variables, defining_opaque_types } = self; - try_visit!(value.visit_with(folder)); - try_visit!(max_universe.visit_with(folder)); - try_visit!(defining_opaque_types.visit_with(folder)); - variables.visit_with(folder) - } -} - /// Information about a canonical variable that is included with the /// canonical value. This is sufficient information for code to create /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Debug(bound = ""))] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + Debug(bound = ""), + Eq(bound = ""), + PartialEq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub struct CanonicalVarInfo { pub kind: CanonicalVarKind, } -impl PartialEq for CanonicalVarInfo { - fn eq(&self, other: &Self) -> bool { - self.kind == other.kind - } -} - -impl Eq for CanonicalVarInfo {} - -impl TypeVisitable for CanonicalVarInfo -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - self.kind.visit_with(visitor) - } -} - -impl TypeFoldable for CanonicalVarInfo -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(CanonicalVarInfo { kind: self.kind.try_fold_with(folder)? }) - } -} - impl CanonicalVarInfo { pub fn universe(self) -> UniverseIndex { self.kind.universe() @@ -216,6 +150,7 @@ impl CanonicalVarInfo { /// that analyzes type-like values. #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Debug(bound = ""))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum CanonicalVarKind { /// Some kind of type inference variable. @@ -258,51 +193,6 @@ impl PartialEq for CanonicalVarKind { } } -impl Eq for CanonicalVarKind {} - -impl TypeVisitable for CanonicalVarKind -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - CanonicalVarKind::Ty(_) - | CanonicalVarKind::PlaceholderTy(_) - | CanonicalVarKind::Region(_) - | CanonicalVarKind::PlaceholderRegion(_) - | CanonicalVarKind::Effect => V::Result::output(), - CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => { - ty.visit_with(visitor) - } - } - } -} - -impl TypeFoldable for CanonicalVarKind -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - CanonicalVarKind::Ty(kind) => CanonicalVarKind::Ty(kind), - CanonicalVarKind::Region(kind) => CanonicalVarKind::Region(kind), - CanonicalVarKind::Const(kind, ty) => { - CanonicalVarKind::Const(kind, ty.try_fold_with(folder)?) - } - CanonicalVarKind::PlaceholderTy(placeholder) => { - CanonicalVarKind::PlaceholderTy(placeholder) - } - CanonicalVarKind::PlaceholderRegion(placeholder) => { - CanonicalVarKind::PlaceholderRegion(placeholder) - } - CanonicalVarKind::PlaceholderConst(placeholder, ty) => { - CanonicalVarKind::PlaceholderConst(placeholder, ty.try_fold_with(folder)?) - } - CanonicalVarKind::Effect => CanonicalVarKind::Effect, - }) - } -} - impl CanonicalVarKind { pub fn universe(self) -> UniverseIndex { match self { @@ -355,6 +245,7 @@ impl CanonicalVarKind { /// usize or f32). In order to faithfully reproduce a type, we need to /// know what set of types a given type variable can be unified with. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] pub enum CanonicalTyVarKind { /// General type variable `?T` that can be unified with arbitrary types. diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index c1506f9252b0..c748cdf6ed27 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -10,7 +10,7 @@ use self::ConstKind::*; /// Represents a constant in Rust. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ConstKind { /// A const generic parameter. @@ -58,8 +58,6 @@ impl PartialEq for ConstKind { } } -impl Eq for ConstKind {} - impl fmt::Debug for ConstKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { WithInfcx::with_no_infcx(self).fmt(f) diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 0fd34e0a65f6..5e9816364389 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -1,5 +1,6 @@ use std::fmt::Debug; use std::hash::Hash; +use std::ops::Deref; use crate::fold::TypeSuperFoldable; use crate::visit::{Flags, TypeSuperVisitable}; @@ -50,7 +51,12 @@ pub trait GenericsOf> { } pub trait GenericArgs>: - Copy + DebugWithInfcx + Hash + Eq + IntoIterator + Copy + + DebugWithInfcx + + Hash + + Eq + + IntoIterator + + Deref> { fn type_at(self, i: usize) -> I::Ty; @@ -83,3 +89,21 @@ pub trait BoundVars { fn has_no_bound_vars(&self) -> bool; } + +pub trait AliasTerm: Copy + DebugWithInfcx + Hash + Eq + Sized { + fn new( + interner: I, + trait_def_id: I::DefId, + args: impl IntoIterator>, + ) -> Self; + + fn def_id(self) -> I::DefId; + + fn args(self) -> I::GenericArgs; + + fn trait_def_id(self, interner: I) -> I::DefId; + + fn self_ty(self) -> I::Ty; + + fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self; +} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index c8bd7fea11b9..af0e833b9e98 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -5,9 +5,23 @@ use std::hash::Hash; use crate::inherent::*; use crate::ir_print::IrPrint; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable}; -use crate::{CanonicalVarInfo, DebugWithInfcx, TraitRef}; +use crate::{ + CanonicalVarInfo, CoercePredicate, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, + NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, +}; -pub trait Interner: Sized + Copy + IrPrint> { +pub trait Interner: + Sized + + Copy + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> + + IrPrint> +{ type DefId: Copy + Debug + Hash + Eq; type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable; type AdtDef: Copy + Debug + Hash + Eq; @@ -25,7 +39,7 @@ pub trait Interner: Sized + Copy + IrPrint> { // Kinds of tys type Ty: Ty; type Tys: Copy + Debug + Hash + Eq + IntoIterator; - type AliasTy: Copy + DebugWithInfcx + Hash + Eq; + type AliasTy: Copy + DebugWithInfcx + Hash + Eq + Sized; type ParamTy: Copy + Debug + Hash + Eq; type BoundTy: Copy + Debug + Hash + Eq; type PlaceholderTy: PlaceholderLike; @@ -60,6 +74,7 @@ pub trait Interner: Sized + Copy + IrPrint> { type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; type TypeOutlivesPredicate: Copy + Debug + Hash + Eq; type ProjectionPredicate: Copy + Debug + Hash + Eq; + type AliasTerm: AliasTerm; type NormalizesTo: Copy + Debug + Hash + Eq; type SubtypePredicate: Copy + Debug + Hash + Eq; type CoercePredicate: Copy + Debug + Hash + Eq; @@ -71,11 +86,15 @@ pub trait Interner: Sized + Copy + IrPrint> { type GenericsOf: GenericsOf; fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf; + fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs; + fn check_and_mk_args( self, def_id: Self::DefId, args: impl IntoIterator>, ) -> Self::GenericArgs; + + fn parent(self, def_id: Self::DefId) -> Self::DefId; } /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` diff --git a/compiler/rustc_type_ir/src/ir_print.rs b/compiler/rustc_type_ir/src/ir_print.rs index 84e889b486af..5885139754af 100644 --- a/compiler/rustc_type_ir/src/ir_print.rs +++ b/compiler/rustc_type_ir/src/ir_print.rs @@ -1,6 +1,9 @@ use std::fmt; -use crate::{Interner, TraitRef}; +use crate::{ + CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner, NormalizesTo, + ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef, +}; pub trait IrPrint { fn print(t: &T, fmt: &mut fmt::Formatter<'_>) -> fmt::Result; @@ -15,7 +18,13 @@ macro_rules! define_display_via_print { >>::print(self, fmt) } } + )* + } +} +macro_rules! define_debug_via_print { + ($($ty:ident),+ $(,)?) => { + $( impl fmt::Debug for $ty { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { >>::print_debug(self, fmt) @@ -25,4 +34,15 @@ macro_rules! define_display_via_print { } } -define_display_via_print!(TraitRef,); +define_display_via_print!( + TraitRef, + TraitPredicate, + ExistentialTraitRef, + ExistentialProjection, + ProjectionPredicate, + NormalizesTo, + SubtypePredicate, + CoercePredicate, +); + +define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 62efa32c9f2f..4560a54da82b 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -37,9 +37,9 @@ mod debug; mod flags; mod infcx; mod interner; +mod predicate; mod predicate_kind; mod region_kind; -mod trait_ref; pub use canonical::*; #[cfg(feature = "nightly")] @@ -49,12 +49,12 @@ pub use debug::{DebugWithInfcx, WithInfcx}; pub use flags::*; pub use infcx::InferCtxtLike; pub use interner::*; +pub use predicate::*; pub use predicate_kind::*; pub use region_kind::*; -pub use trait_ref::*; pub use ty_info::*; pub use ty_kind::*; -pub use AliasKind::*; +pub use AliasTyKind::*; pub use DynKind::*; pub use InferTy::*; pub use RegionKind::*; diff --git a/compiler/rustc_type_ir/src/macros.rs b/compiler/rustc_type_ir/src/macros.rs index 7dcc8851a43f..f2f7b165de52 100644 --- a/compiler/rustc_type_ir/src/macros.rs +++ b/compiler/rustc_type_ir/src/macros.rs @@ -53,4 +53,5 @@ TrivialTypeTraversalImpls! { crate::UniverseIndex, rustc_ast_ir::Mutability, rustc_ast_ir::Movability, + crate::PredicatePolarity, } diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs new file mode 100644 index 000000000000..71f198d2b8e8 --- /dev/null +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -0,0 +1,469 @@ +use std::fmt; + +#[cfg(feature = "nightly")] +use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic}; + +use crate::inherent::*; +use crate::visit::TypeVisitableExt as _; +use crate::{DebugWithInfcx, Interner}; + +/// A complete reference to a trait. These take numerous guises in syntax, +/// but perhaps the most recognizable form is in a where-clause: +/// ```ignore (illustrative) +/// T: Foo +/// ``` +/// This would be represented by a trait-reference where the `DefId` is the +/// `DefId` for the trait `Foo` and the args define `T` as parameter 0, +/// and `U` as parameter 1. +/// +/// Trait references also appear in object types like `Foo`, but in +/// that case the `Self` parameter is absent from the generic parameters. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitRef { + pub def_id: I::DefId, + pub args: I::GenericArgs, + /// This field exists to prevent the creation of `TraitRef` without + /// calling [`TraitRef::new`]. + _use_trait_ref_new_instead: (), +} + +impl TraitRef { + pub fn new( + interner: I, + trait_def_id: I::DefId, + args: impl IntoIterator>, + ) -> Self { + let args = interner.check_and_mk_args(trait_def_id, args); + Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } + } + + pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef { + let generics = interner.generics_of(trait_id); + TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) + } + + /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` + /// are the parameters defined on trait. + pub fn identity(interner: I, def_id: I::DefId) -> TraitRef { + TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id)) + } + + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + TraitRef::new( + interner, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), + ) + } + + #[inline] + pub fn self_ty(&self) -> I::Ty { + self.args.type_at(0) + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct TraitPredicate { + pub trait_ref: TraitRef, + + /// If polarity is Positive: we are proving that the trait is implemented. + /// + /// If polarity is Negative: we are proving that a negative impl of this trait + /// exists. (Note that coherence also checks whether negative impls of supertraits + /// exist via a series of predicates.) + /// + /// If polarity is Reserved: that's a bug. + pub polarity: PredicatePolarity, +} + +impl TraitPredicate { + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } + } + + pub fn def_id(self) -> I::DefId { + self.trait_ref.def_id + } + + pub fn self_ty(self) -> I::Ty { + self.trait_ref.self_ty() + } +} + +impl fmt::Debug for TraitPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // FIXME(effects) printing? + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) + } +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum ImplPolarity { + /// `impl Trait for Type` + Positive, + /// `impl !Trait for Type` + Negative, + /// `#[rustc_reservation_impl] impl Trait for Type` + /// + /// This is a "stability hack", not a real Rust feature. + /// See #64631 for details. + Reservation, +} + +impl fmt::Display for ImplPolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + Self::Reservation => f.write_str("reservation"), + } + } +} + +/// Polarity for a trait predicate. May either be negative or positive. +/// Distinguished from [`ImplPolarity`] since we never compute goals with +/// "reservation" level. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum PredicatePolarity { + /// `Type: Trait` + Positive, + /// `Type: !Trait` + Negative, +} + +impl PredicatePolarity { + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. + pub fn flip(&self) -> PredicatePolarity { + match self { + PredicatePolarity::Positive => PredicatePolarity::Negative, + PredicatePolarity::Negative => PredicatePolarity::Positive, + } + } +} + +impl fmt::Display for PredicatePolarity { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Positive => f.write_str("positive"), + Self::Negative => f.write_str("negative"), + } + } +} + +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum ExistentialPredicate { + /// E.g., `Iterator`. + Trait(ExistentialTraitRef), + /// E.g., `Iterator::Item = T`. + Projection(ExistentialProjection), + /// E.g., `Send`. + AutoTrait(I::DefId), +} + +// FIXME: Implement this the right way after +impl DebugWithInfcx for ExistentialPredicate { + fn fmt>( + this: rustc_type_ir::WithInfcx<'_, Infcx, &Self>, + f: &mut fmt::Formatter<'_>, + ) -> fmt::Result { + fmt::Debug::fmt(&this.data, f) + } +} + +/// An existential reference to a trait, where `Self` is erased. +/// For example, the trait object `Trait<'a, 'b, X, Y>` is: +/// ```ignore (illustrative) +/// exists T. T: Trait<'a, 'b, X, Y> +/// ``` +/// The generic parameters don't include the erased `Self`, only trait +/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above). +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ExistentialTraitRef { + pub def_id: I::DefId, + pub args: I::GenericArgs, +} + +impl ExistentialTraitRef { + pub fn erase_self_ty(interner: I, trait_ref: TraitRef) -> ExistentialTraitRef { + // Assert there is a Self. + trait_ref.args.type_at(0); + + ExistentialTraitRef { + def_id: trait_ref.def_id, + args: interner.mk_args(&trait_ref.args[1..]), + } + } + + /// Object types don't have a self type specified. Therefore, when + /// we convert the principal trait-ref into a normal trait-ref, + /// you must give *some* self type. A common choice is `mk_err()` + /// or some placeholder type. + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> TraitRef { + // otherwise the escaping vars would be captured by the binder + // debug_assert!(!self_ty.has_escaping_bound_vars()); + + TraitRef::new( + interner, + self.def_id, + [self_ty.into()].into_iter().chain(self.args.into_iter()), + ) + } +} + +/// A `ProjectionPredicate` for an `ExistentialTraitRef`. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ExistentialProjection { + pub def_id: I::DefId, + pub args: I::GenericArgs, + pub term: I::Term, +} + +impl ExistentialProjection { + /// Extracts the underlying existential trait reference from this projection. + /// For example, if this is a projection of `exists T. ::Item == X`, + /// then this function would return an `exists T. T: Iterator` existential trait + /// reference. + pub fn trait_ref(&self, tcx: I) -> ExistentialTraitRef { + let def_id = tcx.parent(self.def_id); + let args_count = tcx.generics_of(def_id).count() - 1; + let args = tcx.mk_args(&self.args[..args_count]); + ExistentialTraitRef { def_id, args } + } + + pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate { + // otherwise the escaping regions would be captured by the binders + debug_assert!(!self_ty.has_escaping_bound_vars()); + + ProjectionPredicate { + projection_term: I::AliasTerm::new( + tcx, + self.def_id, + [self_ty.into()].into_iter().chain(self.args), + ), + term: self.term, + } + } + + pub fn erase_self_ty(tcx: I, projection_predicate: ProjectionPredicate) -> Self { + // Assert there is a Self. + projection_predicate.projection_term.args().type_at(0); + + Self { + def_id: projection_predicate.projection_term.def_id(), + args: tcx.mk_args(&projection_predicate.projection_term.args()[1..]), + term: projection_predicate.term, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] +pub enum AliasTermKind { + /// A projection `::AssocType`. + /// Can get normalized away if monomorphic enough. + ProjectionTy, + /// An associated type in an inherent `impl` + InherentTy, + /// An opaque type (usually from `impl Trait` in type aliases or function return types) + /// Can only be normalized away in RevealAll mode + OpaqueTy, + /// A type alias that actually checks its trait bounds. + /// Currently only used if the type alias references opaque types. + /// Can always be normalized away. + WeakTy, + /// An unevaluated const coming from a generic const expression. + UnevaluatedConst, + /// An unevaluated const coming from an associated const. + ProjectionConst, +} + +impl AliasTermKind { + pub fn descr(self) -> &'static str { + match self { + AliasTermKind::ProjectionTy => "associated type", + AliasTermKind::ProjectionConst => "associated const", + AliasTermKind::InherentTy => "inherent associated type", + AliasTermKind::OpaqueTy => "opaque type", + AliasTermKind::WeakTy => "type alias", + AliasTermKind::UnevaluatedConst => "unevaluated constant", + } + } +} + +/// This kind of predicate has no *direct* correspondent in the +/// syntax, but it roughly corresponds to the syntactic forms: +/// +/// 1. `T: TraitRef<..., Item = Type>` +/// 2. `>::Item == Type` (NYI) +/// +/// In particular, form #1 is "desugared" to the combination of a +/// normal trait predicate (`T: TraitRef<...>`) and one of these +/// predicates. Form #2 is a broader form in that it also permits +/// equality between arbitrary types. Processing an instance of +/// Form #2 eventually yields one of these `ProjectionPredicate` +/// instances to normalize the LHS. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct ProjectionPredicate { + pub projection_term: I::AliasTerm, + pub term: I::Term, +} + +impl ProjectionPredicate { + pub fn self_ty(self) -> I::Ty { + self.projection_term.self_ty() + } + + pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate { + Self { projection_term: self.projection_term.with_self_ty(tcx, self_ty), ..self } + } + + pub fn trait_def_id(self, tcx: I) -> I::DefId { + self.projection_term.trait_def_id(tcx) + } + + pub fn def_id(self) -> I::DefId { + self.projection_term.def_id() + } +} + +impl fmt::Debug for ProjectionPredicate { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "ProjectionPredicate({:?}, {:?})", self.projection_term, self.term) + } +} + +/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be +/// proven by actually normalizing `alias`. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct NormalizesTo { + pub alias: I::AliasTerm, + pub term: I::Term, +} + +impl NormalizesTo { + pub fn self_ty(self) -> I::Ty { + self.alias.self_ty() + } + + pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> NormalizesTo { + Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self } + } + + pub fn trait_def_id(self, tcx: I) -> I::DefId { + self.alias.trait_def_id(tcx) + } + + pub fn def_id(self) -> I::DefId { + self.alias.def_id() + } +} + +impl fmt::Debug for NormalizesTo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) + } +} + +/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates +/// whether the `a` type is the type that we should label as "expected" when +/// presenting user diagnostics. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct SubtypePredicate { + pub a_is_expected: bool, + pub a: I::Ty, + pub b: I::Ty, +} + +/// Encodes that we have to coerce *from* the `a` type to the `b` type. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Hash(bound = ""), + PartialEq(bound = ""), + Eq(bound = ""), + Debug(bound = "") +)] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct CoercePredicate { + pub a: I::Ty, + pub b: I::Ty, +} diff --git a/compiler/rustc_type_ir/src/predicate_kind.rs b/compiler/rustc_type_ir/src/predicate_kind.rs index 5260d9061cfc..c477ab14153e 100644 --- a/compiler/rustc_type_ir/src/predicate_kind.rs +++ b/compiler/rustc_type_ir/src/predicate_kind.rs @@ -1,17 +1,15 @@ -use rustc_ast_ir::try_visit; -use rustc_ast_ir::visit::VisitorResult; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; /// A clause is something that can appear in where bounds or be inferred /// by implied bounds. #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum ClauseKind { /// Corresponds to `where Foo: Bar`. `Foo` here would be @@ -55,61 +53,6 @@ impl PartialEq for ClauseKind { } } -impl Eq for ClauseKind {} - -impl TypeFoldable for ClauseKind -where - I::Ty: TypeFoldable, - I::Const: TypeFoldable, - I::GenericArg: TypeFoldable, - I::TraitPredicate: TypeFoldable, - I::ProjectionPredicate: TypeFoldable, - I::TypeOutlivesPredicate: TypeFoldable, - I::RegionOutlivesPredicate: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - ClauseKind::Trait(p) => ClauseKind::Trait(p.try_fold_with(folder)?), - ClauseKind::RegionOutlives(p) => ClauseKind::RegionOutlives(p.try_fold_with(folder)?), - ClauseKind::TypeOutlives(p) => ClauseKind::TypeOutlives(p.try_fold_with(folder)?), - ClauseKind::Projection(p) => ClauseKind::Projection(p.try_fold_with(folder)?), - ClauseKind::ConstArgHasType(c, t) => { - ClauseKind::ConstArgHasType(c.try_fold_with(folder)?, t.try_fold_with(folder)?) - } - ClauseKind::WellFormed(p) => ClauseKind::WellFormed(p.try_fold_with(folder)?), - ClauseKind::ConstEvaluatable(p) => { - ClauseKind::ConstEvaluatable(p.try_fold_with(folder)?) - } - }) - } -} - -impl TypeVisitable for ClauseKind -where - I::Ty: TypeVisitable, - I::Const: TypeVisitable, - I::GenericArg: TypeVisitable, - I::TraitPredicate: TypeVisitable, - I::ProjectionPredicate: TypeVisitable, - I::TypeOutlivesPredicate: TypeVisitable, - I::RegionOutlivesPredicate: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - ClauseKind::Trait(p) => p.visit_with(visitor), - ClauseKind::RegionOutlives(p) => p.visit_with(visitor), - ClauseKind::TypeOutlives(p) => p.visit_with(visitor), - ClauseKind::Projection(p) => p.visit_with(visitor), - ClauseKind::ConstArgHasType(c, t) => { - try_visit!(c.visit_with(visitor)); - t.visit_with(visitor) - } - ClauseKind::WellFormed(p) => p.visit_with(visitor), - ClauseKind::ConstEvaluatable(p) => p.visit_with(visitor), - } - } -} - #[derive(derivative::Derivative)] #[derivative( Clone(bound = ""), @@ -118,6 +61,7 @@ where PartialEq(bound = ""), Eq(bound = "") )] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum PredicateKind { /// Prove a clause @@ -167,69 +111,6 @@ pub enum PredicateKind { AliasRelate(I::Term, I::Term, AliasRelationDirection), } -impl TypeFoldable for PredicateKind -where - I::DefId: TypeFoldable, - I::Const: TypeFoldable, - I::GenericArgs: TypeFoldable, - I::Term: TypeFoldable, - I::CoercePredicate: TypeFoldable, - I::SubtypePredicate: TypeFoldable, - I::NormalizesTo: TypeFoldable, - ClauseKind: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(match self { - PredicateKind::Clause(c) => PredicateKind::Clause(c.try_fold_with(folder)?), - PredicateKind::ObjectSafe(d) => PredicateKind::ObjectSafe(d.try_fold_with(folder)?), - PredicateKind::Subtype(s) => PredicateKind::Subtype(s.try_fold_with(folder)?), - PredicateKind::Coerce(s) => PredicateKind::Coerce(s.try_fold_with(folder)?), - PredicateKind::ConstEquate(a, b) => { - PredicateKind::ConstEquate(a.try_fold_with(folder)?, b.try_fold_with(folder)?) - } - PredicateKind::Ambiguous => PredicateKind::Ambiguous, - PredicateKind::NormalizesTo(p) => PredicateKind::NormalizesTo(p.try_fold_with(folder)?), - PredicateKind::AliasRelate(a, b, d) => PredicateKind::AliasRelate( - a.try_fold_with(folder)?, - b.try_fold_with(folder)?, - d.try_fold_with(folder)?, - ), - }) - } -} - -impl TypeVisitable for PredicateKind -where - I::DefId: TypeVisitable, - I::Const: TypeVisitable, - I::GenericArgs: TypeVisitable, - I::Term: TypeVisitable, - I::CoercePredicate: TypeVisitable, - I::SubtypePredicate: TypeVisitable, - I::NormalizesTo: TypeVisitable, - ClauseKind: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - match self { - PredicateKind::Clause(p) => p.visit_with(visitor), - PredicateKind::ObjectSafe(d) => d.visit_with(visitor), - PredicateKind::Subtype(s) => s.visit_with(visitor), - PredicateKind::Coerce(s) => s.visit_with(visitor), - PredicateKind::ConstEquate(a, b) => { - try_visit!(a.visit_with(visitor)); - b.visit_with(visitor) - } - PredicateKind::Ambiguous => V::Result::output(), - PredicateKind::NormalizesTo(p) => p.visit_with(visitor), - PredicateKind::AliasRelate(a, b, d) => { - try_visit!(a.visit_with(visitor)); - try_visit!(b.visit_with(visitor)); - d.visit_with(visitor) - } - } - } -} - #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[cfg_attr(feature = "nightly", derive(HashStable_NoContext, Encodable, Decodable))] pub enum AliasRelationDirection { diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs index d1b86b495e9d..eaae4ee0130b 100644 --- a/compiler/rustc_type_ir/src/region_kind.rs +++ b/compiler/rustc_type_ir/src/region_kind.rs @@ -115,7 +115,7 @@ use self::RegionKind::*; /// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/ /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))] pub enum RegionKind { /// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`. @@ -208,9 +208,6 @@ impl PartialEq for RegionKind { } } -// This is manually implemented because a derive would require `I: Eq` -impl Eq for RegionKind {} - impl DebugWithInfcx for RegionKind { fn fmt>( this: WithInfcx<'_, Infcx, &Self>, diff --git a/compiler/rustc_type_ir/src/trait_ref.rs b/compiler/rustc_type_ir/src/trait_ref.rs deleted file mode 100644 index 4bd513ab7e19..000000000000 --- a/compiler/rustc_type_ir/src/trait_ref.rs +++ /dev/null @@ -1,109 +0,0 @@ -use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; - -use crate::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::inherent::*; -use crate::lift::Lift; -use crate::visit::{TypeVisitable, TypeVisitor}; -use crate::Interner; - -/// A complete reference to a trait. These take numerous guises in syntax, -/// but perhaps the most recognizable form is in a where-clause: -/// ```ignore (illustrative) -/// T: Foo -/// ``` -/// This would be represented by a trait-reference where the `DefId` is the -/// `DefId` for the trait `Foo` and the args define `T` as parameter 0, -/// and `U` as parameter 1. -/// -/// Trait references also appear in object types like `Foo`, but in -/// that case the `Self` parameter is absent from the generic parameters. -#[derive(derivative::Derivative)] -#[derivative( - Clone(bound = ""), - Copy(bound = ""), - Hash(bound = ""), - PartialEq(bound = ""), - Eq(bound = "") -)] -#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] -pub struct TraitRef { - pub def_id: I::DefId, - pub args: I::GenericArgs, - /// This field exists to prevent the creation of `TraitRef` without - /// calling [`TraitRef::new`]. - _use_trait_ref_new_instead: (), -} - -impl TraitRef { - pub fn new( - interner: I, - trait_def_id: I::DefId, - args: impl IntoIterator>, - ) -> Self { - let args = interner.check_and_mk_args(trait_def_id, args); - Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () } - } - - pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef { - let generics = interner.generics_of(trait_id); - TraitRef::new(interner, trait_id, args.into_iter().take(generics.count())) - } - - /// Returns a `TraitRef` of the form `P0: Foo` where `Pi` - /// are the parameters defined on trait. - pub fn identity(interner: I, def_id: I::DefId) -> TraitRef { - TraitRef::new(interner, def_id, I::GenericArgs::identity_for_item(interner, def_id)) - } - - pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { - TraitRef::new( - interner, - self.def_id, - [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)), - ) - } - - #[inline] - pub fn self_ty(&self) -> I::Ty { - self.args.type_at(0) - } -} - -// FIXME(compiler-errors): Make this into a `Lift_Generic` impl. -impl Lift for TraitRef -where - I::DefId: Lift, - I::GenericArgs: Lift, -{ - type Lifted = TraitRef; - - fn lift_to_tcx(self, tcx: U) -> Option { - Some(TraitRef { - def_id: self.def_id.lift_to_tcx(tcx)?, - args: self.args.lift_to_tcx(tcx)?, - _use_trait_ref_new_instead: (), - }) - } -} - -impl TypeVisitable for TraitRef -where - I::GenericArgs: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - self.args.visit_with(visitor) - } -} - -impl TypeFoldable for TraitRef -where - I::GenericArgs: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(TraitRef { - def_id: self.def_id, - args: self.args.try_fold_with(folder)?, - _use_trait_ref_new_instead: (), - }) - } -} diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index f2e4afecc402..6e544d0e6ace 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -1,14 +1,12 @@ -use rustc_ast_ir::try_visit; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; #[cfg(feature = "nightly")] use rustc_data_structures::unify::{EqUnifyValue, UnifyKey}; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; use std::fmt; -use crate::fold::{FallibleTypeFolder, TypeFoldable}; -use crate::visit::{TypeVisitable, TypeVisitor}; use crate::Interner; use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx}; @@ -33,7 +31,7 @@ pub enum DynKind { #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))] -pub enum AliasKind { +pub enum AliasTyKind { /// A projection `::AssocType`. /// Can get normalized away if monomorphic enough. Projection, @@ -48,13 +46,13 @@ pub enum AliasKind { Weak, } -impl AliasKind { +impl AliasTyKind { pub fn descr(self) -> &'static str { match self { - AliasKind::Projection => "associated type", - AliasKind::Inherent => "inherent associated type", - AliasKind::Opaque => "opaque type", - AliasKind::Weak => "type alias", + AliasTyKind::Projection => "associated type", + AliasTyKind::Inherent => "inherent associated type", + AliasTyKind::Opaque => "opaque type", + AliasTyKind::Weak => "type alias", } } } @@ -65,7 +63,7 @@ impl AliasKind { /// converted to this representation using `::lower_ty`. #[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")] #[derive(derivative::Derivative)] -#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""))] +#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TyKind { /// The primitive boolean type. Written as `bool`. @@ -203,7 +201,7 @@ pub enum TyKind { /// A projection, opaque type, weak type alias, or inherent associated type. /// All of these types are represented as pairs of def-id and args, and can /// be normalized, so they are grouped conceptually. - Alias(AliasKind, I::AliasTy), + Alias(AliasTyKind, I::AliasTy), /// A type parameter; for example, `T` in `fn f(x: T) {}`. Param(I::ParamTy), @@ -341,9 +339,6 @@ impl PartialEq for TyKind { } } -// This is manually implemented because a derive would require `I: Eq` -impl Eq for TyKind {} - impl DebugWithInfcx for TyKind { fn fmt>( this: WithInfcx<'_, Infcx, &Self>, @@ -804,29 +799,8 @@ impl DebugWithInfcx for InferTy { Debug(bound = "") )] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] +#[derive(TypeVisitable_Generic, TypeFoldable_Generic)] pub struct TypeAndMut { pub ty: I::Ty, pub mutbl: Mutability, } - -impl TypeFoldable for TypeAndMut -where - I::Ty: TypeFoldable, -{ - fn try_fold_with>(self, folder: &mut F) -> Result { - Ok(TypeAndMut { - ty: self.ty.try_fold_with(folder)?, - mutbl: self.mutbl.try_fold_with(folder)?, - }) - } -} - -impl TypeVisitable for TypeAndMut -where - I::Ty: TypeVisitable, -{ - fn visit_with>(&self, visitor: &mut V) -> V::Result { - try_visit!(self.ty.visit_with(visitor)); - self.mutbl.visit_with(visitor) - } -} diff --git a/compiler/rustc_type_ir_macros/Cargo.toml b/compiler/rustc_type_ir_macros/Cargo.toml new file mode 100644 index 000000000000..cb95ca683462 --- /dev/null +++ b/compiler/rustc_type_ir_macros/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rustc_type_ir_macros" +version = "0.0.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +# tidy-alphabetical-start +proc-macro2 = "1" +quote = "1" +syn = { version = "2.0.9", features = ["full"] } +synstructure = "0.13.0" +# tidy-alphabetical-end diff --git a/compiler/rustc_type_ir_macros/src/lib.rs b/compiler/rustc_type_ir_macros/src/lib.rs new file mode 100644 index 000000000000..000bcf2d3b27 --- /dev/null +++ b/compiler/rustc_type_ir_macros/src/lib.rs @@ -0,0 +1,159 @@ +use quote::quote; +use syn::{parse_quote, visit_mut::VisitMut}; +use synstructure::decl_derive; + +decl_derive!( + [TypeFoldable_Generic] => type_foldable_derive +); +decl_derive!( + [TypeVisitable_Generic] => type_visitable_derive +); +decl_derive!( + [Lift_Generic] => lift_derive +); + +fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_bounds(synstructure::AddBounds::Fields); + s.bind_with(|_| synstructure::BindStyle::Move); + let body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|_, index| { + let bind = &bindings[index]; + quote! { + ::rustc_type_ir::fold::TypeFoldable::try_fold_with(#bind, __folder)? + } + }) + }); + + s.bound_impl( + quote!(::rustc_type_ir::fold::TypeFoldable), + quote! { + fn try_fold_with<__F: ::rustc_type_ir::fold::FallibleTypeFolder>( + self, + __folder: &mut __F + ) -> Result { + Ok(match self { #body_fold }) + } + }, + ) +} + +fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_bounds(synstructure::AddBounds::None); + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_impl_generic(parse_quote! { J }); + s.add_where_predicate(parse_quote! { J: Interner }); + + let mut wc = vec![]; + s.bind_with(|_| synstructure::BindStyle::Move); + let body_fold = s.each_variant(|vi| { + let bindings = vi.bindings(); + vi.construct(|field, index| { + let ty = field.ty.clone(); + let lifted_ty = lift(ty.clone()); + wc.push(parse_quote! { #ty: ::rustc_type_ir::lift::Lift }); + let bind = &bindings[index]; + quote! { + #bind.lift_to_tcx(interner)? + } + }) + }); + for wc in wc { + s.add_where_predicate(wc); + } + + let (_, ty_generics, _) = s.ast().generics.split_for_impl(); + let name = s.ast().ident.clone(); + let self_ty: syn::Type = parse_quote! { #name #ty_generics }; + let lifted_ty = lift(self_ty); + + s.bound_impl( + quote!(::rustc_type_ir::lift::Lift), + quote! { + type Lifted = #lifted_ty; + + fn lift_to_tcx( + self, + interner: J, + ) -> Option { + Some(match self { #body_fold }) + } + }, + ) +} + +fn lift(mut ty: syn::Type) -> syn::Type { + struct ItoJ; + impl VisitMut for ItoJ { + fn visit_type_path_mut(&mut self, i: &mut syn::TypePath) { + if i.qself.is_none() { + if let Some(first) = i.path.segments.first_mut() { + if first.ident == "I" { + *first = parse_quote! { J }; + } + } + } + syn::visit_mut::visit_type_path_mut(self, i); + } + } + + ItoJ.visit_type_mut(&mut ty); + + ty +} + +fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream { + if let syn::Data::Union(_) = s.ast().data { + panic!("cannot derive on union") + } + + if !s.ast().generics.type_params().any(|ty| ty.ident == "I") { + s.add_impl_generic(parse_quote! { I }); + } + + s.add_where_predicate(parse_quote! { I: Interner }); + s.add_bounds(synstructure::AddBounds::Fields); + let body_visit = s.each(|bind| { + quote! { + match ::rustc_ast_ir::visit::VisitorResult::branch( + ::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor) + ) { + ::core::ops::ControlFlow::Continue(()) => {}, + ::core::ops::ControlFlow::Break(r) => { + return ::rustc_ast_ir::visit::VisitorResult::from_residual(r); + }, + } + } + }); + s.bind_with(|_| synstructure::BindStyle::Move); + + s.bound_impl( + quote!(::rustc_type_ir::visit::TypeVisitable), + quote! { + fn visit_with<__V: ::rustc_type_ir::visit::TypeVisitor>( + &self, + __visitor: &mut __V + ) -> __V::Result { + match *self { #body_visit } + <__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output() + } + }, + ) +} diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index bc6fb34493a6..562516138404 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -897,6 +897,12 @@ pub struct AliasTy { pub args: GenericArgs, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct AliasTerm { + pub def_id: AliasDef, + pub args: GenericArgs, +} + pub type PolyFnSig = Binder; #[derive(Clone, Debug, Eq, PartialEq)] @@ -1350,7 +1356,7 @@ pub type TypeOutlivesPredicate = OutlivesPredicate; #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProjectionPredicate { - pub projection_ty: AliasTy, + pub projection_term: AliasTerm, pub term: TermKind, } diff --git a/config.example.toml b/config.example.toml index 3b76952504f2..224d079b2069 100644 --- a/config.example.toml +++ b/config.example.toml @@ -213,17 +213,17 @@ # the root of the repository. #build-dir = "build" -# Instead of downloading the src/stage0.json version of Cargo specified, use +# Instead of downloading the src/stage0 version of Cargo specified, use # this Cargo binary instead to build all Rust code # If you set this, you likely want to set `rustc` as well. #cargo = "/path/to/cargo" -# Instead of downloading the src/stage0.json version of the compiler +# Instead of downloading the src/stage0 version of the compiler # specified, use this rustc binary instead as the stage0 snapshot compiler. # If you set this, you likely want to set `cargo` as well. #rustc = "/path/to/rustc" -# Instead of downloading the src/stage0.json version of rustfmt specified, +# Instead of downloading the src/stage0 version of rustfmt specified, # use this rustfmt binary instead as the stage0 snapshot rustfmt. #rustfmt = "/path/to/rustfmt" diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index b9918752540f..ae44cab8131b 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -403,7 +403,7 @@ //! is, a formatting implementation must and may only return an error if the //! passed-in [`Formatter`] returns an error. This is because, contrary to what //! the function signature might suggest, string formatting is an infallible -//! operation. This function only returns a result because writing to the +//! operation. This function only returns a [`Result`] because writing to the //! underlying stream might fail and it must provide a way to propagate the fact //! that an error has occurred back up the stack. //! @@ -630,7 +630,9 @@ pub fn format(args: Arguments<'_>) -> string::String { fn format_inner(args: Arguments<'_>) -> string::String { let capacity = args.estimated_capacity(); let mut output = string::String::with_capacity(capacity); - output.write_fmt(args).expect("a formatting trait implementation returned an error"); + output + .write_fmt(args) + .expect("a formatting trait implementation returned an error when the underlying stream did not"); output } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index c245b42c3e88..45b205356758 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -365,6 +365,12 @@ impl Rc { unsafe { self.ptr.as_ref() } } + #[inline] + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); + (this.ptr, unsafe { ptr::read(&this.alloc) }) + } + #[inline] unsafe fn from_inner_in(ptr: NonNull>, alloc: A) -> Self { Self { ptr, phantom: PhantomData, alloc } @@ -1145,12 +1151,9 @@ impl Rc, A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_inner_in(md_self.ptr.cast(), md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -1189,12 +1192,9 @@ impl Rc<[mem::MaybeUninit], A> { /// ``` #[unstable(feature = "new_uninit", issue = "63291")] #[inline] - pub unsafe fn assume_init(self) -> Rc<[T], A> - where - A: Clone, - { - let md_self = mem::ManuallyDrop::new(self); - unsafe { Rc::from_ptr_in(md_self.ptr.as_ptr() as _, md_self.alloc.clone()) } + pub unsafe fn assume_init(self) -> Rc<[T], A> { + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -1809,7 +1809,9 @@ impl Rc { // reference to the allocation. unsafe { &mut this.ptr.as_mut().value } } +} +impl Rc { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// @@ -1845,7 +1847,7 @@ impl Rc { } } -impl Rc { +impl Rc { /// Attempt to downcast the `Rc` to a concrete type. /// /// # Examples @@ -1869,10 +1871,8 @@ impl Rc { pub fn downcast(self) -> Result, Self> { if (*self).is::() { unsafe { - let ptr = self.ptr.cast::>(); - let alloc = self.alloc.clone(); - forget(self); - Ok(Rc::from_inner_in(ptr, alloc)) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Ok(Rc::from_inner_in(ptr.cast(), alloc)) } } else { Err(self) @@ -1909,10 +1909,8 @@ impl Rc { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Rc { unsafe { - let ptr = self.ptr.cast::>(); - let alloc = self.alloc.clone(); - mem::forget(self); - Rc::from_inner_in(ptr, alloc) + let (ptr, alloc) = Rc::into_inner_with_allocator(self); + Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -2661,12 +2659,13 @@ impl From> for Rc<[u8]> { } #[stable(feature = "boxed_slice_try_from", since = "1.43.0")] -impl TryFrom> for Rc<[T; N]> { - type Error = Rc<[T]>; +impl TryFrom> for Rc<[T; N], A> { + type Error = Rc<[T], A>; - fn try_from(boxed_slice: Rc<[T]>) -> Result { + fn try_from(boxed_slice: Rc<[T], A>) -> Result { if boxed_slice.len() == N { - Ok(unsafe { Rc::from_raw(Rc::into_raw(boxed_slice) as *mut [T; N]) }) + let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice); + Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 297a273d274b..a35c99849b34 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -280,8 +280,8 @@ impl Arc { impl Arc { #[inline] - fn internal_into_inner_with_allocator(self) -> (NonNull>, A) { - let this = mem::ManuallyDrop::new(self); + fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { + let this = mem::ManuallyDrop::new(this); (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -1290,7 +1290,7 @@ impl Arc, A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_inner_in(ptr.cast(), alloc) } } } @@ -1332,7 +1332,7 @@ impl Arc<[mem::MaybeUninit], A> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub unsafe fn assume_init(self) -> Arc<[T], A> { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -2227,7 +2227,9 @@ impl Arc { // either unique to begin with, or became one upon cloning the contents. unsafe { Self::get_mut_unchecked(this) } } +} +impl Arc { /// If we have the only reference to `T` then unwrap it. Otherwise, clone `T` and return the /// clone. /// @@ -2499,7 +2501,7 @@ impl Arc { { if (*self).is::() { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Ok(Arc::from_inner_in(ptr.cast(), alloc)) } } else { @@ -2540,7 +2542,7 @@ impl Arc { T: Any + Send + Sync, { unsafe { - let (ptr, alloc) = self.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(self); Arc::from_inner_in(ptr.cast(), alloc) } } @@ -3506,7 +3508,7 @@ impl TryFrom> for Arc<[T; N], A> { fn try_from(boxed_slice: Arc<[T], A>) -> Result { if boxed_slice.len() == N { - let (ptr, alloc) = boxed_slice.internal_into_inner_with_allocator(); + let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) diff --git a/library/core/src/fmt/fmt_trait_method_doc.md b/library/core/src/fmt/fmt_trait_method_doc.md new file mode 100644 index 000000000000..493d929243d2 --- /dev/null +++ b/library/core/src/fmt/fmt_trait_method_doc.md @@ -0,0 +1,8 @@ +Formats the value using the given formatter. + +# Errors + +This function should return [`Err`] if, and only if, the provided [`Formatter`] returns [`Err`]. +String formatting is considered an infallible operation; this function only +returns a [`Result`] because writing to the underlying stream might fail and it must +provide a way to propagate the fact that an error has occurred back up the stack. diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index ce0643a3f5ef..9b372eac5245 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -72,14 +72,24 @@ pub type Result = result::Result<(), Error>; /// The error type which is returned from formatting a message into a stream. /// /// This type does not support transmission of an error other than that an error -/// occurred. Any extra information must be arranged to be transmitted through -/// some other means. +/// occurred. This is because, despite the existence of this error, +/// string formatting is considered an infallible operation. +/// `fmt()` implementors should not return this `Error` unless they received it from their +/// [`Formatter`]. The only time your code should create a new instance of this +/// error is when implementing `fmt::Write`, in order to cancel the formatting operation when +/// writing to the underlying stream fails. /// -/// An important thing to remember is that the type `fmt::Error` should not be +/// Any extra information must be arranged to be transmitted through some other means, +/// such as storing it in a field to be consulted after the formatting operation has been +/// cancelled. (For example, this is how [`std::io::Write::write_fmt()`] propagates IO errors +/// during writing.) +/// +/// This type, `fmt::Error`, should not be /// confused with [`std::io::Error`] or [`std::error::Error`], which you may also /// have in scope. /// /// [`std::io::Error`]: ../../std/io/struct.Error.html +/// [`std::io::Write::write_fmt()`]: ../../std/io/trait.Write.html#method.write_fmt /// [`std::error::Error`]: ../../std/error/trait.Error.html /// /// # Examples @@ -118,8 +128,10 @@ pub trait Write { /// This function will return an instance of [`std::fmt::Error`][Error] on error. /// /// The purpose of that error is to abort the formatting operation when the underlying - /// destination encounters some error preventing it from accepting more text; it should - /// generally be propagated rather than handled, at least when implementing formatting traits. + /// destination encounters some error preventing it from accepting more text; + /// in particular, it does not communicate any information about *what* error occurred. + /// It should generally be propagated rather than handled, at least when implementing + /// formatting traits. /// /// # Examples /// @@ -586,7 +598,7 @@ impl Display for Arguments<'_> { #[rustc_diagnostic_item = "Debug"] #[rustc_trivial_field_reads] pub trait Debug { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples /// @@ -703,7 +715,7 @@ pub use macros::Debug; #[rustc_diagnostic_item = "Display"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] /// /// # Examples /// @@ -777,7 +789,7 @@ pub trait Display { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Octal { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -836,7 +848,7 @@ pub trait Octal { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait Binary { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -891,7 +903,7 @@ pub trait Binary { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait LowerHex { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -946,7 +958,7 @@ pub trait LowerHex { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait UpperHex { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -997,7 +1009,7 @@ pub trait UpperHex { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Pointer"] pub trait Pointer { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -1048,7 +1060,7 @@ pub trait Pointer { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait LowerExp { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } @@ -1099,7 +1111,7 @@ pub trait LowerExp { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait UpperExp { - /// Formats the value using the given formatter. + #[doc = include_str!("fmt_trait_method_doc.md")] #[stable(feature = "rust1", since = "1.0.0")] fn fmt(&self, f: &mut Formatter<'_>) -> Result; } diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 955efb9b0f98..e0c3b9f3b51d 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -1,7 +1,7 @@ use crate::ops::{Deref, DerefMut, DerefPure}; use crate::ptr; -/// A wrapper to inhibit compiler from automatically calling `T`’s destructor. +/// A wrapper to inhibit the compiler from automatically calling `T`’s destructor. /// This wrapper is 0-cost. /// /// `ManuallyDrop` is guaranteed to have the same layout and bit validity as diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index d8597369b9bf..8283fdc459be 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1467,8 +1467,9 @@ mod prim_usize {} /// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API /// boundary, the following invariants must generally be upheld: /// +/// * `t` is non-null /// * `t` is aligned to `align_of_val(t)` -/// * `t` is dereferenceable for `size_of_val(t)` many bytes +/// * if `size_of_val(t) > 0`, then `t` is dereferenceable for `size_of_val(t)` many bytes /// /// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range /// `[a, a + N)` is all contained within a single [allocated object]. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 8d7192c1b0fd..f87b6bbfcfb2 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -63,11 +63,39 @@ //! //! ## Allocated object //! -//! For several operations, such as [`offset`] or field projections (`expr.field`), the notion of an -//! "allocated object" becomes relevant. An allocated object is a contiguous region of memory. -//! Common examples of allocated objects include stack-allocated variables (each variable is a -//! separate allocated object), heap allocations (each allocation created by the global allocator is -//! a separate allocated object), and `static` variables. +//! An *allocated object* is a subset of program memory which is addressable +//! from Rust, and within which pointer arithmetic is possible. Examples of +//! allocated objects include heap allocations, stack-allocated variables, +//! statics, and consts. The safety preconditions of some Rust operations - +//! such as `offset` and field projections (`expr.field`) - are defined in +//! terms of the allocated objects on which they operate. +//! +//! An allocated object has a base address, a size, and a set of memory +//! addresses. It is possible for an allocated object to have zero size, but +//! such an allocated object will still have a base address. The base address +//! of an allocated object is not necessarily unique. While it is currently the +//! case that an allocated object always has a set of memory addresses which is +//! fully contiguous (i.e., has no "holes"), there is no guarantee that this +//! will not change in the future. +//! +//! For any allocated object with `base` address, `size`, and a set of +//! `addresses`, the following are guaranteed: +//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base + +//! size)` (note that this requires `a < base + size`, not `a <= base + size`) +//! - `base` is not equal to [`null()`] (i.e., the address with the numerical +//! value 0) +//! - `base + size <= usize::MAX` +//! - `size <= isize::MAX` +//! +//! As a consequence of these guarantees, given any address `a` within the set +//! of addresses of an allocated object: +//! - It is guaranteed that `a - base` does not overflow `isize` +//! - It is guaranteed that `a - base` is non-negative +//! - It is guaranteed that, given `o = a - base` (i.e., the offset of `a` within +//! the allocated object), `base + o` will not wrap around the address space (in +//! other words, will not overflow `usize`) +//! +//! [`null()`]: null //! //! # Strict Provenance //! diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 5c4f0bf9b2b4..8ad045275ade 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -114,18 +114,17 @@ impl [u8] { /// Returns a byte slice with leading ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n"); /// assert_eq!(b" ".trim_ascii_start(), b""); /// assert_eq!(b"".trim_ascii_start(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_start(&self) -> &[u8] { let mut bytes = self; @@ -144,18 +143,17 @@ impl [u8] { /// Returns a byte slice with trailing ASCII whitespace bytes removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world"); /// assert_eq!(b" ".trim_ascii_end(), b""); /// assert_eq!(b"".trim_ascii_end(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_end(&self) -> &[u8] { let mut bytes = self; @@ -175,18 +173,17 @@ impl [u8] { /// removed. /// /// 'Whitespace' refers to the definition used by - /// `u8::is_ascii_whitespace`. + /// [`u8::is_ascii_whitespace`]. /// /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world"); /// assert_eq!(b" ".trim_ascii(), b""); /// assert_eq!(b"".trim_ascii(), b""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii(&self) -> &[u8] { self.trim_ascii_start().trim_ascii_end() diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index b6f65907d3c3..669cdc92e358 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2531,15 +2531,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!(" \t \u{3000}hello world\n".trim_ascii_start(), "\u{3000}hello world\n"); /// assert_eq!(" ".trim_ascii_start(), ""); /// assert_eq!("".trim_ascii_start(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_start(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2557,15 +2556,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!("\r hello world\u{3000}\n ".trim_ascii_end(), "\r hello world\u{3000}"); /// assert_eq!(" ".trim_ascii_end(), ""); /// assert_eq!("".trim_ascii_end(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii_end(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate @@ -2584,15 +2582,14 @@ impl str { /// # Examples /// /// ``` - /// #![feature(byte_slice_trim_ascii)] - /// /// assert_eq!("\r hello world\n ".trim_ascii(), "hello world"); /// assert_eq!(" ".trim_ascii(), ""); /// assert_eq!("".trim_ascii(), ""); /// ``` - #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")] #[must_use = "this returns the trimmed string as a new slice, \ without modifying the original"] + #[stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "byte_slice_trim_ascii", since = "CURRENT_RUSTC_VERSION")] #[inline] pub const fn trim_ascii(&self) -> &str { // SAFETY: Removing ASCII characters from a `&str` does not invalidate diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 52729ba1f845..1720fe84fa7c 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -31,10 +31,11 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false } addr2line = { version = "0.21.0", optional = true, default-features = false } [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies] -libc = { version = "0.2.153", default-features = false, features = ['rustc-dep-of-std'], public = true } +libc = { version = "=0.2.153", default-features = false, features = ['rustc-dep-of-std'], public = true } +# Pin libc (pending https://github.com/rust-lang/rust/pull/124560) [target.'cfg(all(windows, target_env = "msvc"))'.dependencies] -libc = { version = "0.2.153", default-features = false } +libc = { version = "=0.2.153", default-features = false } [target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies] object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] } diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index af055152cbe7..f55ec1588f91 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1839,7 +1839,11 @@ pub trait Write { if output.error.is_err() { output.error } else { - Err(error::const_io_error!(ErrorKind::Uncategorized, "formatter error")) + // This shouldn't happen: the underlying stream did not error, but somehow + // the formatter still errored? + panic!( + "a formatting trait implementation returned an error when the underlying stream did not" + ); } } } @@ -2040,7 +2044,6 @@ pub trait Seek { /// # Example /// /// ```no_run - /// #![feature(seek_seek_relative)] /// use std::{ /// io::{self, Seek}, /// fs::File, @@ -2055,7 +2058,7 @@ pub trait Seek { /// ``` /// /// [`BufReader`]: crate::io::BufReader - #[unstable(feature = "seek_seek_relative", issue = "117374")] + #[stable(feature = "seek_seek_relative", since = "CURRENT_RUSTC_VERSION")] fn seek_relative(&mut self, offset: i64) -> Result<()> { self.seek(SeekFrom::Current(offset))?; Ok(()) diff --git a/library/std/src/sys/pal/unix/alloc.rs b/library/std/src/sys/pal/unix/alloc.rs index 9938c0bac25b..993bf55edcf1 100644 --- a/library/std/src/sys/pal/unix/alloc.rs +++ b/library/std/src/sys/pal/unix/alloc.rs @@ -61,9 +61,7 @@ unsafe impl GlobalAlloc for System { cfg_if::cfg_if! { if #[cfg(any( target_os = "android", - target_os = "illumos", target_os = "redox", - target_os = "solaris", target_os = "espidf", target_os = "horizon", target_os = "vita", diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs index d8f227b4ef44..e6df109a6b8f 100644 --- a/library/std/src/sys/pal/unix/rand.rs +++ b/library/std/src/sys/pal/unix/rand.rs @@ -59,7 +59,14 @@ mod imp { unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } } - #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))] + #[cfg(any( + target_os = "espidf", + target_os = "horizon", + target_os = "freebsd", + netbsd10, + target_os = "illumos", + target_os = "solaris" + ))] fn getrandom(buf: &mut [u8]) -> libc::ssize_t { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } @@ -83,6 +90,8 @@ mod imp { target_os = "horizon", target_os = "freebsd", target_os = "dragonfly", + target_os = "solaris", + target_os = "illumos", netbsd10 )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { @@ -96,6 +105,8 @@ mod imp { target_os = "horizon", target_os = "freebsd", target_os = "dragonfly", + target_os = "solaris", + target_os = "illumos", netbsd10 ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e464e444fea2..e60e8f0aa1f7 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -3,7 +3,6 @@ import argparse import contextlib import datetime import hashlib -import json import os import re import shutil @@ -52,7 +51,7 @@ def get(base, url, path, checksums, verbose=False): try: if url not in checksums: - raise RuntimeError(("src/stage0.json doesn't contain a checksum for {}. " + raise RuntimeError(("src/stage0 doesn't contain a checksum for {}. " "Pre-built artifacts might not be available for this " "target at this time, see https://doc.rust-lang.org/nightly" "/rustc/platform-support.html for more information.") @@ -421,9 +420,9 @@ def output(filepath): class Stage0Toolchain: - def __init__(self, stage0_payload): - self.date = stage0_payload["date"] - self.version = stage0_payload["version"] + def __init__(self, date, version): + self.date = date + self.version = version def channel(self): return self.version + "-" + self.date @@ -439,7 +438,7 @@ class DownloadInfo: bin_root, tarball_path, tarball_suffix, - checksums_sha256, + stage0_data, pattern, verbose, ): @@ -448,7 +447,7 @@ class DownloadInfo: self.bin_root = bin_root self.tarball_path = tarball_path self.tarball_suffix = tarball_suffix - self.checksums_sha256 = checksums_sha256 + self.stage0_data = stage0_data self.pattern = pattern self.verbose = verbose @@ -458,7 +457,7 @@ def download_component(download_info): download_info.base_download_url, download_info.download_path, download_info.tarball_path, - download_info.checksums_sha256, + download_info.stage0_data, verbose=download_info.verbose, ) @@ -510,11 +509,12 @@ class RustBuild(object): build_dir = args.build_dir or self.get_toml('build-dir', 'build') or 'build' self.build_dir = os.path.abspath(build_dir) - with open(os.path.join(self.rust_root, "src", "stage0.json")) as f: - data = json.load(f) - self.checksums_sha256 = data["checksums_sha256"] - self.stage0_compiler = Stage0Toolchain(data["compiler"]) - self.download_url = os.getenv("RUSTUP_DIST_SERVER") or data["config"]["dist_server"] + self.stage0_data = parse_stage0_file(os.path.join(self.rust_root, "src", "stage0")) + self.stage0_compiler = Stage0Toolchain( + self.stage0_data["compiler_date"], + self.stage0_data["compiler_version"] + ) + self.download_url = os.getenv("RUSTUP_DIST_SERVER") or self.stage0_data["dist_server"] self.build = args.build or self.build_triple() @@ -581,7 +581,7 @@ class RustBuild(object): bin_root=self.bin_root(), tarball_path=os.path.join(rustc_cache, filename), tarball_suffix=tarball_suffix, - checksums_sha256=self.checksums_sha256, + stage0_data=self.stage0_data, pattern=pattern, verbose=self.verbose, ) @@ -1071,6 +1071,16 @@ def parse_args(args): return parser.parse_known_args(args)[0] +def parse_stage0_file(path): + result = {} + with open(path, 'r') as file: + for line in file: + line = line.strip() + if line and not line.startswith('#'): + key, value = line.split('=', 1) + result[key.strip()] = value.strip() + return result + def bootstrap(args): """Configure, fetch, build and run the initial bootstrap""" rust_root = os.path.abspath(os.path.join(__file__, '../../..')) diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 77fa46da0c9d..045cde56f411 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -320,11 +320,13 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ ( "tests", &[ + // tidy-alphabetical-start "tests/assembly", "tests/codegen", "tests/codegen-units", "tests/coverage", "tests/coverage-run-rustdoc", + "tests/crashes", "tests/debuginfo", "tests/incremental", "tests/mir-opt", @@ -340,6 +342,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/rustdoc-ui", "tests/ui", "tests/ui-fulldeps", + // tidy-alphabetical-end ], ), ]; diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 9898d495c023..9710365ef114 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -128,6 +128,26 @@ fn validate_path_remap() { }); } +#[test] +fn check_missing_paths_for_x_test_tests() { + let build = Build::new(configure("test", &["A-A"], &["A-A"])); + + let (_, tests_remap_paths) = + PATH_REMAP.iter().find(|(target_path, _)| *target_path == "tests").unwrap(); + + let tests_dir = fs::read_dir(build.src.join("tests")).unwrap(); + for dir in tests_dir { + let path = dir.unwrap().path(); + + // Skip if not a test directory. + if path.ends_with("tests/auxiliary") || !path.is_dir() { + continue + } + + assert!(tests_remap_paths.iter().any(|item| path.ends_with(*item)), "{} is missing in PATH_REMAP tests list.", path.display()); + } +} + #[test] fn test_exclude() { let mut config = configure("test", &["A-A"], &["A-A"]); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 0167c51fc7e2..bb51433a3dce 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -181,7 +181,7 @@ pub struct Config { pub test_compare_mode: bool, pub color: Color, pub patch_binaries_for_nix: Option, - pub stage0_metadata: Stage0Metadata, + pub stage0_metadata: build_helper::stage0_parser::Stage0, pub android_ndk: Option, /// Whether to use the `c` feature of the `compiler_builtins` crate. pub optimized_compiler_builtins: bool, @@ -351,34 +351,6 @@ pub struct Config { pub paths: Vec, } -#[derive(Default, Deserialize, Clone)] -pub struct Stage0Metadata { - pub compiler: CompilerMetadata, - pub config: Stage0Config, - pub checksums_sha256: HashMap, - pub rustfmt: Option, -} -#[derive(Default, Deserialize, Clone)] -pub struct CompilerMetadata { - pub date: String, - pub version: String, -} - -#[derive(Default, Deserialize, Clone)] -pub struct Stage0Config { - pub dist_server: String, - pub artifacts_server: String, - pub artifacts_with_llvm_assertions_server: String, - pub git_merge_commit_email: String, - pub git_repository: String, - pub nightly_branch: String, -} -#[derive(Default, Deserialize, Clone)] -pub struct RustfmtMetadata { - pub date: String, - pub version: String, -} - #[derive(Clone, Debug, Default)] pub enum RustfmtState { SystemToolchain(PathBuf), @@ -1298,13 +1270,13 @@ impl Config { Some(p) => PathBuf::from(p), None => git_root, }; - // If this doesn't have at least `stage0.json`, we guessed wrong. This can happen when, + // If this doesn't have at least `stage0`, we guessed wrong. This can happen when, // for example, the build directory is inside of another unrelated git directory. // In that case keep the original `CARGO_MANIFEST_DIR` handling. // // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1. - if git_root.join("src").join("stage0.json").exists() { + if git_root.join("src").join("stage0").exists() { config.src = git_root; } } else { @@ -1322,9 +1294,7 @@ impl Config { .to_path_buf(); } - let stage0_json = t!(std::fs::read(config.src.join("src").join("stage0.json"))); - - config.stage0_metadata = t!(serde_json::from_slice::(&stage0_json)); + config.stage0_metadata = build_helper::stage0_parser::parse_stage0_file(); // Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then `./config.toml`, then `config.toml` in the root directory. let toml_path = flags diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index 75e0f646da69..a074d53aa36e 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -9,9 +9,9 @@ use std::{ }; use build_helper::ci::CiEnv; +use build_helper::stage0_parser::VersionMetadata; use xz2::bufread::XzDecoder; -use crate::core::config::RustfmtMetadata; use crate::utils::helpers::{check_run, exe, program_out_of_date}; use crate::{core::build_steps::llvm::detect_llvm_sha, utils::helpers::hex_encode}; use crate::{t, Config}; @@ -408,7 +408,7 @@ impl Config { /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't /// reuse target directories or artifacts pub(crate) fn maybe_download_rustfmt(&self) -> Option { - let RustfmtMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?; + let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?; let channel = format!("{version}-{date}"); let host = self.build; @@ -606,7 +606,7 @@ impl Config { DownloadSource::Dist => { let dist_server = env::var("RUSTUP_DIST_SERVER") .unwrap_or(self.stage0_metadata.config.dist_server.to_string()); - // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0.json + // NOTE: make `dist` part of the URL because that's how it's stored in src/stage0 (dist_server, format!("dist/{key}/{filename}"), true) } }; @@ -616,7 +616,7 @@ impl Config { // this on each and every nightly ... let checksum = if should_verify { let error = format!( - "src/stage0.json doesn't contain a checksum for {url}. \ + "src/stage0 doesn't contain a checksum for {url}. \ Pre-built artifacts might not be available for this \ target at this time, see https://doc.rust-lang.org/nightly\ /rustc/platform-support.html for more information." diff --git a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile index dab0667ed55c..e718437aaaa3 100644 --- a/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-armv7-linux/Dockerfile @@ -25,5 +25,5 @@ ENV CC_armv7_unknown_linux_gnueabihf=armv7-unknown-linux-gnueabihf-gcc \ ENV HOSTS=armv7-unknown-linux-gnueabihf -ENV RUST_CONFIGURE_ARGS --enable-full-tools --disable-docs +ENV RUST_CONFIGURE_ARGS --enable-full-tools --enable-profiler --disable-docs ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index c9c0ee4067f1..c7e3293e35ad 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -74,6 +74,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) + - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.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) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 764798a80e6d..8adc410455ed 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -382,5 +382,6 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support `x86_64-wrs-vxworks` | ? | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) +[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 9c2e05b57f5e..3e1db692f50b 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -387,7 +387,7 @@ meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm ``` *Note: Relative manifest paths are resolved starting from the working directory -of `pm`. Make sure to fill out `` with the path to the downloaded +of `ffx`. Make sure to fill out `` with the path to the downloaded SDK.* The `.manifest` file will be used to describe the contents of the package by @@ -459,12 +459,10 @@ hello_fuchsia/ Next, we'll build a package manifest as defined by our manifest: ```sh -${SDK_PATH}/tools/${ARCH}/pm \ - -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 | awk -F ' ' '{print $2}') \ - -o pkg/hello_fuchsia_manifest \ - -m pkg/hello_fuchsia.manifest \ - build \ - -output-package-manifest pkg/hello_fuchsia_package_manifest +${SDK_PATH}/tools/${ARCH}/ffx package build \ + --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \ + --out pkg/hello_fuchsia_manifest \ + pkg/hello_fuchsia.manifest ``` This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can @@ -498,8 +496,7 @@ to. We can set up our repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm newrepo \ - -repo pkg/repo +${SDK_PATH}/tools/${ARCH}/ffx repository create pkg/repo ``` **Current directory structure** @@ -523,17 +520,17 @@ hello_fuchsia/ We can publish our new package to that repository with: ```sh -${SDK_PATH}/tools/${ARCH}/pm publish \ - -repo pkg/repo \ - -lp -f <(echo "pkg/hello_fuchsia_package_manifest") +${SDK_PATH}/tools/${ARCH}/ffx repository publish \ + --package pkg/hello_fuchsia_package_manifest \ + pkg/repo ``` Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using: ```sh ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \ - pkg/repo \ - -r hello-fuchsia + --repository hello-fuchsia \ + pkg/repo ``` ## Running a Fuchsia component on an emulator diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md new file mode 100644 index 000000000000..5608b5cb7781 --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -0,0 +1,40 @@ +# `x86_64-unknown-linux-none` + +**Tier: 3** + +Freestanding x86-64 linux binary with no dependency on libc. + +## Target maintainers + +- [morr0ne](https://github.com/morr0ne/) + +## Requirements + +This target is cross compiled and can be built from any host. + +This target has no support for host tools, std, or alloc. + +## Building the target + +The target can be built by enabling it for a `rustc` build: + +```toml +[build] +build-stage = 1 +target = ["x86_64-unknown-linux-none"] +``` + +## 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 + +Created binaries will run on linux without any external requirements + +## Cross-compilation toolchains and C code + +Support for C code is currently untested diff --git a/src/doc/rustc/src/symbol-mangling/v0.md b/src/doc/rustc/src/symbol-mangling/v0.md index 61f747fac837..763694a9fdac 100644 --- a/src/doc/rustc/src/symbol-mangling/v0.md +++ b/src/doc/rustc/src/symbol-mangling/v0.md @@ -739,6 +739,8 @@ The type encodings based on the initial tag character are: * `z` — `!` * `p` — [placeholder] `_` +Remaining primitives are encoded as a crate production, e.g. `C4f128`. + * `A` — An [array][reference-array] `[T; N]`. > array-type → `A` *[type]* *[const]* diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index 822f341b370a..69fb7e3313fe 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -273,7 +273,7 @@ will be added. When rendering Rust files, this flag is ignored. -## `--html-in-header`: include more HTML in +## `--html-in-header`: include more HTML in `` Using this flag looks like this: diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index b9a89c20cee4..9d593f808102 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -43,6 +43,7 @@ include: - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". +- Format single associated type `where` clauses on the same line if they fit. ## Rust 2015/2018/2021 style edition diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 0066a4bacb95..c0628691b773 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -295,8 +295,18 @@ Prefer to use single-letter names for generic parameters. These rules apply for `where` clauses on any item. -If immediately following a closing bracket of any kind, write the keyword -`where` on the same line, with a space before it. +If a where clause is short, and appears on a short one-line function +declaration with no body or on a short type with no `=`, format it on +the same line as the declaration: + +```rust +fn new(&self) -> Self where Self: Sized; + +type Item<'a>: SomeTrait where Self: 'a; +``` + +Otherwise, if immediately following a closing bracket of any kind, write the +keyword `where` on the same line, with a space before it. Otherwise, put `where` on a new line at the same indentation level. Put each component of a `where` clause on its own line, block-indented. Use a trailing @@ -347,7 +357,7 @@ where ``` If a `where` clause is very short, prefer using an inline bound on the type -parameter. +parameter if possible. If a component of a `where` clause does not fit and contains `+`, break it before each `+` and block-indent the continuation lines. Put each bound on its @@ -421,9 +431,21 @@ Format associated types like type aliases. Where an associated type has a bound, put a space after the colon but not before: ```rust -pub type Foo: Bar; +type Foo: Bar; ``` +If an associated type is short, has no `=`, and has a `where` clause with only +one entry, format the entire type declaration including the `where` clause on +the same line if it fits: + +```rust +type Item<'a> where Self: 'a; +type Item<'a>: PartialEq + Send where Self: 'a; +``` + +If the associated type has a `=`, or if the `where` clause contains multiple +entries, format it across multiple lines as with a type alias. + ## extern items When writing extern items (such as `extern "C" fn`), always specify the ABI. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 90f2e3d09fe8..0ab23d159a6c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -453,7 +453,15 @@ fn clean_projection_predicate<'tcx>( cx: &mut DocContext<'tcx>, ) -> WherePredicate { WherePredicate::EqPredicate { - lhs: clean_projection(pred.map_bound(|p| p.projection_ty), cx, None), + lhs: clean_projection( + pred.map_bound(|p| { + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + p.projection_term.expect_ty(cx.tcx) + }), + cx, + None, + ), rhs: clean_middle_term(pred.map_bound(|p| p.term), cx), } } @@ -838,7 +846,7 @@ fn clean_ty_generics<'tcx>( } } ty::ClauseKind::Projection(p) => { - if let ty::Param(param) = p.projection_ty.self_ty().kind() { + if let ty::Param(param) = p.projection_term.self_ty().kind() { projection = Some(bound_p.rebind(p)); return Some(param.index); } @@ -857,7 +865,15 @@ fn clean_ty_generics<'tcx>( bounds.extend(pred.get_bounds().into_iter().flatten().cloned()); if let Some(proj) = projection - && let lhs = clean_projection(proj.map_bound(|p| p.projection_ty), cx, None) + && let lhs = clean_projection( + proj.map_bound(|p| { + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + p.projection_term.expect_ty(cx.tcx) + }), + cx, + None, + ) && let Some((_, trait_did, name)) = lhs.projection() { impl_trait_proj.entry(param_idx).or_default().push(( @@ -2126,7 +2142,10 @@ pub(crate) fn clean_middle_ty<'tcx>( // HACK(compiler-errors): Doesn't actually matter what self // type we put here, because we're only using the GAT's args. .with_self_ty(cx.tcx, cx.tcx.types.self_param) - .projection_ty + .projection_term + // FIXME: This needs to be made resilient for `AliasTerm`s + // that are associated consts. + .expect_ty(cx.tcx) }), cx, ), @@ -2284,10 +2303,12 @@ fn clean_middle_opaque_bounds<'tcx>( .iter() .filter_map(|bound| { if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() { - if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() { + if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() { Some(TypeBinding { assoc: projection_to_path_segment( - bound.kind().rebind(proj.projection_ty), + // FIXME: This needs to be made resilient for `AliasTerm`s that + // are associated consts. + bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)), cx, ), kind: TypeBindingKind::Equality { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 0ad4c9c23464..19aa5ef949e6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -686,9 +686,9 @@ pub(crate) fn make_test( } } - // The supplied slice is only used for diagnostics, + // The supplied item is only used for diagnostics, // which are swallowed here anyway. - parser.maybe_consume_incorrect_semicolon(&[]); + parser.maybe_consume_incorrect_semicolon(None); } // Reset errors so that they won't be reported as compiler bugs when dropping the diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 4eeaaa2bb70a..3a71dd82db88 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -8,6 +8,9 @@ use crate::core::DocContext; mod stripper; pub(crate) use stripper::*; +mod strip_aliased_non_local; +pub(crate) use self::strip_aliased_non_local::STRIP_ALIASED_NON_LOCAL; + mod strip_hidden; pub(crate) use self::strip_hidden::STRIP_HIDDEN; @@ -71,6 +74,7 @@ pub(crate) enum Condition { pub(crate) const PASSES: &[Pass] = &[ CHECK_CUSTOM_CODE_CLASSES, CHECK_DOC_TEST_VISIBILITY, + STRIP_ALIASED_NON_LOCAL, STRIP_HIDDEN, STRIP_PRIVATE, STRIP_PRIV_IMPORTS, @@ -86,6 +90,7 @@ pub(crate) const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(CHECK_CUSTOM_CODE_CLASSES), ConditionalPass::always(COLLECT_TRAIT_IMPLS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), + ConditionalPass::always(STRIP_ALIASED_NON_LOCAL), ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), ConditionalPass::new(STRIP_PRIV_IMPORTS, WhenDocumentPrivate), diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs new file mode 100644 index 000000000000..848cbd5ed99f --- /dev/null +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -0,0 +1,57 @@ +use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::Visibility; + +use crate::clean; +use crate::clean::Item; +use crate::core::DocContext; +use crate::fold::{strip_item, DocFolder}; +use crate::passes::Pass; + +pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass { + name: "strip-aliased-non-local", + run: strip_aliased_non_local, + description: "strips all non-local private aliased items from the output", +}; + +fn strip_aliased_non_local(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { + let mut stripper = AliasedNonLocalStripper { tcx: cx.tcx }; + stripper.fold_crate(krate) +} + +struct AliasedNonLocalStripper<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> { + fn fold_item(&mut self, i: Item) -> Option { + Some(match *i.kind { + clean::TypeAliasItem(..) => { + let mut stripper = NonLocalStripper { tcx: self.tcx }; + // don't call `fold_item` as that could strip the type-alias it-self + // which we don't want to strip out + stripper.fold_item_recur(i) + } + _ => self.fold_item_recur(i), + }) + } +} + +struct NonLocalStripper<'tcx> { + tcx: TyCtxt<'tcx>, +} + +impl<'tcx> DocFolder for NonLocalStripper<'tcx> { + fn fold_item(&mut self, i: Item) -> Option { + // If not local, we want to respect the original visibility of + // the field and not the one given by the user for the currrent crate. + // + // FIXME(#125009): Not-local should probably consider same Cargo workspace + if !i.def_id().map_or(true, |did| did.is_local()) { + if i.visibility(self.tcx) != Some(Visibility::Public) || i.is_doc_hidden() { + return Some(strip_item(i)); + } + } + + Some(self.fold_item_recur(i)) + } +} diff --git a/src/stage0 b/src/stage0 new file mode 100644 index 000000000000..5ec8f5b715e0 --- /dev/null +++ b/src/stage0 @@ -0,0 +1,447 @@ +dist_server=https://static.rust-lang.org +artifacts_server=https://ci-artifacts.rust-lang.org/rustc-builds +artifacts_with_llvm_assertions_server=https://ci-artifacts.rust-lang.org/rustc-builds-alt +git_merge_commit_email=bors@rust-lang.org +git_repository=rust-lang/rust +nightly_branch=master + +# The configuration above this comment is editable, and can be changed +# by forks of the repository if they have alternate values. +# +# The section below is generated by `./x.py run src/tools/bump-stage0`, +# run that command again to update the bootstrap compiler. +# +# All changes below this comment will be overridden the next time the +# tool is executed. + +compiler_date=2024-04-29 +compiler_version=beta +rustfmt_date=2024-04-29 +rustfmt_version=nightly + +dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz=5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb +dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz=0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2 +dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz=c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f +dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz=7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz=73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz=db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81 +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz=a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891 +dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz=2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz=7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz=4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz=4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121 +dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz=7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c +dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz=6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e +dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz=c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c +dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz=d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84 +dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz=65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db +dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz=d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403 +dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz=23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba +dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz=b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c +dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz=6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9 +dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz=24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae +dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz=e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da +dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz=8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d +dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz=3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c +dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz=2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c +dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz=64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3 +dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz=d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9 +dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz=fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f +dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz=77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3 +dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz=c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a +dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz=c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e +dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz=47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee +dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz=f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791 +dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz=96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz=517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz=a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317 +dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz=4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e +dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz=08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7 +dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz=9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815 +dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz=7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6 +dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz=4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0 +dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz=0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz=c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz=d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz=0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445 +dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz=70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13 +dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz=f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a +dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz=53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40 +dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz=7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c +dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz=2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62 +dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz=90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736 +dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz=f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz=7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73 +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz=181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807 +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz=4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b +dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz=3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz=9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03 +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz=f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz=d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399 +dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz=c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5 +dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz=52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd +dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz=c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a +dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz=325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588 +dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz=536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123 +dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz=c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b +dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz=0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245 +dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz=c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511 +dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz=6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304 +dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz=58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93 +dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz=dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514 +dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz=e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6 +dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz=fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8 +dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz=b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737 +dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz=2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf +dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz=0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4 +dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz=993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e +dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz=210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9 +dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz=f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f +dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz=3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7 +dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz=0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1 +dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz=9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326 +dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz=49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af +dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz=6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6 +dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz=0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb +dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz=52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab +dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz=8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6 +dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz=509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d +dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz=2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f +dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz=ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0 +dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz=5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz=2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz=aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz=1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8 +dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz=6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9 +dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz=1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328 +dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz=da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4 +dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz=2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5 +dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz=bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529 +dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz=9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e +dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz=50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c +dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz=56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751 +dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz=3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163 +dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz=bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03 +dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz=46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz=9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz=87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8 +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz=4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df +dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz=a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4 +dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz=c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66 +dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz=8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz=33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz=d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz=4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz=fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz=f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725 +dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz=d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz=bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz=d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz=96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591 +dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz=3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89 +dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz=8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2 +dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz=80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff +dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz=2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de +dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz=9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz=f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz=e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz=49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz=0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz=e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz=ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz=14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41 +dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz=ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz=345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz=6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz=a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423 +dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz=3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz=a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554 +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz=e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz=cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4 +dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz=2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c +dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz=6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f +dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz=9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz=7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz=f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz=0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz=a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz=cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz=0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz=eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz=42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz=c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4 +dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz=24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc +dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz=cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8 +dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz=8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f +dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz=e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4 +dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz=d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab +dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz=1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1 +dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz=4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0 +dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz=ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8 +dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz=fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2 +dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz=6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568 +dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz=1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b +dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz=26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e +dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz=c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065 +dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz=f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea +dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz=f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz=8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0 +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz=4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz=cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f +dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz=95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a +dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz=e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08 +dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz=a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e +dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz=d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11 +dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz=4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz=1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz=98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a +dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz=dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284 +dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz=f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29 +dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz=3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887 +dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz=72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz=b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz=88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz=d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz=7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572 +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz=e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b +dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz=364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9 +dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz=c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a +dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz=f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c +dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz=3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39 +dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz=ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60 +dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz=f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270 +dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz=8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49 +dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz=48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7 +dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz=d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af +dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz=0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd +dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz=424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52 +dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz=2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a +dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz=2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a +dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz=69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c +dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz=281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab +dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz=dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271 +dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz=b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec +dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz=7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17 +dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz=bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz=01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz=0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0 +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz=b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d +dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz=0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba +dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz=0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5 +dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz=a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657 +dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz=629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6 +dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz=192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd +dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz=84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7 +dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz=304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa +dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz=25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9 +dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz=5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554 +dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz=a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d +dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz=4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz=32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz=112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz=7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12 +dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz=49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36 +dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz=518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845 +dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz=2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394 +dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz=2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17 +dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz=a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3 +dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz=eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc +dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz=104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45 +dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz=b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9 +dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz=76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz=1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz=cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz=9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81 +dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz=4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb +dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz=731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709 +dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz=8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07 +dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz=7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0 +dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz=d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b +dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz=07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3 +dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz=79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744 +dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz=b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938 +dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz=2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11 +dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz=792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0 +dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz=abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e +dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz=0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b +dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz=c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045 +dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz=7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0 +dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz=f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2 +dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz=01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556 +dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz=9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e +dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz=5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f +dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz=9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b +dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz=d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70 +dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz=6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz=28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz=7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz=ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz=30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz=81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710 +dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz=215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7 +dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz=340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4 +dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz=69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a +dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz=22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f +dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz=30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d +dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz=9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313 +dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz=7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz=e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz=c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz=72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz=867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz=f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz=022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752 +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz=b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e +dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz=e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a +dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz=57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee +dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz=e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6 +dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz=d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce +dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz=5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97 +dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz=0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2 +dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz=b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651 +dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz=24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1 +dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz=1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc +dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz=ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2 +dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz=e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4 +dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz=52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13 +dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz=843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz=ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9 +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz=ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9 +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz=40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd +dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz=804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1 +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz=a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz=7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085 +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz=79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a +dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz=9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc +dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz=ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd +dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz=55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc +dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz=de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1 +dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz=a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b +dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz=88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db +dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz=1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9 +dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz=3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18 +dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz=2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f +dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz=ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b +dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz=492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2 +dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz=c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec +dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz=0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f +dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz=cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651 +dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz=908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201 +dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz=8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249 +dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz=2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a +dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz=526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71 +dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz=fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb +dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz=664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a +dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz=a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d +dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz=59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3 +dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz=f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff +dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz=f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz=045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz=a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8 +dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz=398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9 +dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz=38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17 +dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz=786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff +dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz=7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618 +dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz=bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56 +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz=84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866 +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz=a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz=87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c +dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz=469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67 +dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz=4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf +dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz=45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1 +dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz=0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f +dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz=143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46 +dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz=9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e +dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz=f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz=33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz=03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4 +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz=cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99 +dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz=9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz=a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz=5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz=645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783 +dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz=1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37 +dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz=f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914 +dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz=d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98 +dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz=a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58 +dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz=4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54 +dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz=1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4 +dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz=27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7 +dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz=dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a +dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz=cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad +dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz=34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15 +dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz=c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c +dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz=386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c +dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz=d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272 +dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz=91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa +dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz=ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c +dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz=8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b +dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz=f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e +dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz=a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1 +dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz=af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed +dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz=5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be +dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz=6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb +dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz=64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c +dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz=0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz=58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz=a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz=5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1 +dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz=a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244 +dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz=1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca +dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz=79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e +dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz=7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35 +dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz=d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz=ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz=c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz=3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0 +dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz=c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc +dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz=c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a +dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz=de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275 +dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz=3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d +dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz=e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe +dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz=22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752 +dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz=db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz=fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz=61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz=cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0 +dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz=bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz=13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz=04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz=430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691 +dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz=924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb +dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz=bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f +dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz=34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz=835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz=ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0 +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz=02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39 +dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz=822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942 +dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz=68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf +dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz=6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e +dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz=0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd +dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz=2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57 +dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz=b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac +dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz=64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08 +dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz=100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8 +dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz=38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e +dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz=4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87 +dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz=36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c +dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz=7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5 +dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz=ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20 +dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz=e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd +dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz=e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe +dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz=73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470 +dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz=9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927 +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz=eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz=f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz=ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28 +dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz=04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz=0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz=90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz=5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz=a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz=a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz=21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz=b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz=d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz=9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74 +dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz=019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308 \ No newline at end of file diff --git a/src/stage0.json b/src/stage0.json deleted file mode 100644 index a9a53a7528fe..000000000000 --- a/src/stage0.json +++ /dev/null @@ -1,456 +0,0 @@ -{ - "config": { - "dist_server": "https://static.rust-lang.org", - "artifacts_server": "https://ci-artifacts.rust-lang.org/rustc-builds", - "artifacts_with_llvm_assertions_server": "https://ci-artifacts.rust-lang.org/rustc-builds-alt", - "git_merge_commit_email": "bors@rust-lang.org", - "git_repository": "rust-lang/rust", - "nightly_branch": "master" - }, - "__comments": [ - "The configuration above this comment is editable, and can be changed", - "by forks of the repository if they have alternate values.", - "", - "The section below is generated by `./x.py run src/tools/bump-stage0`,", - "run that command again to update the bootstrap compiler.", - "", - "All changes below this comment will be overridden the next time the", - "tool is executed." - ], - "compiler": { - "date": "2024-04-29", - "version": "beta" - }, - "rustfmt": { - "date": "2024-04-29", - "version": "nightly" - }, - "checksums_sha256": { - "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.gz": "5a8c5e48a88e7c7b41eb720d60fbd2e879b97639c7ff83710526e8e6caaf8afb", - "dist/2024-04-29/cargo-beta-aarch64-apple-darwin.tar.xz": "0d237535ae8d435d99104fa5b9dbf41878e2304bb0f2eb574bf17dd685caadc2", - "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "c56733bb6198af0a9b0df9a44ef979150e00de33b70853c239cccfcce23c328f", - "dist/2024-04-29/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "7da5f887151215ddec640684077d98551fe2aed75a3ece2c73b20698754a70bb", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "73851e304a539d41bedc0d8a5d98800c8279ae623d3e58e863f8c1f8b458b01c", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "db9c28841344b0154756e19a21795ef6e0c4e27c7844be9996824f1039edaa81", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "a706c8c7e37b9e80d7faa000c5d179a772746eef071387fb2879fdeab1f1f891", - "dist/2024-04-29/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "2060634afe1b4a19bae874c6ce3cf4256e613af26e06104b45da5bd71cfb133c", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "7af61e74faea669fdd41793e4b88eb6a37bfacf845af364ee02bb7cf08c612c7", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "4759fb3e3d89ead605c4eeba23be5cb9b3ac98086a9de20f8dbfdfa9282ee486", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "4cab18df2d94702e8b551357373bcae60d1023e644148f0f82e8971023362121", - "dist/2024-04-29/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "7de4f0d72b4e5770376ede82b02d6bcfd450788a40375fad34d75524c941d72c", - "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "6401391a426cf33d6c58f07e7b2828b178720cb4f2b8577ae932b5f5b7d6744e", - "dist/2024-04-29/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c3f6729bc769325046f0f62c51b5bed30068c37dc2a36a6283e50565d8cb7d5c", - "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.gz": "d116c97c1242220c7972b63010aee1ed36bf5353e84a06d3561cd5fe9d7dae84", - "dist/2024-04-29/cargo-beta-i686-pc-windows-gnu.tar.xz": "65eba577f7775b3eef36e7f000b5007264392b20a7759f8ed567f3a45b2877db", - "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.gz": "d418a3371b3631328bde2b1e0c3159700f12424e83b1d8ece1349fea90f9e403", - "dist/2024-04-29/cargo-beta-i686-pc-windows-msvc.tar.xz": "23ae73c776fdb0795944656d743444e3b4c440f45084028206c1aec52333b1ba", - "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.gz": "b6bbdeb7c8bfac2e8a083adb4782caf5321799f47acb4eaf81da32bd11730e9c", - "dist/2024-04-29/cargo-beta-i686-unknown-linux-gnu.tar.xz": "6b409691da6ddb8c04409667b2c3d9d6429c6b5bf53ad18177248406a5f06cb9", - "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "24cd888d14a788e8fb5b886735f3c07a028a8681df48a777b2bb971c62a175ae", - "dist/2024-04-29/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "e8eece6412936fe4dc863a5e19e6766fbb20e81da0069ad7831465e638db23da", - "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "8f007a2aa02e35c5ddb2152cc7589092a0e3083211c6aa23e676e3a3ad5a4b8d", - "dist/2024-04-29/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3e423e693dd0813f5d87d9eded94894076258ece56684f3598321cd013aeef3c", - "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "2eec5e45e389a52b526a5cf683d56a9df92004f6095936b16cd8d7d63722cc6c", - "dist/2024-04-29/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "64c5135cbff9d4fa9575074c55e79d85f72cb1783498a72e1f77865b9b2d1ba3", - "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "d64552a80ca386728e42f00d7f1c700b5e30e5a6939f32ffa15a7ce715d4c8e9", - "dist/2024-04-29/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "fe91adce8ba35bf06251448b5214ed112556dc8814de92e66bc5dc51193c442f", - "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "77aafa8b63a4bf4475e82cd777646be5254e1f62d44b2a8fbd40066fdd7020d3", - "dist/2024-04-29/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "c38f0b4adcc8e48f70b475636bbd5851406bba296d66df12e1ba54888a4bf21a", - "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "c05df24d7e8dff26c01055ad40f9e81e6fcb3ae634ecc1f7cc43c3108677fa0e", - "dist/2024-04-29/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "47e8f4ec4d996600e60ddc49daeeb43d4c21e0583a86c12395c16eddc7db76ee", - "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.gz": "f024bd225b77160dc2fabde78002c8deac5cbb9a35345340964c3b988b0d1791", - "dist/2024-04-29/cargo-beta-x86_64-apple-darwin.tar.xz": "96c9e44bd9f0c85c793e3dd6043cc4f89fbeeab5ddf0fdb5daefca8f690bce05", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "517889f222b62150fe16bcfd3a0eb5f353956b0084d85713480197bff4558145", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "a6653ea4aec51569c1300c044d8bf2517a1f5111f710d12cd352190425b8f317", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "4cb5b5054dffe6721efbbf29192a67e59cda69ea4ab4791aaec6f314eefa5a5e", - "dist/2024-04-29/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "08bc45be22e9e4f615d1c9e70500046c8db89045f5d40dcde853c610591712a7", - "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.gz": "9661357ee8ea8973016fdbaa2de3cb98713136dcd25f07aa9f9d101180276815", - "dist/2024-04-29/cargo-beta-x86_64-unknown-freebsd.tar.xz": "7fab806227d1a3be817602abb121ac7e039ba0bbf81e0a1d47bdcccca74203c6", - "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.gz": "4c79bb48cfe64bd38af7fe3660cd8bdc99ec90738a0d8fdf80843ecda910dab0", - "dist/2024-04-29/cargo-beta-x86_64-unknown-illumos.tar.xz": "0fb9edfdafde1820ccb25c22369cafb0e75e68795effeb615cb284a5837c75ba", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "c1902a072e61ab5ae9737a1092732e3972deee426424bc85fcf8702adffdd41d", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "d39ea1195dcc95e428bd540abd2db5b5d4c997a7661a41a4c0ca41cbdd18d27e", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "0edfdb6f6bb2a4a1a96a5e95cec897c444c936e6624bb4a530ffed4847b97445", - "dist/2024-04-29/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "70c264b7845febdee45d0c6e44b65d47ba7f367ef33ec906a9fd7f992ba7cc13", - "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.gz": "f1bd6417a54f3b53d572ce4af799242db7c11265c71201cc09c78d71be38c13a", - "dist/2024-04-29/cargo-beta-x86_64-unknown-netbsd.tar.xz": "53569810469c483785333759f86434706ee5368d5e18270ee13a17817ad57d40", - "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.gz": "7b693bde61a090854527a145455ff774314c65ec0cd47d25a19c76c6a166d96c", - "dist/2024-04-29/clippy-beta-aarch64-apple-darwin.tar.xz": "2494e9fdd8d342b6bc3e55eecfd555c43e3cca8421f3236df2d5a366288fec62", - "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "90307f09c6fcb0c1fbe3ad1522a5381a17e2f69637c6d00f4a2cb5f3149bf736", - "dist/2024-04-29/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "f7e0dec4a4862bd85d894252366152b3b6a7627e7e5a25ce323fa2db3bd87c2b", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "7c719e38f2a1030ae61985205df52f9a0c37b659463a5e2dea8e60e632de2d73", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "181ff4ae6adced6522a4c29869be3cc5dac8b961c7c88f2957cd31f831490807", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "4e0e63e6f200386995e369a2673867d1bc3005d51d6a57c00ca80056dd85316b", - "dist/2024-04-29/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "3d5b22a13aed6821482e60d9cc8571e2da9d95d82104284b77c56985a35a9c4e", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f788db76a5d55b3ecdd04a70b0e2be466959f76ae9fd3497ca2c503504e0c03", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "f4d8fc103807fba61d71d88b8e25a7016bfbd1a2905330f9a9fb3d7ba082713a", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "d61bec3d017dd0be43e48350190ad18c0a0269e43d964600b62e1f7fd4f84399", - "dist/2024-04-29/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "c00cbdc41a4da0c313a1a282b0158b059dd34f640b582cb7ca18e3d290ca8fa5", - "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "52143a530ca5274fbb760beecddff16f860ea787443d3dc708dda7c8f32ca9bd", - "dist/2024-04-29/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c6d2dfeac6f40811bc9b4cec3c23f9c3bb46f761e006257b9313aa7c1a647b5a", - "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.gz": "325d39e426b1907fa17d93c0752d3d73bd95750f4f967c2a84aab2c5dac8a588", - "dist/2024-04-29/clippy-beta-i686-pc-windows-gnu.tar.xz": "536f591d4da455302029384ed196932d71119ef0160ac5415617d6b777c51123", - "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.gz": "c3684c9bf471669d444853bf484880d17e150ecb0e7505de90883382023e343b", - "dist/2024-04-29/clippy-beta-i686-pc-windows-msvc.tar.xz": "0b00e6132f73d5dc762e359b0005fceab0cf7b01337d8f4aa9eacfb4552f9245", - "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c91c1eadfc4cbae360a0eecf11c32d2509b68aca86c7b1de3b102944f43e1511", - "dist/2024-04-29/clippy-beta-i686-unknown-linux-gnu.tar.xz": "6f7a5a287dd6226c203bb674ff02ec773e5d0813091b2af744b88ecd6997a304", - "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "58383f094995823ea6db6a87b9ad4b33bdae2264d29bab88ab71ec60ccab3b93", - "dist/2024-04-29/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "dbf4680a6fd4dca54acca5503a7fd94502b8e85819bc02346ae9cecd275e4514", - "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e28eb32cda42654c0f0247aa8e15f01f73770b36f7626c8d6f1b7659accc56e6", - "dist/2024-04-29/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "fcc48a83b748e1e46f9daef40563f8e5abbb0e3f014a168b04f3c700c2ace2b8", - "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "b626faf3275fcd196cd627e8a36c67721bae16a56f61cd080c79d137b3ec7737", - "dist/2024-04-29/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "2c599d2dc719d69f67625f3c6573fcc4f1ea3266801557dd3892bdb7c761b4cf", - "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "0bc1f546fe0cef2b9516231ab608de68d55f72022fbc9ced5101b600e005f8c4", - "dist/2024-04-29/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "993294f2ae5202785ab242c1c6567df9c8ab1ef44ad35748c526b7fe854fb94e", - "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "210a4f0d208e0c8e13a57fb3b3e6c98ab5f620e4988d10a127ff1424ac1d5ca9", - "dist/2024-04-29/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f10f7df41a13ee2ecdc25d60e697cba2342129a912ef20d8bfca5f611a9ec97f", - "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "3e24d2af65f0c9667c9997ce091711b2be48e673de3707cddfd8cda455dfecc7", - "dist/2024-04-29/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "0e7b8fbd0207489e38c78c2ae1aa0df4fcbdd84741aa50a86379e4d7ede286b1", - "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.gz": "9c0c47fd97ce72abcd6126315834c62aa7297fe09d447ee4cefa1eb46a116326", - "dist/2024-04-29/clippy-beta-x86_64-apple-darwin.tar.xz": "49dd65c5340fd804399edfa2402cf255fd9bfce1f4aa7fbb3c193c11bc03f8af", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "6c1c3bdf097a1846ae08b098c555c0c5e9e9b646c744d6bb5a855789196b8bf6", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "0a7319d1062f73af1c8f0efe6ad970d10d02259162c5bc84bb1f3a10f3911bcb", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "52fef3f8a64fa58934a633bd4944e8ba9e15f2c2766d0f302dea1a6523864dab", - "dist/2024-04-29/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "8fdbe7590e62ab68a2e463b14da2595e8c4592744f578a813f64d430ed7db4b6", - "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.gz": "509bf535622bd26385184ee0c17e4e27a5061a8aeebf5759f24bd578692b2f5d", - "dist/2024-04-29/clippy-beta-x86_64-unknown-freebsd.tar.xz": "2fcd10ada329ba7633616bebc584dca13f11c465e7cf513e76efeb0c3174486f", - "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.gz": "ea8cea0d4a2379bcd0693f6174b25bc1f90a016dbe8280159cbb61d859806fb0", - "dist/2024-04-29/clippy-beta-x86_64-unknown-illumos.tar.xz": "5a243df8d1345db6bd18e4386ba628e6d302bce1cc572fb447cca4264fda3ee9", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "2ee560d3c1e306e103eb06d8e8033cd1489b3f6ff9df3bd8a95e25e977befa27", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "aaf6e54184a65ad6592bf03955a84ad12b561afd86064b1ac5fa03cf637052f8", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "1b3877424a0a0eb507675a50e9d2c793f00ab85f6f12b1e27f871331070325b8", - "dist/2024-04-29/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "6df5eaae5afb64557ba5c3a53ee3e56dab85455838a6044c7671c1180acfeaf9", - "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.gz": "1ac05ed7b607fff8b77ff203a663e9f4f2487779bc25e2dcd454cdf5b7583328", - "dist/2024-04-29/clippy-beta-x86_64-unknown-netbsd.tar.xz": "da502375b3cee8b254ab5999809f522692c2d1d90ea0544ad03c0ca514c65ef4", - "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.gz": "2fdd35ca3b3e3d6f548f11c93337f5bf2e3c088bc78a79881e6f8e230b38b9a5", - "dist/2024-04-29/rust-std-beta-aarch64-apple-darwin.tar.xz": "bc16b3a1ab6ed69f0121a117c50cbcd201500dae4d72ad0dab148913d04cc529", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "9375c786703c17baae1c2066f8d972ac316bc840e478ecd1b94288a1d428324e", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "50d6818a8dd3ab7a3ddbbd7a062b538d9ff3ceb6eada031d1c22ab1dc7ba512c", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.gz": "56c3a01e8fd5c2ed75df811993b0b724709fb5473cc308ac09e7f5644468f751", - "dist/2024-04-29/rust-std-beta-aarch64-apple-ios.tar.xz": "3527d1f2c99c806479fb4b3801335dc921b514f171b82cd252cbbfc9ed30b163", - "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.gz": "bf8cae7c66489f1aa27f1dea1b37f0d0ae514a6e21b93ff2dc6400dc88feca03", - "dist/2024-04-29/rust-std-beta-aarch64-linux-android.tar.xz": "46799f0bc1b3c13877f6cb732774cb3b33e0d8a081bfb56d0f877e79482aa1de", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.gz": "9f90fadab5104e1d415edf3b4edfaf7222f9f0d55f849851efdec74ffee16f8d", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-gnullvm.tar.xz": "87ed6774202b18691bd6884df6944c7e9fe9c944b57a2837e7a7647518bf94e8", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "4a0692ad28f7f130b472ffa4aa766b745ba01fb75aa921f2da6622c9c68750df", - "dist/2024-04-29/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "a3d45962489a1e18a87e567cbbc8d3665f38809d0ad2ef15bcf0ff9fb9f470a4", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "c724f4eb135f73b9c79618f27a1ab35dc7b9d26ca62ed796accce68f9e747a66", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "8eab25782d16bcee75f86ecbb826346beb4a7525b220b45b3ba05a567c6d4391", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "33ab1f8410edf590570d7468dbe2ebb5a0907125bbc8d360a928dcb355f0d0e6", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "d3d870209a55ac96391affaa347c04f48cf98c089ac5056f340b8bb38bcc8e60", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "4d2bb72b898c30a2fc8d5d3333c2e99a8e30c15891fab641b6a519dc9f0cb611", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "fa343e6b6110fcd0c5dae4287ff1a799de5d7e4a805dbf4e9a034bbaed2bf269", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.gz": "f1ec4139783169fd83e1b0184518ed25d26cee7b21f196deecc74e83a1d78725", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-linux-ohos.tar.xz": "d100be2f6f0346c4b1f5b41aec0c13a47426bf4d49127f2341c8332903e4e782", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "bab6051e1071a58cd126580f6644decf16edb4473fe4be6a34791610d820a294", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "d9b68f06ff23629063e92dfc42aa3115a858238d368e4b52b35c1ea4491b1402", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.gz": "96804c2d9accd3242bdc22dad688b2ccee071952477b9c592f099377aee6c591", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-none.tar.xz": "3fed6812d84bdaf787e85c37e23ba729b81a6d25a2b33fed75320e66e6641c89", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.gz": "8da5f301bff35fc067ec7cfb878ebfa5607af7dbc276a6b34a77404432c700d2", - "dist/2024-04-29/rust-std-beta-aarch64-unknown-uefi.tar.xz": "80d643189dc9af98b6410a01261ce6ad34b1325f3aebf3ff61fb43f1261b41ff", - "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.gz": "2e86b54b0d1f7fefead11d6383bdc80fe0a7b3ccf58381d2a731e6f1c62926de", - "dist/2024-04-29/rust-std-beta-arm-linux-androideabi.tar.xz": "9831a0270457cad2798b5ae4fe956c257c7e10ce5ad211793dc467577cdec29e", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "f96bc303c0c2be9cf589f00aa63b2cf3fb8585ca9dd8860fe525821bfa1fe19a", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "e57a053b1c2bb6fad93dfaffedce7f48fa292196fc8ba6fd2f0c74dc810a13a9", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "49b2cb2ba5296871b5fac5ad9a74a2891e8b78321078a455ba4a65e003bebd40", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "0f9c15d834a9d282a4018934759f7b48ef3d275e09679a68c5fd1b3f047d02e4", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "e59f92827241e670c1aa92b35235ad12340869d59327fb83084b5f4149acbe06", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "ad1cf96bb1fcceaa016e29e8ad34b4cfd711d2e0bd7cabb9cd7cc28abf64d894", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "14a6d318af85bb9fa5c229e45a88a32a71f44ed02cd90a24bb67921eb64dee41", - "dist/2024-04-29/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "ed6b48502ab9169818bceb300b4e6b4fd63366ad5808b047bf9988dae04c2729", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.gz": "345e8a023be55e3b88a0c2677ea28c7bb4fcc5f3ab707638de76065c7592c2d5", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabi.tar.xz": "6d9b11d08f2d62611327a893b45ba07c36df11f077250496ab0881eb7ac84c65", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.gz": "a2ae1bf003a8a12b2ecb6bde9868a978820f184af523f0e4c3fc935edd509423", - "dist/2024-04-29/rust-std-beta-armebv7r-none-eabihf.tar.xz": "3d1dcf8308f9d4590b429f6abbf8f42f04496ab490ccf4ed8c9e381e6d886cae", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "a54106d27e4ce97463e7867ceff9dd22ba456f840ec23229e6909b37d48ad554", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "e6abfaa0905a00efeaee85b9f93793bab93e2cf4e172c9d829c5ba85006c688a", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "cbed18e5dc61fcecb2920affc3890c3b8ae46b7fe5a80b3288689e18d490f3f4", - "dist/2024-04-29/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "2b58bb0dd5cd2c5f7f93f4c6e9135090b931e0ffa27ff9efe2b8ff9fbbb7e48c", - "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.gz": "6a371c2ececd349dfa76a02563069912fc91577ac4446d36c22f96723d7f5e9f", - "dist/2024-04-29/rust-std-beta-armv7-linux-androideabi.tar.xz": "9325daf41ddab02fa845971c10a5e0538a18c7bea14e66fa0f5f6fb16654c7ae", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "7f5ba76cfb7c85333c8dab76fb4ad3f12ddc254b95f9ee07fadb8e1270a4f767", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "f853b7f929b7a309ed6c08ff8c57d583ce0ccb19270674fb30e63a873834dc87", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "0680005d0a12498b687afc583d4f36bd67d0877cd9d3323bfd2df50d15c27afe", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "a494b78fcad01c83df9522d460ac2d35d2d00736a921381f2c611dc516edaa16", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cfa555db31b5470e878b0f53d86617e7342e8bf018fe62cb0271dfe13db95f51", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "0a8ccd6d88cbe79a855111fbda45aa1a728de655b6927f3d429d901d2afc6503", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "eac53424001c884a540c42f0b68447349ec5d0601a030c060aaed76d54895728", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "42d78fca62361ff28db5bc43bb01cef7af5c6f4ab2110fe6170c3dce4707aab8", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.gz": "c88de9f2e667da73177fb9c9309d7f1f467e31c18e3ae50d722c71ec8dd876a4", - "dist/2024-04-29/rust-std-beta-armv7-unknown-linux-ohos.tar.xz": "24b3c04a42d511cdc8c6107b597be38981114f0574eced493d0e90fc748094bc", - "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.gz": "cd4ad182a098c61550265879ccc04733c39110827f7ef62eecfb8c120ae4ece8", - "dist/2024-04-29/rust-std-beta-armv7a-none-eabi.tar.xz": "8499a014dfdf448f474a58f148784c2eef245dc909587d876d2fb9ddc6a4ec3f", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.gz": "e8e1870e5b12b3d8643d712efb91eb86b2081284cada4a140c1526692ab183c4", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabi.tar.xz": "d6029121eacc44bd4dcd9ef6dd3cd0d775cb6e9a3d99f3d62d746fcbf8981cab", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.gz": "1e0fc42c3802e205130c01ca90f92d793c1c5427b34da66fe77b97cf67b4a5c1", - "dist/2024-04-29/rust-std-beta-armv7r-none-eabihf.tar.xz": "4c8cfdb11bb686111fa4842d13430c86d9d14ada30e9df334b3777fe899233e0", - "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.gz": "ff895c1b39b84587f10903f4be13d275b545e690da6761190d12c01acc25c6d8", - "dist/2024-04-29/rust-std-beta-i586-pc-windows-msvc.tar.xz": "fdcbcff7b740235bb16e44174fff9080a7c0a31be358c8abc41805c02c20c3b2", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "6b227f3b9001e148b66b7001f753a6f88fef9677e39d8fcf4d9c35fe8d345568", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "1e29297beb8de3778ba958731294823d9a93aac1e0d8833abc5aa99e2935965b", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.gz": "26481ad5f22a319830d42f69b1c0195bd65900ebe112e659432334b3468f3d0e", - "dist/2024-04-29/rust-std-beta-i586-unknown-linux-musl.tar.xz": "c8a837e0d9da8ad976fc1539541c085365aac9dd28b34e4a289d38a823d1b065", - "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.gz": "f05e28a52f17e22f36ffc70018012a1fe6a07f4b461e774b36464f32bc8f8dea", - "dist/2024-04-29/rust-std-beta-i686-linux-android.tar.xz": "f9501b2691c51e54a6f4cc6fb72e41901eb551d3a7be5f82a94ce2d3e217828b", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.gz": "8d9a782d4f7450bca536aab45147c6ef08bc3847b43fdd171c6449e29762eda0", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnu.tar.xz": "4008712e03fb6494eaba3d79051c5e3fdd93d4c52ae8d86cf8f344b5f051cbca", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.gz": "cfb23242e495834a3d0f7ffa3da4a0b206dcae35872b1455b11faeee5511ba5f", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-gnullvm.tar.xz": "95415742c0171945ffc2b67c913ebd1330e29634af238f5ccc843a965340374a", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.gz": "e9354d69e39ecfac1d2928664d17d73f808256a4076b849171a9667705c0aa08", - "dist/2024-04-29/rust-std-beta-i686-pc-windows-msvc.tar.xz": "a34bb0a91170d84195f35ba52afa4c9be8a2f2706dbeea02bd6e8908e08ac65e", - "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.gz": "d65f286de399ccc9e9acaf7a4dc4f885357c750231d54a144ba9a59181814f11", - "dist/2024-04-29/rust-std-beta-i686-unknown-freebsd.tar.xz": "4c93a7da70a69b2ebbac01df64af16344e523d16470b29e57237b1d0925f7721", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "1b978bfd1a9234be7ef197c8c98c5a6b625f6fbb7b0fca58695986768bdca176", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "98d4eb5b89a593c8c4f86244c9a7c737d9c18c0168aebe5923b8d9145adcf89a", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.gz": "dbf9b3c5b54b3eb0727f976f5632c5b0fcb2f90ac7453962d6cef20f7dae4284", - "dist/2024-04-29/rust-std-beta-i686-unknown-linux-musl.tar.xz": "f209ade093753342dda6e710ee832a538dbdaa08a24d606f9a2a1bc59b83da29", - "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.gz": "3c3ca7f34569b2c70c6b223754418a535dd7dfa087ab6e28ed2ec78d20065887", - "dist/2024-04-29/rust-std-beta-i686-unknown-uefi.tar.xz": "72a7cd0f430ab40d80e93f409b8e26a181010ab4bb75d151e829d51ccdcf8c62", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "b7dfa59bb05cf806c87854d6fce5ef0f160697052fdf6e5a0cad121499108608", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "88bc22f68bab3367cdfa91676418ce1ffc0ec002afb32aed7def880bdd4be402", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "d61019048b941064a99d19e46ff3236a88a2e8fcfb963cedd1d9d1c47963c170", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "7474bda08134c676d74afe5263317af3f271963d8ceaa5efbfa1b657f885c572", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.gz": "e089c77d433d838ca02d7531d6f4a1770fb4a0568acbd96c8f43034d76f2990b", - "dist/2024-04-29/rust-std-beta-loongarch64-unknown-none.tar.xz": "364ae6c89c7a930098286e55193d2f5ee3d5ea80b7cca73046e41725f4a8a2f9", - "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "c17bfad87d16f3a8d26646525dc59a352718db9e7572acb583b68a18cfdc338a", - "dist/2024-04-29/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "f5c4ecef1c08d19ba6fddbd359a0ce94e46888021cae057fce969276026d086c", - "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "3e7e13b0d2e804d228e1e3a9dac0205d294ae29dcc37132f15fb1e218861eb39", - "dist/2024-04-29/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "ea31b7678e6f64c2f9c28a9af120be04ed6f2a25a496e40afbf6e9aa0dd20b60", - "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "f0e1b314c3d5ad1676c68c112581dce62fa06ad557cd5f61034e147b064ed270", - "dist/2024-04-29/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "8ab7bbea6e2f72df1286facc7d306d01809a4dd9f8901dfdec7e50b594658d49", - "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "48f6abda1c7dac185858744aa2cdc3513cdfb6552535282ee83cf9c5365573c7", - "dist/2024-04-29/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "d920d97f15b56ba6ea81e08b3c29dc7f44f5f30b7513c53446edf95843c332af", - "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "0a198a770f6e6043e923b0ab1a508fd8b190612d0370c33c8dd2c5f63b6f19dd", - "dist/2024-04-29/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "424a93313cfe2d85acf956be3d9ac71ea8e34ee61617a550ad6ff5360e1dff52", - "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.gz": "2e2b0a8e41f4ea774d665d6248cbc2fdbe3e582206efeb87d250786ebaad0b1a", - "dist/2024-04-29/rust-std-beta-riscv32im-unknown-none-elf.tar.xz": "2da372c091017b7096e473e5c7016a504d2e041e14173d2520086cb43e0a615a", - "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "69d3b21403181b2df14243816388169db2466477ec34bcca5693fb017703686c", - "dist/2024-04-29/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "281b9c20f8641a3d1b349e762b7f713fb0b91da0d21eec798e639e36a0ea3dab", - "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "dd9bfd3fd8446d35180fe781139dfb4e04dd658b112eb2a749e8f4aea14f0271", - "dist/2024-04-29/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "b1366375e0c5f53da581741dec91972b0c46d7d466052539207e8feaab0ba3ec", - "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "7c6650d8cf8abd51547010e8211af3ef3195099ef43a563460ad4780de20ba17", - "dist/2024-04-29/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "bab46f3c0078ce346de563bb7a248ca92f15dbdc73bf5a3bc520486118442320", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "01735b4ad5bc0a53087dd0ccaef2cf174b27e45bf4d2e3c15e64f7522f059c63", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "0bb272c2c235583ed3e9ec151b3bfc601f8cd07822c2fe47a1258b358be507f0", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "b2c7f8ee0efe6d0812e4b5dd0979f60f105b84d34d4f600ef75f2eacd954893d", - "dist/2024-04-29/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "0d5301fc553a6911af6643ab7f57b6438bf649ffcd050d486278c0c5fe38eeba", - "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "0d1d35ecb88ee717720ad8e74bd5b602fd6011fe321baddb939f3b161e9cd8c5", - "dist/2024-04-29/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a5cf0b98596e68e6f72be2e83c61b8aaa19ead42f248ee2408a3b8f4e97a6657", - "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "629ed749cdae110668ad9ddbc5c61e99e8d400f3dd0981146c3820deadc360f6", - "dist/2024-04-29/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "192819438ed27a565cdb67b51d2f5caeb6ae258de86191d6922574327f132acd", - "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "84286f6cf6f00f3c92dc881f64a31e1ec5910102d8d3d4faf6fc7e2ddf1544a7", - "dist/2024-04-29/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "304b5f876b47dcbb7c3483c49295b822e8ba83234bb568ce67896ae4773ae2fa", - "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.gz": "25062159b859e21dda76ca22d4a31d3aba4fcdb0def78bc5b5cf9887c07c1be9", - "dist/2024-04-29/rust-std-beta-sparcv9-sun-solaris.tar.xz": "5d557ee86457f288462603fe53bcc2e092d84faee543659419fa68c1bd88f554", - "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.gz": "a9663048aad82ef832b2cf82fa9fb94be047f77e283e8aa3e2df6ad957d0782d", - "dist/2024-04-29/rust-std-beta-thumbv6m-none-eabi.tar.xz": "4c4b703a846b4123d09c1eace6322e82784a004b278f1f3b1ca1279e96207f18", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.gz": "32907c33f240abb1cb17ac438da42c5fa3932b270ad08fd6914775c5b59a02f5", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabi.tar.xz": "112583227d2b6abfef6eeb78d980bf2efef392f3b66e433c4959a642d72ffc7b", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "7ba0084527a18479c4b6f6a0dba8ae23a0ed50e9fc5fbfce23cae1babb5a1e12", - "dist/2024-04-29/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "49eb4e2efe3a76713ce1fecacaf915717eeed8552912b92895c7fee068a85a36", - "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.gz": "518a532b52f2dad2825158614cd00b12aac6c6e1983a1ad53e2b0e26d1f1b845", - "dist/2024-04-29/rust-std-beta-thumbv7m-none-eabi.tar.xz": "2895e5796a29fd016462694d880e38eb191cb92c9bdb14414c1d6e63b23d3394", - "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "2af590c063344c4c3f65d704fa255232b5f5954872d03c4c55d48662cbe6bb17", - "dist/2024-04-29/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "a09df5f38183d9fe6116c807619f812410763ddedf06055bfe8040b5794104d3", - "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "eac22c4972bde3a57cf2ec4e31b43db3c4b7d961ae31475d8942e898c07640cc", - "dist/2024-04-29/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "104f2c6490e30cc47833edbd806c2efe6256d1194600b2278339612f94704d45", - "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "b3c9c9d7ce8c1db6f20e8ede542e67aacd6047c52882a5d06c4f96a40a7304d9", - "dist/2024-04-29/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "76bfb114bc7674792934a4892d2db41fdc8f5bd30c3aa96c43e8055199157476", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "1308335fe80dcafaba511ee589959d461145533de5f76118fee29a7e9a15841f", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "cb8acdb8920983c03b9495cf3506a3014384b4d2f6a53e7907924d38a0baf7f0", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "9dd2e5ce7534ab4fbb93ff652196e877f4e9eea3863920c3d34a05d9a3598c81", - "dist/2024-04-29/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "4b6e962facf7c54846965a8d6880e4a980804459151f2e22ac5af79bc79e26bb", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "731603392b6e3d36b3a4956928d084e293ef18c8b8593efa756e753a2a309709", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "8b681b3af47855eb63c4ffe06a2bc6bc4f365354ffbc171ce8cbd8c2a3588a07", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.gz": "7b87e59391493c3147c03794061111e25bdae669aea58190a951cdef111e75e0", - "dist/2024-04-29/rust-std-beta-wasm32-unknown-unknown.tar.xz": "d15eaadb101027906c2fce15b95a3f820bdbc4cf145b705bafc2ac5291289c3b", - "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.gz": "07390ec742b79ec11b2c3ec65f60efe5d7c616f50c33058fce346f6e9ad21af3", - "dist/2024-04-29/rust-std-beta-wasm32-wasi.tar.xz": "79e34d46621c298cadb98c00ce3b25d97474aec300d85255153b47e21b7bb744", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.gz": "b916dc9051b0278f820ea0b093db3ecae2e27de641ef67a9b508df75dc92c938", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1-threads.tar.xz": "2867922a39da3b02ebdb93fb78b010695daf468f87485ad8ab79c7f3eeb18b11", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.gz": "792b718c0a72e97ba85a17ba67ee09e55b85de829fe4021f828ce54ff8cb31e0", - "dist/2024-04-29/rust-std-beta-wasm32-wasip1.tar.xz": "abff86499119bddfeda9059004549941dbcd3d911702d4a9c198b94f60e60f4e", - "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.gz": "0bcc7698efafb42a37f20815f5660e39829a42a2776304e7129d0a4ec0c7520b", - "dist/2024-04-29/rust-std-beta-x86_64-apple-darwin.tar.xz": "c437626e250b0d06c05dc828ab81d0d2c543ffce4b100567910508974ea50045", - "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.gz": "7c98c9f491bfc837111769a45c10ce2f1ef73c22377158ef9ae80b38034892c0", - "dist/2024-04-29/rust-std-beta-x86_64-apple-ios.tar.xz": "f4bda724e6e382e02ddf4e4e7a479120420666a5a1ad3c87a85d4d3c763f2cb2", - "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "01efbb2e48045318e18bfc7b6c190b461a219e81fc1cca6c855bf0c658aef556", - "dist/2024-04-29/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "9bff316c6d2fbb3c0889f9ffe4eae496b293fb3afaf8d597155e6badbf0c6a8e", - "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.gz": "5da713547a8af2c86da7db5d8aa4c27188dea1089fded81ffbbeb0f78952a10f", - "dist/2024-04-29/rust-std-beta-x86_64-linux-android.tar.xz": "9d6a45d6af395360c63ce97bcfc2f9a2967c708afcd979f17fa447239703a92b", - "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.gz": "d1a71110bee002c8edfbcc00e0f5eede5afa005b09944bb2cde469c658049e70", - "dist/2024-04-29/rust-std-beta-x86_64-pc-solaris.tar.xz": "6b8d18c83b9fffdddf9e55c807dc7d5784cc6d7ae90a57c29b87d707f0656964", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "28921ee14426f54aa09523547516437130654b2d9814120d286f209666c88533", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "7c3125cce30978ca2619e9aab150cb5b9b2535fbb6274d4ac1b1d4342c7b0220", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.gz": "ee5c237f092f8a4ba797c4c7769dfd4da81b5c86d2f4b88704d127642d222a22", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-gnullvm.tar.xz": "30c84b04bd2d4d33abf1875cfee5f227ef6484edc67b3cc4c9c96d92c8406d6f", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "81274050e72c5a8ffdead83f7be62434f35a65517a1b3c6f7d9d14d0d59da710", - "dist/2024-04-29/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "215e20c78a2a4edf9b8368a29a09af5f4cf8d0edd1995de3bbf2eff01127cab7", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "340131cba121827a9753e19cb3a4b9ba2ebe30569fb20d7f9300b4dbe2a15cf4", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "69626178bc5309afc8a02c941bd77e70e1aa6917ffb6bf0d67a57d921b5c664a", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "22c6c90533dad3a731ad8a6696e6cdc1b15579e25c658fa2b094185e1893934f", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "30d7ef6684fa98e28037b69d4220cba40489c23e80fe7793c98b388dc161757d", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.gz": "9d7192d32eaa6b6ccb0f615da0f4cd80827ba6484eabeaf401d8217678f1e313", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-illumos.tar.xz": "7a3fb35e0bb252d5f90773136d1417c26d5601beadb77d6da6f5ad3081977f07", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "e987635519c1edc8a1d147ca4a86283637e4dbd0a49736b01d605e45a3a14e8f", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "c3ab6b97dccc0038c68494b03b6d444d534e447226a2b2e140af54c94fca0b2d", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "72e8113687be8f947c50befb42b0957dd564f01693cf4d68d749a9e074032ada", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "867b24f33b19f40727c71818c8a002718d44d4cd4ceca44314331e19c1adc1a4", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "f9b0fd9605bd4e264f5303bd740d9a0195bc147132969965b221f9da0d7875bf", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "022dcf4887df41d776ba2666858b9aaab479758134a71f7c6b2172ed7c1a1752", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.gz": "b5ff4a0ecd7e0f71a9557b6096bb907e5cbc8982431f0d9b01d8e1a895d8b37e", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-linux-ohos.tar.xz": "e40d5bfb46aadf6faf849df548154db3f35f356f8b98037a056802a235922b8a", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "57cfb1fa472dd9c01fc0caf605a55b7248375d616acf84ec12f6430d5e07e2ee", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "e4121f060b917c811d971e85ce02495e83150ddcceb2204615edff24bd55bfa6", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.gz": "d63559803c8eb47e0d10d9f3a2284477b570a2536bb541762774271451e1f0ce", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-none.tar.xz": "5388cf8ecaa234d507e505e8c6d433c5de8811b2717aa254e4caac9f4aa6cd97", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.gz": "0f027163f37618df4330ecd82afece432b0a509ab20333d7b787c0d139ea89c2", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-redox.tar.xz": "b1c722e894b145c2183183fa58762c64402fac077419dc7874f8b08eee665651", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.gz": "24e2ac0d44619ef9b76cb1af6178103d65ab12e2677b366e8aee0604798fe5f1", - "dist/2024-04-29/rust-std-beta-x86_64-unknown-uefi.tar.xz": "1d8a45f1bfe6650edc5ddfc8683190eff5a74384abcb2f73eb3d1e88d566ccfc", - "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.gz": "ea113c567692d54983ab6c376761651b6dcf9bedad5b5d822d28c0d0d0733cf2", - "dist/2024-04-29/rustc-beta-aarch64-apple-darwin.tar.xz": "e36363f1ea531d2fd563f471758e387de37a34e7ef6f4c12175979657333c5b4", - "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "52d77d540fc3f83d82f35f358ccd9055fb75453af3e3bee4b11636742559db13", - "dist/2024-04-29/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "843c56f5431c1feda85ceaeef0daf988e8ae020b3556326fb1f75ea7968bf2df", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "ba2fe37dda1a487a2c75151895f4f6e886e9476a992272ce26e9b5fd7adb11f9", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "ccb7be3935de1920509d2061d38f92f1fb8d2a5dd6cef392492242a929363fa9", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "40636e0936bd311803317825c5fb6b446cdb5536ada1db097b567df04a86d7dd", - "dist/2024-04-29/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "804ef68f24bc0ba5150177d8b8515daa54aa82fcb61472385ef1a1d897c5c3e1", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "a320c2869d1d2c92b698397d4467c8498cad9481f38d28ac810bd165399ca46b", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "7ce92211d87068d9c223806929adc34ca611a1321cd58b5bd81aabb0ec3ff085", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "79c16b902884301882d16be36fe75ecb32a8e49abde0038ce21cfbee883c2c3a", - "dist/2024-04-29/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "9384eb9bdbb585b414b6c04c592a79e90a0c0ebfeeb970e5e1b920cb638807cc", - "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "ff99de5b819a4fb9adce9386a309b9841bd33632eb7d5079415a6ca6fc86b9dd", - "dist/2024-04-29/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "55635cde13af11dd8cc007d2e0499bfee493bdfba87b6efd7b1fa4115f5728dc", - "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.gz": "de82ac745275f069225b84574ed145afaf9f54abde5246592e49d5d1cf40cac1", - "dist/2024-04-29/rustc-beta-i686-pc-windows-gnu.tar.xz": "a8a7bf64d33c95a2f94265fba8dd9ac50bbb727f4bc3e79be5bf61212cb5d22b", - "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.gz": "88967a99c993d6e0c3c7948308510644286ac826266dbd3d89aaa083100711db", - "dist/2024-04-29/rustc-beta-i686-pc-windows-msvc.tar.xz": "1804f75786482946258ff0e827274357c49e90a7f2f568add7353249f2ab78b9", - "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.gz": "3cb7e02c61d4a21d8289289b874b25e8b020c1d553e5af950160bffc14f51c18", - "dist/2024-04-29/rustc-beta-i686-unknown-linux-gnu.tar.xz": "2ad4b1311a0e39c359798375912faa91b4e13cd473bd59efd1e4f721777d254f", - "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "ab19efb741a127615b9022dedf1d895b53c69740cc3da745f9b9888bade9d98b", - "dist/2024-04-29/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "492cc11d54df410c2547890803930fc65950e6b81ced512e24bef56c3e70f3d2", - "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "c5a631a41f417336f3f65c85adefd1fb0bacc02465485f37d29fc1223c9f6cec", - "dist/2024-04-29/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "0701183b615d9eec9daea724d4cd8fa98dede2260cfb6b137d6cbf8ad6b29a4f", - "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "cb70e92d5275862b500614d79eaea3d19319b96798f4850cb19dea9a8038a651", - "dist/2024-04-29/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "908cbe562d82cca1bf176fdc99af867966ea423d244c4a50e14bad19f6878201", - "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8580a3eb6d6df1774f4b6ca06dc1195c42b1e2a463488a5d851e99b0ca6d0249", - "dist/2024-04-29/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "2627948036e905f2e280663c56c86c172e2b0d057311ade7ca238953b7e0c36a", - "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "526e4f129fdb4b2c8f4317c57105a09ff03e71771d6d6bbbc9380917b5440d71", - "dist/2024-04-29/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "fd9dcf60838376478d7cc505ec7fc39f86f9d042646a3b836e9c06825927c7eb", - "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "664c1255a9435d1ad086329a3c215974b9302d481762240cc9d0328d9f1b8c9a", - "dist/2024-04-29/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "a585ce7684e4174f03adb09df17221e1729e8179dbc91b9a0f8813c3ecc0822d", - "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.gz": "59a1d91009b506a5bce3c276993cb8acfd71f73d01f9eaf4195b36114ac822c3", - "dist/2024-04-29/rustc-beta-x86_64-apple-darwin.tar.xz": "f86f3309cf2784b076f14e7da9e921c294a7701ea92d378c609061deccbc6bff", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "f5c074461409b33a9791325d4014e6861ad36f99b9e48e54ecceb73986450be1", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "045431eec6f839b1c40b5a75c5000f80bd6351274a59b29d962833495324ecb6", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "a3abfb68e60544170f47209bbf048f1374e5bb75901a529e2ac2f315758155f8", - "dist/2024-04-29/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "398c41a3219781c7cf1a907406506526b672abca6d3ab59c30556390a5f992c9", - "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.gz": "38895e615efd0bf75ca14b0ab0a085527cca64fae17631d1780a8f51acd26d17", - "dist/2024-04-29/rustc-beta-x86_64-unknown-freebsd.tar.xz": "786f40030dbe5e6897aafe4bda44770920b2010b93fc5ce86574774e531e2eff", - "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.gz": "7003cab7650dae7e3d29032422a57782a2c146024c437a6466ae1dd2b61a6618", - "dist/2024-04-29/rustc-beta-x86_64-unknown-illumos.tar.xz": "bed3cc10203e8bd4d43b6245928c8a607acc5b6e633635caea45eb4eef4bda56", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "84cdea91c9f1e848ea17f554229ca80d18d093fc609641d8f003c4f2d4871866", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "a20fce7512f7c8cc6230a0f63f12855b04370d25e621183f71aa444c90c36b4b", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "87e0c484ade99efab57c655ef96dbabf7a02314540575b65a14372ab5496c36c", - "dist/2024-04-29/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "469757d8f35c9f4210aefd2ba660ee249e4409d47b908a6c68c1e650ee81ae67", - "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.gz": "4a38000480fe78fd5da7f9b71d36f296a6ae103254d932c4de6b902354e86bbf", - "dist/2024-04-29/rustc-beta-x86_64-unknown-netbsd.tar.xz": "45945d6af237fe4c91fde7db02ca19e99bac56a911b8db79be9b6ab8bb3934e1", - "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.gz": "0b07375a9a6507fd4932a05b5aaf28ed349fe2040103f1cb69c8a2494437258f", - "dist/2024-04-29/rustc-nightly-aarch64-apple-darwin.tar.xz": "143bd7ed3ca7b913ddd0cea7cda8d1a0e4c29cc2ccbb7d29f0e45c2a87c3ec46", - "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "9404c111b91fd092367b88adbc37dce10a98c443bd8d9e13a860e1fb4e3af96e", - "dist/2024-04-29/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "f9f432907c276edcae5ad8ade0264f3c03109be02e791a814edc8ad3d229637a", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "33425c90427424f0b30fa2a6331a3b59c680f1c1bd0d8845d7e6bc1e2f80292d", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "03792890c64c72f30143849894b15f0eb3d6ad735fceede9092abd900ee733e4", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "cf6f2bffa0db1b4b9b8e95801bf415dcce413f902e26f4c1831dff1a00752b99", - "dist/2024-04-29/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "9192fdb668df8d4cab776623db7d01e35af42fea94098c1d4ba53190825d81a8", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "a174e7e08da2abc6b84499360670188f5cc61b6d055967e04bf602ff3d831f45", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "5a59811027586863852b15fc2b603e7e69b19841f4c10d2527ef1fc5b77d8af2", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "645bb5dd7a96bb9292b9956cb9705e9aed2408e47728f245564f1f7404ede783", - "dist/2024-04-29/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "1fe34911b082c3a5ca4f24656675c095d2cf56f8005be9ca2517d0ef7d0a2b37", - "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "f2d6403d81bb0afe2e14956828987a0bb044c95f2d9566e1d792dd922dad7914", - "dist/2024-04-29/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "d93fdafcbbfd50c88c3f4feb4c68b053882ccae02c45e1615aeeae5a86f4aa98", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.gz": "a9e997b03559b3dfa2a0eba6ed7a142d7651ea7f4ba4e788d9de807b50558e58", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-gnu.tar.xz": "4412b5fbfab8c5b31e57cf8c4ce9a9d13cfc9c0a8174ea1fc8a7c05281e1cb54", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.gz": "1725c41500dbf6bea554f3d4acaba70167f0e89087aaa3eb3c0f8a99047c55c4", - "dist/2024-04-29/rustc-nightly-i686-pc-windows-msvc.tar.xz": "27db022494afebbe05605f134191e8b2e78bfdeaa638d4215174038ca9dd2fd7", - "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "dc1a05d49b773dba06808c1c50653ecac506b3433f0f6dfa307109a7c621cc1a", - "dist/2024-04-29/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "cc58ce3af8f5481ada4dc129079cd558664717526b2f7f9a02bde6bafb6f45ad", - "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "34cfe803126ae9218b17adfe833a55c697dfa50729ac83b642529f3682d12d15", - "dist/2024-04-29/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "c752dc8962656c09047151fd24166f3134fbeed85006b5d22496691079c7fb9c", - "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "386b086b8aad922050c813dd58bb79a52ef806b2d1413e2e9cc46d6e43b81d7c", - "dist/2024-04-29/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "d9eec9ab7c265444ac5f04d4ec9e77d4c0c3c2e34c5804db8abf5f94c8fd2272", - "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "91df129046443554bfb836d25886aa9807b917acbc9dcf30f6531cde7bf912fa", - "dist/2024-04-29/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "ca9b574b9f2e914b5a6d9e011aba805d1e6f9b687dc1a1868e88f0e4d9e4401c", - "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "8b44f96a1ccd6d501b0af3960edb2c1a6c93957676a1c2cdb831e614de398f8b", - "dist/2024-04-29/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "f8a10a6767b80bf24f73223b9e46e1b18b6bf6746ad2115eb8968a0e482f0e4e", - "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "a197208807503a9cfbc6df938d614a192da48884b2e4892f7b1d234579091be1", - "dist/2024-04-29/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "af3a1a33942bd8a3417593dc118abb1db0373f5410f54771713c05bb86724fed", - "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "5a3a3aa73b6a0f21c63b9a40bdbd0bb4dc59bd75add0a06e292ced791fad31be", - "dist/2024-04-29/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "6d7903f1c9fc95a23448717326d667dce59e54aaff821443d3cd9137cf3537fb", - "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.gz": "64eede54da4bf88b0a42ecf7f7a4bf8002b5550e60a64e1e48244c7f5b04768c", - "dist/2024-04-29/rustc-nightly-x86_64-apple-darwin.tar.xz": "0a8f95e3bb0bebf9bcc8116b91bab3ba97cb6ff4021713586280aaceed9da030", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "58f9e0dd9c1aadde2dfd869528adadd4acc29ab0850236f3cee5f023d4211939", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "a211a962093e0d09358d51a6eb48da0966a02383c6b00c8acc077b5663d7d707", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "5631926874dc54204c319137a77a89de5e6f408de2a832109e2be71ea79f27d1", - "dist/2024-04-29/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "a8cf87bc663b5e3dbcc97b0eb58bb1b9b5b0100aacb47dc0c372fe1612517244", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "1011f98197a9fe82d6095f4521934a06eea5f7e9719a6e4c9e3bf13d68f799ca", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "79599b3f91f9372262e97a417f4e104ef5192c0f6f8df204aea9c8b3ee39430e", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.gz": "7179a453bdcb17e401c0af8f4ab86cb5a4752a8ec80b0cbdd4cf1854c7f36a35", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-illumos.tar.xz": "d565fc366fdbc305fbfe59e72b971c58f201d69e03a9ffa667d2ca0735cdb7f3", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "ae6bd8e20560d48519290d78e3d21f84b983403ca1f8f466a85496276d7866da", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "c7c0f8f44b0275456a27952178caa04c32eb9a1507056ddc05926a0730e17359", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "3246797ddbc9118de819b13b005b83748338f3c825a7436ebd5aa79ca55539c0", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "c7e784e77dbabedad88d24d2ae6dc4abb68bc04b1cd6c9d45f6dc28b6d0e2edc", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "c9452de4b3f15f0cf0b7d737b217b2cc7b88a96543bd8ce587ee14be1e21a90a", - "dist/2024-04-29/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "de9b05278a5c69d53ccbb31223526ea2aa2275c0fb3f046d1c1b4d67c0b0c275", - "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3734353a58dbf6c3831cc6b4ea606357140c191c89e8dfca1d7aa2f3fb8ac53d", - "dist/2024-04-29/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "e5e3a6e609fbfd537aa4acfefd3681d4b6c8029e2801a1ef23e8b09cf5a47bfe", - "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "22f54857e01d759301d099b67547cdc485596499088d0d749d38058c28e0f752", - "dist/2024-04-29/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "db48a9d45dc7c7aad4c9bb0d20789dd35fb6ef7a966948c44fbbae132de4c16b", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "fa5d1fb9f3627e7d59269a1f8008d780c685ea04975473f1808287134e7bc5a7", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "61ab625b47fa9097af90a79a1e75a2f2492a415f4009c9043cf453bd4128f031", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "cc79969341fc60991059d0e3f13a69489c1e0915ea5787a88b8605ed5b7f3cd0", - "dist/2024-04-29/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "bbdb75f922b4b1716b033d91c76c4c0aa53061d6e7fa53a9bf16fe076814bbb2", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "13ca68afc3f3970a37951504664b58035102e1ae06d10a744389603b2f7499f5", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "04b174aa724945b6359a555892506c6a742a7c427464e8206433bb3f9a65fc02", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "430333380a590a9de211c8d735989fedb89321cf9f5f9a0b1ef651ec8b598691", - "dist/2024-04-29/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "924713e648806945cd56e54d4c11dc74b65241c8dbf6cc7b401c5c93d0f7ffdb", - "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "bb6e5a8b5cc88099e613aa5f4d926165976d8e4a7fccbecf4ac3b0eb966d7a0f", - "dist/2024-04-29/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "34d5e970304e1734aacb26c095e926c27a07e1a41fe70db9fa2997bef97ad3ec", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "835447a1d9d60659e99903275f327641809fc0148f35149f980d1a17ff87cc9a", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "ddd84a7f900aa239f93711f7da71e57aaedeeba2c9c8a8f23608acc7e48613c0", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "02f0af2bdae167c6091099a9b54ceb150c22b0f20dc861587a02cac78deb0b39", - "dist/2024-04-29/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "822f78f39dcbe3282bf7888a8cdae04efe7b023ded026a7e7f430e4ff15e7942", - "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "68a6189652c11a2c142c5339e2f5fb09d5f3e85d860bff063f62d5d3a3d111bf", - "dist/2024-04-29/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "6740ea882effa2fb87dd72744c08888ce5ec59c9797c00369156b24847bb180e", - "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "0bb365e2d895ef3c39c4899a01187a23f9b7c5195c30bf845da3917f62f5eafd", - "dist/2024-04-29/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2e54c9887bc6ed1eb09b9f69c8425da843ea12bf33248fa0ccdc0d14387c1c57", - "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "b0c0fe437921d17e2f50cbff87beeac067efa3d5211a241fb6f4c10b8ab500ac", - "dist/2024-04-29/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "64e7282c0cf4a714b11eed1d28be3a64ba0ccc6d899211a872a5a7809d514c08", - "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "100cfde057c81460b8cfde2047fe83ddde360a6df1ff178da5a968b17ecc9df8", - "dist/2024-04-29/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "38e8712e98fa0bc6962ab2fd2e3b96a2a5dcaa6c16161d8caf71131a1ca5031e", - "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "4dab52b50e19348fb39fdad39ab44189c27c10f80b5fbe2cc4723b644611fa87", - "dist/2024-04-29/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "36d1b2c9150fafc5976c296200ba3fac3e923df3e6f18032068200e2a887146c", - "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "7cb4a536320c23d305ce3bd3b7a954d951bf4d358ef3732be75b9b290c4818a5", - "dist/2024-04-29/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ede1afc7dc5892ef6f780e987737e145c4b4d00495da8c2e9902182a3a174e20", - "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "e2d2d561cbfa0add0e5349682976216d3a7cff4094372c1ed26854bb4e4d93fd", - "dist/2024-04-29/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "e0380e65e83e4131f6aa7ee4e185689add4372b0c1653312e2ffd56072fdd0fe", - "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "73a140c7ed9c80f209ff976c63b0a34d625d651553c38692c91f048f4e0ae470", - "dist/2024-04-29/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "9946b7120465181e05916b8023bc075b32bd85cf45a3b1d8bfba2f94ac78d927", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "eda273f27714b1e45adcc2388149f48de0e32a9104db0b9d1a02f6d37de43fef", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "f2955a4b696d050c219a96c093162b42a2fab921f9f3cb7570f8462928306c6d", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "ec900cc2d3c6d45ef039653f4418f9b9a4a5fddd5d7e8077c3fb08b36c539a28", - "dist/2024-04-29/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "04e6999a3405acc79f5fdcafeeab52880e5eeeedd3909b5f3c57e7647c86ef99", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "0730c5ebd576fec5371085f9fac0adde9424e1d7626456ed33bc66351b0ad307", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "90cbd84b8d48f0235a1954166f5edd53dc3031532ec6dfcb364f9a9624c9ce11", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "5f5c62d321db27eb495f6ea312ef8bea0bf17a7a501a44e062986c416951700f", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "a3bf64e2f22436e4484fc818f69d2f750fddd05a96463fd4abfcf655edce36b9", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "a847a6f9c7a3ce71c7cd8d81bdfcfcd8e4d128aa28ba0dafea89b0cc37c6c36c", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "21fa794456566c64d08f629a385f89b3cfe9d9b69f317ae85fbe7425419108ff", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "b3f792f10a98993b4b55d1df951727a4422102d51b1145e51824268d48587ad0", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "d791f0ec3c004e7baa0381962bf8ca2f18a3c861152702de5301d0149260e7fa", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "9807b2887e976d29f0c04484f8459175b4f6b70ef000037cdc4dada48e3cbd74", - "dist/2024-04-29/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "019920d64778af62879e2146c2c13d9f6e2165a38bbfa1982694bfb48864d308" - } -} diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index 575f3677155e..6a4e86eb1dfe 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -2,3 +2,4 @@ pub mod ci; pub mod git; pub mod metrics; pub mod util; +pub mod stage0_parser; diff --git a/src/tools/build_helper/src/stage0_parser.rs b/src/tools/build_helper/src/stage0_parser.rs new file mode 100644 index 000000000000..ff05b1169895 --- /dev/null +++ b/src/tools/build_helper/src/stage0_parser.rs @@ -0,0 +1,76 @@ +use std::collections::BTreeMap; + +#[derive(Default, Clone)] +pub struct Stage0 { + pub compiler: VersionMetadata, + pub rustfmt: Option, + pub config: Stage0Config, + pub checksums_sha256: BTreeMap, +} + +#[derive(Default, Clone)] +pub struct VersionMetadata { + pub date: String, + pub version: String, +} + +#[derive(Default, Clone)] +pub struct Stage0Config { + pub dist_server: String, + pub artifacts_server: String, + pub artifacts_with_llvm_assertions_server: String, + pub git_merge_commit_email: String, + pub git_repository: String, + pub nightly_branch: String, +} + +pub fn parse_stage0_file() -> Stage0 { + let stage0_content = include_str!("../../../stage0"); + + let mut stage0 = Stage0::default(); + for line in stage0_content.lines() { + let line = line.trim(); + + if line.is_empty() { + continue; + } + + // Ignore comments + if line.starts_with('#') { + continue; + } + + let (key, value) = line.split_once('=').unwrap(); + + match key { + "dist_server" => stage0.config.dist_server = value.to_owned(), + "artifacts_server" => stage0.config.artifacts_server = value.to_owned(), + "artifacts_with_llvm_assertions_server" => { + stage0.config.artifacts_with_llvm_assertions_server = value.to_owned() + } + "git_merge_commit_email" => stage0.config.git_merge_commit_email = value.to_owned(), + "git_repository" => stage0.config.git_repository = value.to_owned(), + "nightly_branch" => stage0.config.nightly_branch = value.to_owned(), + + "compiler_date" => stage0.compiler.date = value.to_owned(), + "compiler_version" => stage0.compiler.version = value.to_owned(), + + "rustfmt_date" => { + stage0.rustfmt.get_or_insert(VersionMetadata::default()).date = value.to_owned(); + } + "rustfmt_version" => { + stage0.rustfmt.get_or_insert(VersionMetadata::default()).version = value.to_owned(); + } + + dist if dist.starts_with("dist") => { + stage0.checksums_sha256.insert(key.to_owned(), value.to_owned()); + } + + unsupported => { + println!("'{unsupported}' field is not supported."); + } + } + } + + stage0 +} diff --git a/src/tools/bump-stage0/Cargo.toml b/src/tools/bump-stage0/Cargo.toml index 4680a7ab6610..de5d821133d5 100644 --- a/src/tools/bump-stage0/Cargo.toml +++ b/src/tools/bump-stage0/Cargo.toml @@ -7,8 +7,8 @@ edition = "2021" [dependencies] anyhow = "1.0.34" +build_helper = { path = "../build_helper" } curl = "0.4.38" indexmap = { version = "2.0.0", features = ["serde"] } serde = { version = "1.0.125", features = ["derive"] } -serde_json = { version = "1.0.59", features = ["preserve_order"] } toml = "0.5.7" diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs index bd97b4eaa3e4..bb06e113c0e9 100644 --- a/src/tools/bump-stage0/src/main.rs +++ b/src/tools/bump-stage0/src/main.rs @@ -1,15 +1,17 @@ +#![deny(unused_variables)] + use anyhow::{Context, Error}; +use build_helper::stage0_parser::{parse_stage0_file, Stage0Config, VersionMetadata}; use curl::easy::Easy; use indexmap::IndexMap; use std::collections::HashMap; -const PATH: &str = "src/stage0.json"; +const PATH: &str = "src/stage0"; const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo", "clippy-preview"]; const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview", "rustc"]; struct Tool { - config: Config, - comments: Vec, + config: Stage0Config, channel: Channel, date: Option, @@ -35,37 +37,64 @@ impl Tool { .try_into() .map_err(|_| anyhow::anyhow!("failed to parse version"))?; - let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?; + let existing = parse_stage0_file(); - Ok(Self { - channel, - version, - date, - config: existing.config, - comments: existing.comments, - checksums: IndexMap::new(), - }) + Ok(Self { channel, version, date, config: existing.config, checksums: IndexMap::new() }) } - fn update_json(mut self) -> Result<(), Error> { - std::fs::write( - PATH, - format!( - "{}\n", - serde_json::to_string_pretty(&Stage0 { - compiler: self.detect_compiler()?, - rustfmt: self.detect_rustfmt()?, - checksums_sha256: { - // Keys are sorted here instead of beforehand because values in this map - // are added while filling the other struct fields just above this block. - self.checksums.sort_keys(); - self.checksums - }, - config: self.config, - comments: self.comments, - })? - ), - )?; + fn update_stage0_file(mut self) -> Result<(), Error> { + const COMMENTS: &str = r#"# The configuration above this comment is editable, and can be changed +# by forks of the repository if they have alternate values. +# +# The section below is generated by `./x.py run src/tools/bump-stage0`, +# run that command again to update the bootstrap compiler. +# +# All changes below this comment will be overridden the next time the +# tool is executed. + "#; + + let mut file_content = String::new(); + + // Destructure `Stage0Config` here to ensure the stage0 file is synced with any new + // fields when they are added. + let Stage0Config { + dist_server, + artifacts_server, + artifacts_with_llvm_assertions_server, + git_merge_commit_email, + git_repository, + nightly_branch, + } = &self.config; + + file_content.push_str(&format!("dist_server={}", dist_server)); + file_content.push_str(&format!("\nartifacts_server={}", artifacts_server)); + file_content.push_str(&format!( + "\nartifacts_with_llvm_assertions_server={}", + artifacts_with_llvm_assertions_server + )); + file_content.push_str(&format!("\ngit_merge_commit_email={}", git_merge_commit_email)); + file_content.push_str(&format!("\ngit_repository={}", git_repository)); + file_content.push_str(&format!("\nnightly_branch={}", nightly_branch)); + + file_content.push_str("\n\n"); + file_content.push_str(COMMENTS); + + let compiler = self.detect_compiler()?; + file_content.push_str(&format!("\ncompiler_date={}", compiler.date)); + file_content.push_str(&format!("\ncompiler_version={}", compiler.version)); + + if let Some(rustfmt) = self.detect_rustfmt()? { + file_content.push_str(&format!("\nrustfmt_date={}", rustfmt.date)); + file_content.push_str(&format!("\nrustfmt_version={}", rustfmt.version)); + } + + file_content.push_str("\n"); + + for (key, value) in self.checksums { + file_content.push_str(&format!("\n{}={}", key, value)); + } + + std::fs::write(PATH, file_content)?; Ok(()) } @@ -76,7 +105,7 @@ impl Tool { // On the master branch the compiler version is configured to `beta` whereas if you're looking // at the beta or stable channel you'll likely see `1.x.0` as the version, with the previous // release's version number. - fn detect_compiler(&mut self) -> Result { + fn detect_compiler(&mut self) -> Result { let channel = match self.channel { Channel::Stable | Channel::Beta => { // The 1.XX manifest points to the latest point release of that minor release. @@ -87,7 +116,7 @@ impl Tool { let manifest = fetch_manifest(&self.config, &channel, self.date.as_deref())?; self.collect_checksums(&manifest, COMPILER_COMPONENTS)?; - Ok(Stage0Toolchain { + Ok(VersionMetadata { date: manifest.date, version: if self.channel == Channel::Nightly { "beta".to_string() @@ -106,14 +135,14 @@ impl Tool { /// We use a nightly rustfmt to format the source because it solves some bootstrapping issues /// with use of new syntax in this repo. For the beta/stable channels rustfmt is not provided, /// as we don't want to depend on rustfmt from nightly there. - fn detect_rustfmt(&mut self) -> Result, Error> { + fn detect_rustfmt(&mut self) -> Result, Error> { if self.channel != Channel::Nightly { return Ok(None); } let manifest = fetch_manifest(&self.config, "nightly", self.date.as_deref())?; self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?; - Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() })) + Ok(Some(VersionMetadata { date: manifest.date, version: "nightly".into() })) } fn collect_checksums(&mut self, manifest: &Manifest, components: &[&str]) -> Result<(), Error> { @@ -143,11 +172,15 @@ impl Tool { fn main() -> Result<(), Error> { let tool = Tool::new(std::env::args().nth(1))?; - tool.update_json()?; + tool.update_stage0_file()?; Ok(()) } -fn fetch_manifest(config: &Config, channel: &str, date: Option<&str>) -> Result { +fn fetch_manifest( + config: &Stage0Config, + channel: &str, + date: Option<&str>, +) -> Result { let url = if let Some(date) = date { format!("{}/dist/{}/channel-rust-{}.toml", config.dist_server, date, channel) } else { @@ -180,42 +213,6 @@ enum Channel { Nightly, } -#[derive(Debug, serde::Serialize, serde::Deserialize)] -struct Stage0 { - config: Config, - // Comments are explicitly below the config, do not move them above. - // - // Downstream forks of the compiler codebase can change the configuration values defined above, - // but doing so would risk merge conflicts whenever they import new changes that include a - // bootstrap compiler bump. - // - // To lessen the pain, a big block of comments is placed between the configuration and the - // auto-generated parts of the file, preventing git diffs of the config to include parts of the - // auto-generated content and vice versa. This should prevent merge conflicts. - #[serde(rename = "__comments")] - comments: Vec, - compiler: Stage0Toolchain, - rustfmt: Option, - checksums_sha256: IndexMap, -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -struct Config { - dist_server: String, - // There are other fields in the configuration, which will be read by src/bootstrap or other - // tools consuming stage0.json. To avoid the need to update bump-stage0 every time a new field - // is added, we collect all the fields in an untyped Value and serialize them back with the - // same order and structure they were deserialized in. - #[serde(flatten)] - other: serde_json::Value, -} - -#[derive(Debug, serde::Serialize, serde::Deserialize)] -struct Stage0Toolchain { - date: String, - version: String, -} - #[derive(Debug, serde::Serialize, serde::Deserialize)] struct Manifest { date: String, diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 386d4c3c317f..6715de52649d 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_hir; use rustc_hir::{intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::layout::LayoutOf; @@ -105,8 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal { too_large_for_stack: self.too_large_for_stack, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new(&mut v, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v).consume_body(body).into_ok(); for node in v.set { span_lint_hir( diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 2c44c3881aa7..a8bfbbdd9eca 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -8,6 +8,7 @@ #![feature(never_type)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] +#![feature(unwrap_infallible)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![allow( diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 5047092192f4..6b9ecf5f1413 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -4,7 +4,6 @@ use clippy_utils::{get_enclosing_block, higher, path_to_local}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty; @@ -61,15 +60,12 @@ fn check_for_mutation( span_low: None, span_high: None, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( - &mut delegate, - &infcx, + ExprUseVisitor::for_clippy( + cx, body.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), + &mut delegate, ) - .walk_expr(body); + .walk_expr(body).into_ok(); delegate.mutation_span() } diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs index deac159457a6..a52d38790a2b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs @@ -9,7 +9,6 @@ use rustc_lint::LateContext; use rustc_middle::mir::{FakeReadCause, Mutability}; use rustc_middle::ty::{self, BorrowKind}; use rustc_span::sym; -use rustc_trait_selection::infer::TyCtxtInferExt; use super::ITER_OVEREAGER_CLONED; use crate::redundant_clone::REDUNDANT_CLONE; @@ -69,16 +68,13 @@ pub(super) fn check<'tcx>( let mut delegate = MoveDelegate { used_move: HirIdSet::default(), }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( + ExprUseVisitor::for_clippy( + cx, + closure.def_id, &mut delegate, - &infcx, - closure.body.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), ) - .consume_body(body); + .consume_body(body).into_ok(); let mut to_be_discarded = false; diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index d3347466be98..ae9aa83efd68 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -417,7 +417,7 @@ fn get_input_traits_and_projections<'tcx>( } }, ClauseKind::Projection(projection_predicate) => { - if projection_predicate.projection_ty.self_ty() == input { + if projection_predicate.projection_term.self_ty() == input { projection_predicates.push(projection_predicate); } }, diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs index e6c6a15b8d48..ae6cf992ef7b 100644 --- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs +++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs @@ -320,11 +320,11 @@ fn is_mixed_projection_predicate<'tcx>( && (term_param_ty.index as usize) < generics.parent_count { // The inner-most self type is a type parameter from the current function. - let mut projection_ty = projection_predicate.projection_ty; + let mut projection_term = projection_predicate.projection_term; loop { - match projection_ty.self_ty().kind() { + match *projection_term.self_ty().kind() { ty::Alias(ty::Projection, inner_projection_ty) => { - projection_ty = *inner_projection_ty; + projection_term = inner_projection_ty.into(); }, ty::Param(param_ty) => { return (param_ty.index as usize) >= generics.parent_count; @@ -404,14 +404,11 @@ fn replace_types<'tcx>( // The `replaced.insert(...)` check provides some protection against infinite loops. if replaced.insert(param_ty.index) { for projection_predicate in projection_predicates { - if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx) + if projection_predicate.projection_term.self_ty() == param_ty.to_ty(cx.tcx) && let Some(term_ty) = projection_predicate.term.ty() && let ty::Param(term_param_ty) = term_ty.kind() { - let projection = cx.tcx.mk_ty_from_kind(ty::Alias( - ty::Projection, - projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty), - )); + let projection = projection_predicate.projection_term.with_self_ty(cx.tcx, new_ty).expect_ty(cx.tcx).to_ty(cx.tcx); if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) && args[term_param_ty.index as usize] != GenericArg::from(projected_ty) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs index 9e47c3ad0b7f..9b852f52ea1e 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -11,7 +11,6 @@ use rustc_hir::{ PatKind, }; use rustc_hir_typeck::expr_use_visitor as euv; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; @@ -102,7 +101,6 @@ fn should_skip<'tcx>( fn check_closures<'tcx>( ctx: &mut MutablyUsedVariablesCtxt<'tcx>, cx: &LateContext<'tcx>, - infcx: &InferCtxt<'tcx>, checked_closures: &mut FxHashSet, closures: FxHashSet, ) { @@ -119,7 +117,7 @@ fn check_closures<'tcx>( .associated_body() .map(|(_, body_id)| hir.body(body_id)) { - euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx).consume_body(body).into_ok(); } } } @@ -196,8 +194,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { async_closures: FxHashSet::default(), tcx: cx.tcx, }; - let infcx = cx.tcx.infer_ctxt().build(); - euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok(); let mut checked_closures = FxHashSet::default(); @@ -210,13 +207,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { } ControlFlow::<()>::Continue(()) }); - check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures); + check_closures(&mut ctx, cx, &mut checked_closures, closures); if is_async { while !ctx.async_closures.is_empty() { let async_closures = ctx.async_closures.clone(); ctx.async_closures.clear(); - check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures); + check_closures(&mut ctx, cx, &mut checked_closures, async_closures); } } ctx.generate_mutably_used_ids_from_aliases() diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 39d374d0d27f..0986571d0f28 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -13,7 +13,6 @@ use rustc_hir::{ TyKind, }; use rustc_hir_typeck::expr_use_visitor as euv; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; @@ -134,8 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { // function body. let MovedVariablesCtxt { moved_vars } = { let mut ctx = MovedVariablesCtxt::default(); - let infcx = cx.tcx.infer_ctxt().build(); - euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body); + euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx).consume_body(body).into_ok(); ctx }; diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 435eb9048f58..910e584a7a0f 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -11,7 +11,6 @@ use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, Pl use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::BorrowKind; -use rustc_trait_selection::infer::TyCtxtInferExt; use super::ASSIGN_OP_PATTERN; @@ -119,15 +118,8 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } let mut s = S(HirIdSet::default()); - let infcx = cx.tcx.infer_ctxt().build(); - let mut v = ExprUseVisitor::new( - &mut s, - &infcx, - cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), - cx.param_env, - cx.typeck_results(), - ); - v.consume_expr(e); + let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); + v.consume_expr(e).into_ok(); s.0 } @@ -151,14 +143,7 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { } let mut s = S(HirIdSet::default()); - let infcx = cx.tcx.infer_ctxt().build(); - let mut v = ExprUseVisitor::new( - &mut s, - &infcx, - cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()), - cx.param_env, - cx.typeck_results(), - ); - v.consume_expr(e); + let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s); + v.consume_expr(e).into_ok(); s.0 } diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 214b69dc9250..f0d1458a59b2 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -66,7 +66,7 @@ fn get_projection_pred<'tcx>( let projection_pred = cx .tcx .instantiate_bound_regions_with_erased(proj_pred.kind().rebind(pred)); - if projection_pred.projection_ty.args == trait_pred.trait_ref.args { + if projection_pred.projection_term.args == trait_pred.trait_ref.args { return Some(projection_pred); } } diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs index 2622abd59cbd..5b2841dcd833 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap.rs @@ -6,7 +6,6 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor}; use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -252,16 +251,13 @@ impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> { local_id: unwrap_info.local_id, }; - let infcx = self.cx.tcx.infer_ctxt().build(); - let mut vis = ExprUseVisitor::new( - &mut delegate, - &infcx, + let vis = ExprUseVisitor::for_clippy( + self.cx, cond.hir_id.owner.def_id, - self.cx.param_env, - self.cx.typeck_results(), + &mut delegate, ); - vis.walk_expr(cond); - vis.walk_expr(branch); + vis.walk_expr(cond).into_ok(); + vis.walk_expr(branch).into_ok(); if delegate.is_mutated { // if the variable is mutated, we don't know whether it can be unwrapped. diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index a49414a058b1..99d7aba2f7a1 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -7,6 +7,7 @@ #![feature(never_type)] #![feature(rustc_private)] #![feature(assert_matches)] +#![feature(unwrap_infallible)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![allow( diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 8d6057272c4e..bf03c6c16015 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -11,7 +11,6 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{EarlyContext, LateContext, LintContext}; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::{FakeReadCause, Mutability}; @@ -831,8 +830,9 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti applicability: Applicability::MachineApplicable, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new(&mut visitor, &infcx, def_id, cx.param_env, cx.typeck_results()).consume_body(closure_body); + ExprUseVisitor::for_clippy(cx, def_id, &mut visitor) + .consume_body(closure_body) + .into_ok(); if !visitor.suggestion_start.is_empty() { return Some(DerefClosure { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 97bba8648c5f..e3ab42c3107c 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -795,7 +795,7 @@ fn sig_from_bounds<'tcx>( inputs = Some(i); }, ty::ClauseKind::Projection(p) - if Some(p.projection_ty.def_id) == lang_items.fn_once_output() && p.projection_ty.self_ty() == ty => + if Some(p.projection_term.def_id) == lang_items.fn_once_output() && p.projection_term.self_ty() == ty => { if output.is_some() { // Multiple different fn trait impls. Is this even allowed? @@ -834,7 +834,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option } inputs = Some(i); }, - ty::ClauseKind::Projection(p) if Some(p.projection_ty.def_id) == lang_items.fn_once_output() => { + ty::ClauseKind::Projection(p) if Some(p.projection_term.def_id) == lang_items.fn_once_output() => { if output.is_some() { // Multiple different fn trait impls. Is this even allowed? return None; diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index a145920aa85e..9abb4ef9b8d3 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -5,7 +5,6 @@ use hir::def::Res; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{self as hir, Expr, ExprKind, HirId, HirIdSet}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceBase, PlaceWithHirId}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::hir::nested_filter; use rustc_middle::mir::FakeReadCause; @@ -17,15 +16,13 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> used_mutably: HirIdSet::default(), skip: false, }; - let infcx = cx.tcx.infer_ctxt().build(); - ExprUseVisitor::new( - &mut delegate, - &infcx, + ExprUseVisitor::for_clippy( + cx, expr.hir_id.owner.def_id, - cx.param_env, - cx.typeck_results(), + &mut delegate, ) - .walk_expr(expr); + .walk_expr(expr) + .into_ok(); if delegate.skip { return None; diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 9888ca2d1ed9..cc81d23a8ff0 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -54,6 +54,15 @@ pub fn static_lib(name: &str) -> PathBuf { tmp_dir().join(static_lib_name(name)) } +pub fn python_command() -> Command { + let python_path = std::env::var("PYTHON").expect("PYTHON environment variable does not exist"); + Command::new(python_path) +} + +pub fn source_path() -> PathBuf { + std::env::var("S").expect("S variable does not exist").into() +} + /// Construct the static library name based on the platform. pub fn static_lib_name(name: &str) -> String { // See tools.mk (irrelevant lines omitted): diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index de773d688ef0..1671a01860ae 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,5 +1,5 @@ use std::env; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::io::Write; use std::path::Path; use std::process::{Command, Output, Stdio}; @@ -176,6 +176,13 @@ impl Rustc { self } + /// Specify the crate name. + pub fn crate_name>(&mut self, name: S) -> &mut Self { + self.cmd.arg("--crate-name"); + self.cmd.arg(name.as_ref()); + self + } + /// Get the [`Output`][::std::process::Output] of the finished process. #[track_caller] pub fn command_output(&mut self) -> ::std::process::Output { diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index aa3c7dcf0e35..c4f4e9f9bd23 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,4 +1,5 @@ use std::env; +use std::ffi::OsStr; use std::io::Write; use std::path::Path; use std::process::{Command, Output, Stdio}; @@ -45,6 +46,21 @@ impl Rustdoc { Self { cmd, stdin: None } } + /// Specify where an external library is located. + pub fn extern_>(&mut self, crate_name: &str, path: P) -> &mut Self { + assert!( + !crate_name.contains(|c: char| c.is_whitespace() || c == '\\' || c == '/'), + "crate name cannot contain whitespace or path separators" + ); + + let path = path.as_ref().to_string_lossy(); + + self.cmd.arg("--extern"); + self.cmd.arg(format!("{crate_name}={path}")); + + self + } + /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); @@ -107,6 +123,34 @@ impl Rustdoc { self } + /// Specify the target triple, or a path to a custom target json spec file. + pub fn target(&mut self, target: &str) -> &mut Self { + self.cmd.arg(format!("--target={target}")); + self + } + + /// Specify the crate type. + pub fn crate_type(&mut self, crate_type: &str) -> &mut Self { + self.cmd.arg("--crate-type"); + self.cmd.arg(crate_type); + self + } + + /// Specify the crate name. + pub fn crate_name>(&mut self, name: S) -> &mut Self { + self.cmd.arg("--crate-name"); + self.cmd.arg(name.as_ref()); + self + } + + /// Add a directory to the library search path. It corresponds to the `-L` + /// rustdoc option. + pub fn library_search_path>(&mut self, path: P) -> &mut Self { + self.cmd.arg("-L"); + self.cmd.arg(path.as_ref()); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index e87950b36d9d..83a3ea84b24d 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,6 +1,3 @@ -run-make/alloc-no-oom-handling/Makefile -run-make/alloc-no-rc/Makefile -run-make/alloc-no-sync/Makefile run-make/allocator-shim-circular-deps/Makefile run-make/allow-non-lint-warnings-cmdline/Makefile run-make/allow-warnings-cmdline-stability/Makefile @@ -12,7 +9,6 @@ run-make/c-dynamic-dylib/Makefile run-make/c-dynamic-rlib/Makefile run-make/c-link-to-rust-dylib/Makefile run-make/c-link-to-rust-staticlib/Makefile -run-make/c-link-to-rust-va-list-fn/Makefile run-make/c-static-dylib/Makefile run-make/c-static-rlib/Makefile run-make/c-unwind-abi-catch-lib-panic/Makefile @@ -248,12 +244,9 @@ run-make/rustdoc-io-error/Makefile run-make/rustdoc-scrape-examples-invalid-expr/Makefile run-make/rustdoc-scrape-examples-macros/Makefile run-make/rustdoc-scrape-examples-multiple/Makefile -run-make/rustdoc-scrape-examples-ordering/Makefile run-make/rustdoc-scrape-examples-remap/Makefile run-make/rustdoc-scrape-examples-test/Makefile run-make/rustdoc-scrape-examples-whitespace/Makefile -run-make/rustdoc-shared-flags/Makefile -run-make/rustdoc-target-spec-json-path/Makefile run-make/rustdoc-themes/Makefile run-make/rustdoc-verify-output-files/Makefile run-make/rustdoc-with-out-dir-option/Makefile diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 1d24c59b356f..1b73b67b7557 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -395,6 +395,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index 3563aec6d807..0db2a3580026 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -555,6 +555,9 @@ //@ revisions: x86_64_unknown_linux_ohos //@ [x86_64_unknown_linux_ohos] compile-flags: --target x86_64-unknown-linux-ohos //@ [x86_64_unknown_linux_ohos] needs-llvm-components: x86 +//@ revisions: x86_64_unknown_linux_none +//@ [x86_64_unknown_linux_none] compile-flags: --target x86_64-unknown-linux-none +//@ [x86_64_unknown_linux_none] needs-llvm-components: x86 //@ revisions: x86_64_unknown_netbsd //@ [x86_64_unknown_netbsd] compile-flags: --target x86_64-unknown-netbsd //@ [x86_64_unknown_netbsd] needs-llvm-components: x86 diff --git a/tests/auxiliary/rust_test_helpers.c b/tests/auxiliary/rust_test_helpers.c index 965df44c6760..34cc7fd5dfbe 100644 --- a/tests/auxiliary/rust_test_helpers.c +++ b/tests/auxiliary/rust_test_helpers.c @@ -27,10 +27,10 @@ rust_dbg_extern_identity_u8(char u) { return u; } -typedef void *(*dbg_callback)(void*); +typedef uint64_t (*dbg_callback)(uint64_t); -void * -rust_dbg_call(dbg_callback cb, void *data) { +uint64_t +rust_dbg_call(dbg_callback cb, uint64_t data) { return cb(data); } diff --git a/tests/codegen-units/partitioning/extern-drop-glue.rs b/tests/codegen-units/partitioning/extern-drop-glue.rs index 84eb802f264b..d3bce7b4223c 100644 --- a/tests/codegen-units/partitioning/extern-drop-glue.rs +++ b/tests/codegen-units/partitioning/extern-drop-glue.rs @@ -1,7 +1,4 @@ -// - -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/extern-generic.rs b/tests/codegen-units/partitioning/extern-generic.rs index abd3918094d7..0e4b6a37f712 100644 --- a/tests/codegen-units/partitioning/extern-generic.rs +++ b/tests/codegen-units/partitioning/extern-generic.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager -Zshare-generics=y diff --git a/tests/codegen-units/partitioning/incremental-merging.rs b/tests/codegen-units/partitioning/incremental-merging.rs index b44090c866a0..6834bb2bebf5 100644 --- a/tests/codegen-units/partitioning/incremental-merging.rs +++ b/tests/codegen-units/partitioning/incremental-merging.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Ccodegen-units=3 diff --git a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs index 74734d3cf38a..d021f467f1f9 100644 --- a/tests/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/tests/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/local-drop-glue.rs b/tests/codegen-units/partitioning/local-drop-glue.rs index 0974187ade0d..5fa1df95cbc8 100644 --- a/tests/codegen-units/partitioning/local-drop-glue.rs +++ b/tests/codegen-units/partitioning/local-drop-glue.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation // We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/local-generic.rs b/tests/codegen-units/partitioning/local-generic.rs index 2cfdc27ccb14..06f46b23db6a 100644 --- a/tests/codegen-units/partitioning/local-generic.rs +++ b/tests/codegen-units/partitioning/local-generic.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager diff --git a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs index 49a2ce7c5d9d..2f9cbe83f1d5 100644 --- a/tests/codegen-units/partitioning/local-inlining-but-not-all.rs +++ b/tests/codegen-units/partitioning/local-inlining-but-not-all.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus=no diff --git a/tests/codegen-units/partitioning/local-inlining.rs b/tests/codegen-units/partitioning/local-inlining.rs index 726cf2b87d26..2329a876c960 100644 --- a/tests/codegen-units/partitioning/local-inlining.rs +++ b/tests/codegen-units/partitioning/local-inlining.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/local-transitive-inlining.rs b/tests/codegen-units/partitioning/local-transitive-inlining.rs index 355eb6cf3954..4ccc53aea1d1 100644 --- a/tests/codegen-units/partitioning/local-transitive-inlining.rs +++ b/tests/codegen-units/partitioning/local-transitive-inlining.rs @@ -1,6 +1,4 @@ -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen-units/partitioning/methods-are-with-self-type.rs b/tests/codegen-units/partitioning/methods-are-with-self-type.rs index 2e54725ff285..3ba53334cc90 100644 --- a/tests/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/tests/codegen-units/partitioning/methods-are-with-self-type.rs @@ -3,9 +3,7 @@ // much sense at the moment. //@ ignore-test -// -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/regular-modules.rs b/tests/codegen-units/partitioning/regular-modules.rs index 0eb0848e4544..68601975d062 100644 --- a/tests/codegen-units/partitioning/regular-modules.rs +++ b/tests/codegen-units/partitioning/regular-modules.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=eager diff --git a/tests/codegen-units/partitioning/shared-generics.rs b/tests/codegen-units/partitioning/shared-generics.rs index 25ea7fab7355..5b78794316c6 100644 --- a/tests/codegen-units/partitioning/shared-generics.rs +++ b/tests/codegen-units/partitioning/shared-generics.rs @@ -1,4 +1,3 @@ -// //@ no-prefer-dynamic // NOTE: We always compile this test with -Copt-level=0 because higher opt-levels // prevent drop-glue from participating in share-generics. diff --git a/tests/codegen-units/partitioning/statics.rs b/tests/codegen-units/partitioning/statics.rs index 9503a91b0ab4..c7eef1f3789d 100644 --- a/tests/codegen-units/partitioning/statics.rs +++ b/tests/codegen-units/partitioning/statics.rs @@ -1,5 +1,4 @@ -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy diff --git a/tests/codegen-units/partitioning/vtable-through-const.rs b/tests/codegen-units/partitioning/vtable-through-const.rs index 111b4fa1b9ac..ca4d3822b549 100644 --- a/tests/codegen-units/partitioning/vtable-through-const.rs +++ b/tests/codegen-units/partitioning/vtable-through-const.rs @@ -1,7 +1,4 @@ -// - -// We specify incremental here because we want to test the partitioning for -//@ incremental compilation +// We specify incremental here because we want to test the partitioning for incremental compilation //@ incremental //@ compile-flags:-Zprint-mono-items=lazy //@ compile-flags:-Zinline-in-all-cgus diff --git a/tests/codegen/mir-aggregate-no-alloca.rs b/tests/codegen/mir-aggregate-no-alloca.rs index a7752d714fe3..c0e7e1a05e39 100644 --- a/tests/codegen/mir-aggregate-no-alloca.rs +++ b/tests/codegen/mir-aggregate-no-alloca.rs @@ -55,7 +55,7 @@ pub fn make_cell_of_bool(b: bool) -> std::cell::Cell { std::cell::Cell::new(b) } -// CHECK-LABLE: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s) +// CHECK-LABEL: { i8, i16 } @make_cell_of_bool_and_short(i1 noundef zeroext %b, i16 noundef %s) #[no_mangle] pub fn make_cell_of_bool_and_short(b: bool, s: u16) -> std::cell::Cell<(bool, u16)> { // CHECK-NOT: alloca diff --git a/tests/codegen/option-niche-eq.rs b/tests/codegen/option-niche-eq.rs index 7b955332fd3b..25ea5dd595c3 100644 --- a/tests/codegen/option-niche-eq.rs +++ b/tests/codegen/option-niche-eq.rs @@ -7,7 +7,7 @@ use core::cmp::Ordering; use core::ptr::NonNull; use core::num::NonZero; -// CHECK-lABEL: @non_zero_eq +// CHECK-LABEL: @non_zero_eq #[no_mangle] pub fn non_zero_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -16,7 +16,7 @@ pub fn non_zero_eq(l: Option>, r: Option>) -> bool { l == r } -// CHECK-lABEL: @non_zero_signed_eq +// CHECK-LABEL: @non_zero_signed_eq #[no_mangle] pub fn non_zero_signed_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -25,7 +25,7 @@ pub fn non_zero_signed_eq(l: Option>, r: Option>) -> b l == r } -// CHECK-lABEL: @non_null_eq +// CHECK-LABEL: @non_null_eq #[no_mangle] pub fn non_null_eq(l: Option>, r: Option>) -> bool { // CHECK: start: @@ -34,7 +34,7 @@ pub fn non_null_eq(l: Option>, r: Option>) -> bool { l == r } -// CHECK-lABEL: @ordering_eq +// CHECK-LABEL: @ordering_eq #[no_mangle] pub fn ordering_eq(l: Option, r: Option) -> bool { // CHECK: start: @@ -54,7 +54,7 @@ pub enum EnumWithNiche { G, } -// CHECK-lABEL: @niche_eq +// CHECK-LABEL: @niche_eq #[no_mangle] pub fn niche_eq(l: Option, r: Option) -> bool { // CHECK: start: @@ -64,7 +64,7 @@ pub fn niche_eq(l: Option, r: Option) -> bool { } // FIXME: This should work too -// // FIXME-CHECK-lABEL: @bool_eq +// // FIXME-CHECK-LABEL: @bool_eq // #[no_mangle] // pub fn bool_eq(l: Option, r: Option) -> bool { // // FIXME-CHECK: start: diff --git a/tests/codegen/sanitizer/no-sanitize-inlining.rs b/tests/codegen/sanitizer/no-sanitize-inlining.rs index 623bfa608ca3..d5e47884f858 100644 --- a/tests/codegen/sanitizer/no-sanitize-inlining.rs +++ b/tests/codegen/sanitizer/no-sanitize-inlining.rs @@ -16,7 +16,7 @@ // ASAN: } // // LSAN-LABEL: define void @test -// LSAN-NO: call +// LSAN-NOT: call // LSAN: } #[no_mangle] pub fn test(n: &mut u32) { diff --git a/tests/codegen/simd/issue-120720-reduce-nan.rs b/tests/codegen/simd/issue-120720-reduce-nan.rs index 2c6098c04891..0372582bf7f3 100644 --- a/tests/codegen/simd/issue-120720-reduce-nan.rs +++ b/tests/codegen/simd/issue-120720-reduce-nan.rs @@ -8,7 +8,7 @@ #![feature(stdarch_x86_avx512, avx512_target_feature)] use std::arch::x86_64::*; -// CHECK-label: @demo( +// CHECK-LABEL: @demo( #[no_mangle] #[target_feature(enable = "avx512f")] // Function-level target feature mismatches inhibit inlining pub unsafe fn demo() -> bool { diff --git a/tests/crashes/123901.rs b/tests/crashes/123901.rs deleted file mode 100644 index 06722f0bf292..000000000000 --- a/tests/crashes/123901.rs +++ /dev/null @@ -1,8 +0,0 @@ -//@ known-bug: #123901 -//@ edition:2021 - -pub fn test(test: &u64, temp: &u64) { - async |check, a, b| { - temp.abs_diff(12); - }; -} diff --git a/tests/run-make/alloc-no-oom-handling/Makefile b/tests/run-make/alloc-no-oom-handling/Makefile deleted file mode 100644 index 7c3ae90b58d6..000000000000 --- a/tests/run-make/alloc-no-oom-handling/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_global_oom_handling feature is turned on. -# See https://github.com/rust-lang/rust/pull/84266 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_global_oom_handling diff --git a/tests/run-make/alloc-no-oom-handling/rmake.rs b/tests/run-make/alloc-no-oom-handling/rmake.rs new file mode 100644 index 000000000000..fec3c6532940 --- /dev/null +++ b/tests/run-make/alloc-no-oom-handling/rmake.rs @@ -0,0 +1,15 @@ +// This test checks that alloc can still compile correctly +// when the unstable no_global_oom_handling feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_global_oom_handling") + .run(); +} diff --git a/tests/run-make/alloc-no-rc/Makefile b/tests/run-make/alloc-no-rc/Makefile deleted file mode 100644 index fcfe1603b6ce..000000000000 --- a/tests/run-make/alloc-no-rc/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_rc feature is turned on. -# See https://github.com/rust-lang/rust/pull/89891 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_rc diff --git a/tests/run-make/alloc-no-rc/rmake.rs b/tests/run-make/alloc-no-rc/rmake.rs new file mode 100644 index 000000000000..c5744a3f5eef --- /dev/null +++ b/tests/run-make/alloc-no-rc/rmake.rs @@ -0,0 +1,15 @@ +// This test checks that alloc can still compile correctly +// when the unstable no_rc feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_rc") + .run(); +} diff --git a/tests/run-make/alloc-no-sync/Makefile b/tests/run-make/alloc-no-sync/Makefile deleted file mode 100644 index 997dbcf66036..000000000000 --- a/tests/run-make/alloc-no-sync/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# This test checks that alloc can still compile correctly when the unstable no_sync feature is turned on. -# See https://github.com/rust-lang/rust/pull/89891 - -include ../tools.mk - -all: - $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../library/alloc/src/lib.rs --cfg no_sync diff --git a/tests/run-make/alloc-no-sync/rmake.rs b/tests/run-make/alloc-no-sync/rmake.rs new file mode 100644 index 000000000000..6410eca80abf --- /dev/null +++ b/tests/run-make/alloc-no-sync/rmake.rs @@ -0,0 +1,15 @@ +// This test checks that alloc can still compile correctly +// when the unstable no_sync feature is turned on. +// See https://github.com/rust-lang/rust/pull/84266 + +use run_make_support::rustc; + +fn main() { + rustc() + .edition("2021") + .arg("-Dwarnings") + .crate_type("rlib") + .input("../../../library/alloc/src/lib.rs") + .cfg("no_sync") + .run(); +} diff --git a/tests/run-make/c-link-to-rust-va-list-fn/Makefile b/tests/run-make/c-link-to-rust-va-list-fn/Makefile deleted file mode 100644 index 596c0fce3cea..000000000000 --- a/tests/run-make/c-link-to-rust-va-list-fn/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -all: - $(RUSTC) checkrust.rs - $(CC) test.c $(call STATICLIB,checkrust) $(call OUT_EXE,test) $(EXTRACFLAGS) - $(call RUN,test) diff --git a/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs new file mode 100644 index 000000000000..7a450efff942 --- /dev/null +++ b/tests/run-make/c-link-to-rust-va-list-fn/rmake.rs @@ -0,0 +1,18 @@ +// test.c and its static library checkrust.rs make use of variadic functions (VaList). +// This test checks that the use of this feature does not +// prevent the creation of a functional binary. +// See https://github.com/rust-lang/rust/pull/49878 + +//@ ignore-cross-compile + +use run_make_support::{cc, extra_c_flags, run, rustc, static_lib}; + +fn main() { + rustc().input("checkrust.rs").run(); + cc().input("test.c") + .input(static_lib("checkrust")) + .out_exe("test") + .args(&extra_c_flags()) + .run(); + run("test"); +} diff --git a/tests/run-make/core-no-fp-fmt-parse/rmake.rs b/tests/run-make/core-no-fp-fmt-parse/rmake.rs index e3484888ca5a..aef28fd25281 100644 --- a/tests/run-make/core-no-fp-fmt-parse/rmake.rs +++ b/tests/run-make/core-no-fp-fmt-parse/rmake.rs @@ -2,7 +2,6 @@ // support for formatting and parsing floating-point numbers. use run_make_support::rustc; -use std::path::PathBuf; fn main() { rustc() diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile b/tests/run-make/rustdoc-scrape-examples-ordering/Makefile deleted file mode 100644 index bf45b8148c03..000000000000 --- a/tests/run-make/rustdoc-scrape-examples-ordering/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -deps := ex1 ex2 - -include ../rustdoc-scrape-examples-multiple/scrape.mk - -all: scrape diff --git a/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs new file mode 100644 index 000000000000..edcf3406d47f --- /dev/null +++ b/tests/run-make/rustdoc-scrape-examples-ordering/rmake.rs @@ -0,0 +1,55 @@ +use run_make_support::{python_command, rustc, rustdoc, source_path, tmp_dir}; +use std::fs::read_dir; +use std::path::Path; + +fn main() { + let lib_dir = tmp_dir(); + let out_dir = tmp_dir().join("rustdoc"); + let crate_name = "foobar"; + let deps = read_dir("examples") + .unwrap() + .filter_map(|entry| entry.ok().map(|e| e.path())) + .filter(|path| path.is_file() && path.extension().is_some_and(|ext| ext == "rs")) + .collect::>(); + + rustc().input("src/lib.rs").crate_name(crate_name).crate_type("lib").emit("metadata").run(); + + let mut out_deps = Vec::with_capacity(deps.len()); + for dep in deps { + let dep_stem = dep.file_stem().unwrap(); + let out_example = out_dir.join(format!("{}.calls", dep_stem.to_str().unwrap())); + rustdoc() + .input(&dep) + .crate_name(&dep_stem) + .crate_type("bin") + .output(&out_dir) + .extern_(crate_name, lib_dir.join(format!("lib{crate_name}.rmeta"))) + .arg("-Zunstable-options") + .arg("--scrape-examples-output-path") + .arg(&out_example) + .arg("--scrape-examples-target-crate") + .arg(crate_name) + .run(); + out_deps.push(out_example); + } + + let mut rustdoc = rustdoc(); + rustdoc + .input("src/lib.rs") + .output(&out_dir) + .crate_name(crate_name) + .crate_type("lib") + .arg("-Zunstable-options"); + for dep in out_deps { + rustdoc.arg("--with-examples").arg(dep); + } + rustdoc.run(); + + python_command() + .arg(source_path().join("/src/etc/htmldocck.py")) + .arg(out_dir) + .arg("src/lib.rs") + .status() + .unwrap() + .success(); +} diff --git a/tests/run-make/rustdoc-shared-flags/Makefile b/tests/run-make/rustdoc-shared-flags/Makefile deleted file mode 100644 index a2a7d7b3634a..000000000000 --- a/tests/run-make/rustdoc-shared-flags/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -include ../tools.mk - -all: z_help c_help list_passes - -c_help: - $(RUSTC) -C help > $(TMPDIR)/rustc.c_help.txt - $(RUSTDOC) -C help > $(TMPDIR)/rustdoc.c_help.txt - $(DIFF) $(TMPDIR)/rustc.c_help.txt $(TMPDIR)/rustdoc.c_help.txt - -z_help: - $(RUSTC) -Z help > $(TMPDIR)/rustc.z_help.txt - $(RUSTDOC) -Z help > $(TMPDIR)/rustdoc.z_help.txt - $(DIFF) $(TMPDIR)/rustc.z_help.txt $(TMPDIR)/rustdoc.z_help.txt - -list_passes: - $(RUSTC) -C passes=list > $(TMPDIR)/rustc.passes.txt - $(RUSTDOC) -C passes=list > $(TMPDIR)/rustdoc.passes.txt - $(DIFF) $(TMPDIR)/rustc.passes.txt $(TMPDIR)/rustdoc.passes.txt diff --git a/tests/run-make/rustdoc-shared-flags/rmake.rs b/tests/run-make/rustdoc-shared-flags/rmake.rs new file mode 100644 index 000000000000..2db613f78176 --- /dev/null +++ b/tests/run-make/rustdoc-shared-flags/rmake.rs @@ -0,0 +1,14 @@ +use run_make_support::{rustc, rustdoc, Diff}; + +fn compare_outputs(args: &[&str]) { + let rustc_output = String::from_utf8(rustc().args(args).command_output().stdout).unwrap(); + let rustdoc_output = String::from_utf8(rustdoc().args(args).command_output().stdout).unwrap(); + + Diff::new().expected_text("rustc", rustc_output).actual_text("rustdoc", rustdoc_output).run(); +} + +fn main() { + compare_outputs(&["-C", "help"]); + compare_outputs(&["-Z", "help"]); + compare_outputs(&["-C", "passes=list"]); +} diff --git a/tests/run-make/rustdoc-target-spec-json-path/Makefile b/tests/run-make/rustdoc-target-spec-json-path/Makefile deleted file mode 100644 index 6d0bc4186f22..000000000000 --- a/tests/run-make/rustdoc-target-spec-json-path/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include ../tools.mk - -# Test that rustdoc will properly canonicalize the target spec json path just like rustc - -OUTPUT_DIR := "$(TMPDIR)/rustdoc-target-spec-json-path" - -all: - $(RUSTC) --crate-type lib dummy_core.rs --target target.json - $(RUSTDOC) -o $(OUTPUT_DIR) -L $(TMPDIR) my_crate.rs --target target.json diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs new file mode 100644 index 000000000000..66530a4f08ee --- /dev/null +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -0,0 +1,14 @@ +// Test that rustdoc will properly canonicalize the target spec json path just like rustc. + +use run_make_support::{rustc, rustdoc, tmp_dir}; + +fn main() { + let out_dir = tmp_dir().join("rustdoc-target-spec-json-path"); + rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustdoc() + .input("my_crate.rs") + .output(out_dir) + .library_search_path(tmp_dir()) + .target("target.json") + .run(); +} diff --git a/tests/rustdoc-ui/issues/issue-91713.stdout b/tests/rustdoc-ui/issues/issue-91713.stdout index bbea7e5c212e..cc3c8385d9a8 100644 --- a/tests/rustdoc-ui/issues/issue-91713.stdout +++ b/tests/rustdoc-ui/issues/issue-91713.stdout @@ -1,6 +1,7 @@ Available passes for running rustdoc: check-custom-code-classes - check for custom code classes without the feature-gate enabled check_doc_test_visibility - run various visibility-related lints on doctests +strip-aliased-non-local - strips all non-local private aliased items from the output strip-hidden - strips all `#[doc(hidden)]` items from the output strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate @@ -14,6 +15,7 @@ Default passes for rustdoc: check-custom-code-classes collect-trait-impls check_doc_test_visibility +strip-aliased-non-local strip-hidden (when not --document-hidden-items) strip-private (when not --document-private-items) strip-priv-imports (when --document-private-items) diff --git a/tests/rustdoc/inline_cross/assoc-const-equality.rs b/tests/rustdoc/inline_cross/assoc-const-equality.rs index 89ed808de620..cdf74389e764 100644 --- a/tests/rustdoc/inline_cross/assoc-const-equality.rs +++ b/tests/rustdoc/inline_cross/assoc-const-equality.rs @@ -1,5 +1,6 @@ //@ aux-crate:assoc_const_equality=assoc-const-equality.rs //@ edition:2021 +//@ ignore-test (FIXME: #125092) #![crate_name = "user"] diff --git a/tests/rustdoc/private-non-local-fields-2.rs b/tests/rustdoc/private-non-local-fields-2.rs new file mode 100644 index 000000000000..615b957f697e --- /dev/null +++ b/tests/rustdoc/private-non-local-fields-2.rs @@ -0,0 +1,11 @@ +//! This test makes sure that with never show the inner fields in the +//! aliased type view of type alias. + +//@ compile-flags: -Z unstable-options --document-private-items + +#![crate_name = "foo"] + +use std::collections::BTreeMap; + +// @has 'foo/type.FooBar.html' '//*[@class="rust item-decl"]/code' 'struct FooBar { /* private fields */ }' +pub type FooBar = BTreeMap; diff --git a/tests/rustdoc/private-non-local-fields.rs b/tests/rustdoc/private-non-local-fields.rs new file mode 100644 index 000000000000..7922ce074dd1 --- /dev/null +++ b/tests/rustdoc/private-non-local-fields.rs @@ -0,0 +1,9 @@ +//! This test makes sure that with never show the inner fields in the +//! aliased type view of type alias. + +#![crate_name = "foo"] + +use std::collections::BTreeMap; + +// @has 'foo/type.FooBar.html' '//*[@class="rust item-decl"]/code' 'struct FooBar { /* private fields */ }' +pub type FooBar = BTreeMap; diff --git a/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs b/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs index 9c61518b9414..6b2187710966 100644 --- a/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs +++ b/tests/ui/abi/extern/auxiliary/extern-crosscrate-source.rs @@ -1,28 +1,21 @@ #![crate_name = "externcallback"] #![crate_type = "lib"] -#![feature(rustc_private)] -extern crate libc; - -pub mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +pub fn fact(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } -pub extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +pub extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { fact(data - 1) * data } } diff --git a/tests/ui/abi/extern/extern-call-deep.rs b/tests/ui/abi/extern/extern-call-deep.rs index 062e70b1b6ee..40457ae57207 100644 --- a/tests/ui/abi/extern/extern-call-deep.rs +++ b/tests/ui/abi/extern/extern-call-deep.rs @@ -1,35 +1,27 @@ //@ run-pass //@ ignore-emscripten blows the JS stack -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { count(data - 1) + 1 } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } pub fn main() { let result = count(1000); - println!("result = {}", result); + println!("result = {:?}", result); assert_eq!(result, 1000); } diff --git a/tests/ui/abi/extern/extern-call-deep2.rs b/tests/ui/abi/extern/extern-call-deep2.rs index c021bc223482..91ca28d80c80 100644 --- a/tests/ui/abi/extern/extern-call-deep2.rs +++ b/tests/ui/abi/extern/extern-call-deep2.rs @@ -1,31 +1,24 @@ //@ run-pass -#![allow(unused_must_use)] //@ needs-threads -#![feature(rustc_private)] -extern crate libc; use std::thread; -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { - if data == 1 { data } else { count(data - 1) + 1 } +extern "C" fn cb(data: u64) -> u64 { + if data == 1 { data } else { count(data - 1 ) + 1 } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } @@ -37,5 +30,5 @@ pub fn main() { println!("result = {}", result); assert_eq!(result, 1000); }) - .join(); + .join().unwrap(); } diff --git a/tests/ui/abi/extern/extern-call-indirect.rs b/tests/ui/abi/extern/extern-call-indirect.rs index 18fb07d8c8bb..ef1e8ae5e760 100644 --- a/tests/ui/abi/extern/extern-call-indirect.rs +++ b/tests/ui/abi/extern/extern-call-indirect.rs @@ -1,29 +1,21 @@ //@ run-pass -#![feature(rustc_private)] - -extern crate libc; - -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { fact(data - 1) * data } } -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +fn fact(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } diff --git a/tests/ui/abi/extern/extern-call-scrub.rs b/tests/ui/abi/extern/extern-call-scrub.rs index 7edf8975ad81..7df3a8f04ef1 100644 --- a/tests/ui/abi/extern/extern-call-scrub.rs +++ b/tests/ui/abi/extern/extern-call-scrub.rs @@ -1,35 +1,27 @@ //@ run-pass -#![allow(unused_must_use)] +//@ needs-threads // This time we're testing repeatedly going up and down both stacks to // make sure the stack pointers are maintained properly in both // directions -//@ needs-threads -#![feature(rustc_private)] - -extern crate libc; use std::thread; -mod rustrt { - extern crate libc; - - #[link(name = "rust_test_helpers", kind = "static")] - extern "C" { - pub fn rust_dbg_call( - cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t, - data: libc::uintptr_t, - ) -> libc::uintptr_t; - } +#[link(name = "rust_test_helpers", kind = "static")] +extern "C" { + pub fn rust_dbg_call( + cb: extern "C" fn(u64) -> u64, + data: u64, + ) -> u64; } -extern "C" fn cb(data: libc::uintptr_t) -> libc::uintptr_t { +extern "C" fn cb(data: u64) -> u64 { if data == 1 { data } else { count(data - 1) + count(data - 1) } } -fn count(n: libc::uintptr_t) -> libc::uintptr_t { +fn count(n: u64) -> u64 { unsafe { println!("n = {}", n); - rustrt::rust_dbg_call(cb, n) + rust_dbg_call(cb, n) } } @@ -41,5 +33,5 @@ pub fn main() { println!("result = {}", result); assert_eq!(result, 2048); }) - .join(); + .join().unwrap(); } diff --git a/tests/ui/abi/extern/extern-crosscrate.rs b/tests/ui/abi/extern/extern-crosscrate.rs index c283cbe32163..b467d9929844 100644 --- a/tests/ui/abi/extern/extern-crosscrate.rs +++ b/tests/ui/abi/extern/extern-crosscrate.rs @@ -1,15 +1,12 @@ //@ run-pass //@ aux-build:extern-crosscrate-source.rs -#![feature(rustc_private)] - extern crate externcallback; -extern crate libc; -fn fact(n: libc::uintptr_t) -> libc::uintptr_t { +fn fact(n: u64) -> u64 { unsafe { - println!("n = {}", n); - externcallback::rustrt::rust_dbg_call(externcallback::cb, n) + println!("n = {:?}", n); + externcallback::rust_dbg_call(externcallback::cb, n) } } diff --git a/tests/ui/abi/foreign/foreign-call-no-runtime.rs b/tests/ui/abi/foreign/foreign-call-no-runtime.rs deleted file mode 100644 index fccd62b6100f..000000000000 --- a/tests/ui/abi/foreign/foreign-call-no-runtime.rs +++ /dev/null @@ -1,60 +0,0 @@ -//@ run-pass -//@ needs-threads - -#![feature(rustc_private)] - -extern crate libc; - -use std::mem; -use std::thread; - -#[link(name = "rust_test_helpers", kind = "static")] -extern "C" { - fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t), data: libc::uintptr_t) -> libc::uintptr_t; -} - -pub fn main() { - unsafe { - thread::spawn(move || { - let i: isize = 100; - rust_dbg_call(callback_isize, mem::transmute(&i)); - }) - .join() - .unwrap(); - - thread::spawn(move || { - let i: i32 = 100; - rust_dbg_call(callback_i32, mem::transmute(&i)); - }) - .join() - .unwrap(); - - thread::spawn(move || { - let i: i64 = 100; - rust_dbg_call(callback_i64, mem::transmute(&i)); - }) - .join() - .unwrap(); - } -} - -extern "C" fn callback_isize(data: libc::uintptr_t) { - unsafe { - let data = data as *const isize; - assert_eq!(*data, 100); - } -} - -extern "C" fn callback_i64(data: libc::uintptr_t) { - unsafe { - let data = data as *const i64; - assert_eq!(*data, 100); - } -} - -extern "C" fn callback_i32(data: libc::uintptr_t) { - unsafe { - let data = data as *const i32; - assert_eq!(*data, 100); - } -} diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs index fb2169ab43f2..959bb4fe7aca 100644 --- a/tests/ui/associated-consts/issue-105330.rs +++ b/tests/ui/associated-consts/issue-105330.rs @@ -11,7 +11,6 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404 fn foo>() { //~ ERROR E0658 foo::()(); //~^ ERROR is not satisfied - //~| ERROR type mismatch //~| ERROR expected function, found `()` } @@ -19,6 +18,5 @@ fn main>() { //~^ ERROR E0658 //~| ERROR E0131 foo::(); - //~^ ERROR type mismatch - //~| ERROR is not satisfied + //~^ ERROR is not satisfied } diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index bde3675b48c0..725271935554 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -26,7 +26,7 @@ LL | fn foo>() { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: associated const equality is incomplete - --> $DIR/issue-105330.rs:18:29 + --> $DIR/issue-105330.rs:17:29 | LL | fn main>() { | ^^^^ @@ -44,7 +44,7 @@ LL | impl TraitWAssocConst for impl Demo { = note: `impl Trait` is only allowed in arguments and return types of functions and methods error[E0131]: `main` function is not allowed to have generic parameters - --> $DIR/issue-105330.rs:18:8 + --> $DIR/issue-105330.rs:17:8 | LL | fn main>() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters @@ -61,20 +61,6 @@ note: required by a bound in `foo` LL | fn foo>() { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:12:11 - | -LL | foo::()(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` - error[E0618]: expected function, found `()` --> $DIR/issue-105330.rs:12:5 | @@ -86,7 +72,7 @@ LL | foo::()(); | call expression requires function error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied - --> $DIR/issue-105330.rs:21:11 + --> $DIR/issue-105330.rs:20:11 | LL | foo::(); | ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo` @@ -97,21 +83,7 @@ note: required by a bound in `foo` LL | fn foo>() { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo` -error[E0271]: type mismatch resolving `::A == 32` - --> $DIR/issue-105330.rs:21:11 - | -LL | foo::(); - | ^^^^ expected `32`, found `::A` - | - = note: expected constant `32` - found constant `::A` -note: required by a bound in `foo` - --> $DIR/issue-105330.rs:11:28 - | -LL | fn foo>() { - | ^^^^ required by this bound in `foo` +error: aborting due to 9 previous errors -error: aborting due to 11 previous errors - -Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658. +Some errors have detailed explanations: E0131, E0277, E0404, E0562, E0618, E0658. For more information about an error, try `rustc --explain E0131`. diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.rs b/tests/ui/async-await/async-closures/ambiguous-arg.rs new file mode 100644 index 000000000000..d76a1cf953e4 --- /dev/null +++ b/tests/ui/async-await/async-closures/ambiguous-arg.rs @@ -0,0 +1,15 @@ +//@ edition:2021 + +// Regression test for #123901. We previously ICE'd as we silently +// swallowed an in the `ExprUseVisitor`. + +#![feature(async_closure)] + +pub fn test(test: &u64, temp: &u64) { + async |check, a, b| { + //~^ ERROR type annotations needed + temp.abs_diff(12); + }; +} + +fn main() {} diff --git a/tests/ui/async-await/async-closures/ambiguous-arg.stderr b/tests/ui/async-await/async-closures/ambiguous-arg.stderr new file mode 100644 index 000000000000..01f72e94eccf --- /dev/null +++ b/tests/ui/async-await/async-closures/ambiguous-arg.stderr @@ -0,0 +1,13 @@ +error[E0282]: type annotations needed + --> $DIR/ambiguous-arg.rs:9:25 + | +LL | async |check, a, b| { + | _________________________^ +LL | | +LL | | temp.abs_diff(12); +LL | | }; + | |_____^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.rs b/tests/ui/cast/ice-cast-type-with-error-124848.rs new file mode 100644 index 000000000000..9b3732b02db4 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.rs @@ -0,0 +1,18 @@ +// Regression test for ICE #124848 +// Tests that there is no ICE when a cast +// involves a type with error + +use std::cell::Cell; + +struct MyType<'a>(Cell>>, Pin); +//~^ ERROR use of undeclared lifetime name `'unpinned` +//~| ERROR cannot find type `Pin` in this scope + +fn main() { + let mut unpinned = MyType(Cell::new(None)); + //~^ ERROR his struct takes 2 arguments but 1 argument was supplied + let bad_addr = &unpinned as *const Cell>> as usize; + //~^ ERROR use of undeclared lifetime name `'a` + //~| ERROR use of undeclared lifetime name `'a` + //~| ERROR casting `&MyType<'_>` as `*const Cell>>` is invalid +} diff --git a/tests/ui/cast/ice-cast-type-with-error-124848.stderr b/tests/ui/cast/ice-cast-type-with-error-124848.stderr new file mode 100644 index 000000000000..2d86bf76d110 --- /dev/null +++ b/tests/ui/cast/ice-cast-type-with-error-124848.stderr @@ -0,0 +1,63 @@ +error[E0261]: use of undeclared lifetime name `'unpinned` + --> $DIR/ice-cast-type-with-error-124848.rs:7:32 + | +LL | struct MyType<'a>(Cell>>, Pin); + | - ^^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'unpinned` here: `'unpinned,` + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:53 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/ice-cast-type-with-error-124848.rs:14:67 + | +LL | fn main() { + | - help: consider introducing lifetime `'a` here: `<'a>` +... +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^ undeclared lifetime + +error[E0412]: cannot find type `Pin` in this scope + --> $DIR/ice-cast-type-with-error-124848.rs:7:60 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^ not found in this scope + | +help: consider importing this struct + | +LL + use std::pin::Pin; + | + +error[E0061]: this struct takes 2 arguments but 1 argument was supplied + --> $DIR/ice-cast-type-with-error-124848.rs:12:24 + | +LL | let mut unpinned = MyType(Cell::new(None)); + | ^^^^^^----------------- an argument is missing + | +note: tuple struct defined here + --> $DIR/ice-cast-type-with-error-124848.rs:7:8 + | +LL | struct MyType<'a>(Cell>>, Pin); + | ^^^^^^ +help: provide the argument + | +LL | let mut unpinned = MyType(Cell::new(None), /* value */); + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0606]: casting `&MyType<'_>` as `*const Cell>>` is invalid + --> $DIR/ice-cast-type-with-error-124848.rs:14:20 + | +LL | let bad_addr = &unpinned as *const Cell>> as usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0061, E0261, E0412, E0606. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.rs b/tests/ui/coercion/pin-dyn-dispatch-sound.rs new file mode 100644 index 000000000000..b9d43ebac8bf --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.rs @@ -0,0 +1,19 @@ +use std::marker::PhantomPinned; +use std::pin::Pin; + +trait MyUnpinTrait { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned>; +} +impl MyUnpinTrait for PhantomPinned { + fn into_pinned_type(self: Pin<&mut Self>) -> Pin<&mut PhantomPinned> { + self + } +} +impl Unpin for dyn MyUnpinTrait {} //~ ERROR E0321 + +// It would be unsound for this function to compile. +fn pin_it(not_yet_pinned: &mut PhantomPinned) -> Pin<&mut PhantomPinned> { + Pin::new(not_yet_pinned as &mut dyn MyUnpinTrait).into_pinned_type() +} + +fn main() {} diff --git a/tests/ui/coercion/pin-dyn-dispatch-sound.stderr b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr new file mode 100644 index 000000000000..45860bfcfc76 --- /dev/null +++ b/tests/ui/coercion/pin-dyn-dispatch-sound.stderr @@ -0,0 +1,9 @@ +error[E0321]: cross-crate traits with a default impl, like `Unpin`, can only be implemented for a struct/enum type, not `(dyn MyUnpinTrait + 'static)` + --> $DIR/pin-dyn-dispatch-sound.rs:12:1 + | +LL | impl Unpin for dyn MyUnpinTrait {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0321`. diff --git a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr index f8bed86ccf59..a26c617dc931 100644 --- a/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr +++ b/tests/ui/higher-ranked/trait-bounds/issue-59311.stderr @@ -1,19 +1,33 @@ error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` error: implementation of `Trait` is not general enough --> $DIR/issue-59311.rs:17:5 | -LL | v.t(|| {}); - | ^^^^^^^^^^ implementation of `Trait` is not general enough +LL | / pub fn crash(v: &V) +LL | | where +LL | | for<'a> &'a V: Trait + 'static, + | |____________________-----__________- due to a where-clause on `crash`... + | | + | doesn't satisfy where-clause +LL | { +LL | v.t(|| {}); + | ^^^^^^^^^^ | - = note: `Trait` would have to be implemented for the type `&'a V` + = note: ...`Trait` would have to be implemented for the type `&'a V` = note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs new file mode 100644 index 000000000000..fa76686cc8b6 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.rs @@ -0,0 +1,11 @@ +// Minimized test from #59311. + +pub fn crash() +where + for<'a> &'a (): 'static, +{ + || {}; + //~^ ERROR higher-ranked lifetime error +} + +fn main() {} diff --git a/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr new file mode 100644 index 000000000000..9e0d7e4b7be0 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/trivial-does-not-hold.stderr @@ -0,0 +1,10 @@ +error: higher-ranked lifetime error + --> $DIR/trivial-does-not-hold.rs:7:5 + | +LL | || {}; + | ^^^^^ + | + = note: could not prove `for<'a> &'a (): 'b` + +error: aborting due to 1 previous error + diff --git a/tests/ui/impl-trait/precise-capturing/apit.stderr b/tests/ui/impl-trait/precise-capturing/apit.stderr index 36bf80d9e2f9..96548f5732f5 100644 --- a/tests/ui/impl-trait/precise-capturing/apit.stderr +++ b/tests/ui/impl-trait/precise-capturing/apit.stderr @@ -11,7 +11,7 @@ error: `use<...>` precise capturing syntax not allowed on argument-position `imp --> $DIR/apit.rs:4:18 | LL | fn hello(_: impl use<> Sized) {} - | ^^^ + | ^^^^^ error: aborting due to 1 previous error; 1 warning emitted diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed new file mode 100644 index 000000000000..014ab23e4ebc --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.fixed @@ -0,0 +1,29 @@ +//@ run-rustfix + +#![feature(precise_capturing)] +#![allow(unused, incomplete_features)] +#![deny(impl_trait_overcaptures)] + +fn named<'a>(x: &'a i32) -> impl use<> Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn implicit(x: &i32) -> impl use<> Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +struct W; +impl W { + fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self } + //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 +} + +trait Higher<'a> { + type Output; +} +impl Higher<'_> for () { + type Output = (); +} + +fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {} +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs new file mode 100644 index 000000000000..e4b7828d60ff --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.rs @@ -0,0 +1,29 @@ +//@ run-rustfix + +#![feature(precise_capturing)] +#![allow(unused, incomplete_features)] +#![deny(impl_trait_overcaptures)] + +fn named<'a>(x: &'a i32) -> impl Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn implicit(x: &i32) -> impl Sized { *x } +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +struct W; +impl W { + fn hello(&self, x: &i32) -> impl Sized + '_ { self } + //~^ ERROR `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 +} + +trait Higher<'a> { + type Output; +} +impl Higher<'_> for () { + type Output = (); +} + +fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} +//~^ ERROR `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr new file mode 100644 index 000000000000..16cb8b7e94b1 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr @@ -0,0 +1,75 @@ +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:7:29 + | +LL | fn named<'a>(x: &'a i32) -> impl Sized { *x } + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:7:10 + | +LL | fn named<'a>(x: &'a i32) -> impl Sized { *x } + | ^^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +note: the lint level is defined here + --> $DIR/overcaptures-2024.rs:5:9 + | +LL | #![deny(impl_trait_overcaptures)] + | ^^^^^^^^^^^^^^^^^^^^^^^ +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn named<'a>(x: &'a i32) -> impl use<> Sized { *x } + | +++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:10:25 + | +LL | fn implicit(x: &i32) -> impl Sized { *x } + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:10:16 + | +LL | fn implicit(x: &i32) -> impl Sized { *x } + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn implicit(x: &i32) -> impl use<> Sized { *x } + | +++++ + +error: `impl Sized + '_` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:15:33 + | +LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } + | ^^^^^^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:15:24 + | +LL | fn hello(&self, x: &i32) -> impl Sized + '_ { self } + | ^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn hello(&self, x: &i32) -> impl use<'_> Sized + '_ { self } + | +++++++ + +error: `impl Sized` will capture more lifetimes than possibly intended in edition 2024 + --> $DIR/overcaptures-2024.rs:26:47 + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} + | ^^^^^^^^^^ + | +note: specifically, this lifetime is in scope but not mentioned in the type's bounds + --> $DIR/overcaptures-2024.rs:26:23 + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl Sized> {} + | ^^ + = note: all lifetimes in scope will be captured by `impl Trait`s in edition 2024 +help: use the precise capturing `use<...>` syntax to make the captures explicit + | +LL | fn hrtb() -> impl for<'a> Higher<'a, Output = impl use<> Sized> {} + | +++++ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/impl-trait/precise-capturing/redundant.rs b/tests/ui/impl-trait/precise-capturing/redundant.rs new file mode 100644 index 000000000000..108a4cb64aa8 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.rs @@ -0,0 +1,25 @@ +//@ compile-flags: -Zunstable-options --edition=2024 +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello<'a>() -> impl use<'a> Sized {} +//~^ WARN all possible in-scope parameters are already captured + +struct Inherent; +impl Inherent { + fn inherent(&self) -> impl use<'_> Sized {} + //~^ WARN all possible in-scope parameters are already captured +} + +trait Test<'a> { + fn in_trait() -> impl use<'a, Self> Sized; + //~^ WARN all possible in-scope parameters are already captured +} +impl<'a> Test<'a> for () { + fn in_trait() -> impl use<'a> Sized {} + //~^ WARN all possible in-scope parameters are already captured +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/redundant.stderr b/tests/ui/impl-trait/precise-capturing/redundant.stderr new file mode 100644 index 000000000000..325f04d3536a --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/redundant.stderr @@ -0,0 +1,45 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/redundant.rs:4:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:7:19 + | +LL | fn hello<'a>() -> impl use<'a> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + | + = note: `#[warn(impl_trait_redundant_captures)]` on by default + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:12:27 + | +LL | fn inherent(&self) -> impl use<'_> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:17:22 + | +LL | fn in_trait() -> impl use<'a, Self> Sized; + | ^^^^^-------------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: all possible in-scope parameters are already captured, so `use<...>` syntax is redundant + --> $DIR/redundant.rs:21:22 + | +LL | fn in_trait() -> impl use<'a> Sized {} + | ^^^^^-------^^^^^^ + | | + | help: remove the `use<...>` syntax + +warning: 5 warnings emitted + diff --git a/tests/ui/lint/lint-unnecessary-parens.fixed b/tests/ui/lint/lint-unnecessary-parens.fixed index 973bbd70f257..760897c5143f 100644 --- a/tests/ui/lint/lint-unnecessary-parens.fixed +++ b/tests/ui/lint/lint-unnecessary-parens.fixed @@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 { macro_rules! baz { ($($foo:expr),+) => { ($($foo),*) + }; +} + +macro_rules! unit { + () => { + () + }; +} + +struct One; + +impl std::ops::Sub for () { + type Output = i32; + fn sub(self, _: One) -> Self::Output { + -1 + } +} + +impl std::ops::Neg for One { + type Output = i32; + fn neg(self) -> Self::Output { + -1 } } @@ -94,4 +116,13 @@ fn main() { let _a = baz!(3, 4); let _b = baz!(3); + + let _ = { + unit!() - One //~ ERROR unnecessary parentheses around block return value + } + { + unit![] - One //~ ERROR unnecessary parentheses around block return value + } + { + // FIXME: false positive. This parenthesis is required. + unit! {} - One //~ ERROR unnecessary parentheses around block return value + }; } diff --git a/tests/ui/lint/lint-unnecessary-parens.rs b/tests/ui/lint/lint-unnecessary-parens.rs index 40cd61fcc2c0..7cbaac8ae540 100644 --- a/tests/ui/lint/lint-unnecessary-parens.rs +++ b/tests/ui/lint/lint-unnecessary-parens.rs @@ -46,6 +46,28 @@ pub fn parens_with_keyword(e: &[()]) -> i32 { macro_rules! baz { ($($foo:expr),+) => { ($($foo),*) + }; +} + +macro_rules! unit { + () => { + () + }; +} + +struct One; + +impl std::ops::Sub for () { + type Output = i32; + fn sub(self, _: One) -> Self::Output { + -1 + } +} + +impl std::ops::Neg for One { + type Output = i32; + fn neg(self) -> Self::Output { + -1 } } @@ -94,4 +116,13 @@ fn main() { let _a = baz!(3, 4); let _b = baz!(3); + + let _ = { + (unit!() - One) //~ ERROR unnecessary parentheses around block return value + } + { + (unit![] - One) //~ ERROR unnecessary parentheses around block return value + } + { + // FIXME: false positive. This parenthesis is required. + (unit! {} - One) //~ ERROR unnecessary parentheses around block return value + }; } diff --git a/tests/ui/lint/lint-unnecessary-parens.stderr b/tests/ui/lint/lint-unnecessary-parens.stderr index ba7a78b8da1a..755dd5fc3094 100644 --- a/tests/ui/lint/lint-unnecessary-parens.stderr +++ b/tests/ui/lint/lint-unnecessary-parens.stderr @@ -124,7 +124,7 @@ LL + return 1; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:52:31 + --> $DIR/lint-unnecessary-parens.rs:74:31 | LL | pub const CONST_ITEM: usize = (10); | ^ ^ @@ -136,7 +136,7 @@ LL + pub const CONST_ITEM: usize = 10; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:53:33 + --> $DIR/lint-unnecessary-parens.rs:75:33 | LL | pub static STATIC_ITEM: usize = (10); | ^ ^ @@ -148,7 +148,7 @@ LL + pub static STATIC_ITEM: usize = 10; | error: unnecessary parentheses around function argument - --> $DIR/lint-unnecessary-parens.rs:57:9 + --> $DIR/lint-unnecessary-parens.rs:79:9 | LL | bar((true)); | ^ ^ @@ -160,7 +160,7 @@ LL + bar(true); | error: unnecessary parentheses around `if` condition - --> $DIR/lint-unnecessary-parens.rs:59:8 + --> $DIR/lint-unnecessary-parens.rs:81:8 | LL | if (true) {} | ^ ^ @@ -172,7 +172,7 @@ LL + if true {} | error: unnecessary parentheses around `while` condition - --> $DIR/lint-unnecessary-parens.rs:60:11 + --> $DIR/lint-unnecessary-parens.rs:82:11 | LL | while (true) {} | ^ ^ @@ -184,7 +184,7 @@ LL + while true {} | error: unnecessary parentheses around `match` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:61:11 + --> $DIR/lint-unnecessary-parens.rs:83:11 | LL | match (true) { | ^ ^ @@ -196,7 +196,7 @@ LL + match true { | error: unnecessary parentheses around `let` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:64:16 + --> $DIR/lint-unnecessary-parens.rs:86:16 | LL | if let 1 = (1) {} | ^ ^ @@ -208,7 +208,7 @@ LL + if let 1 = 1 {} | error: unnecessary parentheses around `let` scrutinee expression - --> $DIR/lint-unnecessary-parens.rs:65:19 + --> $DIR/lint-unnecessary-parens.rs:87:19 | LL | while let 1 = (2) {} | ^ ^ @@ -220,7 +220,7 @@ LL + while let 1 = 2 {} | error: unnecessary parentheses around method argument - --> $DIR/lint-unnecessary-parens.rs:81:24 + --> $DIR/lint-unnecessary-parens.rs:103:24 | LL | X { y: false }.foo((true)); | ^ ^ @@ -232,7 +232,7 @@ LL + X { y: false }.foo(true); | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:83:18 + --> $DIR/lint-unnecessary-parens.rs:105:18 | LL | let mut _a = (0); | ^ ^ @@ -244,7 +244,7 @@ LL + let mut _a = 0; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:84:10 + --> $DIR/lint-unnecessary-parens.rs:106:10 | LL | _a = (0); | ^ ^ @@ -256,7 +256,7 @@ LL + _a = 0; | error: unnecessary parentheses around assigned value - --> $DIR/lint-unnecessary-parens.rs:85:11 + --> $DIR/lint-unnecessary-parens.rs:107:11 | LL | _a += (1); | ^ ^ @@ -268,7 +268,7 @@ LL + _a += 1; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:87:8 + --> $DIR/lint-unnecessary-parens.rs:109:8 | LL | let(mut _a) = 3; | ^ ^ @@ -280,7 +280,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:88:9 + --> $DIR/lint-unnecessary-parens.rs:110:9 | LL | let (mut _a) = 3; | ^ ^ @@ -292,7 +292,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:89:8 + --> $DIR/lint-unnecessary-parens.rs:111:8 | LL | let( mut _a) = 3; | ^^ ^ @@ -304,7 +304,7 @@ LL + let mut _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:91:8 + --> $DIR/lint-unnecessary-parens.rs:113:8 | LL | let(_a) = 3; | ^ ^ @@ -316,7 +316,7 @@ LL + let _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:92:9 + --> $DIR/lint-unnecessary-parens.rs:114:9 | LL | let (_a) = 3; | ^ ^ @@ -328,7 +328,7 @@ LL + let _a = 3; | error: unnecessary parentheses around pattern - --> $DIR/lint-unnecessary-parens.rs:93:8 + --> $DIR/lint-unnecessary-parens.rs:115:8 | LL | let( _a) = 3; | ^^ ^ @@ -339,5 +339,41 @@ LL - let( _a) = 3; LL + let _a = 3; | -error: aborting due to 28 previous errors +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:121:9 + | +LL | (unit!() - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit!() - One) +LL + unit!() - One + | + +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:123:9 + | +LL | (unit![] - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit![] - One) +LL + unit![] - One + | + +error: unnecessary parentheses around block return value + --> $DIR/lint-unnecessary-parens.rs:126:9 + | +LL | (unit! {} - One) + | ^ ^ + | +help: remove these parentheses + | +LL - (unit! {} - One) +LL + unit! {} - One + | + +error: aborting due to 31 previous errors diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs index 87a682249b00..87fa42f94775 100644 --- a/tests/ui/lint/reference_casting.rs +++ b/tests/ui/lint/reference_casting.rs @@ -261,6 +261,13 @@ unsafe fn bigger_layout() { let ptr = r as *mut i32 as *mut Vec3; unsafe { *ptr = Vec3(0, 0, 0) } } + + unsafe fn deref(v: &mut Vec3) { + let r = &mut v.0; + let r = &mut *r; + let ptr = &mut *(r as *mut i32 as *mut Vec3); + unsafe { *ptr = Vec3(0, 0, 0) } + } } const RAW_PTR: *mut u8 = 1 as *mut u8; diff --git a/tests/ui/macros/nonterminal-matching.stderr b/tests/ui/macros/nonterminal-matching.stderr index 499f9a7637d2..d19141145fa1 100644 --- a/tests/ui/macros/nonterminal-matching.stderr +++ b/tests/ui/macros/nonterminal-matching.stderr @@ -1,8 +1,6 @@ error: no rules expected the token `enum E {}` --> $DIR/nonterminal-matching.rs:19:10 | -LL | macro complex_nonterminal($nt_item: item) { - | -------------- LL | macro n(a $nt_item b) { | --------------------- when calling this macro ... diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 492bd2450b1b..6b215ba525de 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -213,6 +213,21 @@ fn test_expr() { "match () { _ => ({ 1 }) - 1, }", "match () { _ => { 1 } - 1 }", ); + c2_match_arm!( + [ m!() - 1 ], + "match () { _ => m!() - 1, }", + "match () { _ => m!() - 1 }", + ); + c2_match_arm!( + [ m![] - 1 ], + "match () { _ => m![] - 1, }", + "match () { _ => m![] - 1 }", + ); + c2_match_arm!( + [ m! {} - 1 ], + "match () { _ => m! {} - 1, }", + "match () { _ => m! {} - 1 }", + ); // ExprKind::Closure c1!(expr, [ || {} ], "|| {}"); @@ -660,6 +675,11 @@ fn test_stmt() { "let (a, b): (u32, u32) = (1, 2);", "let (a, b): (u32, u32) = (1, 2)" ); + c2!(stmt, + [ let _ = f() else { return; } ], + "let _ = f() else { return; };", + "let _ = f() else { return; }", + ); macro_rules! c2_let_expr_minus_one { ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { c2!(stmt, [ let _ = $expr - 1 ], $stmt_expected, $tokens_expected); @@ -670,6 +690,16 @@ fn test_stmt() { "let _ = match void {} - 1;", "let _ = match void {} - 1", ); + macro_rules! c2_let_expr_else_return { + ([ $expr:expr ], $stmt_expected:expr, $tokens_expected:expr $(,)?) => { + c2!(stmt, [ let _ = $expr else { return; } ], $stmt_expected, $tokens_expected); + }; + } + c2_let_expr_else_return!( + [ f() ], + "let _ = f() else { return; };", + "let _ = f() else { return; }", + ); // StmtKind::Item c1!(stmt, [ struct S; ], "struct S;"); @@ -720,6 +750,21 @@ fn test_stmt() { "(loop { break 1; }) - 1;", "loop { break 1; } - 1", ); + c2_minus_one!( + [ m!() ], + "m!() - 1;", + "m!() - 1" + ); + c2_minus_one!( + [ m![] ], + "m![] - 1;", + "m![] - 1" + ); + c2_minus_one!( + [ m! {} ], + "(m! {}) - 1;", + "m! {} - 1" + ); // StmtKind::Empty c1!(stmt, [ ; ], ";"); diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 69607600b55c..665dcc7d0913 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -73,14 +73,10 @@ error: expected expression, found pattern `1 + 1` --> $DIR/trace_faulty_macros.rs:49:37 | LL | (let $p:pat = $e:expr) => {test!(($p,$e))}; - | ------- -- this is interpreted as expression, but it is expected to be pattern - | | - | this macro fragment matcher is expression + | -- this is interpreted as expression, but it is expected to be pattern ... LL | (($p:pat, $e:pat)) => {let $p = $e;}; - | ------ ^^ expected expression - | | - | this macro fragment matcher is pattern + | ^^ expected expression ... LL | test!(let x = 1+1); | ------------------ diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index f1ac3e340e91..62e4f82a3ffb 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -53,6 +53,12 @@ pub fn main() { if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { let _: u32 = x; } + if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + let _: u32 = x; + } + if let Some(&Some(x)) = &mut Some(Some(0)) { + let _: u32 = x; + } let &mut x = &&mut 0; let _: &u32 = x; diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index ec091bb17467..96b4ff77ddb4 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -14,18 +14,20 @@ pub fn main() { let _: &mut u32 = x; //~^ ERROR: mismatched types } - if let Some(&Some(&_)) = Some(&Some(&mut 0)) { - //~^ ERROR: mismatched types - } if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { //~^ ERROR: mismatched types } if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { //~^ ERROR: mismatched types } + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&mut Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + } - - let &mut _= &&0; + let &mut _ = &&0; //~^ ERROR: mismatched types let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index be71ee606c76..e06a645fc0d3 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -34,17 +34,6 @@ LL | let _: &mut u32 = x; error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 | -LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) { - | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` - | | - | types differ in mutability - | - = note: expected mutable reference `&mut {integer}` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23 - | LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` | | @@ -54,7 +43,7 @@ LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:29 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:29 | LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { | ^^^^^^ ------------------------- this expression has type `&Option>>` @@ -65,10 +54,32 @@ LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:17 | -LL | let &mut _= &&0; - | ^^^^^^ --- this expression has type `&&{integer}` +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:26:17 + | +LL | if let Some(&mut Some(x)) = &Some(Some(0)) { + | ^^^^^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&mut _` + | + = note: expected enum `Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:30:9 + | +LL | let &mut _ = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` | | | expected integer, found `&mut _` | @@ -76,7 +87,7 @@ LL | let &mut _= &&0; found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:33:9 | LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` @@ -86,6 +97,6 @@ LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; = note: expected type `{integer}` found mutable reference `&mut _` -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs index 364554884073..3cdf47c1dbfe 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs @@ -8,4 +8,7 @@ pub fn main() { //~^ ERROR: cannot move out of a shared reference [E0507] let _: &u32 = x; } + + let &ref mut x = &0; + //~^ cannot borrow data in a `&` reference as mutable [E0596] } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr index ccfb5c7a0c07..8b86fa65c4d8 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr @@ -12,6 +12,13 @@ help: consider borrowing the pattern binding LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) { | +++ -error: aborting due to 1 previous error +error[E0596]: cannot borrow data in a `&` reference as mutable + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:12:10 + | +LL | let &ref mut x = &0; + | ^^^^^^^^^ cannot borrow as mutable -For more information about this error, try `rustc --explain E0507`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0507, E0596. +For more information about an error, try `rustc --explain E0507`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed new file mode 100644 index 000000000000..bc7a58a382d6 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.fixed @@ -0,0 +1,30 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ run-rustfix +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&mut Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + if let &mut Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &mut pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + + let &mut (ref mut a, ref mut b) = &mut (true, false); + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //~| ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut bool = a; + let _: &mut bool = b; +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs new file mode 100644 index 000000000000..c6d72b0a9d77 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs @@ -0,0 +1,30 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +//@ run-rustfix +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + } + + macro_rules! pat { + ($var:ident) => { ref mut $var }; + } + let &pat!(x) = &mut 0; + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut u8 = x; + + let &(ref mut a, ref mut b) = &mut (true, false); + //~^ ERROR: cannot borrow as mutable inside an `&` pattern + //~| ERROR: cannot borrow as mutable inside an `&` pattern + let _: &mut bool = a; + let _: &mut bool = b; +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr new file mode 100644 index 000000000000..964e9f36596b --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_ref_mut_inside_and.stderr @@ -0,0 +1,43 @@ +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:8:31 + | +LL | if let Some(&Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:13:31 + | +LL | if let &Some(Some(ref mut x)) = &mut Some(Some(0)) { + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:21:15 + | +LL | let &pat!(x) = &mut 0; + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:19 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error[E0596]: cannot borrow as mutable inside an `&` pattern + --> $DIR/ref_pat_eat_one_layer_2024_ref_mut_inside_and.rs:25:30 + | +LL | let &(ref mut a, ref mut b) = &mut (true, false); + | - ^ + | | + | help: replace this `&` with `&mut`: `&mut` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0596`. diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs b/tests/ui/match/ref_pat_everywhere-fail.rs similarity index 63% rename from tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs rename to tests/ui/match/ref_pat_everywhere-fail.rs index 9dd7a7893ec7..d1b1c04730d3 100644 --- a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs +++ b/tests/ui/match/ref_pat_everywhere-fail.rs @@ -5,11 +5,7 @@ pub fn main() { //~^ ERROR: mismatched types [E0308] let _: u32 = x; } - if let &Some(x) = &mut Some(0) { - //~^ ERROR: mismatched types [E0308] - let _: u32 = x; - } - if let Some(&x) = &mut Some(0) { + if let Some(&mut x) = Some(&0) { //~^ ERROR: mismatched types [E0308] let _: u32 = x; } diff --git a/tests/ui/match/ref_pat_everywhere-fail.stderr b/tests/ui/match/ref_pat_everywhere-fail.stderr new file mode 100644 index 000000000000..25a01129f4a9 --- /dev/null +++ b/tests/ui/match/ref_pat_everywhere-fail.stderr @@ -0,0 +1,38 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_everywhere-fail.rs:4:17 + | +LL | if let Some(&x) = Some(0) { + | ^^ ------- this expression has type `Option<{integer}>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(x) = Some(0) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_everywhere-fail.rs:8:17 + | +LL | if let Some(&mut x) = Some(&0) { + | ^^^^^^ -------- this expression has type `Option<&{integer}>` + | | + | types differ in mutability + | + = note: expected reference `&{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_everywhere-fail.rs:8:17 + | +LL | if let Some(&mut x) = Some(&0) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(x) = Some(&0) { + | ~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr deleted file mode 100644 index d512ea5f957d..000000000000 --- a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:4:17 - | -LL | if let Some(&x) = Some(0) { - | ^^ ------- this expression has type `Option<{integer}>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL | if let Some(x) = Some(0) { - | ~ - -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:8:12 - | -LL | if let &Some(x) = &mut Some(0) { - | ^^^^^^^^ ------------ this expression has type `&mut Option<{integer}>` - | | - | types differ in mutability - | - = note: expected mutable reference `&mut Option<{integer}>` - found reference `&_` - -error[E0308]: mismatched types - --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:12:17 - | -LL | if let Some(&x) = &mut Some(0) { - | ^^ ------------ this expression has type `&mut Option<{integer}>` - | | - | expected integer, found `&_` - | - = note: expected type `{integer}` - found reference `&_` -help: consider removing `&` from the pattern - | -LL | if let Some(x) = &mut Some(0) { - | ~ - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_everywhere.rs b/tests/ui/match/ref_pat_everywhere.rs index b3daca484092..9a79c548475f 100644 --- a/tests/ui/match/ref_pat_everywhere.rs +++ b/tests/ui/match/ref_pat_everywhere.rs @@ -15,4 +15,10 @@ pub fn main() { if let Some(Some(&x)) = &Some(&mut Some(0)) { let _: u32 = x; } + if let &Some(x) = &mut Some(0) { + let _: u32 = x; + } + if let Some(&x) = &mut Some(0) { + let _: u32 = x; + } } diff --git a/tests/ui/parser/else-no-if.rs b/tests/ui/parser/else-no-if.rs index f0b40ecde666..ad5262cd2cc9 100644 --- a/tests/ui/parser/else-no-if.rs +++ b/tests/ui/parser/else-no-if.rs @@ -1,3 +1,7 @@ +macro_rules! falsy { + () => { false }; +} + fn foo() { if true { } else false { @@ -25,6 +29,32 @@ fn foo4() { {} } +fn foo5() { + if true { + } else falsy!() { + //~^ ERROR expected `{`, found `falsy` + } +} + +fn foo6() { + if true { + } else falsy!(); + //~^ ERROR expected `{`, found `falsy` +} + +fn foo7() { + if true { + } else falsy! {} { + //~^ ERROR expected `{`, found `falsy` + } +} + +fn foo8() { + if true { + } else falsy! {}; + //~^ ERROR expected `{`, found `falsy` +} + fn falsy() -> bool { false } diff --git a/tests/ui/parser/else-no-if.stderr b/tests/ui/parser/else-no-if.stderr index b9c1a75276c1..2e3e8f6b50e9 100644 --- a/tests/ui/parser/else-no-if.stderr +++ b/tests/ui/parser/else-no-if.stderr @@ -1,5 +1,5 @@ error: expected `{`, found keyword `false` - --> $DIR/else-no-if.rs:3:12 + --> $DIR/else-no-if.rs:7:12 | LL | } else false { | ---- ^^^^^ @@ -12,7 +12,7 @@ LL | } else if false { | ++ error: expected `{`, found `falsy` - --> $DIR/else-no-if.rs:10:12 + --> $DIR/else-no-if.rs:14:12 | LL | } else falsy() { | ---- ^^^^^ @@ -25,7 +25,7 @@ LL | } else if falsy() { | ++ error: expected `{`, found `falsy` - --> $DIR/else-no-if.rs:17:12 + --> $DIR/else-no-if.rs:21:12 | LL | } else falsy(); | ^^^^^ expected `{` @@ -36,7 +36,7 @@ LL | } else { falsy() }; | + + error: expected `{`, found keyword `loop` - --> $DIR/else-no-if.rs:23:12 + --> $DIR/else-no-if.rs:27:12 | LL | } else loop{} | ^^^^ expected `{` @@ -46,5 +46,51 @@ help: try placing this code inside a block LL | } else { loop{} } | + + -error: aborting due to 4 previous errors +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:34:12 + | +LL | } else falsy!() { + | ---- ^^^^^ + | | + | expected an `if` or a block after this `else` + | +help: add an `if` if this is the condition of a chained `else if` statement + | +LL | } else if falsy!() { + | ++ + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:41:12 + | +LL | } else falsy!(); + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy!() }; + | + + + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:47:12 + | +LL | } else falsy! {} { + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy! {} } { + | + + + +error: expected `{`, found `falsy` + --> $DIR/else-no-if.rs:54:12 + | +LL | } else falsy! {}; + | ^^^^^ expected `{` + | +help: try placing this code inside a block + | +LL | } else { falsy! {} }; + | + + + +error: aborting due to 8 previous errors diff --git a/tests/ui/parser/macro/statement-boundaries.rs b/tests/ui/parser/macro/statement-boundaries.rs new file mode 100644 index 000000000000..67a6aa30f0c5 --- /dev/null +++ b/tests/ui/parser/macro/statement-boundaries.rs @@ -0,0 +1,104 @@ +//@ run-pass +//@ edition:2021 + +// This is a test of several uses of rustc_ast::util::classify::expr_requires_semi_to_be_stmt +// by the Rust parser, which relates to the insertion of statement boundaries +// after certain kinds of expressions if they appear at the head of a statement. + +#![allow(unused_braces, unused_unsafe)] + +macro_rules! unit { + () => { + { () } + }; +} + +#[derive(Copy, Clone)] +struct X; + +fn main() { + let x = X; + + // There is a statement boundary before `|x| x`, so it's a closure. + let _: fn(X) -> X = { if true {} |x| x }; + let _: fn(X) -> X = { if true {} else {} |x| x }; + let _: fn(X) -> X = { match () { () => {} } |x| x }; + let _: fn(X) -> X = { { () } |x| x }; + let _: fn(X) -> X = { unsafe {} |x| x }; + let _: fn(X) -> X = { while false {} |x| x }; + let _: fn(X) -> X = { loop { break; } |x| x }; + let _: fn(X) -> X = { for _ in 0..0 {} |x| x }; + let _: fn(X) -> X = { const {} |x| x }; + let _: fn(X) -> X = { unit! {} |x| x }; + + // No statement boundary, so `|x| x` is 2× BitOr operation. + () = { "" |x| x }; + () = { ("") |x| x }; + () = { [""] |x| x }; + () = { unit!() |x| x }; + () = { unit![] |x| x }; + + // All the same cases, but as a match arm. + () = match x { + // Statement boundary before `| X`, which becomes a new arm with leading vert. + X if false => if true {} | X if false => {} + X if false => if true {} else {} | X if false => {} + X if false => match () { () => {} } | X if false => {} + X if false => { () } | X if false => {} + X if false => unsafe {} | X if false => {} + X if false => while false {} | X if false => {} + X if false => loop { break; } | X if false => {} + X if false => for _ in 0..0 {} | X if false => {} + X if false => const {} | X if false => {} + + // No statement boundary, so `| X` is BitOr. + X if false => "" | X, + X if false => ("") | X, + X if false => [""] | X, + X if false => unit! {} | X, // !! inconsistent with braced mac call in statement position + X if false => unit!() | X, + X if false => unit![] | X, + + X => {} + }; + + // Test how the statement boundary logic interacts with macro metavariables / + // "invisible delimiters". + macro_rules! assert_statement_boundary { + ($expr:expr) => { + let _: fn(X) -> X = { $expr |x| x }; + + () = match X { + X if false => $expr | X if false => {} + X => {} + }; + }; + } + macro_rules! assert_no_statement_boundary { + ($expr:expr) => { + () = { $expr |x| x }; + + () = match x { + X if false => $expr | X, + X => {} + }; + }; + } + assert_statement_boundary!(if true {}); + assert_no_statement_boundary!(""); +} + +impl std::ops::BitOr for () { + type Output = (); + fn bitor(self, _: X) {} +} + +impl std::ops::BitOr for &str { + type Output = (); + fn bitor(self, _: X) {} +} + +impl std::ops::BitOr for [T; N] { + type Output = (); + fn bitor(self, _: X) {} +} diff --git a/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs new file mode 100644 index 000000000000..0b70e4404abc --- /dev/null +++ b/tests/ui/pattern/auxiliary/match_ergonomics_2024_macros.rs @@ -0,0 +1,12 @@ +//@ edition: 2024 +//@ compile-flags: -Z unstable-options + +// This contains a binding in edition 2024, so if matched with a reference binding mode it will end +// up with a `mut ref mut` binding mode. We use this to test the migration lint on patterns with +// mixed editions. +#[macro_export] +macro_rules! mixed_edition_pat { + ($foo:ident) => { + Some(mut $foo) + }; +} diff --git a/tests/ui/pattern/match_ergonomics_2024.fixed b/tests/ui/pattern/match_ergonomics_2024.fixed new file mode 100644 index 000000000000..d8dbcb217c04 --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.fixed @@ -0,0 +1,57 @@ +//@ edition: 2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ aux-build:match_ergonomics_2024_macros.rs +#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features, unused)] +#![deny(rust_2024_incompatible_pat)] + +extern crate match_ergonomics_2024_macros; + +struct Foo(u8); + +fn main() { + let &Foo(mut a) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + let &mut Foo(mut a) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + if let &&&&&Some(&_) = &&&&&Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + struct Struct { + a: u32, + b: u32, + c: u32, + } + let s = Struct { a: 0, b: 0, c: 0 }; + let &Struct { ref a, mut b, ref c } = &s; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + #[warn(rust_2024_incompatible_pat)] + match &(Some(0), Some(0)) { + // The two patterns are the same syntactically, but because they're defined in different + // editions they don't mean the same thing. + (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + //~^ WARN: the semantics of this pattern will change in edition 2024 + _x = 4; + _y = &7; + } + _ => {} + } +} diff --git a/tests/ui/pattern/match_ergonomics_2024.rs b/tests/ui/pattern/match_ergonomics_2024.rs new file mode 100644 index 000000000000..38dc0c8bebb2 --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.rs @@ -0,0 +1,57 @@ +//@ edition: 2021 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ aux-build:match_ergonomics_2024_macros.rs +#![feature(mut_preserve_binding_mode_2024, ref_pat_eat_one_layer_2024)] +#![allow(incomplete_features, unused)] +#![deny(rust_2024_incompatible_pat)] + +extern crate match_ergonomics_2024_macros; + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + let Foo(mut a) = &mut Foo(0); + //~^ ERROR: the semantics of this pattern will change in edition 2024 + a = 42; + + if let Some(&_) = &&&&&Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut _) = &&&&&Some(&mut 0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&_) = &&&&&mut Some(&0u8) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + struct Struct { + a: u32, + b: u32, + c: u32, + } + let s = Struct { a: 0, b: 0, c: 0 }; + let Struct { a, mut b, c } = &s; + //~^ ERROR: the semantics of this pattern will change in edition 2024 + + #[warn(rust_2024_incompatible_pat)] + match &(Some(0), Some(0)) { + // The two patterns are the same syntactically, but because they're defined in different + // editions they don't mean the same thing. + (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + //~^ WARN: the semantics of this pattern will change in edition 2024 + _x = 4; + _y = &7; + } + _ => {} + } +} diff --git a/tests/ui/pattern/match_ergonomics_2024.stderr b/tests/ui/pattern/match_ergonomics_2024.stderr new file mode 100644 index 000000000000..11844434ad21 --- /dev/null +++ b/tests/ui/pattern/match_ergonomics_2024.stderr @@ -0,0 +1,97 @@ +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:14:9 + | +LL | let Foo(mut a) = &Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&` + | +note: the lint level is defined here + --> $DIR/match_ergonomics_2024.rs:7:9 + | +LL | #![deny(rust_2024_incompatible_pat)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:18:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | -^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:22:12 + | +LL | if let Some(&_) = &&&&&Some(&0u8) {} + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:25:12 + | +LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {} + | -^^^^^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:28:12 + | +LL | if let Some(&_) = &&&&&mut Some(&0u8) {} + | -^^^^^^^ + | | + | help: desugar the match ergonomics: `&&&&&mut` + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:31:12 + | +LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ++++ ++++ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:34:12 + | +LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {} + | ++++ ++++ +++++++ + +error: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:43:9 + | +LL | let Struct { a, mut b, c } = &s; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: desugar the match ergonomics + | +LL | let &Struct { ref a, mut b, ref c } = &s; + | + +++ +++ + +warning: the semantics of this pattern will change in edition 2024 + --> $DIR/match_ergonomics_2024.rs:50:9 + | +LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/match_ergonomics_2024.rs:46:12 + | +LL | #[warn(rust_2024_incompatible_pat)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: desugar the match ergonomics + | +LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => { + | + +++ + +error: aborting due to 8 previous errors; 1 warning emitted + diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs deleted file mode 100644 index 249f251d2cd2..000000000000 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs +++ /dev/null @@ -1,16 +0,0 @@ -//@ edition: 2021 -#![feature(mut_preserve_binding_mode_2024)] -#![allow(incomplete_features, unused)] -#![forbid(dereferencing_mut_binding)] - -struct Foo(u8); - -fn main() { - let Foo(mut a) = &Foo(0); - //~^ ERROR: dereferencing `mut` binding - a = 42; - - let Foo(mut a) = &mut Foo(0); - //~^ ERROR: dereferencing `mut` binding - a = 42; -} diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr deleted file mode 100644 index e8d11acd83e5..000000000000 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error: dereferencing `mut` binding - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^^ `mut` dereferences the type of this binding - | -help: this will change in edition 2024 - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 - | -LL | let Foo(mut a) = &Foo(0); - | ^^^^^ -note: the lint level is defined here - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:4:11 - | -LL | #![forbid(dereferencing_mut_binding)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: dereferencing `mut` binding - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^^ `mut` dereferences the type of this binding - | -help: this will change in edition 2024 - --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 - | -LL | let Foo(mut a) = &mut Foo(0); - | ^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr index fee83eb5c181..e068fdb5abac 100644 --- a/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr +++ b/tests/ui/suggestions/recover-from-semicolon-trailing-item.stderr @@ -3,6 +3,8 @@ error: expected item, found `;` | LL | mod M {}; | ^ help: remove this semicolon + | + = help: module declarations are not followed by a semicolon error: expected item, found `;` --> $DIR/recover-from-semicolon-trailing-item.rs:4:12 @@ -17,6 +19,8 @@ error: expected item, found `;` | LL | fn foo(a: usize) {}; | ^ help: remove this semicolon + | + = help: function declarations are not followed by a semicolon error[E0308]: mismatched types --> $DIR/recover-from-semicolon-trailing-item.rs:10:20 diff --git a/tests/ui/symbol-names/types.legacy.stderr b/tests/ui/symbol-names/types.legacy.stderr index a4984d5629f7..87c3acae0bd6 100644 --- a/tests/ui/symbol-names/types.legacy.stderr +++ b/tests/ui/symbol-names/types.legacy.stderr @@ -1,470 +1,506 @@ error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b15Type$LT$f16$GT$17h[HASH]E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:108:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b16Type$LT$f128$GT$17h[HASH]E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:135:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<()>::h[HASH]) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<()>) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,)>::h[HASH]) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,)>) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16)>::h[HASH]) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16)>) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH]) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16,u32)>) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*const u8>::h[HASH]) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*const u8>) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*mut u8>::h[HASH]) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*mut u8>) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&str>::h[HASH]) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&str>) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&mut str>::h[HASH]) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&mut str>) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[u8; 0]>::h[HASH]) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[u8; 0]>) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[T; N]>::h[HASH]) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[T; N]>) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 78 previous errors +error: aborting due to 84 previous errors diff --git a/tests/ui/symbol-names/types.rs b/tests/ui/symbol-names/types.rs index b121408c843b..7ed19e0e5a82 100644 --- a/tests/ui/symbol-names/types.rs +++ b/tests/ui/symbol-names/types.rs @@ -1,169 +1,270 @@ //@ build-fail -//@ revisions: legacy verbose-legacy -//@ compile-flags: --crate-name=a -C symbol-mangling-version=legacy -Z unstable-options -//@[verbose-legacy]compile-flags: -Zverbose-internals +//@ revisions: legacy verbose-legacy v0 +//@ compile-flags: --crate-name=a -Z unstable-options +//@ [legacy] compile-flags: -Csymbol-mangling-version=legacy +//@ [verbose-legacy] compile-flags: -Csymbol-mangling-version=legacy -Zverbose-internals +//@ [v0] compile-flags: -Csymbol-mangling-version=v0 //@ normalize-stderr-test: "h[[:xdigit:]]{16}" -> "h[HASH]" +//@ [v0] normalize-stderr-test: "\[[[:xdigit:]]{16}\]" -> "[HASH]" #![feature(never_type)] #![feature(rustc_attrs)] +#![feature(f128)] +#![feature(f16)] pub fn b() { struct Type(T); #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b16Type$LT$bool$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$bool$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMNvCsCRATE_HASH_1a1bINtB_4TypebE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b16Type$LT$char$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$char$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs_NvCsCRATE_HASH_1a1bINtB_4TypecE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b14Type$LT$i8$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b14Type$LT$i8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs0_NvCsCRATE_HASH_1a1bINtB_4TypeaE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i16$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs1_NvCsCRATE_HASH_1a1bINtB_4TypesE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs2_NvCsCRATE_HASH_1a1bINtB_4TypelE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$i64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$i64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs3_NvCsCRATE_HASH_1a1bINtB_4TypexE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b14Type$LT$u8$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b14Type$LT$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs4_NvCsCRATE_HASH_1a1bINtB_4TypehE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u16$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs5_NvCsCRATE_HASH_1a1bINtB_4TypetE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs6_NvCsCRATE_HASH_1a1bINtB_4TypemE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$u64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$u64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs7_NvCsCRATE_HASH_1a1bINtB_4TypeyE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f32$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f16$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs8_NvCsCRATE_HASH_1a1bINtB_4TypeC3f16E) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) + impl Type {} + + #[rustc_symbol_name] + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f32$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMs9_NvCsCRATE_HASH_1a1bINtB_4TypefE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$f64$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$f64$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsa_NvCsCRATE_HASH_1a1bINtB_4TypedE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b15Type$LT$str$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b16Type$LT$f128$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsb_NvCsCRATE_HASH_1a1bINtB_4TypeC4f128E) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) + impl Type {} + + #[rustc_symbol_name] + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b15Type$LT$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsc_NvCsCRATE_HASH_1a1bINtB_4TypeeE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b17Type$LT$$u21$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b17Type$LT$$u21$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsd_NvCsCRATE_HASH_1a1bINtB_4TypezE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT - //~| ERROR demangling(a::b::Type<()>:: - //~| ERROR demangling-alt(a::b::Type<()>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<()>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<()>) + //[v0]~^^^^ ERROR symbol-name(_RMse_NvCsCRATE_HASH_1a1bINtB_4TypeuE) + //[v0]~| ERROR ::b::Type<()>>) + //[v0]~| ERROR demangling-alt(>) impl Type<()> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,)>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,)>) + //[v0]~^^^^ ERROR symbol-name(_RMsf_NvCsCRATE_HASH_1a1bINtB_4TypeThEE) + //[v0]~| ERROR ::b::Type<(u8,)>>) + //[v0]~| ERROR demangling-alt(>) impl Type<(u8,)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,u16)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,u16)>) - impl Type<(u8,u16)> {} + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,u16)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,u16)>) + //[v0]~^^^^ ERROR symbol-name(_RMsg_NvCsCRATE_HASH_1a1bINtB_4TypeThtEE) + //[v0]~| ERROR ::b::Type<(u8, u16)>>) + //[v0]~| ERROR demangling-alt(>) + impl Type<(u8, u16)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$ - //~| ERROR demangling(a::b::Type<(u8,u16,u32)>:: - //~| ERROR demangling-alt(a::b::Type<(u8,u16,u32)>) - impl Type<(u8,u16,u32)> {} + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<(u8,u16,u32)>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<(u8,u16,u32)>) + //[v0]~^^^^ ERROR symbol-name(_RMsh_NvCsCRATE_HASH_1a1bINtB_4TypeThtmEE) + //[v0]~| ERROR ::b::Type<(u8, u16, u32)>>) + //[v0]~| ERROR demangling-alt(>) + impl Type<(u8, u16, u32)> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$ - //~| ERROR demangling(a::b::Type<*const u8>:: - //~| ERROR demangling-alt(a::b::Type<*const u8>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<*const u8>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<*const u8>) + //[v0]~^^^^ ERROR symbol-name(_RMsi_NvCsCRATE_HASH_1a1bINtB_4TypePhE) + //[v0]~| ERROR ::b::Type<*const u8>>) + //[v0]~| ERROR demangling-alt(>) impl Type<*const u8> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$ - //~| ERROR demangling(a::b::Type<*mut u8>:: - //~| ERROR demangling-alt(a::b::Type<*mut u8>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<*mut u8>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<*mut u8>) + //[v0]~^^^^ ERROR symbol-name(_RMsj_NvCsCRATE_HASH_1a1bINtB_4TypeOhE) + //[v0]~| ERROR ::b::Type<*mut u8>>) + //[v0]~| ERROR demangling-alt(>) impl Type<*mut u8> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$ - //~| ERROR demangling(a::b::Type<&str>:: - //~| ERROR demangling-alt(a::b::Type<&str>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<&str>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<&str>) + //[v0]~^^^^ ERROR symbol-name(_RMsk_NvCsCRATE_HASH_1a1bINtB_4TypeReE) + //[v0]~| ERROR ::b::Type<&str>>) + //[v0]~| ERROR demangling-alt(>) impl Type<&str> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$ - //~| ERROR demangling(a::b::Type<&mut str>:: - //~| ERROR demangling-alt(a::b::Type<&mut str>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<&mut str>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<&mut str>) + //[v0]~^^^^ ERROR symbol-name(_RMsl_NvCsCRATE_HASH_1a1bINtB_4TypeQeE) + //[v0]~| ERROR ::b::Type<&mut str>>) + //[v0]~| ERROR demangling-alt(>) impl Type<&mut str> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$ - //~| ERROR demangling(a::b::Type<[u8; 0]>:: - //~| ERROR demangling-alt(a::b::Type<[u8; 0]>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[u8; 0]>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[u8; 0]>) + //[v0]~^^^^ ERROR symbol-name(_RMsm_NvCsCRATE_HASH_1a1bINtB_4TypeAhj0_E) + //[v0]~| ERROR ::b::Type<[u8; 0usize]>>) + //[v0]~| ERROR demangling-alt(>) impl Type<[u8; 0]> {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMsn_NvCsCRATE_HASH_1a1bINtB_4TypeFEuE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$ - //~| ERROR demangling(a::b::Type:: - //~| ERROR demangling-alt(a::b::Type) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type) + //[v0]~^^^^ ERROR symbol-name(_RMso_NvCsCRATE_HASH_1a1bINtB_4TypeFUKCEuE) + //[v0]~| ERROR ::b::Type>) + //[v0]~| ERROR demangling-alt(>) impl Type {} #[rustc_symbol_name] - //~^ ERROR symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$ - //~| ERROR demangling(a::b::Type<[T; N]>:: - //~| ERROR demangling-alt(a::b::Type<[T; N]>) + //[legacy,verbose-legacy]~^ ERROR symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$ + //[legacy,verbose-legacy]~| ERROR demangling(a::b::Type<[T; N]>:: + //[legacy,verbose-legacy]~| ERROR demangling-alt(a::b::Type<[T; N]>) + //[v0]~^^^^ ERROR symbol-name(_RMsp_NvCsCRATE_HASH_1a1bINtB_4TypeAppEB_) + //[v0]~| ERROR ::b::Type<[_; _]>>) + //[v0]~| ERROR demangling-alt(>) impl Type<[T; N]> {} } diff --git a/tests/ui/symbol-names/types.v0.stderr b/tests/ui/symbol-names/types.v0.stderr new file mode 100644 index 000000000000..58680e002022 --- /dev/null +++ b/tests/ui/symbol-names/types.v0.stderr @@ -0,0 +1,506 @@ +error: symbol-name(_RMNvCsCRATE_HASH_1a1bINtB_4TypebE) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:18:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs_NvCsCRATE_HASH_1a1bINtB_4TypecE) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:27:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs0_NvCsCRATE_HASH_1a1bINtB_4TypeaE) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:36:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs1_NvCsCRATE_HASH_1a1bINtB_4TypesE) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:45:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs2_NvCsCRATE_HASH_1a1bINtB_4TypelE) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:54:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs3_NvCsCRATE_HASH_1a1bINtB_4TypexE) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:63:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs4_NvCsCRATE_HASH_1a1bINtB_4TypehE) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:72:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs5_NvCsCRATE_HASH_1a1bINtB_4TypetE) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:81:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs6_NvCsCRATE_HASH_1a1bINtB_4TypemE) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:90:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs7_NvCsCRATE_HASH_1a1bINtB_4TypeyE) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs8_NvCsCRATE_HASH_1a1bINtB_4TypeC3f16E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMs9_NvCsCRATE_HASH_1a1bINtB_4TypefE) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:117:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsa_NvCsCRATE_HASH_1a1bINtB_4TypedE) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsb_NvCsCRATE_HASH_1a1bINtB_4TypeC4f128E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsc_NvCsCRATE_HASH_1a1bINtB_4TypeeE) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:144:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsd_NvCsCRATE_HASH_1a1bINtB_4TypezE) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:153:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMse_NvCsCRATE_HASH_1a1bINtB_4TypeuE) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:162:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsf_NvCsCRATE_HASH_1a1bINtB_4TypeThEE) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:171:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsg_NvCsCRATE_HASH_1a1bINtB_4TypeThtEE) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:180:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsh_NvCsCRATE_HASH_1a1bINtB_4TypeThtmEE) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:189:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsi_NvCsCRATE_HASH_1a1bINtB_4TypePhE) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:198:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsj_NvCsCRATE_HASH_1a1bINtB_4TypeOhE) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:207:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsk_NvCsCRATE_HASH_1a1bINtB_4TypeReE) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:216:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsl_NvCsCRATE_HASH_1a1bINtB_4TypeQeE) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:225:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsm_NvCsCRATE_HASH_1a1bINtB_4TypeAhj0_E) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:234:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsn_NvCsCRATE_HASH_1a1bINtB_4TypeFEuE) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:243:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMso_NvCsCRATE_HASH_1a1bINtB_4TypeFUKCEuE) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:252:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_RMsp_NvCsCRATE_HASH_1a1bINtB_4TypeAppEB_) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(>) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(>) + --> $DIR/types.rs:261:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 84 previous errors + diff --git a/tests/ui/symbol-names/types.verbose-legacy.stderr b/tests/ui/symbol-names/types.verbose-legacy.stderr index a4984d5629f7..87c3acae0bd6 100644 --- a/tests/ui/symbol-names/types.verbose-legacy.stderr +++ b/tests/ui/symbol-names/types.verbose-legacy.stderr @@ -1,470 +1,506 @@ error: symbol-name(_ZN1a1b16Type$LT$bool$GT$17h[HASH]E) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:13:5 + --> $DIR/types.rs:18:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b16Type$LT$char$GT$17h[HASH]E) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:19:5 + --> $DIR/types.rs:27:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$i8$GT$17h[HASH]E) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:25:5 + --> $DIR/types.rs:36:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i16$GT$17h[HASH]E) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:31:5 + --> $DIR/types.rs:45:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i32$GT$17h[HASH]E) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:37:5 + --> $DIR/types.rs:54:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$i64$GT$17h[HASH]E) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:43:5 + --> $DIR/types.rs:63:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b14Type$LT$u8$GT$17h[HASH]E) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:49:5 + --> $DIR/types.rs:72:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u16$GT$17h[HASH]E) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:55:5 + --> $DIR/types.rs:81:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u32$GT$17h[HASH]E) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:61:5 + --> $DIR/types.rs:90:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$u64$GT$17h[HASH]E) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:67:5 + --> $DIR/types.rs:99:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b15Type$LT$f16$GT$17h[HASH]E) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:108:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:108:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f32$GT$17h[HASH]E) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:73:5 + --> $DIR/types.rs:117:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$f64$GT$17h[HASH]E) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:79:5 + --> $DIR/types.rs:126:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN1a1b16Type$LT$f128$GT$17h[HASH]E) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(a::b::Type::h[HASH]) + --> $DIR/types.rs:135:5 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(a::b::Type) + --> $DIR/types.rs:135:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b15Type$LT$str$GT$17h[HASH]E) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:85:5 + --> $DIR/types.rs:144:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b17Type$LT$$u21$$GT$17h[HASH]E) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:91:5 + --> $DIR/types.rs:153:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b20Type$LT$$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<()>::h[HASH]) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<()>) - --> $DIR/types.rs:97:5 + --> $DIR/types.rs:162:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b25Type$LT$$LP$u8$C$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,)>::h[HASH]) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,)>) - --> $DIR/types.rs:103:5 + --> $DIR/types.rs:171:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$LP$u8$C$u16$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16)>::h[HASH]) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16)>) - --> $DIR/types.rs:109:5 + --> $DIR/types.rs:180:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$LP$u8$C$u16$C$u32$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<(u8,u16,u32)>::h[HASH]) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<(u8,u16,u32)>) - --> $DIR/types.rs:115:5 + --> $DIR/types.rs:189:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b28Type$LT$$BP$const$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*const u8>::h[HASH]) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*const u8>) - --> $DIR/types.rs:121:5 + --> $DIR/types.rs:198:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b26Type$LT$$BP$mut$u20$u8$GT$17h[HASH]E) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<*mut u8>::h[HASH]) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<*mut u8>) - --> $DIR/types.rs:127:5 + --> $DIR/types.rs:207:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b19Type$LT$$RF$str$GT$17h[HASH]E) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&str>::h[HASH]) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&str>) - --> $DIR/types.rs:133:5 + --> $DIR/types.rs:216:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b27Type$LT$$RF$mut$u20$str$GT$17h[HASH]E) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<&mut str>::h[HASH]) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<&mut str>) - --> $DIR/types.rs:139:5 + --> $DIR/types.rs:225:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b35Type$LT$$u5b$u8$u3b$$u20$0$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[u8; 0]>::h[HASH]) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[u8; 0]>) - --> $DIR/types.rs:145:5 + --> $DIR/types.rs:234:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b22Type$LT$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:151:5 + --> $DIR/types.rs:243:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b60Type$LT$unsafe$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RP$$GT$17h[HASH]E) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type::h[HASH]) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type) - --> $DIR/types.rs:157:5 + --> $DIR/types.rs:252:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: symbol-name(_ZN1a1b34Type$LT$$u5b$T$u3b$$u20$N$u5d$$GT$17h[HASH]E) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling(a::b::Type<[T; N]>::h[HASH]) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ error: demangling-alt(a::b::Type<[T; N]>) - --> $DIR/types.rs:163:5 + --> $DIR/types.rs:261:5 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 78 previous errors +error: aborting due to 84 previous errors diff --git a/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs new file mode 100644 index 000000000000..6567f2752404 --- /dev/null +++ b/tests/ui/traits/next-solver/typeck/normalize-in-upvar-collection.rs @@ -0,0 +1,19 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// Fixes a regression in icu_provider_adaptors where we weren't normalizing the +// return type of a function type before performing a `Ty::builtin_deref` call, +// leading to an ICE. + +struct Struct { + field: i32, +} + +fn hello(f: impl Fn() -> &'static Box<[i32]>, f2: impl Fn() -> &'static Struct) { + let cl = || { + let x = &f()[0]; + let y = &f2().field; + }; +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs b/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs new file mode 100644 index 000000000000..1bb0acf9b754 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/static-lifetime-through-closure-issue-122775.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![feature(type_alias_impl_trait)] + +fn spawn(future: F) -> impl Sized +where + F: FnOnce() -> T, +{ + future +} + +fn spawn_task(sender: &'static ()) -> impl Sized { + type Tait = impl Sized + 'static; + spawn::(move || sender) +} + +fn main() {} diff --git a/tests/ui/unpretty/pretty-let-else.rs b/tests/ui/unpretty/let-else-hir.rs similarity index 100% rename from tests/ui/unpretty/pretty-let-else.rs rename to tests/ui/unpretty/let-else-hir.rs diff --git a/tests/ui/unpretty/pretty-let-else.stdout b/tests/ui/unpretty/let-else-hir.stdout similarity index 100% rename from tests/ui/unpretty/pretty-let-else.stdout rename to tests/ui/unpretty/let-else-hir.stdout diff --git a/tests/ui/unpretty/let-else.rs b/tests/ui/unpretty/let-else.rs new file mode 100644 index 000000000000..4db6eca99b18 --- /dev/null +++ b/tests/ui/unpretty/let-else.rs @@ -0,0 +1,11 @@ +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +macro_rules! expr { + ($e:expr) => { $e }; +} + +fn main() { + let _ = expr!(1 + 1) else { return; }; + let _ = expr!(loop {}) else { return; }; +} diff --git a/tests/ui/unpretty/let-else.stdout b/tests/ui/unpretty/let-else.stdout new file mode 100644 index 000000000000..4bc4d9e085f9 --- /dev/null +++ b/tests/ui/unpretty/let-else.stdout @@ -0,0 +1,15 @@ +#![feature(prelude_import)] +#![no_std] +#[prelude_import] +use ::std::prelude::rust_2015::*; +#[macro_use] +extern crate std; +//@ compile-flags: -Zunpretty=expanded +//@ check-pass + +macro_rules! expr { ($e:expr) => { $e }; } + +fn main() { + let _ = 1 + 1 else { return; }; + let _ = (loop {}) else { return; }; +} diff --git a/tests/ui/write-fmt-errors.rs b/tests/ui/write-fmt-errors.rs index f194e25b5567..1dafb9a784b3 100644 --- a/tests/ui/write-fmt-errors.rs +++ b/tests/ui/write-fmt-errors.rs @@ -1,9 +1,11 @@ //@ run-pass +//@ needs-unwind #![feature(io_error_uncategorized)] use std::fmt; use std::io::{self, Error, Write, sink}; +use std::panic::catch_unwind; struct ErrorDisplay; @@ -15,7 +17,6 @@ impl fmt::Display for ErrorDisplay { struct ErrorWriter; -const FORMAT_ERROR: io::ErrorKind = io::ErrorKind::Uncategorized; const WRITER_ERROR: io::ErrorKind = io::ErrorKind::NotConnected; impl Write for ErrorWriter { @@ -27,22 +28,28 @@ impl Write for ErrorWriter { } fn main() { - // Test that the error from the formatter is propagated. - let res = write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar"); - assert!(res.is_err(), "formatter error did not propagate"); - assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); - // Test that an underlying error is propagated let res = write!(ErrorWriter, "abc"); assert!(res.is_err(), "writer error did not propagate"); - // Writer error + // Test that the error from the formatter is detected. + let res = catch_unwind(|| write!(sink(), "{} {} {}", 1, ErrorDisplay, "bar")); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); + + // Writer error when there's some string before the first `{}` let res = write!(ErrorWriter, "abc {}", ErrorDisplay); assert!(res.is_err(), "writer error did not propagate"); assert_eq!(res.unwrap_err().kind(), WRITER_ERROR); - // Formatter error - let res = write!(ErrorWriter, "{} abc", ErrorDisplay); - assert!(res.is_err(), "formatter error did not propagate"); - assert_eq!(res.unwrap_err().kind(), FORMAT_ERROR); + // Formatter error when the `{}` comes first + let res = catch_unwind(|| write!(ErrorWriter, "{} abc", ErrorDisplay)); + let err = res.expect_err("formatter error did not lead to panic").downcast::<&str>().unwrap(); + assert!( + err.contains("formatting trait implementation returned an error"), + "unexpected panic: {}", err + ); } diff --git a/triagebot.toml b/triagebot.toml index dd6a03faaaff..ddab67017864 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -310,7 +310,7 @@ trigger_files = [ "configure", "Cargo.toml", "config.example.toml", - "src/stage0.json", + "src/stage0", "src/tools/compiletest", "src/tools/tidy", "src/tools/rustdoc-gui-test", @@ -370,7 +370,7 @@ trigger_files = [ [autolabel."T-release"] trigger_files = [ "RELEASES.md", - "src/stage0.json", + "src/stage0", "src/version" ] @@ -419,7 +419,7 @@ message_on_add = """\ - Priority? - Regression? - Notify people/groups? -- Needs `I-nominated`? +- Needs `I-{team}-nominated`? """ message_on_remove = "Issue #{number}'s prioritization request has been removed." message_on_close = "Issue #{number} has been closed while requested for prioritization." @@ -933,11 +933,13 @@ arena = [ mir = [ "@davidtwco", "@oli-obk", - "@matthewjasper" + "@matthewjasper", + "@saethlin", ] mir-opt = [ "@oli-obk", "@wesleywiser", + "@saethlin", ] types = [ "@compiler-errors", @@ -1003,6 +1005,7 @@ project-exploit-mitigations = [ "/compiler/rustc_lexer" = ["compiler", "lexer"] "/compiler/rustc_llvm" = ["@cuviper"] "/compiler/rustc_codegen_llvm/src/debuginfo" = ["compiler", "debuginfo"] +"/compiler/rustc_codegen_ssa" = ["compiler", "@saethlin"] "/compiler/rustc_middle/src/mir" = ["compiler", "mir"] "/compiler/rustc_middle/src/traits" = ["compiler", "types"] "/compiler/rustc_middle/src/ty" = ["compiler", "types"] @@ -1046,7 +1049,7 @@ project-exploit-mitigations = [ "/src/librustdoc" = ["rustdoc"] "/src/llvm-project" = ["@cuviper"] "/src/rustdoc-json-types" = ["rustdoc"] -"/src/stage0.json" = ["bootstrap"] +"/src/stage0" = ["bootstrap"] "/tests/run-make" = ["@jieyouxu"] "/tests/ui" = ["compiler"] "/src/tools/cargo" = ["@ehuss"]