diff --git a/Cargo.lock b/Cargo.lock index 54b1bf593e0a..ba8b2c270059 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5a59f105fb9635e9eebdc1e29d53e764fa5795b9cf899a638a53e61567ef61" +checksum = "086b0afab3b349e5691143adbfb26983821e3eec4ba4c51957104d372c2e1b7d" dependencies = [ "anstyle", "unicode-width", @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" dependencies = [ "windows-sys 0.52.0", ] @@ -266,7 +266,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -501,9 +501,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" [[package]] name = "cfg-if" @@ -568,9 +568,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.4" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7" dependencies = [ "clap_builder", "clap_derive", @@ -588,9 +588,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df" dependencies = [ "anstream", "anstyle", @@ -601,30 +601,30 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.2" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" +checksum = "d2020fa13af48afc65a9a87335bda648309ab3d154cd03c7ff95b378c7ed39c4" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" [[package]] name = "clippy" @@ -644,7 +644,7 @@ dependencies = [ "regex", "rustc_tools_util", "serde", - "syn 2.0.64", + "syn 2.0.66", "tempfile", "termize", "tokio", @@ -754,7 +754,7 @@ dependencies = [ "nom", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -878,18 +878,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -915,9 +915,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -990,7 +990,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1001,7 +1001,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1027,7 +1027,7 @@ version = "0.1.80" dependencies = [ "itertools 0.12.1", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1068,7 +1068,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1078,7 +1078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1101,7 +1101,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1196,7 +1196,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1516,7 +1516,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1588,9 +1588,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1757,7 +1757,7 @@ dependencies = [ "markup5ever 0.12.1", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -1800,9 +1800,9 @@ dependencies = [ [[package]] name = "icu_list" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6c04ec71ad1bacdbfb47164d4801f80a0533d9340f94f1a880f521eff59f54" +checksum = "bbfeda1d7775b6548edd4e8b7562304a559a91ed56ab56e18961a053f367c365" dependencies = [ "displaydoc", "icu_list_data", @@ -1814,15 +1814,15 @@ dependencies = [ [[package]] name = "icu_list_data" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f6afcf7a9a7fedece70b7f17d7a7ecdfb8df145d37ae46d0277cd1e3932532" +checksum = "e1825170d2c6679cb20dbd96a589d034e49f698aed9a2ef4fafc9a0101ed298f" [[package]] name = "icu_locid" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0aa2536adc14c07e2a521e95512b75ed8ef832f0fdf9299d4a0a45d2be2a9d" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", @@ -1833,9 +1833,9 @@ dependencies = [ [[package]] name = "icu_locid_transform" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c17d8f6524fdca4471101dd71f0a132eb6382b5d6d7f2970441cb25f6f435a" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", @@ -1847,15 +1847,15 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c6c3e8bf9580e2dafee8de6f9ec14826aaf359787789c7724f1f85f47d3dc" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] name = "icu_provider" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba58e782287eb6950247abbf11719f83f5d4e4a5c1f2cd490d30a334bc47c2f4" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", @@ -1870,9 +1870,9 @@ dependencies = [ [[package]] name = "icu_provider_adapters" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a229f978260da7c3aabb68cb7dc7316589936680570fe55e50fdd3f97711a4dd" +checksum = "d6324dfd08348a8e0374a447ebd334044d766b1839bb8d5ccf2482a99a77c0bc" dependencies = [ "icu_locid", "icu_locid_transform", @@ -1883,13 +1883,13 @@ dependencies = [ [[package]] name = "icu_provider_macros" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2abdd3a62551e8337af119c5899e600ca0c88ec8f23a46c60ba216c803dcf1a" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -2196,9 +2196,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.16" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" +checksum = "c15da26e5af7e25c90b37a2d75cdbf940cf4a55316de9d84c679c9b8bfabf82e" dependencies = [ "cc", "libc", @@ -2252,9 +2252,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d642685b028806386b2b6e75685faadd3eb65a85fff7df711ce18446a422da" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" [[package]] name = "lld-wrapper" @@ -2415,7 +2415,7 @@ dependencies = [ "pulldown-cmark-to-cmark", "serde_json", "thiserror", - "toml 0.8.13", + "toml 0.8.14", "xmlparser", ] @@ -2608,9 +2608,9 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.49.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c073d3c1930d0751774acf49e66653acecb416c3a54c6ec095a9b11caddb5a68" +checksum = "dd2800e1520bdc966782168a627aa5d1ad92e33b984bf7c7615d31280c83ff14" dependencies = [ "windows-sys 0.48.0", ] @@ -2849,9 +2849,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2931,7 +2931,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -3142,9 +3142,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" dependencies = [ "unicode-ident", ] @@ -3246,9 +3246,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47196f636c4cc0634b73b0405323d177753c2e15e866952c64ea22902567a34" +checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -3627,7 +3627,6 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "smallvec", ] [[package]] @@ -3708,7 +3707,6 @@ dependencies = [ "icu_locid", "icu_locid_transform", "icu_provider", - "icu_provider_adapters", "zerovec", ] @@ -3889,7 +3887,6 @@ dependencies = [ "portable-atomic", "rustc-hash", "rustc-rayon", - "rustc-rayon-core", "rustc_arena", "rustc_graphviz", "rustc_index", @@ -3930,7 +3927,6 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_fluent_macro", - "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", "rustc_hir_typeck", @@ -4058,7 +4054,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "unic-langid", ] @@ -4192,8 +4188,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", - "synstructure", + "syn 2.0.66", ] [[package]] @@ -4341,7 +4336,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -4385,7 +4380,6 @@ dependencies = [ "field-offset", "gsgdt", "polonius-engine", - "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", "rustc_arena", @@ -4417,7 +4411,6 @@ dependencies = [ name = "rustc_mir_build" version = "0.0.0" dependencies = [ - "either", "itertools 0.12.1", "rustc_apfloat", "rustc_arena", @@ -4436,7 +4429,6 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_trait_selection", - "smallvec", "tracing", ] @@ -4511,14 +4503,7 @@ dependencies = [ name = "rustc_next_trait_solver" version = "0.0.0" dependencies = [ - "derivative", - "rustc_ast_ir", - "rustc_data_structures", - "rustc_macros", - "rustc_serialize", "rustc_type_ir", - "rustc_type_ir_macros", - "tracing", ] [[package]] @@ -4623,7 +4608,6 @@ version = "0.0.0" dependencies = [ "field-offset", "measureme", - "rustc-rayon-core", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4920,7 +4904,7 @@ version = "0.0.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -5018,7 +5002,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5154,22 +5138,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5281,9 +5265,9 @@ dependencies = [ [[package]] name = "spanned" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccdf4f5590b7e6fbd4f2e80d442789079a6fff7c12ef921a9de358b7b353098e" +checksum = "ed14ba8b4b82241bd5daba2c49185d4a0581a0058355fe96537338f002b8605d" dependencies = [ "bstr", "color-eyre", @@ -5329,7 +5313,6 @@ name = "stable_mir" version = "0.1.0-preview" dependencies = [ "scoped-tls", - "tracing", ] [[package]] @@ -5463,9 +5446,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.64" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ad3dee41f36859875573074334c200d1add8e4a87bb37113ebd31d926b7b11f" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -5480,7 +5463,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5540,9 +5523,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" dependencies = [ "filetime", "libc", @@ -5625,8 +5608,6 @@ dependencies = [ "core", "getopts", "libc", - "panic_abort", - "panic_unwind", "std", ] @@ -5659,7 +5640,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5744,9 +5725,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", @@ -5769,9 +5750,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -5801,14 +5782,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.13", + "toml_edit 0.22.14", ] [[package]] @@ -5835,15 +5816,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.8", + "winnow 0.6.13", ] [[package]] @@ -5872,7 +5853,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] @@ -5927,11 +5908,11 @@ dependencies = [ [[package]] name = "tracing-tree" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65139ecd2c3f6484c3b99bc01c77afe21e95473630747c7aca525e78b0666675" +checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe" dependencies = [ - "nu-ansi-term 0.49.0", + "nu-ansi-term 0.50.0", "tracing-core", "tracing-log", "tracing-subscriber", @@ -6011,7 +5992,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29e5f4ffcbab82453958fbf59990e981b8e8a177dcd60c2bd8f9b52c3036a6e1" dependencies = [ - "annotate-snippets 0.11.2", + "annotate-snippets 0.11.3", "anyhow", "bstr", "cargo-platform", @@ -6072,7 +6053,7 @@ checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.64", + "syn 2.0.66", "unic-langid-impl", ] @@ -6143,9 +6124,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -6222,9 +6203,9 @@ checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" @@ -6304,7 +6285,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -6326,7 +6307,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6407,7 +6388,7 @@ dependencies = [ "rayon", "serde", "serde_json", - "syn 2.0.64", + "syn 2.0.66", "windows-metadata", ] @@ -6576,18 +6557,18 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.8" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" dependencies = [ "memchr", ] [[package]] name = "writeable" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad7bb64b8ef9c0aa27b6da38b452b0ee9fd82beaf276a87dd796fb55cbae14e" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "xattr" @@ -6635,9 +6616,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e71b2e4f287f467794c671e2b8f8a5f3716b3c829079a1c44740148eff07e4" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ "serde", "stable_deref_trait", @@ -6647,13 +6628,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6936f0cce458098a201c245a11bef556c6a0181129c7034d10d76d1ec3a2b8" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] @@ -6674,35 +6655,35 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] [[package]] name = "zerofrom" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", "synstructure", ] [[package]] name = "zerovec" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff4439ae91fb5c72b8abc12f3f2dbf51bd27e6eadb9f8a5bc8898dddb0e27ea" +checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c" dependencies = [ "yoke", "zerofrom", @@ -6711,11 +6692,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4e5997cbf58990550ef1f0e5124a05e47e1ebd33a84af25739be6031a62c20" +checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.64", + "syn 2.0.66", ] diff --git a/RELEASES.md b/RELEASES.md index 3080f03c7210..c1311ab14c53 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,131 @@ +Version 1.79.0 (2024-06-13) +========================== + + + +Language +-------- +- [Stabilize inline `const {}` expressions.](https://github.com/rust-lang/rust/pull/104087/) +- [Prevent opaque types being instantiated twice with different regions within the same function.](https://github.com/rust-lang/rust/pull/116935/) +- [Stabilize WebAssembly target features that are in phase 4 and 5.](https://github.com/rust-lang/rust/pull/117457/) +- [Add the `redundant_lifetimes` lint to detect lifetimes which are semantically redundant.](https://github.com/rust-lang/rust/pull/118391/) +- [Stabilize the `unnameable_types` lint for public types that can't be named.](https://github.com/rust-lang/rust/pull/120144/) +- [Enable debuginfo in macros, and stabilize `-C collapse-macro-debuginfo` and `#[collapse_debuginfo]`.](https://github.com/rust-lang/rust/pull/120845/) +- [Propagate temporary lifetime extension into `if` and `match` expressions.](https://github.com/rust-lang/rust/pull/121346/) +- [Restrict promotion of `const fn` calls.](https://github.com/rust-lang/rust/pull/121557/) +- [Warn against refining impls of crate-private traits with `refining_impl_trait` lint.](https://github.com/rust-lang/rust/pull/121720/) +- [Stabilize associated type bounds (RFC 2289).](https://github.com/rust-lang/rust/pull/122055/) +- [Stabilize importing `main` from other modules or crates.](https://github.com/rust-lang/rust/pull/122060/) +- [Check return types of function types for well-formedness](https://github.com/rust-lang/rust/pull/115538) +- [Rework `impl Trait` lifetime inference](https://github.com/rust-lang/rust/pull/116891/) +- [Change inductive trait solver cycles to be ambiguous](https://github.com/rust-lang/rust/pull/122791) + + + +Compiler +-------- +- [Define `-C strip` to only affect binaries, not artifacts like `.pdb`.](https://github.com/rust-lang/rust/pull/115120/) +- [Stabilize `-Crelro-level` for controlling runtime link hardening.](https://github.com/rust-lang/rust/pull/121694/) +- [Stabilize checking of `cfg` names and values at compile-time with `--check-cfg`.](https://github.com/rust-lang/rust/pull/123501/) + *Note that this only stabilizes the compiler part, the Cargo part is still unstable in this release.* +- [Add `aarch64-apple-visionos` and `aarch64-apple-visionos-sim` tier 3 targets.](https://github.com/rust-lang/rust/pull/121419/) +- [Add `riscv32ima-unknown-none-elf` tier 3 target.](https://github.com/rust-lang/rust/pull/122696/) +- [Promote several Windows targets to tier 2](https://github.com/rust-lang/rust/pull/121712): `aarch64-pc-windows-gnullvm`, `i686-pc-windows-gnullvm`, and `x86_64-pc-windows-gnullvm`. + +Refer to Rust's [platform support page][platform-support-doc] +for more information on Rust's tiered platform support. + + + +Libraries +--------- + +- [Implement `FromIterator` for `(impl Default + Extend, impl Default + Extend)`.](https://github.com/rust-lang/rust/pull/107462/) +- [Implement `{Div,Rem}Assign>` on `X`.](https://github.com/rust-lang/rust/pull/121952/) +- [Document overrides of `clone_from()` in core/std.](https://github.com/rust-lang/rust/pull/122201/) +- [Link MSVC default lib in core.](https://github.com/rust-lang/rust/pull/122268/) +- [Caution against using `transmute` between pointers and integers.](https://github.com/rust-lang/rust/pull/122379/) +- [Enable frame pointers for the standard library.](https://github.com/rust-lang/rust/pull/122646/) + + + +Stabilized APIs +--------------- + +- [`{integer}::unchecked_add`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_add) +- [`{integer}::unchecked_mul`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_mul) +- [`{integer}::unchecked_sub`](https://doc.rust-lang.org/stable/core/primitive.i32.html#method.unchecked_sub) +- [`<[T]>::split_at_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_unchecked) +- [`<[T]>::split_at_mut_unchecked`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.split_at_mut_unchecked) +- [`<[u8]>::utf8_chunks`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.utf8_chunks) +- [`str::Utf8Chunks`](https://doc.rust-lang.org/stable/core/str/struct.Utf8Chunks.html) +- [`str::Utf8Chunk`](https://doc.rust-lang.org/stable/core/str/struct.Utf8Chunk.html) +- [`<*const T>::is_aligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_aligned) +- [`<*mut T>::is_aligned`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_aligned-1) +- [`NonNull::is_aligned`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.is_aligned) +- [`<*const [T]>::len`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.len) +- [`<*mut [T]>::len`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.len-1) +- [`<*const [T]>::is_empty`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_empty) +- [`<*mut [T]>::is_empty`](https://doc.rust-lang.org/stable/core/primitive.pointer.html#method.is_empty-1) +- [`NonNull::<[T]>::is_empty`](https://doc.rust-lang.org/stable/core/ptr/struct.NonNull.html#method.is_empty) +- [`CStr::count_bytes`](https://doc.rust-lang.org/stable/core/ffi/c_str/struct.CStr.html#method.count_bytes) +- [`io::Error::downcast`](https://doc.rust-lang.org/stable/std/io/struct.Error.html#method.downcast) +- [`num::NonZero`](https://doc.rust-lang.org/stable/core/num/struct.NonZero.html) +- [`path::absolute`](https://doc.rust-lang.org/stable/std/path/fn.absolute.html) +- [`proc_macro::Literal::byte_character`](https://doc.rust-lang.org/stable/proc_macro/struct.Literal.html#method.byte_character) +- [`proc_macro::Literal::c_string`](https://doc.rust-lang.org/stable/proc_macro/struct.Literal.html#method.c_string) + +These APIs are now stable in const contexts: + +- [`Atomic*::into_inner`](https://doc.rust-lang.org/stable/core/sync/atomic/struct.AtomicUsize.html#method.into_inner) +- [`io::Cursor::new`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.new) +- [`io::Cursor::get_ref`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_ref) +- [`io::Cursor::position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.position) +- [`io::empty`](https://doc.rust-lang.org/stable/std/io/fn.empty.html) +- [`io::repeat`](https://doc.rust-lang.org/stable/std/io/fn.repeat.html) +- [`io::sink`](https://doc.rust-lang.org/stable/std/io/fn.sink.html) +- [`panic::Location::caller`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.caller) +- [`panic::Location::file`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.file) +- [`panic::Location::line`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.line) +- [`panic::Location::column`](https://doc.rust-lang.org/stable/std/panic/struct.Location.html#method.column) + + + +Cargo +----- + +- [Prevent dashes in `lib.name`, always normalizing to `_`.](https://github.com/rust-lang/cargo/pull/12783/) +- [Stabilize MSRV-aware version requirement selection in `cargo add`.](https://github.com/rust-lang/cargo/pull/13608/) +- [Switch to using `gitoxide` by default for listing files.](https://github.com/rust-lang/cargo/pull/13696/) +- [Error on `[project]` in Edition 2024; `cargo fix --edition` will change it to `[package]`.](https://github.com/rust-lang/cargo/pull/13747/) + + + +Rustdoc +----- + +- [Always display stability version even if it's the same as the containing item.](https://github.com/rust-lang/rust/pull/118441/) +- [Show a single search result for items with multiple paths.](https://github.com/rust-lang/rust/pull/119912/) +- [Support typing `/` in docs to begin a search.](https://github.com/rust-lang/rust/pull/123355/) + + + +Misc +---- + + + +Compatibility Notes +------------------- + +- [Update the minimum external LLVM to 17.](https://github.com/rust-lang/rust/pull/122649/) +- [`RustcEncodable` and `RustcDecodable` are soft-destabilized, to be removed + from the prelude in next edition.](https://github.com/rust-lang/rust/pull/116016/) +- [The `wasm_c_abi` future-incompatibility lint will warn about use of the + non-spec-compliant C ABI.](https://github.com/rust-lang/rust/pull/117918/) + Use `wasm-bindgen v0.2.88` to generate forward-compatible bindings. +- [Check return types of function types for well-formedness](https://github.com/rust-lang/rust/pull/115538) + Version 1.78.0 (2024-05-02) ========================== diff --git a/compiler/rustc_ast_ir/Cargo.toml b/compiler/rustc_ast_ir/Cargo.toml index e761b7adad3f..a78c91e0615b 100644 --- a/compiler/rustc_ast_ir/Cargo.toml +++ b/compiler/rustc_ast_ir/Cargo.toml @@ -9,7 +9,6 @@ rustc_data_structures = { path = "../rustc_data_structures", optional = true } 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" } # tidy-alphabetical-end [features] diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml index 48af4e6f600b..e6cfb4887c91 100644 --- a/compiler/rustc_baked_icu_data/Cargo.toml +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -9,7 +9,6 @@ icu_list = "1.2" icu_locid = "1.2" icu_locid_transform = "1.3.2" icu_provider = "1.2" -icu_provider_adapters = "1.2" zerovec = "0.10.0" # tidy-alphabetical-end diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 963e5de91cef..6d26ca0b899b 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -832,9 +832,10 @@ fn codegen_stmt<'tcx>( let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(fx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => fx + .tcx + .offset_of_subfield(ParamEnv::reveal_all(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => { let val = fx.tcx.sess.ub_checks(); let val = CValue::by_val( diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index ba98f2e772cb..a53598018f4a 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -110,7 +110,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_some() { return CValue::const_val(fx, layout, int); } else { - let raw_val = int.size().truncate(int.assert_bits(int.size())); + let raw_val = int.size().truncate(int.to_bits(int.size())); let val = match int.size().bytes() { 1 => fx.bcx.ins().iconst(types::I8, raw_val as i64), 2 => fx.bcx.ins().iconst(types::I16, raw_val as i64), @@ -501,12 +501,12 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( Ordering::Equal => scalar_int, Ordering::Less => match ty.kind() { ty::Uint(_) => ScalarInt::try_from_uint( - scalar_int.assert_uint(scalar_int.size()), + scalar_int.to_uint(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), ty::Int(_) => ScalarInt::try_from_int( - scalar_int.assert_int(scalar_int.size()), + scalar_int.to_int(scalar_int.size()), fx.layout_of(*ty).size, ) .unwrap(), diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index 27b55ecc72ee..d454f3c1de7e 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -902,7 +902,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestri` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -955,7 +955,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Index argument for `_mm_cmpestrm` is not a constant"); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1003,7 +1003,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1040,7 +1040,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( ); }; - let imm8 = imm8.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", imm8)); + let imm8 = imm8.to_u8(); codegen_inline_asm_inner( fx, @@ -1195,7 +1195,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>( .span_fatal(span, "Func argument for `_mm_sha1rnds4_epu32` is not a constant"); }; - let func = func.try_to_u8().unwrap_or_else(|_| panic!("kind not scalar: {:?}", func)); + let func = func.to_u8(); codegen_inline_asm_inner( fx, diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 65eeaf156d84..ca910dccb0d0 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -147,8 +147,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let total_len = lane_count * 2; - let indexes = - idx.iter().map(|idx| idx.unwrap_leaf().try_to_u32().unwrap()).collect::>(); + let indexes = idx.iter().map(|idx| idx.unwrap_leaf().to_u32()).collect::>(); for &idx in &indexes { assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len); @@ -282,9 +281,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.tcx.dcx().span_fatal(span, "Index argument for `simd_insert` is not a constant"); }; - let idx: u32 = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx: u32 = idx_const.to_u32(); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( @@ -330,9 +327,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const - .try_to_u32() - .unwrap_or_else(|_| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.to_u32(); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if u64::from(idx) >= lane_count { fx.tcx.dcx().span_fatal( diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 512a96450a4b..1aa28daeafc7 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -327,7 +327,7 @@ impl<'tcx> CValue<'tcx> { let val = match layout.ty.kind() { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { - let const_val = const_val.assert_bits(layout.size); + let const_val = const_val.to_bits(layout.size); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) @@ -339,7 +339,7 @@ impl<'tcx> CValue<'tcx> { | ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) => { - let raw_val = const_val.size().truncate(const_val.assert_bits(layout.size)); + let raw_val = const_val.size().truncate(const_val.to_bits(layout.size)); fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F32) => { diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 78d943192db0..548c23cc7948 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -166,7 +166,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; match cv { Scalar::Int(int) => { - let data = int.assert_bits(layout.size(self)); + let data = int.to_bits(layout.size(self)); // FIXME(antoyo): there's some issues with using the u128 code that follows, so hard-code // the paths for floating-point values. diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index ab8036a1410f..4ffc92eb6335 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -244,7 +244,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let bitsize = if layout.is_bool() { 1 } else { layout.size(self).bits() }; match cv { Scalar::Int(int) => { - let data = int.assert_bits(layout.size(self)); + let data = int.to_bits(layout.size(self)); let llval = self.const_uint_big(self.type_ix(bitsize), data); if matches!(layout.primitive(), Pointer(_)) { unsafe { llvm::LLVMConstIntToPtr(llval, llty) } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 7b1038d56176..b5b0086f7405 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -1109,10 +1109,12 @@ fn generic_simd_intrinsic<'ll, 'tcx>( tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), callee_ty.fn_sig(tcx)); let arg_tys = sig.inputs(); - // Vectors must be immediates (non-power-of-2 #[repr(packed)] are not) - for (ty, arg) in arg_tys.iter().zip(args) { - if ty.is_simd() && !matches!(arg.val, OperandValue::Immediate(_)) { - return_error!(InvalidMonomorphization::SimdArgument { span, name, ty: *ty }); + // Sanity-check: all vector arguments must be immediates. + if cfg!(debug_assertions) { + for (ty, arg) in arg_tys.iter().zip(args) { + if ty.is_simd() { + assert!(matches!(arg.val, OperandValue::Immediate(_))); + } } } @@ -1221,7 +1223,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>( .iter() .enumerate() .map(|(arg_idx, val)| { - let idx = val.unwrap_leaf().try_to_i32().unwrap(); + let idx = val.unwrap_leaf().to_i32(); if idx >= i32::try_from(total_len).unwrap() { bx.sess().dcx().emit_err(InvalidMonomorphization::SimdIndexOutOfBounds { span, diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index e4a36b3f5918..27b0f127e926 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -163,7 +163,7 @@ pub fn asm_const_to_str<'tcx>( let mir::ConstValue::Scalar(scalar) = const_value else { span_bug!(sp, "expected Scalar for promoted asm const, but got {:#?}", const_value) }; - let value = scalar.assert_bits(ty_and_layout.size); + let value = scalar.assert_scalar_int().to_bits(ty_and_layout.size); match ty_and_layout.ty.kind() { ty::Uint(_) => value.to_string(), ty::Int(int_ty) => match int_ty.normalize(tcx.sess.target.pointer_width) { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index c23867be3a10..ad6b3f1159de 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -680,7 +680,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.cx().const_usize(val) } mir::NullOp::OffsetOf(fields) => { - let val = layout.offset_of_subfield(bx.cx(), fields.iter()).bytes(); + let val = bx + .tcx() + .offset_of_subfield(bx.param_env(), layout, fields.iter()) + .bytes(); bx.cx().const_usize(val) } mir::NullOp::UbChecks => { diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 5312f1f946f5..66993476bef4 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -95,10 +95,10 @@ fn const_to_valtree_inner<'tcx>( } ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { let val = ecx.read_immediate(place)?; - let val = val.to_scalar(); + let val = val.to_scalar_int().unwrap(); *num_nodes += 1; - Ok(ty::ValTree::Leaf(val.assert_int())) + Ok(ty::ValTree::Leaf(val)) } ty::Pat(base, ..) => { @@ -125,7 +125,7 @@ fn const_to_valtree_inner<'tcx>( let val = val.to_scalar(); // We are in the CTFE machine, so ptr-to-int casts will fail. // This can only be `Ok` if `val` already is an integer. - let Ok(val) = val.try_to_int() else { + let Ok(val) = val.try_to_scalar_int() else { return Err(ValTreeCreationError::NonSupportedType); }; // It's just a ScalarInt! @@ -411,7 +411,7 @@ fn valtree_into_mplace<'tcx>( ty::Adt(def, _) if def.is_enum() => { // First element of valtree corresponds to variant let scalar_int = branches[0].unwrap_leaf(); - let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap()); + let variant_idx = VariantIdx::from_u32(scalar_int.to_u32()); let variant = def.variant(variant_idx); debug!(?variant); diff --git a/compiler/rustc_const_eval/src/interpret/discriminant.rs b/compiler/rustc_const_eval/src/interpret/discriminant.rs index 67fbf9642bf0..0dbee8c1d948 100644 --- a/compiler/rustc_const_eval/src/interpret/discriminant.rs +++ b/compiler/rustc_const_eval/src/interpret/discriminant.rs @@ -123,14 +123,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // (`tag_bits` itself is only used for error messages below.) let tag_bits = tag_val .to_scalar() - .try_to_int() + .try_to_scalar_int() .map_err(|dbg_val| err_ub!(InvalidTag(dbg_val)))? - .assert_bits(tag_layout.size); + .to_bits(tag_layout.size); // Cast bits from tag layout to discriminant layout. // After the checks we did above, this cannot fail, as // discriminants are int-like. let discr_val = self.int_to_int_or_float(&tag_val, discr_layout).unwrap(); - let discr_bits = discr_val.to_scalar().assert_bits(discr_layout.size); + let discr_bits = discr_val.to_scalar().to_bits(discr_layout.size)?; // Convert discriminant to variant index, and catch invalid discriminants. let index = match *ty.kind() { ty::Adt(adt, _) => { @@ -152,7 +152,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // discriminant (encoded in niche/tag) and variant index are the same. let variants_start = niche_variants.start().as_u32(); let variants_end = niche_variants.end().as_u32(); - let variant = match tag_val.try_to_int() { + let variant = match tag_val.try_to_scalar_int() { Err(dbg_val) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. @@ -167,7 +167,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { untagged_variant } Ok(tag_bits) => { - let tag_bits = tag_bits.assert_bits(tag_layout.size); + let tag_bits = tag_bits.to_bits(tag_layout.size); // We need to use machine arithmetic to get the relative variant idx: // variant_index_relative = tag_val - niche_start_val let tag_val = ImmTy::from_uint(tag_bits, tag_layout); @@ -175,7 +175,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let variant_index_relative_val = self.binary_op(mir::BinOp::Sub, &tag_val, &niche_start_val)?; let variant_index_relative = - variant_index_relative_val.to_scalar().assert_bits(tag_val.layout.size); + variant_index_relative_val.to_scalar().to_bits(tag_val.layout.size)?; // Check if this is in the range that indicates an actual discriminant. if variant_index_relative <= u128::from(variants_end - variants_start) { let variant_index_relative = u32::try_from(variant_index_relative) @@ -294,8 +294,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { ImmTy::from_uint(variant_index_relative, tag_layout); let tag = self .binary_op(mir::BinOp::Add, &variant_index_relative_val, &niche_start_val)? - .to_scalar() - .assert_int(); + .to_scalar_int()?; Ok(Some((tag, tag_field))) } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 18b76443cd95..dac5c10addc2 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`. // First, check x % y != 0 (or if that computation overflows). let rem = self.binary_op(BinOp::Rem, a, b)?; - if rem.to_scalar().assert_bits(a.layout.size) != 0 { + if rem.to_scalar().to_bits(a.layout.size)? != 0 { throw_ub_custom!( fluent::const_eval_exact_div_has_remainder, a = format!("{a}"), diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 521f28b7123e..7eb73e9b52f6 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -1344,7 +1344,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Test if this value might be null. /// If the machine does not support ptr-to-int casts, this is conservative. pub fn scalar_may_be_null(&self, scalar: Scalar) -> InterpResult<'tcx, bool> { - Ok(match scalar.try_to_int() { + Ok(match scalar.try_to_scalar_int() { Ok(int) => int.is_null(), Err(_) => { // Can only happen during CTFE. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index bbb2c2f39385..0a7e9853763f 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -87,6 +87,12 @@ impl Immediate { } } + #[inline] + #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) + pub fn to_scalar_int(self) -> ScalarInt { + self.to_scalar().try_to_scalar_int().unwrap() + } + #[inline] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn to_scalar_pair(self) -> (Scalar, Scalar) { @@ -219,19 +225,11 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { Self::from_scalar(Scalar::from(s), layout) } - #[inline] - pub fn try_from_uint(i: impl Into, layout: TyAndLayout<'tcx>) -> Option { - Some(Self::from_scalar(Scalar::try_from_uint(i, layout.size)?, layout)) - } #[inline] pub fn from_uint(i: impl Into, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_uint(i, layout.size), layout) } - #[inline] - pub fn try_from_int(i: impl Into, layout: TyAndLayout<'tcx>) -> Option { - Some(Self::from_scalar(Scalar::try_from_int(i, layout.size)?, layout)) - } #[inline] pub fn from_int(i: impl Into, layout: TyAndLayout<'tcx>) -> Self { Self::from_scalar(Scalar::from_int(i, layout.size), layout) @@ -276,7 +274,8 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> { #[inline] pub fn to_const_int(self) -> ConstInt { assert!(self.layout.ty.is_integral()); - let int = self.to_scalar().assert_int(); + let int = self.imm.to_scalar_int(); + assert_eq!(int.size(), self.layout.size); ConstInt::new(int, self.layout.ty.is_signed(), self.layout.ty.is_ptr_sized_integral()) } diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 6d005dfcd864..c821c98073d7 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -95,10 +95,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { let l = left.to_scalar_int()?; let r = right.to_scalar_int()?; // Prepare to convert the values to signed or unsigned form. - let l_signed = || l.assert_int(left.layout.size); - let l_unsigned = || l.assert_uint(left.layout.size); - let r_signed = || r.assert_int(right.layout.size); - let r_unsigned = || r.assert_uint(right.layout.size); + let l_signed = || l.to_int(left.layout.size); + let l_unsigned = || l.to_uint(left.layout.size); + let r_signed = || r.to_int(right.layout.size); + let r_unsigned = || r.to_uint(right.layout.size); let throw_ub_on_overflow = match bin_op { AddUnchecked => Some(sym::unchecked_add), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 4a86ec3f57a4..046ff34e3d07 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -499,13 +499,14 @@ where &self, mplace: &MPlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> { - // Basically we just transmute this place into an array following simd_size_and_type. - // (Transmuting is okay since this is an in-memory place. We also double-check the size - // stays the same.) + // Basically we want to transmute this place into an array following simd_size_and_type. let (len, e_ty) = mplace.layout.ty.simd_size_and_type(*self.tcx); - let array = Ty::new_array(self.tcx.tcx, e_ty, len); - let layout = self.layout_of(array)?; - let mplace = mplace.transmute(layout, self)?; + // Some SIMD types have padding, so `len` many `e_ty` does not cover the entire place. + // Therefore we cannot transmute, and instead we project at offset 0, which side-steps + // the size check. + let array_layout = self.layout_of(Ty::new_array(self.tcx.tcx, e_ty, len))?; + assert!(array_layout.size <= mplace.layout.size); + let mplace = mplace.offset(Size::ZERO, array_layout, self)?; Ok((mplace, len)) } diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 0e594914c3a7..09e1a59dfa1a 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -81,6 +81,8 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug { ecx: &InterpCx<'tcx, M>, ) -> InterpResult<'tcx, Self> { assert!(layout.is_sized()); + // We sometimes do pointer arithmetic with this function, disregarding the source type. + // So we don't check the sizes here. self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx) } diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index d0bb821862aa..1baf62baa816 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -253,7 +253,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Scalar::from_target_usize(val, self) } mir::NullOp::OffsetOf(fields) => { - let val = layout.offset_of_subfield(self, fields.iter()).bytes(); + let val = self + .tcx + .offset_of_subfield(self.param_env, layout, fields.iter()) + .bytes(); Scalar::from_target_usize(val, self) } mir::NullOp::UbChecks => Scalar::from_bool(self.tcx.sess.ub_checks()), diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 3407c7b8c792..f532f6bbe371 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -653,8 +653,8 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { let WrappingRange { start, end } = valid_range; let max_value = size.unsigned_int_max(); assert!(end <= max_value); - let bits = match scalar.try_to_int() { - Ok(int) => int.assert_bits(size), + let bits = match scalar.try_to_scalar_int() { + Ok(int) => int.to_bits(size), Err(_) => { // So this is a pointer then, and casting to an int failed. // Can only happen during CTFE. diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 2b61e17efa28..6876046a5838 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -16,7 +16,6 @@ libc = "0.2" measureme = "11" rustc-hash = "1.1.0" rustc-rayon = { version = "0.5.0", optional = true } -rustc-rayon-core = { version = "0.5.0", optional = true } rustc_arena = { path = "../rustc_arena" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_index = { path = "../rustc_index", package = "rustc_index" } @@ -52,5 +51,5 @@ portable-atomic = "1.5.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon", "rustc-rayon-core"] +rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon"] # tidy-alphabetical-end diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 5f7504add8d6..91cbffcd7072 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -19,7 +19,6 @@ rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } -rustc_hir = { path = "../rustc_hir" } rustc_hir_analysis = { path = "../rustc_hir_analysis" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_hir_typeck = { path = "../rustc_hir_typeck" } diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 3196b8260854..25e961d60090 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -30,11 +30,11 @@ impl MutVisitor for Marker { // it's some advanced case with macro-generated macros. So if we cache the marked version // of that context once, we'll typically have a 100% cache hit rate after that. let Marker(expn_id, transparency, ref mut cache) = *self; - let data = span.data(); - let marked_ctxt = *cache - .entry(data.ctxt) - .or_insert_with(|| data.ctxt.apply_mark(expn_id.to_expn_id(), transparency)); - *span = data.with_ctxt(marked_ctxt); + span.update_ctxt(|ctxt| { + *cache + .entry(ctxt) + .or_insert_with(|| ctxt.apply_mark(expn_id.to_expn_id(), transparency)) + }); } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index d67422849d8a..2410019868a1 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -559,6 +559,8 @@ declare_features! ( (unstable, offset_of_enum, "1.75.0", Some(120141)), /// Allows using multiple nested field accesses in offset_of! (unstable, offset_of_nested, "1.77.0", Some(120140)), + /// Allows using fields with slice type in offset_of! + (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows postfix match `expr.match { ... }` diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5d30b2a71e09..d2a5924c8bbb 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -827,7 +827,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) else { return; }; - let in_scope_methods = self.probe_for_name_many( + + let Ok(in_scope_methods) = self.probe_for_name_many( probe::Mode::MethodCall, path.ident, Some(expected), @@ -835,11 +836,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, deref.hir_id, probe::ProbeScope::TraitsInScope, - ); + ) else { + return; + }; + let other_methods_in_scope: Vec<_> = in_scope_methods.iter().filter(|c| c.item.def_id != pick.item.def_id).collect(); - let all_methods = self.probe_for_name_many( + let Ok(all_methods) = self.probe_for_name_many( probe::Mode::MethodCall, path.ident, Some(expected), @@ -847,7 +851,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, deref.hir_id, probe::ProbeScope::AllTraits, - ); + ) else { + return; + }; + let suggestions: Vec<_> = all_methods .into_iter() .filter(|c| c.item.def_id != pick.item.def_id) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index d5d360ca0479..5b27ebe3416a 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3363,7 +3363,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let field_ty = self.field_ty(expr.span, field, args); - // FIXME: DSTs with static alignment should be allowed + // Enums are anyway always sized. But just to safeguard against future + // language extensions, let's double-check. self.require_type_is_sized(field_ty, expr.span, ObligationCauseCode::Misc); if field.vis.is_accessible_from(sub_def_scope, self.tcx) { @@ -3391,8 +3392,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let field_ty = self.field_ty(expr.span, field, args); - // FIXME: DSTs with static alignment should be allowed - self.require_type_is_sized(field_ty, expr.span, ObligationCauseCode::Misc); + if self.tcx.features().offset_of_slice { + self.require_type_has_static_alignment( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } else { + self.require_type_is_sized( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } if field.vis.is_accessible_from(def_scope, self.tcx) { self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); @@ -3412,10 +3424,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Ok(index) = field.as_str().parse::() && field.name == sym::integer(index) { - for ty in tys.iter().take(index + 1) { - self.require_type_is_sized(ty, expr.span, ObligationCauseCode::Misc); - } if let Some(&field_ty) = tys.get(index) { + if self.tcx.features().offset_of_slice { + self.require_type_has_static_alignment( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } else { + self.require_type_is_sized( + field_ty, + expr.span, + ObligationCauseCode::Misc, + ); + } + field_indices.push((FIRST_VARIANT, index.into())); current_container = field_ty; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 85c6d4dc12c5..e354e1ec59c6 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -386,6 +386,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + pub fn require_type_has_static_alignment( + &self, + ty: Ty<'tcx>, + span: Span, + code: traits::ObligationCauseCode<'tcx>, + ) { + if !ty.references_error() { + let tail = + self.tcx.struct_tail_with_normalize(ty, |ty| self.normalize(span, ty), || {}); + // Sized types have static alignment, and so do slices. + if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) { + // Nothing else is required here. + } else { + // We can't be sure, let's required full `Sized`. + let lang_item = self.tcx.require_lang_item(LangItem::Sized, None); + self.require_type_meets(ty, span, code, lang_item); + } + } + } + pub fn register_bound( &self, ty: Ty<'tcx>, diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ab0f16bd87d0..e842bba34bf8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -306,7 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty: Ty<'tcx>, scope_expr_id: HirId, scope: ProbeScope, - ) -> Vec> { + ) -> Result>, MethodError<'tcx>> { self.probe_op( item_name.span, mode, @@ -324,7 +324,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect()) }, ) - .unwrap() } pub(crate) fn probe_op( diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index c1e14f7fb753..bbe4a8791c69 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1640,10 +1640,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(Ty::new_misc_error(self.tcx)), ); - // FIXME: `probe_for_name_many` searches for methods in inherent implementations, - // so it may return a candidate that doesn't belong to this `revr_ty`. We need to - // check whether the instantiated type matches the received one. - for _matched_method in self.probe_for_name_many( + let Ok(candidates) = self.probe_for_name_many( Mode::MethodCall, item_name, None, @@ -1651,7 +1648,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { rcvr_ty, source_expr.hir_id, ProbeScope::TraitsInScope, - ) { + ) else { + return; + }; + + // FIXME: `probe_for_name_many` searches for methods in inherent implementations, + // so it may return a candidate that doesn't belong to this `revr_ty`. We need to + // check whether the instantiated type matches the received one. + for _matched_method in candidates { // found a match, push to stack stack_methods.push(rcvr_ty); } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index be91e7d45b61..9476dc704831 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2385,11 +2385,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { min_len: u64, ) -> (Option>, Ty<'tcx>) { let len = match len.eval(self.tcx, self.param_env, span) { - // FIXME(BoxyUwU): Assert the `Ty` is a `usize`? Ok((_, val)) => val .try_to_scalar() - .and_then(|scalar| scalar.try_to_int().ok()) - .and_then(|int| int.try_to_target_usize(self.tcx).ok()), + .and_then(|scalar| scalar.try_to_scalar_int().ok()) + .map(|int| int.to_target_usize(self.tcx)), Err(ErrorHandled::Reported(..)) => { let guar = self.error_scrutinee_unfixed_length(span); return (Some(Ty::new_error(self.tcx, guar)), arr_ty); diff --git a/compiler/rustc_index_macros/Cargo.toml b/compiler/rustc_index_macros/Cargo.toml index c4ca29db3c2d..07ee81788ce4 100644 --- a/compiler/rustc_index_macros/Cargo.toml +++ b/compiler/rustc_index_macros/Cargo.toml @@ -7,11 +7,10 @@ edition = "2021" proc-macro = true [dependencies] -synstructure = "0.13.0" syn = { version = "2.0.9", features = ["full"] } proc-macro2 = "1" quote = "1" [features] default = ["nightly"] -nightly = [] \ No newline at end of file +nightly = [] diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b88677b3a4ec..effb4090692c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -32,6 +32,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { diag.note("no two closures, even if identical, have the same type"); diag.help("consider boxing your closure and/or using it as a trait object"); } + (ty::Coroutine(def_id1, ..), ty::Coroutine(def_id2, ..)) + if self.tcx.coroutine_is_async(def_id1) + && self.tcx.coroutine_is_async(def_id2) => + { + diag.note("no two async blocks, even if identical, have the same type"); + diag.help( + "consider pinning your async block and casting it to a trait object", + ); + } (ty::Alias(ty::Opaque, ..), ty::Alias(ty::Opaque, ..)) => { // Issue #63167 diag.note("distinct uses of `impl Trait` result in different opaque types"); diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index d1cdabc293dd..3dc592980fdb 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -11,7 +11,6 @@ either = "1.5.0" field-offset = "0.3.5" gsgdt = "0.1.2" polonius-engine = "0.13.0" -rustc-rayon = { version = "0.5.0", optional = true } rustc-rayon-core = { version = "0.5.0", optional = true } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } @@ -41,5 +40,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon", "rustc-rayon-core"] +rustc_use_parallel_compiler = ["rustc-rayon-core"] # tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index cc8979dd990e..89f5acacf9d1 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -84,11 +84,11 @@ impl<'tcx> ConstValue<'tcx> { } pub fn try_to_scalar_int(&self) -> Option { - self.try_to_scalar()?.try_to_int().ok() + self.try_to_scalar()?.try_to_scalar_int().ok() } pub fn try_to_bits(&self, size: Size) -> Option { - self.try_to_scalar_int()?.try_to_bits(size).ok() + Some(self.try_to_scalar_int()?.to_bits(size)) } pub fn try_to_bool(&self) -> Option { @@ -96,7 +96,7 @@ impl<'tcx> ConstValue<'tcx> { } pub fn try_to_target_usize(&self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int()?.try_to_target_usize(tcx).ok() + Some(self.try_to_scalar_int()?.to_target_usize(tcx)) } pub fn try_to_bits_for_ty( @@ -300,7 +300,7 @@ impl<'tcx> Const<'tcx> { #[inline] pub fn try_to_bits(self, size: Size) -> Option { - self.try_to_scalar_int()?.try_to_bits(size).ok() + Some(self.try_to_scalar_int()?.to_bits(size)) } #[inline] @@ -367,7 +367,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.try_eval_scalar(tcx, param_env)?.try_to_int().ok() + self.try_eval_scalar(tcx, param_env)?.try_to_scalar_int().ok() } #[inline] @@ -375,7 +375,7 @@ impl<'tcx> Const<'tcx> { let int = self.try_eval_scalar_int(tcx, param_env)?; let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(self.ty())).ok()?.size; - int.try_to_bits(size).ok() + Some(int.to_bits(size)) } /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. @@ -391,7 +391,7 @@ impl<'tcx> Const<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Option { - self.try_eval_scalar_int(tcx, param_env)?.try_to_target_usize(tcx).ok() + Some(self.try_eval_scalar_int(tcx, param_env)?.to_target_usize(tcx)) } #[inline] diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index 853572656879..70e5ad0635ba 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -122,16 +122,12 @@ impl Scalar { Scalar::Int(c.into()) } - #[inline] - pub fn try_from_uint(i: impl Into, size: Size) -> Option { - ScalarInt::try_from_uint(i, size).map(Scalar::Int) - } - #[inline] pub fn from_uint(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_uint(i, size) + ScalarInt::try_from_uint(i, size) .unwrap_or_else(|| bug!("Unsigned value {:#x} does not fit in {} bits", i, size.bits())) + .into() } #[inline] @@ -164,16 +160,12 @@ impl Scalar { Self::from_uint(i, cx.data_layout().pointer_size) } - #[inline] - pub fn try_from_int(i: impl Into, size: Size) -> Option { - ScalarInt::try_from_int(i, size).map(Scalar::Int) - } - #[inline] pub fn from_int(i: impl Into, size: Size) -> Self { let i = i.into(); - Self::try_from_int(i, size) + ScalarInt::try_from_int(i, size) .unwrap_or_else(|| bug!("Signed value {:#x} does not fit in {} bits", i, size.bits())) + .into() } #[inline] @@ -227,7 +219,7 @@ impl Scalar { } /// This is almost certainly not the method you want! You should dispatch on the type - /// and use `to_{u8,u16,...}`/`scalar_to_ptr` to perform ptr-to-int / int-to-ptr casts as needed. + /// and use `to_{u8,u16,...}`/`to_pointer` to perform ptr-to-int / int-to-ptr casts as needed. /// /// This method only exists for the benefit of low-level operations that truly need to treat the /// scalar in whatever form it is. @@ -289,7 +281,7 @@ impl<'tcx, Prov: Provenance> Scalar { /// The error type is `AllocId`, not `CtfeProvenance`, since `AllocId` is the "minimal" /// component all provenance types must have. #[inline] - pub fn try_to_int(self) -> Result> { + pub fn try_to_scalar_int(self) -> Result> { match self { Scalar::Int(int) => Ok(int), Scalar::Ptr(ptr, sz) => { @@ -307,13 +299,13 @@ impl<'tcx, Prov: Provenance> Scalar { #[inline(always)] pub fn to_scalar_int(self) -> InterpResult<'tcx, ScalarInt> { - self.try_to_int().map_err(|_| err_unsup!(ReadPointerAsInt(None)).into()) + self.try_to_scalar_int().map_err(|_| err_unsup!(ReadPointerAsInt(None)).into()) } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) - pub fn assert_int(self) -> ScalarInt { - self.try_to_int().unwrap() + pub fn assert_scalar_int(self) -> ScalarInt { + self.try_to_scalar_int().expect("got a pointer where a ScalarInt was expected") } /// This throws UB (instead of ICEing) on a size mismatch since size mismatches can arise in @@ -330,13 +322,6 @@ impl<'tcx, Prov: Provenance> Scalar { }) } - #[inline(always)] - #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) - pub fn assert_bits(self, target_size: Size) -> u128 { - self.to_bits(target_size) - .unwrap_or_else(|_| panic!("assertion failed: {self:?} fits {target_size:?}")) - } - pub fn to_bool(self) -> InterpResult<'tcx, bool> { let val = self.to_u8()?; match val { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 454897aa6720..7c8b0ec671a4 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1033,8 +1033,8 @@ impl<'tcx> PatRangeBoundary<'tcx> { if let (Some(a), Some(b)) = (a.try_to_scalar_int(), b.try_to_scalar_int()) { let sz = ty.primitive_size(tcx); let cmp = match ty.kind() { - ty::Uint(_) | ty::Char => a.assert_uint(sz).cmp(&b.assert_uint(sz)), - ty::Int(_) => a.assert_int(sz).cmp(&b.assert_int(sz)), + ty::Uint(_) | ty::Char => a.to_uint(sz).cmp(&b.to_uint(sz)), + ty::Int(_) => a.to_int(sz).cmp(&b.to_int(sz)), _ => unreachable!(), }; return Some(cmp); diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index cc1daeb64191..12f0c38b054a 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -376,7 +376,7 @@ impl<'tcx> Const<'tcx> { param_env: ParamEnv<'tcx>, ) -> Option<(Ty<'tcx>, ScalarInt)> { let (ty, scalar) = self.try_eval_scalar(tcx, param_env)?; - let val = scalar.try_to_int().ok()?; + let val = scalar.try_to_scalar_int().ok()?; Some((ty, val)) } @@ -388,7 +388,7 @@ impl<'tcx> Const<'tcx> { let (ty, scalar) = self.try_eval_scalar_int(tcx, param_env)?; let size = tcx.layout_of(param_env.with_reveal_all_normalized(tcx).and(ty)).ok()?.size; // if `ty` does not depend on generic parameters, use an empty param_env - scalar.try_to_bits(size).ok() + Some(scalar.to_bits(size)) } #[inline] @@ -405,7 +405,7 @@ impl<'tcx> Const<'tcx> { param_env: ParamEnv<'tcx>, ) -> Option { let (_, scalar) = self.try_eval_scalar_int(tcx, param_env)?; - scalar.try_to_target_usize(tcx).ok() + Some(scalar.to_target_usize(tcx)) } #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/int.rs b/compiler/rustc_middle/src/ty/consts/int.rs index 40ac87873a0a..52320dd141ba 100644 --- a/compiler/rustc_middle/src/ty/consts/int.rs +++ b/compiler/rustc_middle/src/ty/consts/int.rs @@ -246,6 +246,10 @@ impl ScalarInt { Self::try_from_uint(i, tcx.data_layout.pointer_size) } + /// Try to convert this ScalarInt to the raw underlying bits. + /// Fails if the size is wrong. Generally a wrong size should lead to a panic, + /// but Miri sometimes wants to be resilient to size mismatches, + /// so the interpreter will generally use this `try` method. #[inline] pub fn try_to_bits(self, target_size: Size) -> Result { assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST"); @@ -258,165 +262,149 @@ impl ScalarInt { } #[inline] - pub fn assert_bits(self, target_size: Size) -> u128 { + pub fn to_bits(self, target_size: Size) -> u128 { self.try_to_bits(target_size).unwrap_or_else(|size| { bug!("expected int of size {}, but got size {}", target_size.bytes(), size.bytes()) }) } - /// Tries to convert the `ScalarInt` to an unsigned integer of the given size. - /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the - /// `ScalarInt`s size in that case. + /// Extracts the bits from the scalar without checking the size. #[inline] - pub fn try_to_uint(self, size: Size) -> Result { - self.try_to_bits(size) + pub fn to_bits_unchecked(self) -> u128 { + self.check_data(); + self.data + } + + /// Converts the `ScalarInt` to an unsigned integer of the given size. + /// Panics if the size of the `ScalarInt` is not equal to `size`. + #[inline] + pub fn to_uint(self, size: Size) -> u128 { + self.to_bits(size) + } + + /// Converts the `ScalarInt` to `u8`. + /// Panics if the `size` of the `ScalarInt`in not equal to 1 byte. + #[inline] + pub fn to_u8(self) -> u8 { + self.to_uint(Size::from_bits(8)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u16`. + /// Panics if the size of the `ScalarInt` in not equal to 2 bytes. + #[inline] + pub fn to_u16(self) -> u16 { + self.to_uint(Size::from_bits(16)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u32`. + /// Panics if the `size` of the `ScalarInt` in not equal to 4 bytes. + #[inline] + pub fn to_u32(self) -> u32 { + self.to_uint(Size::from_bits(32)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u64`. + /// Panics if the `size` of the `ScalarInt` in not equal to 8 bytes. + #[inline] + pub fn to_u64(self) -> u64 { + self.to_uint(Size::from_bits(64)).try_into().unwrap() + } + + /// Converts the `ScalarInt` to `u128`. + /// Panics if the `size` of the `ScalarInt` in not equal to 16 bytes. + #[inline] + pub fn to_u128(self) -> u128 { + self.to_uint(Size::from_bits(128)) } #[inline] - pub fn assert_uint(self, size: Size) -> u128 { - self.assert_bits(size) + pub fn to_target_usize(&self, tcx: TyCtxt<'_>) -> u64 { + self.to_uint(tcx.data_layout.pointer_size).try_into().unwrap() } - // Tries to convert the `ScalarInt` to `u8`. Fails if the `size` of the `ScalarInt` - // in not equal to 1 byte and returns the `size` value of the `ScalarInt` in - // that case. + /// Converts the `ScalarInt` to `bool`. + /// Panics if the `size` of the `ScalarInt` is not equal to 1 byte. + /// Errors if it is not a valid `bool`. #[inline] - pub fn try_to_u8(self) -> Result { - self.try_to_uint(Size::from_bits(8)).map(|v| u8::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u16`. Fails if the size of the `ScalarInt` - /// in not equal to 2 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u16(self) -> Result { - self.try_to_uint(Size::from_bits(16)).map(|v| u16::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u32`. Fails if the `size` of the `ScalarInt` - /// in not equal to 4 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u32(self) -> Result { - self.try_to_uint(Size::from_bits(32)).map(|v| u32::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u64`. Fails if the `size` of the `ScalarInt` - /// in not equal to 8 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u64(self) -> Result { - self.try_to_uint(Size::from_bits(64)).map(|v| u64::try_from(v).unwrap()) - } - - /// Tries to convert the `ScalarInt` to `u128`. Fails if the `size` of the `ScalarInt` - /// in not equal to 16 bytes and returns the `size` value of the `ScalarInt` in - /// that case. - #[inline] - pub fn try_to_u128(self) -> Result { - self.try_to_uint(Size::from_bits(128)) - } - - #[inline] - pub fn try_to_target_usize(&self, tcx: TyCtxt<'_>) -> Result { - self.try_to_uint(tcx.data_layout.pointer_size).map(|v| u64::try_from(v).unwrap()) - } - - // Tries to convert the `ScalarInt` to `bool`. Fails if the `size` of the `ScalarInt` - // in not equal to 1 byte or if the value is not 0 or 1 and returns the `size` - // value of the `ScalarInt` in that case. - #[inline] - pub fn try_to_bool(self) -> Result { - match self.try_to_u8()? { + pub fn try_to_bool(self) -> Result { + match self.to_u8() { 0 => Ok(false), 1 => Ok(true), - _ => Err(self.size()), + _ => Err(()), } } - /// Tries to convert the `ScalarInt` to a signed integer of the given size. - /// Fails if the size of the `ScalarInt` is not equal to `size` and returns the - /// `ScalarInt`s size in that case. + /// Converts the `ScalarInt` to a signed integer of the given size. + /// Panics if the size of the `ScalarInt` is not equal to `size`. #[inline] - pub fn try_to_int(self, size: Size) -> Result { - let b = self.try_to_bits(size)?; - Ok(size.sign_extend(b) as i128) - } - - #[inline] - pub fn assert_int(self, size: Size) -> i128 { - let b = self.assert_bits(size); + pub fn to_int(self, size: Size) -> i128 { + let b = self.to_bits(size); size.sign_extend(b) as i128 } - /// Tries to convert the `ScalarInt` to i8. - /// Fails if the size of the `ScalarInt` is not equal to 1 byte - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i8(self) -> Result { - self.try_to_int(Size::from_bits(8)).map(|v| i8::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i8. + /// Panics if the size of the `ScalarInt` is not equal to 1 byte. + pub fn to_i8(self) -> i8 { + self.to_int(Size::from_bits(8)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i16. - /// Fails if the size of the `ScalarInt` is not equal to 2 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i16(self) -> Result { - self.try_to_int(Size::from_bits(16)).map(|v| i16::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i16. + /// Panics if the size of the `ScalarInt` is not equal to 2 bytes. + pub fn to_i16(self) -> i16 { + self.to_int(Size::from_bits(16)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i32. - /// Fails if the size of the `ScalarInt` is not equal to 4 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i32(self) -> Result { - self.try_to_int(Size::from_bits(32)).map(|v| i32::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i32. + /// Panics if the size of the `ScalarInt` is not equal to 4 bytes. + pub fn to_i32(self) -> i32 { + self.to_int(Size::from_bits(32)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i64. - /// Fails if the size of the `ScalarInt` is not equal to 8 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i64(self) -> Result { - self.try_to_int(Size::from_bits(64)).map(|v| i64::try_from(v).unwrap()) + /// Converts the `ScalarInt` to i64. + /// Panics if the size of the `ScalarInt` is not equal to 8 bytes. + pub fn to_i64(self) -> i64 { + self.to_int(Size::from_bits(64)).try_into().unwrap() } - /// Tries to convert the `ScalarInt` to i128. - /// Fails if the size of the `ScalarInt` is not equal to 16 bytes - /// and returns the `ScalarInt`s size in that case. - pub fn try_to_i128(self) -> Result { - self.try_to_int(Size::from_bits(128)) + /// Converts the `ScalarInt` to i128. + /// Panics if the size of the `ScalarInt` is not equal to 16 bytes. + pub fn to_i128(self) -> i128 { + self.to_int(Size::from_bits(128)) } #[inline] - pub fn try_to_target_isize(&self, tcx: TyCtxt<'_>) -> Result { - self.try_to_int(tcx.data_layout.pointer_size).map(|v| i64::try_from(v).unwrap()) + pub fn to_target_isize(&self, tcx: TyCtxt<'_>) -> i64 { + self.to_int(tcx.data_layout.pointer_size).try_into().unwrap() } #[inline] - pub fn try_to_float(self) -> Result { + pub fn to_float(self) -> F { // Going through `to_uint` to check size and truncation. - Ok(F::from_bits(self.try_to_bits(Size::from_bits(F::BITS))?)) + F::from_bits(self.to_bits(Size::from_bits(F::BITS))) } #[inline] - pub fn try_to_f16(self) -> Result { - self.try_to_float() + pub fn to_f16(self) -> Half { + self.to_float() } #[inline] - pub fn try_to_f32(self) -> Result { - self.try_to_float() + pub fn to_f32(self) -> Single { + self.to_float() } #[inline] - pub fn try_to_f64(self) -> Result { - self.try_to_float() + pub fn to_f64(self) -> Double { + self.to_float() } #[inline] - pub fn try_to_f128(self) -> Result { - self.try_to_float() + pub fn to_f128(self) -> Quad { + self.to_float() } } -macro_rules! from { +macro_rules! from_x_for_scalar_int { ($($ty:ty),*) => { $( impl From<$ty> for ScalarInt { @@ -432,30 +420,29 @@ macro_rules! from { } } -macro_rules! try_from { +macro_rules! from_scalar_int_for_x { ($($ty:ty),*) => { $( - impl TryFrom for $ty { - type Error = Size; + impl From for $ty { #[inline] - fn try_from(int: ScalarInt) -> Result { + fn from(int: ScalarInt) -> Self { // The `unwrap` cannot fail because to_bits (if it succeeds) // is guaranteed to return a value that fits into the size. - int.try_to_bits(Size::from_bytes(std::mem::size_of::<$ty>())) - .map(|u| u.try_into().unwrap()) + int.to_bits(Size::from_bytes(std::mem::size_of::<$ty>())) + .try_into().unwrap() } } )* } } -from!(u8, u16, u32, u64, u128, bool); -try_from!(u8, u16, u32, u64, u128); +from_x_for_scalar_int!(u8, u16, u32, u64, u128, bool); +from_scalar_int_for_x!(u8, u16, u32, u64, u128); impl TryFrom for bool { - type Error = Size; + type Error = (); #[inline] - fn try_from(int: ScalarInt) -> Result { + fn try_from(int: ScalarInt) -> Result { int.try_to_bool() } } @@ -463,7 +450,7 @@ impl TryFrom for bool { impl From for ScalarInt { #[inline] fn from(c: char) -> Self { - Self { data: c as u128, size: NonZero::new(std::mem::size_of::() as u8).unwrap() } + (c as u32).into() } } @@ -476,10 +463,7 @@ impl TryFrom for char { #[inline] fn try_from(int: ScalarInt) -> Result { - let Ok(bits) = int.try_to_bits(Size::from_bytes(std::mem::size_of::())) else { - return Err(CharTryFromScalarInt); - }; - match char::from_u32(bits.try_into().unwrap()) { + match char::from_u32(int.to_u32()) { Some(c) => Ok(c), None => Err(CharTryFromScalarInt), } @@ -494,11 +478,10 @@ impl From for ScalarInt { } } -impl TryFrom for Half { - type Error = Size; +impl From for Half { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(2)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(2))) } } @@ -510,11 +493,10 @@ impl From for ScalarInt { } } -impl TryFrom for Single { - type Error = Size; +impl From for Single { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(4)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(4))) } } @@ -526,11 +508,10 @@ impl From for ScalarInt { } } -impl TryFrom for Double { - type Error = Size; +impl From for Double { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(8)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(8))) } } @@ -542,11 +523,10 @@ impl From for ScalarInt { } } -impl TryFrom for Quad { - type Error = Size; +impl From for Quad { #[inline] - fn try_from(int: ScalarInt) -> Result { - int.try_to_bits(Size::from_bytes(16)).map(Self::from_bits) + fn from(int: ScalarInt) -> Self { + Self::from_bits(int.to_bits(Size::from_bytes(16))) } } diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 96bc5515a569..efc91357af8c 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -79,7 +79,7 @@ impl<'tcx> ValTree<'tcx> { } pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option { - self.try_to_scalar_int().and_then(|s| s.try_to_target_usize(tcx).ok()) + self.try_to_scalar_int().map(|s| s.to_target_usize(tcx)) } /// Get the values inside the ValTree as a slice of bytes. This only works for @@ -100,8 +100,9 @@ impl<'tcx> ValTree<'tcx> { _ => return None, } - Some(tcx.arena.alloc_from_iter( - self.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().try_to_u8().unwrap()), - )) + Some( + tcx.arena + .alloc_from_iter(self.unwrap_branch().into_iter().map(|v| v.unwrap_leaf().to_u8())), + ) } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 142872009bf2..56945bf6be4f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1351,3 +1351,37 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { } impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} + +impl<'tcx> TyCtxt<'tcx> { + pub fn offset_of_subfield( + self, + param_env: ty::ParamEnv<'tcx>, + mut layout: TyAndLayout<'tcx>, + indices: I, + ) -> Size + where + I: Iterator, + { + let cx = LayoutCx { tcx: self, param_env }; + let mut offset = Size::ZERO; + + for (variant, field) in indices { + layout = layout.for_variant(&cx, variant); + let index = field.index(); + offset += layout.fields.offset(index); + layout = layout.field(&cx, index); + if !layout.is_sized() { + // If it is not sized, then the tail must still have at least a known static alignment. + let tail = self.struct_tail_erasing_lifetimes(layout.ty, param_env); + if !matches!(tail.kind(), ty::Slice(..)) { + bug!( + "offset of not-statically-aligned field (type {:?}) cannot be computed statically", + layout.ty + ); + } + } + } + + offset + } +} diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 49d46eb3c4bf..662eafd0ccb6 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1652,7 +1652,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { if let ty::ConstKind::Value(_, ty::ValTree::Leaf(int)) = len.kind() { match self.tcx().try_get_global_alloc(prov.alloc_id()) { Some(GlobalAlloc::Memory(alloc)) => { - let len = int.assert_bits(self.tcx().data_layout.pointer_size); + let len = int.to_bits(self.tcx().data_layout.pointer_size); let range = AllocRange { start: offset, size: Size::from_bytes(len) }; if let Ok(byte_str) = @@ -1730,7 +1730,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { } // Pointer types ty::Ref(..) | ty::RawPtr(_, _) | ty::FnPtr(_) => { - let data = int.assert_bits(self.tcx().data_layout.pointer_size); + let data = int.to_bits(self.tcx().data_layout.pointer_size); self.typed_value( |this| { write!(this, "0x{data:x}")?; diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 77f27236437d..5d828d0093f3 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -5,7 +5,6 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -either = "1" itertools = "0.12" rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } @@ -24,6 +23,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } -smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 193f0d124bb8..601e5d4d3dc7 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -15,11 +15,10 @@ use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; -use rustc_middle::mir::interpret::Scalar; 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::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -1014,14 +1013,14 @@ fn parse_float_into_constval<'tcx>( float_ty: ty::FloatTy, neg: bool, ) -> Option> { - parse_float_into_scalar(num, float_ty, neg).map(ConstValue::Scalar) + parse_float_into_scalar(num, float_ty, neg).map(|s| ConstValue::Scalar(s.into())) } pub(crate) fn parse_float_into_scalar( num: Symbol, float_ty: ty::FloatTy, neg: bool, -) -> Option { +) -> Option { let num = num.as_str(); match float_ty { // FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64` @@ -1030,7 +1029,7 @@ pub(crate) fn parse_float_into_scalar( if neg { f = -f; } - Some(Scalar::from_f16(f)) + Some(ScalarInt::from(f)) } ty::FloatTy::F32 => { let Ok(rust_f) = num.parse::() else { return None }; @@ -1053,7 +1052,7 @@ pub(crate) fn parse_float_into_scalar( f = -f; } - Some(Scalar::from_f32(f)) + Some(ScalarInt::from(f)) } ty::FloatTy::F64 => { let Ok(rust_f) = num.parse::() else { return None }; @@ -1076,7 +1075,7 @@ pub(crate) fn parse_float_into_scalar( f = -f; } - Some(Scalar::from_f64(f)) + Some(ScalarInt::from(f)) } // FIXME(f16_f128): When available, compare to the library parser as with `f32` and `f64` ty::FloatTy::F128 => { @@ -1084,7 +1083,7 @@ pub(crate) fn parse_float_into_scalar( if neg { f = -f; } - Some(Scalar::from_f128(f)) + Some(ScalarInt::from(f)) } } } diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 31bc72184caa..a98e046d4dc0 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -58,11 +58,9 @@ pub(crate) fn lit_to_const<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ty::ValTree::from_scalar_int((*b).into()), (ast::LitKind::Float(n, _), ty::Float(fty)) => { - let bits = parse_float_into_scalar(*n, *fty, neg) - .ok_or_else(|| { - tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit)) - })? - .assert_int(); + let bits = parse_float_into_scalar(*n, *fty, neg).ok_or_else(|| { + tcx.dcx().bug(format!("couldn't parse float literal: {:?}", lit_input.lit)) + })?; ty::ValTree::from_scalar_int(bits) } (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()), 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 36495101d3f4..192d706bce2c 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 @@ -282,8 +282,7 @@ impl<'tcx> ConstToPat<'tcx> { } ty::Adt(adt_def, args) if adt_def.is_enum() => { let (&variant_index, fields) = cv.unwrap_branch().split_first().unwrap(); - let variant_index = - VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); + let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32()); PatKind::Variant { adt_def: *adt_def, args, @@ -371,8 +370,8 @@ impl<'tcx> ConstToPat<'tcx> { let v = cv.unwrap_leaf(); let is_nan = match flt { ty::FloatTy::F16 => unimplemented!("f16_f128"), - ty::FloatTy::F32 => v.try_to_f32().unwrap().is_nan(), - ty::FloatTy::F64 => v.try_to_f64().unwrap().is_nan(), + ty::FloatTy::F32 => v.to_f32().is_nan(), + ty::FloatTy::F64 => v.to_f64().is_nan(), ty::FloatTy::F128 => unimplemented!("f16_f128"), }; if is_nan { diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs deleted file mode 100644 index e4e4270c4995..000000000000 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Finds locals which are assigned once to a const and unused except for debuginfo and converts -//! their debuginfo to use the const directly, allowing the local to be removed. - -use rustc_middle::{ - mir::{ - visit::{PlaceContext, Visitor}, - Body, ConstOperand, Local, Location, Operand, Rvalue, StatementKind, VarDebugInfoContents, - }, - ty::TyCtxt, -}; - -use crate::MirPass; -use rustc_index::{bit_set::BitSet, IndexVec}; - -pub struct ConstDebugInfo; - -impl<'tcx> MirPass<'tcx> for ConstDebugInfo { - fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.mir_opt_level() > 0 - } - - fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - trace!("running ConstDebugInfo on {:?}", body.source); - - for (local, constant) in find_optimization_opportunities(body) { - for debuginfo in &mut body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value { - if p.local == local && p.projection.is_empty() { - trace!( - "changing debug info for {:?} from place {:?} to constant {:?}", - debuginfo.name, - p, - constant - ); - debuginfo.value = VarDebugInfoContents::Const(constant); - } - } - } - } - } -} - -struct LocalUseVisitor { - local_mutating_uses: IndexVec, - local_assignment_locations: IndexVec>, -} - -fn find_optimization_opportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, ConstOperand<'tcx>)> { - let mut visitor = LocalUseVisitor { - local_mutating_uses: IndexVec::from_elem(0, &body.local_decls), - local_assignment_locations: IndexVec::from_elem(None, &body.local_decls), - }; - - visitor.visit_body(body); - - let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len()); - for debuginfo in &body.var_debug_info { - if let VarDebugInfoContents::Place(p) = debuginfo.value - && let Some(l) = p.as_local() - { - locals_to_debuginfo.insert(l); - } - } - - let mut eligible_locals = Vec::new(); - for (local, mutating_uses) in visitor.local_mutating_uses.drain_enumerated(..) { - if mutating_uses != 1 || !locals_to_debuginfo.contains(local) { - continue; - } - - if let Some(location) = visitor.local_assignment_locations[local] { - let bb = &body[location.block]; - - // The value is assigned as the result of a call, not a constant - if bb.statements.len() == location.statement_index { - continue; - } - - if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(box c)))) = - &bb.statements[location.statement_index].kind - { - if let Some(local) = p.as_local() { - eligible_locals.push((local, *c)); - } - } - } - } - - eligible_locals -} - -impl Visitor<'_> for LocalUseVisitor { - fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) { - if context.is_mutating_use() { - self.local_mutating_uses[local] = self.local_mutating_uses[local].saturating_add(1); - - if context.is_place_assignment() { - self.local_assignment_locations[local] = Some(location); - } - } - } -} diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a8caead46f2f..0fd85eb345d0 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -10,7 +10,7 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{ Map, PlaceIndex, State, TrackElem, ValueAnalysis, ValueAnalysisWrapper, ValueOrPlace, @@ -285,9 +285,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { let val = match null_op { NullOp::SizeOf if layout.is_sized() => layout.size.bytes(), NullOp::AlignOf if layout.is_sized() => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(&self.ecx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .ecx + .tcx + .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .bytes(), _ => return ValueOrPlace::Value(FlatSet::Top), }; FlatSet::Elem(Scalar::from_target_usize(val, &self.tcx)) @@ -324,7 +326,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { // This allows the set of visited edges to grow monotonically with the lattice. FlatSet::Bottom => TerminatorEdges::None, FlatSet::Elem(scalar) => { - let choice = scalar.assert_bits(scalar.size()); + let choice = scalar.assert_scalar_int().to_bits_unchecked(); TerminatorEdges::Single(targets.target_for_value(choice)) } FlatSet::Top => TerminatorEdges::SwitchInt { discr, targets }, @@ -607,7 +609,7 @@ fn propagatable_scalar( map: &Map, ) -> Option { if let FlatSet::Elem(value) = state.get_idx(place, map) - && value.try_to_int().is_ok() + && value.try_to_scalar_int().is_ok() { // Do not attempt to propagate pointers, as we may fail to preserve their identity. Some(value) @@ -668,7 +670,7 @@ fn try_write_constant<'tcx>( let FlatSet::Elem(Scalar::Int(discr)) = state.get_idx(discr, map) else { throw_machine_stop_str!("discriminant with provenance") }; - let discr_bits = discr.assert_bits(discr.size()); + let discr_bits = discr.to_bits(discr.size()); let Some((variant, _)) = def.discriminants(*ecx.tcx).find(|(_, var)| discr_bits == var.val) else { throw_machine_stop_str!("illegal discriminant for enum") }; diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index acde16fcb757..121a3b99a39e 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -83,8 +83,8 @@ //! that contain `AllocId`s. use rustc_const_eval::const_eval::DummyMachine; -use rustc_const_eval::interpret::{intern_const_alloc_for_constprop, MemoryKind}; -use rustc_const_eval::interpret::{ImmTy, InterpCx, OpTy, Projectable, Scalar}; +use rustc_const_eval::interpret::{intern_const_alloc_for_constprop, MemPlaceMeta, MemoryKind}; +use rustc_const_eval::interpret::{ImmTy, Immediate, InterpCx, OpTy, Projectable, Scalar}; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_hir::def::DefKind; @@ -95,11 +95,11 @@ use rustc_middle::bug; use rustc_middle::mir::interpret::GlobalAlloc; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{HasParamEnv, LayoutOf}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::DUMMY_SP; -use rustc_target::abi::{self, Abi, Size, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{self, Abi, FieldIdx, Size, VariantIdx, FIRST_VARIANT}; use smallvec::SmallVec; use std::borrow::Cow; @@ -177,6 +177,12 @@ enum AggregateTy<'tcx> { Array, Tuple, Def(DefId, ty::GenericArgsRef<'tcx>), + RawPtr { + /// Needed for cast propagation. + data_pointer_ty: Ty<'tcx>, + /// The data pointer can be anything thin, so doesn't determine the output. + output_pointer_ty: Ty<'tcx>, + }, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] @@ -385,11 +391,22 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { AggregateTy::Def(def_id, args) => { self.tcx.type_of(def_id).instantiate(self.tcx, args) } + AggregateTy::RawPtr { output_pointer_ty, .. } => output_pointer_ty, }; let variant = if ty.is_enum() { Some(variant) } else { None }; let ty = self.ecx.layout_of(ty).ok()?; if ty.is_zst() { ImmTy::uninit(ty).into() + } else if matches!(kind, AggregateTy::RawPtr { .. }) { + // Pointers don't have fields, so don't `project_field` them. + let data = self.ecx.read_pointer(fields[0]).ok()?; + let meta = if fields[1].layout.is_zst() { + MemPlaceMeta::None + } else { + MemPlaceMeta::Meta(self.ecx.read_scalar(fields[1]).ok()?) + }; + let ptr_imm = Immediate::new_pointer_with_meta(data, meta, &self.ecx); + ImmTy::from_immediate(ptr_imm, ty).into() } else if matches!(ty.abi, Abi::Scalar(..) | Abi::ScalarPair(..)) { let dest = self.ecx.allocate(ty, MemoryKind::Stack).ok()?; let variant_dest = if let Some(variant) = variant { @@ -471,7 +488,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let slice = self.evaluated[slice].as_ref()?; let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); let len = slice.len(&self.ecx).ok()?; - let imm = ImmTy::try_from_uint(len, usize_layout)?; + let imm = ImmTy::from_uint(len, usize_layout); imm.into() } NullaryOp(null_op, ty) => { @@ -484,13 +501,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(&self.ecx, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .ecx + .tcx + .offset_of_subfield(self.ecx.param_env(), layout, fields.iter()) + .bytes(), NullOp::UbChecks => return None, }; let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap(); - let imm = ImmTy::try_from_uint(val, usize_layout)?; + let imm = ImmTy::from_uint(val, usize_layout); imm.into() } UnaryOp(un_op, operand) => { @@ -862,10 +881,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { rvalue: &mut Rvalue<'tcx>, location: Location, ) -> Option { - let Rvalue::Aggregate(box ref kind, ref mut fields) = *rvalue else { bug!() }; + let Rvalue::Aggregate(box ref kind, ref mut field_ops) = *rvalue else { bug!() }; let tcx = self.tcx; - if fields.is_empty() { + if field_ops.is_empty() { let is_zst = match *kind { AggregateKind::Array(..) | AggregateKind::Tuple @@ -884,13 +903,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } - let (ty, variant_index) = match *kind { + let (mut ty, variant_index) = match *kind { AggregateKind::Array(..) => { - assert!(!fields.is_empty()); + assert!(!field_ops.is_empty()); (AggregateTy::Array, FIRST_VARIANT) } AggregateKind::Tuple => { - assert!(!fields.is_empty()); + assert!(!field_ops.is_empty()); (AggregateTy::Tuple, FIRST_VARIANT) } AggregateKind::Closure(did, args) @@ -901,15 +920,49 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } // Do not track unions. AggregateKind::Adt(_, _, _, _, Some(_)) => return None, - // FIXME: Do the extra work to GVN `from_raw_parts` - AggregateKind::RawPtr(..) => return None, + AggregateKind::RawPtr(pointee_ty, mtbl) => { + assert_eq!(field_ops.len(), 2); + let data_pointer_ty = field_ops[FieldIdx::ZERO].ty(self.local_decls, self.tcx); + let output_pointer_ty = Ty::new_ptr(self.tcx, pointee_ty, mtbl); + (AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty }, FIRST_VARIANT) + } }; - let fields: Option> = fields + let fields: Option> = field_ops .iter_mut() .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) .collect(); - let fields = fields?; + let mut fields = fields?; + + if let AggregateTy::RawPtr { data_pointer_ty, output_pointer_ty } = &mut ty { + let mut was_updated = false; + + // Any thin pointer of matching mutability is fine as the data pointer. + while let Value::Cast { + kind: CastKind::PtrToPtr, + value: cast_value, + from: cast_from, + to: _, + } = self.get(fields[0]) + && let ty::RawPtr(from_pointee_ty, from_mtbl) = cast_from.kind() + && let ty::RawPtr(_, output_mtbl) = output_pointer_ty.kind() + && from_mtbl == output_mtbl + && from_pointee_ty.is_sized(self.tcx, self.param_env) + { + fields[0] = *cast_value; + *data_pointer_ty = *cast_from; + was_updated = true; + } + + if was_updated { + if let Some(const_) = self.try_as_constant(fields[0]) { + field_ops[FieldIdx::ZERO] = Operand::Constant(Box::new(const_)); + } else if let Some(local) = self.try_as_local(fields[0], location) { + field_ops[FieldIdx::ZERO] = Operand::Copy(Place::from(local)); + self.reused_locals.insert(local); + } + } + } if let AggregateTy::Array = ty && fields.len() > 4 @@ -941,6 +994,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { (UnOp::Not, Value::BinaryOp(BinOp::Ne, lhs, rhs)) => { Value::BinaryOp(BinOp::Eq, *lhs, *rhs) } + (UnOp::PtrMetadata, Value::Aggregate(AggregateTy::RawPtr { .. }, _, fields)) => { + return Some(fields[1]); + } _ => return None, }; @@ -1092,6 +1148,23 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { return self.new_opaque(); } + let mut was_updated = false; + + // If that cast just casts away the metadata again, + if let PtrToPtr = kind + && let Value::Aggregate(AggregateTy::RawPtr { data_pointer_ty, .. }, _, fields) = + self.get(value) + && let ty::RawPtr(to_pointee, _) = to.kind() + && to_pointee.is_sized(self.tcx, self.param_env) + { + from = *data_pointer_ty; + value = fields[0]; + was_updated = true; + if *data_pointer_ty == to { + return Some(fields[0]); + } + } + if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind && let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } = *self.get(value) @@ -1100,9 +1173,13 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { from = inner_from; value = inner_value; *kind = PtrToPtr; + was_updated = true; if inner_from == to { return Some(inner_value); } + } + + if was_updated { if let Some(const_) = self.try_as_constant(value) { *operand = Operand::Constant(Box::new(const_)); } else if let Some(local) = self.try_as_local(value, location) { @@ -1178,7 +1255,7 @@ fn op_to_prop_const<'tcx>( // If this constant has scalar ABI, return it as a `ConstValue::Scalar`. if let Abi::Scalar(abi::Scalar::Initialized { .. }) = op.layout.abi && let Ok(scalar) = ecx.read_scalar(op) - && scalar.try_to_int().is_ok() + && scalar.try_to_scalar_int().is_ok() { return Some(ConstValue::Scalar(scalar)); } diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 8b46658b3225..6a20b46e7f9c 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -356,15 +356,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { debug!("check_binary_op: reporting assert for {:?}", location); let panic = AssertKind::Overflow( op, - match l { - Some(l) => l.to_const_int(), - // Invent a dummy value, the diagnostic ignores it anyway - None => ConstInt::new( - ScalarInt::try_from_uint(1_u8, left_size).unwrap(), - left_ty.is_signed(), - left_ty.is_ptr_sized_integral(), - ), - }, + // Invent a dummy value, the diagnostic ignores it anyway + ConstInt::new( + ScalarInt::try_from_uint(1_u8, left_size).unwrap(), + left_ty.is_signed(), + left_ty.is_ptr_sized_integral(), + ), r.to_const_int(), ); self.report_assert_as_lint(location, AssertLintKind::ArithmeticOverflow, panic); @@ -625,9 +622,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let val = match null_op { NullOp::SizeOf => op_layout.size.bytes(), NullOp::AlignOf => op_layout.align.abi.bytes(), - NullOp::OffsetOf(fields) => { - op_layout.offset_of_subfield(self, fields.iter()).bytes() - } + NullOp::OffsetOf(fields) => self + .tcx + .offset_of_subfield(self.param_env, op_layout, fields.iter()) + .bytes(), NullOp::UbChecks => return None, }; ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into() @@ -786,8 +784,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { TerminatorKind::SwitchInt { ref discr, ref targets } => { if let Some(ref value) = self.eval_operand(discr) && let Some(value_const) = self.use_ecx(|this| this.ecx.read_scalar(value)) - && let Ok(constant) = value_const.try_to_int() - && let Ok(constant) = constant.try_to_bits(constant.size()) + && let Ok(constant) = value_const.to_bits(value_const.size()) { // We managed to evaluate the discriminant, so we know we only need to visit // one target. diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e4670633914e..551760f4703d 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -55,7 +55,6 @@ mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup mod add_subtyping_projections; pub mod cleanup_post_borrowck; -mod const_debuginfo; mod copy_prop; mod coroutine; mod cost_checker; @@ -106,6 +105,7 @@ mod check_alignment; pub mod simplify; mod simplify_branches; mod simplify_comparison_integral; +mod single_use_consts; mod sroa; mod unreachable_enum_branching; mod unreachable_prop; @@ -593,7 +593,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &gvn::GVN, &simplify::SimplifyLocals::AfterGVN, &dataflow_const_prop::DataflowConstProp, - &const_debuginfo::ConstDebugInfo, + &single_use_consts::SingleUseConsts, &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &jump_threading::JumpThreading, &early_otherwise_branch::EarlyOtherwiseBranch, diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index 1411d9be2236..6ab4ec6fe7e6 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -372,7 +372,7 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp { } fn int_equal(l: ScalarInt, r: impl Into, size: Size) -> bool { - l.assert_int(l.size()) == ScalarInt::try_from_uint(r, size).unwrap().assert_int(size) + l.to_bits_unchecked() == ScalarInt::try_from_uint(r, size).unwrap().to_bits_unchecked() } // We first compare the two branches, and then the other branches need to fulfill the same conditions. diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs index 7ec59cc983f5..ecd1179ca995 100644 --- a/compiler/rustc_mir_transform/src/promote_consts.rs +++ b/compiler/rustc_mir_transform/src/promote_consts.rs @@ -500,14 +500,14 @@ impl<'tcx> Validator<'_, 'tcx> { } _ => None, }; - match rhs_val.map(|x| x.assert_uint(sz)) { + match rhs_val.map(|x| x.to_uint(sz)) { // for the zero test, int vs uint does not matter Some(x) if x != 0 => {} // okay _ => return Err(Unpromotable), // value not known or 0 -- not okay } // Furthermore, for signed divison, we also have to exclude `int::MIN / -1`. if lhs_ty.is_signed() { - match rhs_val.map(|x| x.assert_int(sz)) { + match rhs_val.map(|x| x.to_int(sz)) { Some(-1) | None => { // The RHS is -1 or unknown, so we have to be careful. // But is the LHS int::MIN? @@ -518,7 +518,7 @@ impl<'tcx> Validator<'_, 'tcx> { _ => None, }; let lhs_min = sz.signed_int_min(); - match lhs_val.map(|x| x.assert_int(sz)) { + match lhs_val.map(|x| x.to_int(sz)) { Some(x) if x != lhs_min => {} // okay _ => return Err(Unpromotable), // value not known or int::MIN -- not okay } diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index 03907babf2b0..e174cccdad6b 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -49,7 +49,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let layout = tcx .layout_of(param_env.and(opt.branch_value_ty)) .expect("if we have an evaluated constant we must know the layout"); - int.assert_bits(layout.size) + int.to_bits(layout.size) } Scalar::Ptr(..) => continue, }; diff --git a/compiler/rustc_mir_transform/src/single_use_consts.rs b/compiler/rustc_mir_transform/src/single_use_consts.rs new file mode 100644 index 000000000000..93736e55996e --- /dev/null +++ b/compiler/rustc_mir_transform/src/single_use_consts.rs @@ -0,0 +1,199 @@ +use rustc_index::{bit_set::BitSet, IndexVec}; +use rustc_middle::bug; +use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +/// Various parts of MIR building introduce temporaries that are commonly not needed. +/// +/// Notably, `if CONST` and `match CONST` end up being used-once temporaries, which +/// obfuscates the structure for other passes and codegen, which would like to always +/// be able to just see the constant directly. +/// +/// At higher optimization levels fancier passes like GVN will take care of this +/// in a more general fashion, but this handles the easy cases so can run in debug. +/// +/// This only removes constants with a single-use because re-evaluating constants +/// isn't always an improvement, especially for large ones. +/// +/// It also removes *never*-used constants, since it had all the information +/// needed to do that too, including updating the debug info. +pub struct SingleUseConsts; + +impl<'tcx> MirPass<'tcx> for SingleUseConsts { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + sess.mir_opt_level() > 0 + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let mut finder = SingleUseConstsFinder { + ineligible_locals: BitSet::new_empty(body.local_decls.len()), + locations: IndexVec::from_elem(LocationPair::new(), &body.local_decls), + locals_in_debug_info: BitSet::new_empty(body.local_decls.len()), + }; + + finder.ineligible_locals.insert_range(..=Local::from_usize(body.arg_count)); + + finder.visit_body(body); + + for (local, locations) in finder.locations.iter_enumerated() { + if finder.ineligible_locals.contains(local) { + continue; + } + + let Some(init_loc) = locations.init_loc else { + continue; + }; + + // We're only changing an operand, not the terminator kinds or successors + let basic_blocks = body.basic_blocks.as_mut_preserves_cfg(); + let init_statement = + basic_blocks[init_loc.block].statements[init_loc.statement_index].replace_nop(); + let StatementKind::Assign(place_and_rvalue) = init_statement.kind else { + bug!("No longer an assign?"); + }; + let (place, rvalue) = *place_and_rvalue; + assert_eq!(place.as_local(), Some(local)); + let Rvalue::Use(operand) = rvalue else { bug!("No longer a use?") }; + + let mut replacer = LocalReplacer { tcx, local, operand: Some(operand) }; + + if finder.locals_in_debug_info.contains(local) { + for var_debug_info in &mut body.var_debug_info { + replacer.visit_var_debug_info(var_debug_info); + } + } + + let Some(use_loc) = locations.use_loc else { continue }; + + let use_block = &mut basic_blocks[use_loc.block]; + if let Some(use_statement) = use_block.statements.get_mut(use_loc.statement_index) { + replacer.visit_statement(use_statement, use_loc); + } else { + replacer.visit_terminator(use_block.terminator_mut(), use_loc); + } + + if replacer.operand.is_some() { + bug!( + "operand wasn't used replacing local {local:?} with locations {locations:?} in body {body:#?}" + ); + } + } + } +} + +#[derive(Copy, Clone, Debug)] +struct LocationPair { + init_loc: Option, + use_loc: Option, +} + +impl LocationPair { + fn new() -> Self { + Self { init_loc: None, use_loc: None } + } +} + +struct SingleUseConstsFinder { + ineligible_locals: BitSet, + locations: IndexVec, + locals_in_debug_info: BitSet, +} + +impl<'tcx> Visitor<'tcx> for SingleUseConstsFinder { + fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { + if let Some(local) = place.as_local() + && let Rvalue::Use(operand) = rvalue + && let Operand::Constant(_) = operand + { + let locations = &mut self.locations[local]; + if locations.init_loc.is_some() { + self.ineligible_locals.insert(local); + } else { + locations.init_loc = Some(location); + } + } else { + self.super_assign(place, rvalue, location); + } + } + + fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) { + if let Some(place) = operand.place() + && let Some(local) = place.as_local() + { + let locations = &mut self.locations[local]; + if locations.use_loc.is_some() { + self.ineligible_locals.insert(local); + } else { + locations.use_loc = Some(location); + } + } else { + self.super_operand(operand, location); + } + } + + fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) { + match &statement.kind { + // Storage markers are irrelevant to this. + StatementKind::StorageLive(_) | StatementKind::StorageDead(_) => {} + _ => self.super_statement(statement, location), + } + } + + fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) { + if let VarDebugInfoContents::Place(place) = &var_debug_info.value + && let Some(local) = place.as_local() + { + self.locals_in_debug_info.insert(local); + } else { + self.super_var_debug_info(var_debug_info); + } + } + + fn visit_local(&mut self, local: Local, _context: PlaceContext, _location: Location) { + // If there's any path that gets here, rather than being understood elsewhere, + // then we'd better not do anything with this local. + self.ineligible_locals.insert(local); + } +} + +struct LocalReplacer<'tcx> { + tcx: TyCtxt<'tcx>, + local: Local, + operand: Option>, +} + +impl<'tcx> MutVisitor<'tcx> for LocalReplacer<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _location: Location) { + if let Operand::Copy(place) | Operand::Move(place) = operand + && let Some(local) = place.as_local() + && local == self.local + { + *operand = self.operand.take().unwrap_or_else(|| { + bug!("there was a second use of the operand"); + }); + } + } + + fn visit_var_debug_info(&mut self, var_debug_info: &mut VarDebugInfo<'tcx>) { + if let VarDebugInfoContents::Place(place) = &var_debug_info.value + && let Some(local) = place.as_local() + && local == self.local + { + let const_op = self + .operand + .as_ref() + .unwrap_or_else(|| { + bug!("the operand was already stolen"); + }) + .constant() + .unwrap() + .clone(); + var_debug_info.value = VarDebugInfoContents::Const(const_op); + } + } +} diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 3b4d4c938771..586c12549953 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -5,12 +5,12 @@ use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; use rustc_infer::traits::Reveal; use rustc_middle::mir::coverage::CoverageKind; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ - self, CoroutineArgsExt, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt, Variance, + self, CoroutineArgsExt, InstanceDef, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, + Variance, }; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{Size, FIRST_VARIANT}; @@ -1478,7 +1478,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { }); for (value, _) in targets.iter() { - if Scalar::<()>::try_from_uint(value, size).is_none() { + if ScalarInt::try_from_uint(value, size).is_none() { self.fail( location, format!("the value {value:#x} is not a proper {switch_ty:?}"), diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index c30d21fd7843..50dbc991f8fd 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -5,22 +5,9 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } -rustc_data_structures = { path = "../rustc_data_structures", optional = true } -rustc_macros = { path = "../rustc_macros", optional = true } -rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_type_ir = { path = "../rustc_type_ir", default-features = false } -rustc_type_ir_macros = { path = "../rustc_type_ir_macros" } -tracing = "0.1" # tidy-alphabetical-end [features] default = ["nightly"] -nightly = [ - "rustc_type_ir/nightly", - "rustc_macros", - "rustc_serialize", - "rustc_data_structures", - "rustc_ast_ir/nightly", -] +nightly = ["rustc_type_ir/nightly"] diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 81c5f3552319..8391c694c64b 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -6,11 +6,12 @@ use rustc_hir::def_id::DefId; use rustc_hir::HirId; use rustc_index::{Idx, IndexVec}; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::{self, Const}; use rustc_middle::thir::{self, FieldPat, Pat, PatKind, PatRange, PatRangeBoundary}; use rustc_middle::ty::layout::IntegerExt; -use rustc_middle::ty::{self, FieldDef, OpaqueTypeKey, Ty, TyCtxt, TypeVisitableExt, VariantDef}; +use rustc_middle::ty::{ + self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef, +}; use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; @@ -701,9 +702,9 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ty::Int(_) => miint.as_finite_int(size.bits()).unwrap(), _ => miint.as_finite_uint().unwrap(), }; - match Scalar::try_from_uint(bits, size) { + match ScalarInt::try_from_uint(bits, size) { Some(scalar) => { - let value = mir::Const::from_scalar(tcx, scalar, ty.inner()); + let value = mir::Const::from_scalar(tcx, scalar.into(), ty.inner()); PatRangeBoundary::Finite(value) } // The value doesn't fit. Since `x >= 0` and 0 always encodes the minimum value diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index c57f22a0da2b..2bb1be22b985 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" # tidy-alphabetical-start field-offset = "0.3.5" measureme = "11" -rustc-rayon-core = { version = "0.5.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } @@ -23,5 +22,5 @@ tracing = "0.1" [features] # tidy-alphabetical-start -rustc_use_parallel_compiler = ["rustc-rayon-core", "rustc_query_system/rustc_use_parallel_compiler"] +rustc_use_parallel_compiler = ["rustc_query_system/rustc_use_parallel_compiler"] # tidy-alphabetical-end diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 82179a4a0586..99fcaf917fe9 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -521,7 +521,7 @@ impl SpanData { Span::new(self.lo, hi, self.ctxt, self.parent) } #[inline] - pub fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { + fn with_ctxt(&self, ctxt: SyntaxContext) -> Span { Span::new(self.lo, self.hi, ctxt, self.parent) } #[inline] @@ -576,8 +576,9 @@ impl Span { self.data().with_hi(hi) } #[inline] - pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span { - self.data_untracked().with_ctxt(ctxt) + pub fn with_ctxt(mut self, ctxt: SyntaxContext) -> Span { + self.update_ctxt(|_| ctxt); + self } #[inline] pub fn parent(self) -> Option { @@ -1058,9 +1059,9 @@ impl Span { } #[inline] - pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency)) + pub fn apply_mark(mut self, expn_id: ExpnId, transparency: Transparency) -> Span { + self.update_ctxt(|ctxt| ctxt.apply_mark(expn_id, transparency)); + self } #[inline] @@ -1108,15 +1109,15 @@ impl Span { } #[inline] - pub fn normalize_to_macros_2_0(self) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.normalize_to_macros_2_0()) + pub fn normalize_to_macros_2_0(mut self) -> Span { + self.update_ctxt(|ctxt| ctxt.normalize_to_macros_2_0()); + self } #[inline] - pub fn normalize_to_macro_rules(self) -> Span { - let span = self.data(); - span.with_ctxt(span.ctxt.normalize_to_macro_rules()) + pub fn normalize_to_macro_rules(mut self) -> Span { + self.update_ctxt(|ctxt| ctxt.normalize_to_macro_rules()); + self } } diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index 6a0282266316..52a1267f8918 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -87,6 +87,45 @@ pub struct Span { ctxt_or_parent_or_marker: u16, } +impl Span { + #[inline] + fn data_inline_ctxt(self) -> SpanData { + let len = self.len_with_tag_or_marker as u32; + debug_assert!(len <= MAX_LEN); + SpanData { + lo: BytePos(self.lo_or_index), + hi: BytePos(self.lo_or_index.debug_strict_add(len)), + ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), + parent: None, + } + } + #[inline] + fn data_inline_parent(self) -> SpanData { + let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; + debug_assert!(len <= MAX_LEN); + let parent = LocalDefId { + local_def_index: DefIndex::from_u32(self.ctxt_or_parent_or_marker as u32), + }; + SpanData { + lo: BytePos(self.lo_or_index), + hi: BytePos(self.lo_or_index.debug_strict_add(len)), + ctxt: SyntaxContext::root(), + parent: Some(parent), + } + } + #[inline] + fn data_partially_interned(self) -> SpanData { + SpanData { + ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), + ..with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + } + } + #[inline] + fn data_interned(self) -> SpanData { + with_span_interner(|interner| interner.spans[self.lo_or_index as usize]) + } +} + // `MAX_LEN` is chosen so that `PARENT_TAG | MAX_LEN` is distinct from // `BASE_LEN_INTERNED_MARKER`. (If `MAX_LEN` was 1 higher, this wouldn't be true.) const MAX_LEN: u32 = 0b0111_1111_1111_1110; @@ -111,42 +150,49 @@ impl Span { std::mem::swap(&mut lo, &mut hi); } - let (lo2, len, ctxt2) = (lo.0, hi.0 - lo.0, ctxt.as_u32()); - + // Small len may enable one of fully inline formats (or may not). + let (len, ctxt32) = (hi.0 - lo.0, ctxt.as_u32()); if len <= MAX_LEN { - if ctxt2 <= MAX_CTXT && parent.is_none() { + if ctxt32 <= MAX_CTXT && parent.is_none() { // Inline-context format. return Span { - lo_or_index: lo2, + lo_or_index: lo.0, len_with_tag_or_marker: len as u16, - ctxt_or_parent_or_marker: ctxt2 as u16, + ctxt_or_parent_or_marker: ctxt32 as u16, }; - } else if ctxt2 == SyntaxContext::root().as_u32() + } else if ctxt32 == 0 && let Some(parent) = parent - && let parent2 = parent.local_def_index.as_u32() - && parent2 <= MAX_CTXT + && let parent32 = parent.local_def_index.as_u32() + && parent32 <= MAX_CTXT { // Inline-parent format. return Span { - lo_or_index: lo2, + lo_or_index: lo.0, len_with_tag_or_marker: PARENT_TAG | len as u16, - ctxt_or_parent_or_marker: parent2 as u16, + ctxt_or_parent_or_marker: parent32 as u16, }; } } - // Partially-interned or fully-interned format. - let index = - with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })); - let ctxt_or_parent_or_marker = if ctxt2 <= MAX_CTXT { - ctxt2 as u16 // partially-interned - } else { - CTXT_INTERNED_MARKER // fully-interned + // Otherwise small ctxt may enable the partially inline format. + let index = |ctxt| { + with_span_interner(|interner| interner.intern(&SpanData { lo, hi, ctxt, parent })) }; - Span { - lo_or_index: index, - len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, - ctxt_or_parent_or_marker, + if ctxt32 <= MAX_CTXT { + // Partially-interned format. + Span { + // Interned ctxt should never be read, so it can use any value. + lo_or_index: index(SyntaxContext::from_u32(u32::MAX)), + len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, + ctxt_or_parent_or_marker: ctxt32 as u16, + } + } else { + // Interned format. + Span { + lo_or_index: index(ctxt), + len_with_tag_or_marker: BASE_LEN_INTERNED_MARKER, + ctxt_or_parent_or_marker: CTXT_INTERNED_MARKER, + } } } @@ -166,34 +212,17 @@ impl Span { if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { if self.len_with_tag_or_marker & PARENT_TAG == 0 { // Inline-context format. - let len = self.len_with_tag_or_marker as u32; - debug_assert!(len <= MAX_LEN); - SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), - ctxt: SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32), - parent: None, - } + self.data_inline_ctxt() } else { // Inline-parent format. - let len = (self.len_with_tag_or_marker & !PARENT_TAG) as u32; - debug_assert!(len <= MAX_LEN); - let parent = LocalDefId { - local_def_index: DefIndex::from_u32(self.ctxt_or_parent_or_marker as u32), - }; - SpanData { - lo: BytePos(self.lo_or_index), - hi: BytePos(self.lo_or_index.debug_strict_add(len)), - ctxt: SyntaxContext::root(), - parent: Some(parent), - } + self.data_inline_parent() } + } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { + // Partially-interned format. + self.data_partially_interned() } else { - // Fully-interned or partially-interned format. In either case, - // the interned value contains all the data, so we don't need to - // distinguish them. - let index = self.lo_or_index; - with_span_interner(|interner| interner.spans[index as usize]) + // Interned format. + self.data_interned() } } @@ -214,27 +243,73 @@ impl Span { } } + // For optimization we are interested in cases in which the context is inline and the context + // update doesn't change format. All non-inline or format changing scenarios require accessing + // interner and can fall back to `Span::new`. + #[inline] + pub fn update_ctxt(&mut self, update: impl FnOnce(SyntaxContext) -> SyntaxContext) { + let (updated_ctxt32, data); + if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + if self.len_with_tag_or_marker & PARENT_TAG == 0 { + // Inline-context format. + updated_ctxt32 = + update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); + // Any small new context including zero will preserve the format. + if updated_ctxt32 <= MAX_CTXT { + self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; + return; + } + data = self.data_inline_ctxt(); + } else { + // Inline-parent format. + updated_ctxt32 = update(SyntaxContext::root()).as_u32(); + // Only if the new context is zero the format will be preserved. + if updated_ctxt32 == 0 { + // Do nothing. + return; + } + data = self.data_inline_parent(); + } + } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { + // Partially-interned format. + updated_ctxt32 = + update(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)).as_u32(); + // Any small new context excluding zero will preserve the format. + // Zero may change the format to `InlineParent` if parent and len are small enough. + if updated_ctxt32 <= MAX_CTXT && updated_ctxt32 != 0 { + self.ctxt_or_parent_or_marker = updated_ctxt32 as u16; + return; + } + data = self.data_partially_interned(); + } else { + // Interned format. + data = self.data_interned(); + updated_ctxt32 = update(data.ctxt).as_u32(); + } + + // We could not keep the span in the same inline format, fall back to the complete logic. + *self = data.with_ctxt(SyntaxContext::from_u32(updated_ctxt32)); + } + // Returns either syntactic context, if it can be retrieved without taking the interner lock, // or an index into the interner if it cannot. #[inline] fn inline_ctxt(self) -> Result { - Ok(if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { + if self.len_with_tag_or_marker != BASE_LEN_INTERNED_MARKER { if self.len_with_tag_or_marker & PARENT_TAG == 0 { // Inline-context format. - SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32) + Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) } else { - // Inline-parent format. We know that the SyntaxContext is root. - SyntaxContext::root() + // Inline-parent format. + Ok(SyntaxContext::root()) } } else if self.ctxt_or_parent_or_marker != CTXT_INTERNED_MARKER { - // Partially-interned format. This path avoids looking up the - // interned value, and is the whole point of the - // partially-interned format. - SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32) + // Partially-interned format. + Ok(SyntaxContext::from_u32(self.ctxt_or_parent_or_marker as u32)) } else { - // Fully-interned format. - return Err(self.lo_or_index as usize); - }) + // Interned format. + Err(self.lo_or_index as usize) + } } /// This function is used as a fast path when decoding the full `SpanData` is not necessary. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 935942641677..e245dfb9f5d7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1304,6 +1304,7 @@ symbols! { offset_of, offset_of_enum, offset_of_nested, + offset_of_slice, ok_or_else, omit_gdb_pretty_printer_section, on, diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 666efd9deca2..737e9a8eab02 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -256,29 +256,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } - pub fn offset_of_subfield(self, cx: &C, indices: I) -> Size - where - Ty: TyAbiInterface<'a, C>, - I: Iterator, - { - let mut layout = self; - let mut offset = Size::ZERO; - - for (variant, field) in indices { - layout = layout.for_variant(cx, variant); - let index = field.index(); - offset += layout.fields.offset(index); - layout = layout.field(cx, index); - assert!( - layout.is_sized(), - "offset of unsized field (type {:?}) cannot be computed statically", - layout.ty - ); - } - - offset - } - /// Finds the one field that is not a 1-ZST. /// Returns `None` if there are multiple non-1-ZST fields or only 1-ZST-fields. pub fn non_1zst_field(&self, cx: &C) -> Option<(usize, Self)> diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 604b68d2cd4a..eae1a9dfaa2c 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -420,7 +420,7 @@ pub(crate) mod rustc { fn from_tag(tag: ScalarInt, tcx: TyCtxt<'tcx>) -> Self { use rustc_target::abi::Endian; let size = tag.size(); - let bits = tag.assert_bits(size); + let bits = tag.to_bits(size); let bytes: [u8; 16]; let bytes = match tcx.data_layout.endian { Endian::Little => { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 1aec40e95f69..58f812fc7cfa 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -47,7 +47,7 @@ fn destructure_const<'tcx>( ty::Adt(def, args) => { let (variant_idx, branches) = if def.is_enum() { let (head, rest) = branches.split_first().unwrap(); - (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest) + (VariantIdx::from_u32(head.unwrap_leaf().to_u32()), rest) } else { (FIRST_VARIANT, branches) }; diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index c61e217bf9f0..4ed611527365 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -4,5 +4,4 @@ version = "0.1.0-preview" edition = "2021" [dependencies] -tracing = "0.1" scoped-tls = "1.0" diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 9362dc876549..129f62fb43d1 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -68,6 +68,13 @@ pub mod consts { pub const FRAC_1_SQRT_PI: f128 = 0.564189583547756286948079451560772585844050629328998856844086_f128; + /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] + #[unstable(feature = "f128", issue = "116909")] + // Also, #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f128 = + 0.398942280401432677939946059934381868475858631164934657665926_f128; + /// 2/π #[unstable(feature = "f128", issue = "116909")] pub const FRAC_2_PI: f128 = 0.636619772367581343075535053490057448137838582961825794990669_f128; diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index c4d4584544ba..7a488cd6bf6f 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -67,6 +67,12 @@ pub mod consts { // Also, #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f16 = 0.564189583547756286948079451560772586_f16; + /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] + #[unstable(feature = "f16", issue = "116909")] + // Also, #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f16 = 0.398942280401432677939946059934381868_f16; + /// 2/π #[unstable(feature = "f16", issue = "116909")] pub const FRAC_2_PI: f16 = 0.636619772367581343075535053490057448_f16; diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 22b24937cbce..9d34d3da9e95 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -327,6 +327,11 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f32 = 0.564189583547756286948079451560772586_f32; + /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] + #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f32 = 0.398942280401432677939946059934381868_f32; + /// 2/π #[stable(feature = "rust1", since = "1.0.0")] pub const FRAC_2_PI: f32 = 0.636619772367581343075535053490057448_f32; diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 34357d1b05ad..95f021b2541a 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -327,6 +327,11 @@ pub mod consts { #[unstable(feature = "more_float_constants", issue = "103883")] pub const FRAC_1_SQRT_PI: f64 = 0.564189583547756286948079451560772586_f64; + /// 1/sqrt(2π) + #[doc(alias = "FRAC_1_SQRT_TAU")] + #[unstable(feature = "more_float_constants", issue = "103883")] + pub const FRAC_1_SQRT_2PI: f64 = 0.398942280401432677939946059934381868_f64; + /// 2/π #[stable(feature = "rust1", since = "1.0.0")] pub const FRAC_2_PI: f64 = 0.636619772367581343075535053490057448_f64; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index fcdd983343d6..863f0d61df37 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -517,9 +517,13 @@ macro_rules! nonzero_integer { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ").unwrap();")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(", $leading_zeros_test, ")?;")] /// /// assert_eq!(n.leading_zeros(), 0); + /// # Some(()) + /// # } /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] @@ -545,9 +549,13 @@ macro_rules! nonzero_integer { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000).unwrap();")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::new(0b0101000)?;")] /// /// assert_eq!(n.trailing_zeros(), 3); + /// # Some(()) + /// # } /// ``` #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")] @@ -1101,9 +1109,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ").unwrap().ilog2(), 2);")] - #[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ").unwrap().ilog2(), 3);")] - #[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ").unwrap().ilog2(), 3);")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("assert_eq!(NonZero::new(7", stringify!($Int), ")?.ilog2(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(8", stringify!($Int), ")?.ilog2(), 3);")] + #[doc = concat!("assert_eq!(NonZero::new(9", stringify!($Int), ")?.ilog2(), 3);")] + /// # Some(()) + /// # } /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1126,9 +1138,13 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` /// # use std::num::NonZero; /// # - #[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ").unwrap().ilog10(), 1);")] - #[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ").unwrap().ilog10(), 2);")] - #[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ").unwrap().ilog10(), 2);")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("assert_eq!(NonZero::new(99", stringify!($Int), ")?.ilog10(), 1);")] + #[doc = concat!("assert_eq!(NonZero::new(100", stringify!($Int), ")?.ilog10(), 2);")] + #[doc = concat!("assert_eq!(NonZero::new(101", stringify!($Int), ")?.ilog10(), 2);")] + /// # Some(()) + /// # } /// ``` #[stable(feature = "int_log", since = "1.67.0")] #[rustc_const_stable(feature = "int_log", since = "1.67.0")] @@ -1187,10 +1203,16 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// Basic usage: /// /// ``` - #[doc = concat!("let eight = std::num::NonZero::new(8", stringify!($Int), ").unwrap();")] + /// # use std::num::NonZero; + /// # + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let eight = NonZero::new(8", stringify!($Int), ")?;")] /// assert!(eight.is_power_of_two()); - #[doc = concat!("let ten = std::num::NonZero::new(10", stringify!($Int), ").unwrap();")] + #[doc = concat!("let ten = NonZero::new(10", stringify!($Int), ")?;")] /// assert!(!ten.is_power_of_two()); + /// # Some(()) + /// # } /// ``` #[must_use] #[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")] diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index b5c7d30da7bc..2e71ceceb58b 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -462,21 +462,21 @@ pub fn current_exe() -> io::Result { #[cfg(target_os = "haiku")] pub fn current_exe() -> io::Result { + let mut name = vec![0; libc::PATH_MAX as usize]; unsafe { - let mut info: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let mut cookie: i32 = 0; - // the executable can be found at team id 0 - let result = libc::_get_next_image_info( - 0, - &mut cookie, - info.as_mut_ptr(), - mem::size_of::(), + let result = libc::find_path( + crate::ptr::null_mut(), + libc::path_base_directory::B_FIND_PATH_IMAGE_PATH, + crate::ptr::null_mut(), + name.as_mut_ptr(), + name.len(), ); - if result != 0 { + if result != libc::B_OK { use crate::io::ErrorKind; Err(io::const_io_error!(ErrorKind::Uncategorized, "Error getting executable path")) } else { - let name = CStr::from_ptr((*info.as_ptr()).name.as_ptr()).to_bytes(); + // find_path adds the null terminator. + let name = CStr::from_ptr(name.as_ptr()).to_bytes(); Ok(PathBuf::from(OsStr::from_bytes(name))) } } diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index e2fca8c7e63d..72bda90a9ba7 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -1053,6 +1053,10 @@ fn signal_string(signal: i32) -> &'static str { libc::SIGINFO => " (SIGINFO)", #[cfg(target_os = "hurd")] libc::SIGLOST => " (SIGLOST)", + #[cfg(target_os = "freebsd")] + libc::SIGTHR => " (SIGTHR)", + #[cfg(target_os = "freebsd")] + libc::SIGLIBRT => " (SIGLIBRT)", _ => "", } } diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs index 555ad581b856..17a0e47ad595 100644 --- a/library/std/src/sys/pal/windows/api.rs +++ b/library/std/src/sys/pal/windows/api.rs @@ -251,3 +251,39 @@ pub fn get_last_error() -> WinError { pub struct WinError { pub code: u32, } +impl WinError { + const fn new(code: u32) -> Self { + Self { code } + } +} + +// Error code constants. +// The constant names should be the same as the winapi constants except for the leading `ERROR_`. +// Due to the sheer number of codes, error codes should only be added here on an as-needed basis. +// However, they should never be removed as the assumption is they may be useful again in the future. +#[allow(unused)] +impl WinError { + /// Success is not an error. + /// Some Windows APIs do use this to distinguish between a zero return and an error return + /// but we should never return this to users as an error. + pub const SUCCESS: Self = Self::new(c::ERROR_SUCCESS); + // tidy-alphabetical-start + pub const ACCESS_DENIED: Self = Self::new(c::ERROR_ACCESS_DENIED); + pub const ALREADY_EXISTS: Self = Self::new(c::ERROR_ALREADY_EXISTS); + pub const CANT_ACCESS_FILE: Self = Self::new(c::ERROR_CANT_ACCESS_FILE); + pub const DELETE_PENDING: Self = Self::new(c::ERROR_DELETE_PENDING); + pub const DIRECTORY: Self = Self::new(c::ERROR_DIRECTORY); + pub const FILE_NOT_FOUND: Self = Self::new(c::ERROR_FILE_NOT_FOUND); + pub const INSUFFICIENT_BUFFER: Self = Self::new(c::ERROR_INSUFFICIENT_BUFFER); + pub const INVALID_FUNCTION: Self = Self::new(c::ERROR_INVALID_FUNCTION); + pub const INVALID_HANDLE: Self = Self::new(c::ERROR_INVALID_HANDLE); + pub const INVALID_PARAMETER: Self = Self::new(c::ERROR_INVALID_PARAMETER); + pub const NO_MORE_FILES: Self = Self::new(c::ERROR_NO_MORE_FILES); + pub const NOT_FOUND: Self = Self::new(c::ERROR_NOT_FOUND); + pub const NOT_SUPPORTED: Self = Self::new(c::ERROR_NOT_SUPPORTED); + pub const OPERATION_ABORTED: Self = Self::new(c::ERROR_OPERATION_ABORTED); + pub const PATH_NOT_FOUND: Self = Self::new(c::ERROR_PATH_NOT_FOUND); + pub const SHARING_VIOLATION: Self = Self::new(c::ERROR_SHARING_VIOLATION); + pub const TIMEOUT: Self = Self::new(c::ERROR_TIMEOUT); + // tidy-alphabetical-end +} diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index e92c5e80eac9..629ff114b5a8 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -18,7 +18,8 @@ use crate::sys::{c, cvt, Align8}; use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::thread; -use super::{api, to_u16s, IoResult}; +use super::api::{self, WinError}; +use super::{to_u16s, IoResult}; use crate::sys::path::maybe_verbatim; pub struct File { @@ -130,10 +131,11 @@ impl Iterator for ReadDir { let mut wfd = mem::zeroed(); loop { if c::FindNextFileW(self.handle.0, &mut wfd) == 0 { - if api::get_last_error().code == c::ERROR_NO_MORE_FILES { - return None; - } else { - return Some(Err(Error::last_os_error())); + match api::get_last_error() { + WinError::NO_MORE_FILES => return None, + WinError { code } => { + return Some(Err(Error::from_raw_os_error(code as i32))); + } } } if let Some(e) = DirEntry::new(&self.root, &wfd) { @@ -244,8 +246,6 @@ impl OpenOptions { } fn get_access_mode(&self) -> io::Result { - const ERROR_INVALID_PARAMETER: i32 = 87; - match (self.read, self.write, self.append, self.access_mode) { (.., Some(mode)) => Ok(mode), (true, false, false, None) => Ok(c::GENERIC_READ), @@ -255,23 +255,23 @@ impl OpenOptions { (true, _, true, None) => { Ok(c::GENERIC_READ | (c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA)) } - (false, false, false, None) => Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)), + (false, false, false, None) => { + Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)) + } } } fn get_creation_mode(&self) -> io::Result { - const ERROR_INVALID_PARAMETER: i32 = 87; - match (self.write, self.append) { (true, false) => {} (false, false) => { if self.truncate || self.create || self.create_new { - return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); + return Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)); } } (_, true) => { if self.truncate && !self.create_new { - return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)); + return Err(Error::from_raw_os_error(c::ERROR_INVALID_PARAMETER as i32)); } } } @@ -315,7 +315,7 @@ impl File { // Manual truncation. See #115745. if opts.truncate && creation == c::OPEN_ALWAYS - && unsafe { c::GetLastError() } == c::ERROR_ALREADY_EXISTS + && api::get_last_error() == WinError::ALREADY_EXISTS { unsafe { // This originally used `FileAllocationInfo` instead of @@ -845,7 +845,7 @@ fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result< // We make a special exception for `STATUS_DELETE_PENDING` because // otherwise this will be mapped to `ERROR_ACCESS_DENIED` which is // very unhelpful. - Err(io::Error::from_raw_os_error(c::ERROR_DELETE_PENDING as _)) + Err(io::Error::from_raw_os_error(c::ERROR_DELETE_PENDING as i32)) } else if status == c::STATUS_INVALID_PARAMETER && ATTRIBUTES.load(Ordering::Relaxed) == c::OBJ_DONT_REPARSE { @@ -1097,7 +1097,7 @@ pub fn readdir(p: &Path) -> io::Result { // // See issue #120040: https://github.com/rust-lang/rust/issues/120040. let last_error = api::get_last_error(); - if last_error.code == c::ERROR_FILE_NOT_FOUND { + if last_error == WinError::FILE_NOT_FOUND { return Ok(ReadDir { handle: FindNextFileHandle(find_handle), root: Arc::new(root), diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs index bc19c402d9c1..08b7fe300dc3 100644 --- a/library/std/src/sys/pal/windows/futex.rs +++ b/library/std/src/sys/pal/windows/futex.rs @@ -1,4 +1,4 @@ -use super::api; +use super::api::{self, WinError}; use crate::sys::c; use crate::sys::dur2timeout; use core::ffi::c_void; @@ -72,7 +72,7 @@ pub fn wake_by_address_all(address: &T) { pub fn futex_wait(futex: &W::Atomic, expected: W, timeout: Option) -> bool { // return false only on timeout - wait_on_address(futex, expected, timeout) || api::get_last_error().code != c::ERROR_TIMEOUT + wait_on_address(futex, expected, timeout) || api::get_last_error() != WinError::TIMEOUT } pub fn futex_wake(futex: &T) -> bool { diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 483b8b0072c8..62199c16bfed 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -17,7 +17,8 @@ use crate::ptr; use crate::slice; use crate::sys::{c, cvt}; -use super::{api, to_u16s}; +use super::api::{self, WinError}; +use super::to_u16s; pub fn errno() -> i32 { api::get_last_error().code as i32 @@ -333,7 +334,7 @@ fn home_dir_crt() -> Option { buf, &mut sz, ) { - 0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0, + 0 if api::get_last_error() != WinError::INSUFFICIENT_BUFFER => 0, 0 => sz, _ => sz - 1, // sz includes the null terminator } @@ -358,7 +359,7 @@ fn home_dir_crt() -> Option { super::fill_utf16_buf( |buf, mut sz| { match c::GetUserProfileDirectoryW(token, buf, &mut sz) { - 0 if api::get_last_error().code != c::ERROR_INSUFFICIENT_BUFFER => 0, + 0 if api::get_last_error() != WinError::INSUFFICIENT_BUFFER => 0, 0 => sz, _ => sz - 1, // sz includes the null terminator } diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index dfa938d4d576..67ef3ca82da0 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -12,6 +12,7 @@ use crate::sys::c; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; use crate::sys::hashmap_random_keys; +use crate::sys::pal::windows::api::{self, WinError}; use crate::sys_common::{FromInner, IntoInner}; //////////////////////////////////////////////////////////////////////////////// @@ -124,20 +125,19 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res // testing strategy // For more info, see https://github.com/rust-lang/rust/pull/37677. if handle == c::INVALID_HANDLE_VALUE { - let err = io::Error::last_os_error(); - let raw_os_err = err.raw_os_error(); + let error = api::get_last_error(); if tries < 10 { - if raw_os_err == Some(c::ERROR_ACCESS_DENIED as i32) { + if error == WinError::ACCESS_DENIED { continue; } else if reject_remote_clients_flag != 0 - && raw_os_err == Some(c::ERROR_INVALID_PARAMETER as i32) + && error == WinError::INVALID_PARAMETER { reject_remote_clients_flag = 0; tries -= 1; continue; } } - return Err(err); + return Err(io::Error::from_raw_os_error(error.code as i32)); } ours = Handle::from_raw_handle(handle); break; diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index e4ab2ca7da1c..2da986a1494e 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -31,6 +31,8 @@ use crate::sys_common::IntoInner; use core::ffi::c_void; +use super::api::{self, WinError}; + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -645,12 +647,12 @@ impl Process { pub fn kill(&mut self) -> io::Result<()> { let result = unsafe { c::TerminateProcess(self.handle.as_raw_handle(), 1) }; if result == c::FALSE { - let error = unsafe { c::GetLastError() }; + let error = api::get_last_error(); // TerminateProcess returns ERROR_ACCESS_DENIED if the process has already been // terminated (by us, or for any other reason). So check if the process was actually // terminated, and if so, do not return an error. - if error != c::ERROR_ACCESS_DENIED || self.try_wait().is_err() { - return Err(crate::io::Error::from_raw_os_error(error as i32)); + if error != WinError::ACCESS_DENIED || self.try_wait().is_err() { + return Err(crate::io::Error::from_raw_os_error(error.code as i32)); } } Ok(()) diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 96c23f82aec2..690b60d1decc 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -1,6 +1,6 @@ #![unstable(issue = "none", feature = "windows_stdio")] -use super::api; +use super::api::{self, WinError}; use crate::cmp; use crate::io; use crate::mem::MaybeUninit; @@ -370,7 +370,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit]) -> io::Result) { + builder.build.update_submodule(Path::new("src/tools/rustc-perf")); + let mut cmd = builder.tool_cmd(Tool::Tidy); cmd.arg(&builder.src); cmd.arg(&builder.initial_cargo); @@ -1487,12 +1489,6 @@ impl Step for RunMake { } } -host_test!(RunMakeFullDeps { - path: "tests/run-make-fulldeps", - mode: "run-make", - suite: "run-make-fulldeps" -}); - default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); /// Coverage tests are a bit more complicated than other test suites, because @@ -1973,9 +1969,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd); } - if !builder.config.dry_run() - && (matches!(suite, "run-make" | "run-make-fulldeps") || mode == "coverage-run") - { + if !builder.config.dry_run() && matches!(mode, "run-make" | "coverage-run") { // The llvm/bin directory contains many useful cross-platform // tools. Pass the path to run-make tests so they can use them. // (The coverage-run tests also need these tools to process @@ -1987,7 +1981,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--llvm-bin-dir").arg(llvm_bin_path); } - if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && mode == "run-make" { // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = @@ -2007,7 +2001,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the // Only pass correct values for these flags for the `run-make` suite as it // requires that a C++ compiler was configured which isn't always the case. - if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") { + if !builder.config.dry_run() && mode == "run-make" { cmd.arg("--cc") .arg(builder.cc(target)) .arg("--cxx") diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index b3d8465cda98..12d2bb18ab7c 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -332,7 +332,6 @@ const PATH_REMAP: &[(&str, &[&str])] = &[ "tests/mir-opt", "tests/pretty", "tests/run-make", - "tests/run-make-fulldeps", "tests/run-pass-valgrind", "tests/rustdoc", "tests/rustdoc-gui", @@ -828,7 +827,6 @@ impl<'a> Builder<'a> { test::RustAnalyzer, test::ErrorIndex, test::Distcheck, - test::RunMakeFullDeps, test::Nomicon, test::Reference, test::RustdocBook, @@ -1038,14 +1036,26 @@ impl<'a> Builder<'a> { } pub fn doc_rust_lang_org_channel(&self) -> String { - let channel = match &*self.config.channel { - "stable" => &self.version, - "beta" => "beta", - "nightly" | "dev" => "nightly", - // custom build of rustdoc maybe? link to the latest stable docs just in case - _ => "stable", + // When using precompiled compiler from CI, we need to use CI rustc's channel and + // ignore `rust.channel` from the configuration. Otherwise most of the rustdoc tests + // will fail due to incompatible `DOC_RUST_LANG_ORG_CHANNEL`. + let channel = if let Some(commit) = self.config.download_rustc_commit() { + self.config + .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) + .trim() + .to_owned() + } else { + match &*self.config.channel { + "stable" => &self.version, + "beta" => "beta", + "nightly" | "dev" => "nightly", + // custom build of rustdoc maybe? link to the latest stable docs just in case + _ => "stable", + } + .to_owned() }; - "https://doc.rust-lang.org/".to_owned() + channel + + format!("https://doc.rust-lang.org/{channel}") } fn run_step_descriptions(&self, v: &[StepDescription], paths: &[PathBuf]) { diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 17e37c1ecd23..36b44d0169c9 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1608,19 +1608,8 @@ impl Config { set(&mut config.channel, channel); config.download_rustc_commit = config.download_ci_rustc_commit(download_rustc); - // This list is incomplete, please help by expanding it! - if config.download_rustc_commit.is_some() { - // We need the channel used by the downloaded compiler to match the one we set for rustdoc; - // otherwise rustdoc-ui tests break. - if config.channel != ci_channel - && !(config.channel == "dev" && ci_channel == "nightly") - { - panic!( - "setting rust.channel={} is incompatible with download-rustc", - config.channel - ); - } - } + + // FIXME: handle download-rustc incompatible options. debug = debug_toml; debug_assertions = debug_assertions_toml; @@ -2134,17 +2123,29 @@ impl Config { args } + /// Returns the content of the given file at a specific commit. + pub(crate) fn read_file_by_commit(&self, file: &Path, commit: &str) -> String { + assert!( + self.rust_info.is_managed_git_subrepository(), + "`Config::read_file_by_commit` is not supported in non-git sources." + ); + + let mut git = self.git(); + git.arg("show").arg(format!("{commit}:{}", file.to_str().unwrap())); + output(&mut git) + } + /// Bootstrap embeds a version number into the name of shared libraries it uploads in CI. /// Return the version it would have used for the given commit. pub(crate) fn artifact_version_part(&self, commit: &str) -> String { let (channel, version) = if self.rust_info.is_managed_git_subrepository() { - let mut channel = self.git(); - channel.arg("show").arg(format!("{commit}:src/ci/channel")); - let channel = output(&mut channel); - let mut version = self.git(); - version.arg("show").arg(format!("{commit}:src/version")); - let version = output(&mut version); - (channel.trim().to_owned(), version.trim().to_owned()) + let channel = self + .read_file_by_commit(&PathBuf::from("src/ci/channel"), commit) + .trim() + .to_owned(); + let version = + self.read_file_by_commit(&PathBuf::from("src/version"), commit).trim().to_owned(); + (channel, version) } else { let channel = fs::read_to_string(self.src.join("src/ci/channel")); let version = fs::read_to_string(self.src.join("src/version")); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index e3556cb16b05..b5f17b9f54ed 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -128,7 +128,6 @@ pub fn check(build: &mut Build) { eprintln!( "Consider upgrading libstdc++ or disabling the `llvm.download-ci-llvm` option." ); - crate::exit!(1); } } tool::LibcxxVersion::Llvm(_) => { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 9af368ef4450..824c904e17f7 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -233,7 +233,7 @@ For targets: `aarch64-unknown-linux-gnu` - Operating System > Linux kernel version = 4.1.49 - Binary utilities > Version of binutils = 2.29.1 - C-library > glibc version = 2.17 -- aarch64 support was introduced in this version -- C compiler > gcc version = 8.5.0 +- C compiler > gcc version = 13.2.0 - C compiler > C++ = ENABLE -- to cross compile LLVM ### `i586-linux-gnu.defconfig` diff --git a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig index 47e984ef85a2..520b1667c8be 100644 --- a/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig +++ b/src/ci/docker/host-x86_64/dist-aarch64-linux/aarch64-linux-gnu.defconfig @@ -6,7 +6,5 @@ CT_ARCH_ARM=y CT_ARCH_64=y CT_KERNEL_LINUX=y CT_LINUX_V_4_1=y -CT_BINUTILS_V_2_29=y CT_GLIBC_V_2_17=y -CT_GCC_V_8=y CT_CC_LANG_CXX=y diff --git a/src/ci/docker/host-x86_64/rfl/Dockerfile b/src/ci/docker/host-x86_64/rfl/Dockerfile new file mode 100644 index 000000000000..97298519cf20 --- /dev/null +++ b/src/ci/docker/host-x86_64/rfl/Dockerfile @@ -0,0 +1,40 @@ +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive + +# libclang1 is required for libclang.so, required by bindgen +# clang, llvm and lld is required by RfL to compile host code +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + git \ + cmake \ + flex \ + bison \ + bc \ + clang-15 \ + libclang1-15 \ + llvm-15 \ + lld-15 \ + libelf-dev \ + libedit-dev \ + libssl-dev \ + pkg-config \ + zlib1g-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +# RfL needs access to cland, lld and llvm tools +ENV PATH="${PATH}:/usr/lib/llvm-15/bin" + +ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu + +COPY /scripts/rfl-build.sh /tmp/rfl-build.sh +ENV SCRIPT bash /tmp/rfl-build.sh diff --git a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock index b0c17d9a296c..dacf531e4048 100644 --- a/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock +++ b/src/ci/docker/host-x86_64/test-various/uefi_qemu_test/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "r-efi" -version = "4.4.0" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47196f636c4cc0634b73b0405323d177753c2e15e866952c64ea22902567a34" +checksum = "e9e935efc5854715dfc0a4c9ef18dc69dee0ec3bf9cc3ab740db831c0fdd86a3" [[package]] name = "uefi_qemu_test" diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile index e4534d0f8408..64a1fb093b49 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-debug/Dockerfile @@ -44,6 +44,14 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-linux-gnu.cc=clang \ --set target.x86_64-unknown-linux-gnu.cxx=clang++ +# This job appears to be checking two separate things: +# - That we can build the compiler with `--enable-debug` +# (without necessarily testing the result). +# - That the tests with `//@ needs-matching-clang` pass, since they +# don't run by default unless RUSTBUILD_FORCE_CLANG_BASED_TESTS is set. +# - FIXME(https://github.com/rust-lang/rust/pull/126155#issuecomment-2156314273): +# Currently we only run the subset of tests with "clang" in their name. + ENV SCRIPT \ python3 ../x.py --stage 2 build && \ - python3 ../x.py --stage 2 test tests/run-make-fulldeps --test-args clang + python3 ../x.py --stage 2 test tests/run-make --test-args clang diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh new file mode 100755 index 000000000000..da7b029ca732 --- /dev/null +++ b/src/ci/docker/scripts/rfl-build.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -euo pipefail + +LINUX_VERSION=c13320499ba0efd93174ef6462ae8a7a2933f6e7 + +# Build rustc, rustdoc and cargo +../x.py build --stage 1 library rustdoc +../x.py build --stage 0 cargo + +# Install rustup so that we can use the built toolchain easily, and also +# install bindgen in an easy way. +curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs +sh rustup.sh -y --default-toolchain none + +source /cargo/env + +BUILD_DIR=$(realpath ./build) +rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage1 +rustup default local + +mkdir -p rfl +cd rfl + +# Remove existing directory to make local builds easier +rm -rf linux || true + +# Download Linux at a specific commit +mkdir -p linux +git -C linux init +git -C linux remote add origin https://github.com/torvalds/linux.git +git -C linux fetch --depth 1 origin ${LINUX_VERSION} +git -C linux checkout FETCH_HEAD + +# Install bindgen +"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \ + --version $(linux/scripts/min-tool-version.sh bindgen) \ + bindgen-cli + +# Configure Rust for Linux +cat < linux/kernel/configs/rfl-for-rust-ci.config +# CONFIG_WERROR is not set + +CONFIG_RUST=y + +CONFIG_SAMPLES=y +CONFIG_SAMPLES_RUST=y + +CONFIG_SAMPLE_RUST_MINIMAL=m +CONFIG_SAMPLE_RUST_PRINT=y + +CONFIG_RUST_PHYLIB_ABSTRACTIONS=y +CONFIG_AX88796B_PHY=y +CONFIG_AX88796B_RUST_PHY=y + +CONFIG_KUNIT=y +CONFIG_RUST_KERNEL_DOCTESTS=y +EOF + +make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + rustavailable \ + defconfig \ + rfl-for-rust-ci.config + +make -C linux LLVM=1 -j$(($(nproc) + 1)) \ + samples/rust/rust_minimal.o \ + samples/rust/rust_print.o \ + drivers/net/phy/ax88796b_rust.o diff --git a/src/ci/docker/scripts/x86_64-gnu-llvm.sh b/src/ci/docker/scripts/x86_64-gnu-llvm.sh index 876b300d35c6..b3921f114217 100755 --- a/src/ci/docker/scripts/x86_64-gnu-llvm.sh +++ b/src/ci/docker/scripts/x86_64-gnu-llvm.sh @@ -4,13 +4,7 @@ set -ex # Only run the stage 1 tests on merges, not on PR CI jobs. if [[ -z "${PR_CI_JOB}" ]]; then - # When running gcc backend tests, we need to install `libgccjit` and to not run llvm codegen - # tests as it will fail them. - if [[ "${ENABLE_GCC_CODEGEN}" == "1" ]]; then - ../x.py --stage 1 test --skip src/tools/tidy --skip tests/codegen - else - ../x.py --stage 1 test --skip src/tools/tidy - fi + ../x.py --stage 1 test --skip src/tools/tidy # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have @@ -29,14 +23,8 @@ if [[ -z "${PR_CI_JOB}" ]]; then --rustc-args "--cfg feature=\"optimize_for_size\"" fi -# When running gcc backend tests, we need to install `libgccjit` and to not run llvm codegen -# tests as it will fail them. # NOTE: intentionally uses all of `x.py`, `x`, and `x.ps1` to make sure they all work on Linux. -if [[ "${ENABLE_GCC_CODEGEN}" == "1" ]]; then - ../x.py --stage 2 test --skip src/tools/tidy --skip tests/codegen -else - ../x.py --stage 2 test --skip src/tools/tidy -fi +../x.py --stage 2 test --skip src/tools/tidy # Run the `mir-opt` tests again but this time for a 32-bit target. # This enforces that tests using `// EMIT_MIR_FOR_EACH_BIT_WIDTH` have diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 8c84e721f5de..62836acc2d9a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -37,7 +37,7 @@ runners: envs: env-x86_64-apple-tests: &env-x86_64-apple-tests - SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps + SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc RUSTC_RETRY_LINKER_ON_SEGFAULT: 1 MACOSX_DEPLOYMENT_TARGET: 10.12 @@ -294,7 +294,7 @@ auto: - image: x86_64-apple-2 env: - SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps + SCRIPT: ./x.py --stage 2 test tests/ui tests/rustdoc <<: *env-x86_64-apple-tests <<: *job-macos-xl @@ -465,3 +465,8 @@ auto: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler SCRIPT: python x.py dist bootstrap --include-default-paths <<: *job-windows-8c + + # Tests integration with Rust for Linux. + # Builds stage 1 compiler and tries to compile a few RfL examples with it. + - image: rfl + <<: *job-linux-8c diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 56070c2ec34e..51a397a38d20 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -160,8 +160,7 @@ export exclude_tests=' --exclude src/tools/linkchecker --exclude tests/ui-fulldeps --exclude rustc - --exclude rustdoc - --exclude tests/run-make-fulldeps' + --exclude rustdoc' env $build_env \ ./x.py test \ diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7fc3d4508d7d..7c83d4387193 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -431,8 +431,7 @@ fn print_const_with_custom_print_scalar<'tcx>( (mir::Const::Val(mir::ConstValue::Scalar(int), _), ty::Int(i)) => { let ty = ct.ty(); let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size; - let data = int.assert_bits(size); - let sign_extended_data = size.sign_extend(data) as i128; + let sign_extended_data = int.assert_scalar_int().to_int(size); let mut output = if with_underscores { format_integer_with_underscore_sep(&sign_extended_data.to_string()) } else { diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 012afada1e5e..78d4129f6422 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -128,6 +128,8 @@ pub(crate) struct Options { pub(crate) enable_per_target_ignores: bool, /// Do not run doctests, compile them if should_test is active. pub(crate) no_run: bool, + /// What sources are being mapped. + pub(crate) remap_path_prefix: Vec<(PathBuf, PathBuf)>, /// The path to a rustc-like binary to build tests with. If not set, we /// default to loading from `$sysroot/bin/rustc`. @@ -211,6 +213,7 @@ impl fmt::Debug for Options { .field("run_check", &self.run_check) .field("no_run", &self.no_run) .field("test_builder_wrappers", &self.test_builder_wrappers) + .field("remap-file-prefix", &self.remap_path_prefix) .field("nocapture", &self.nocapture) .field("scrape_examples_options", &self.scrape_examples_options) .field("unstable_features", &self.unstable_features) @@ -372,6 +375,13 @@ impl Options { let codegen_options = CodegenOptions::build(early_dcx, matches); let unstable_opts = UnstableOptions::build(early_dcx, matches); + let remap_path_prefix = match parse_remap_path_prefix(&matches) { + Ok(prefix_mappings) => prefix_mappings, + Err(err) => { + early_dcx.early_fatal(err); + } + }; + let dcx = new_dcx(error_format, None, diagnostic_width, &unstable_opts); // check for deprecated options @@ -772,6 +782,7 @@ impl Options { run_check, no_run, test_builder_wrappers, + remap_path_prefix, nocapture, crate_name, output_format, @@ -820,6 +831,21 @@ impl Options { } } +fn parse_remap_path_prefix( + matches: &getopts::Matches, +) -> Result, &'static str> { + matches + .opt_strs("remap-path-prefix") + .into_iter() + .map(|remap| { + remap + .rsplit_once('=') + .ok_or("--remap-path-prefix must contain '=' between FROM and TO") + .map(|(from, to)| (PathBuf::from(from), PathBuf::from(to))) + }) + .collect() +} + /// Prints deprecation warnings for deprecated options fn check_deprecated_options(matches: &getopts::Matches, dcx: &rustc_errors::DiagCtxt) { let deprecated_flags = []; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index a732e645b6ba..81a7463decad 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -129,6 +129,7 @@ pub(crate) fn run( edition: options.edition, target_triple: options.target.clone(), crate_name: options.crate_name.clone(), + remap_path_prefix: options.remap_path_prefix.clone(), ..config::Options::default() }; @@ -572,7 +573,6 @@ fn make_maybe_absolute_path(path: PathBuf) -> PathBuf { std::env::current_dir().map(|c| c.join(&path)).unwrap_or_else(|_| path) } } - struct IndividualTestOptions { outdir: DirState, test_id: String, @@ -651,7 +651,7 @@ impl CreateRunnableDoctests { if !item_path.is_empty() { item_path.push(' '); } - format!("{} - {item_path}(line {line})", filename.prefer_local()) + format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly()) } fn add_test(&mut self, test: ScrapedDoctest) { diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index e6bef395fa9c..fc8e119ccc23 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -27,11 +27,13 @@ struct RustCollector { impl RustCollector { fn get_filename(&self) -> FileName { let filename = self.source_map.span_to_filename(self.position); - if let FileName::Real(ref filename) = filename - && let Ok(cur_dir) = env::current_dir() - && let Some(local_path) = filename.local_path() - && let Ok(path) = local_path.strip_prefix(&cur_dir) - { + if let FileName::Real(ref filename) = filename { + let path = filename.remapped_path_if_available(); + // Strip the cwd prefix from the path. This will likely exist if + // the path was not remapped. + let path = env::current_dir() + .map(|cur_dir| path.strip_prefix(&cur_dir).unwrap_or(path)) + .unwrap_or(path); return path.to_owned().into(); } filename diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 8ac4b53673f4..a0ab262bf0b0 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2399,15 +2399,19 @@ function initSearch(rawSearchIndex) { * @param {boolean} isAssocType */ function convertNameToId(elem, isAssocType) { - if (typeNameIdMap.has(elem.normalizedPathLast) && - (isAssocType || !typeNameIdMap.get(elem.normalizedPathLast).assocOnly)) { - elem.id = typeNameIdMap.get(elem.normalizedPathLast).id; + const loweredName = elem.pathLast.toLowerCase(); + if (typeNameIdMap.has(loweredName) && + (isAssocType || !typeNameIdMap.get(loweredName).assocOnly)) { + elem.id = typeNameIdMap.get(loweredName).id; } else if (!parsedQuery.literalSearch) { let match = null; let matchDist = maxEditDistance + 1; let matchName = ""; for (const [name, {id, assocOnly}] of typeNameIdMap) { - const dist = editDistance(name, elem.normalizedPathLast, maxEditDistance); + const dist = Math.min( + editDistance(name, loweredName, maxEditDistance), + editDistance(name, elem.normalizedPathLast, maxEditDistance), + ); if (dist <= matchDist && dist <= maxEditDistance && (isAssocType || !assocOnly)) { if (dist === matchDist && matchName > name) { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3b6bddf263a9..d6e715d48ea5 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -555,6 +555,14 @@ fn opts() -> Vec { unstable("no-run", |o| { o.optflagmulti("", "no-run", "Compile doctests without running them") }), + unstable("remap-path-prefix", |o| { + o.optmulti( + "", + "remap-path-prefix", + "Remap source names in compiler messages", + "FROM=TO", + ) + }), unstable("show-type-layout", |o| { o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs") }), diff --git a/src/tools/build_helper/README.md b/src/tools/build_helper/README.md new file mode 100644 index 000000000000..f81b631c3fdb --- /dev/null +++ b/src/tools/build_helper/README.md @@ -0,0 +1 @@ +Types and functions shared across tools in this workspace. diff --git a/src/tools/build_helper/src/lib.rs b/src/tools/build_helper/src/lib.rs index 2abda5d3ebf2..15807d1c0d8f 100644 --- a/src/tools/build_helper/src/lib.rs +++ b/src/tools/build_helper/src/lib.rs @@ -1,5 +1,30 @@ +//! Types and functions shared across tools in this workspace. + pub mod ci; pub mod git; pub mod metrics; pub mod stage0_parser; pub mod util; + +/// The default set of crates for opt-dist to collect LLVM profiles. +pub const LLVM_PGO_CRATES: &[&str] = &[ + "syn-1.0.89", + "cargo-0.60.0", + "serde-1.0.136", + "ripgrep-13.0.0", + "regex-1.5.5", + "clap-3.1.6", + "hyper-0.14.18", +]; + +/// The default set of crates for opt-dist to collect rustc profiles. +pub const RUSTC_PGO_CRATES: &[&str] = &[ + "externs", + "ctfe-stress-5", + "cargo-0.60.0", + "token-stream-stress", + "match-stress", + "tuple-stress", + "diesel-1.4.8", + "bitmaps-3.1.0", +]; diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 77d05020c828..7f8197c0cc01 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -55,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity() && let ty::Array(element_type, cst) = ty.kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) + && let element_count = element_count.to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && self.maximum_allowed_size < u128::from(element_count) * u128::from(element_size) { diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs index f0f3f53647b9..c9bfc9c85d95 100644 --- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs @@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { && !self.is_from_vec_macro(cx, expr.span) && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) + && let element_count = element_count.to_target_usize(cx.tcx) && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()) && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| { matches!( diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 76d9cee18aa7..20a97645af95 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -199,7 +199,7 @@ impl<'tcx> NonCopyConst<'tcx> { .any(|field| Self::is_value_unfrozen_raw_inner(cx, *field, ty)), ty::Adt(def, args) if def.is_enum() => { let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); - let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); + let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().to_u32()); fields .iter() .copied() diff --git a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs index 848b49130dc2..8796b8f61d16 100644 --- a/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/zero_repeat_side_effects.rs @@ -56,8 +56,7 @@ impl LateLintPass<'_> for ZeroRepeatSideEffects { } else if let ExprKind::Repeat(inner_expr, _) = expr.kind && let ty::Array(_, cst) = cx.typeck_results().expr_ty(expr).kind() && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind() - && let Ok(element_count) = element_count.try_to_target_usize(cx.tcx) - && element_count == 0 + && element_count.to_target_usize(cx.tcx) == 0 { inner_check(cx, expr, inner_expr, false); } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 5c9cad2b45d4..e9e1aa7e4453 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -810,14 +810,14 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> (ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() { ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)), ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)), - ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))), + ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.to_bits(int.size()))), ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( int.try_into().expect("invalid f32 bit representation"), ))), ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( int.try_into().expect("invalid f64 bit representation"), ))), - ty::RawPtr(_, _) => Some(Constant::RawPtr(int.assert_bits(int.size()))), + ty::RawPtr(_, _) => Some(Constant::RawPtr(int.to_bits(int.size()))), _ => None, }, (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => { diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f0dac6f5d9c4..6e5626297c95 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -23,7 +23,7 @@ use rustc_middle::ty::{ }; use rustc_span::symbol::Ident; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; -use rustc_target::abi::{Size, VariantIdx}; +use rustc_target::abi::VariantIdx; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Obligation, ObligationCause}; @@ -865,22 +865,8 @@ impl core::ops::Add for EnumValue { pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { match tcx.type_of(id).instantiate_identity().kind() { - ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { - 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), - 2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16), - 4 => i128::from(value.assert_bits(Size::from_bytes(4)) as u32 as i32), - 8 => i128::from(value.assert_bits(Size::from_bytes(8)) as u64 as i64), - 16 => value.assert_bits(Size::from_bytes(16)) as i128, - _ => return None, - })), - ty::Uint(_) => Some(EnumValue::Unsigned(match value.size().bytes() { - 1 => value.assert_bits(Size::from_bytes(1)), - 2 => value.assert_bits(Size::from_bytes(2)), - 4 => value.assert_bits(Size::from_bytes(4)), - 8 => value.assert_bits(Size::from_bytes(8)), - 16 => value.assert_bits(Size::from_bytes(16)), - _ => return None, - })), + ty::Int(_) => Some(EnumValue::Signed(value.to_int(value.size()))), + ty::Uint(_) => Some(EnumValue::Unsigned(value.to_uint(value.size()))), _ => None, } } else { diff --git a/src/tools/clippy/tests/ui/unicode.stderr b/src/tools/clippy/tests/ui/unicode.stderr index 9c365e1097db..b004493300ee 100644 --- a/src/tools/clippy/tests/ui/unicode.stderr +++ b/src/tools/clippy/tests/ui/unicode.stderr @@ -11,7 +11,7 @@ error: invisible character detected --> tests/ui/unicode.rs:7:12 | LL | print!("Here >­< is a SHY, and ­another"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >\u{AD}< is a SHY, and \u{AD}another"` error: invisible character detected --> tests/ui/unicode.rs:9:12 diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs index b2b81df55bb3..c3b34f0c0c6b 100644 --- a/src/tools/miri/src/intrinsics/simd.rs +++ b/src/tools/miri/src/intrinsics/simd.rs @@ -645,8 +645,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { for i in 0..dest_len { let src_index: u64 = index[usize::try_from(i).unwrap()] .unwrap_leaf() - .try_to_u32() - .unwrap() + .to_u32() .into(); let dest = this.project_index(&dest, i)?; diff --git a/src/tools/miri/src/shims/unix/socket.rs b/src/tools/miri/src/shims/unix/socket.rs index c14cb750146f..02f49713b568 100644 --- a/src/tools/miri/src/shims/unix/socket.rs +++ b/src/tools/miri/src/shims/unix/socket.rs @@ -222,9 +222,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let fds = &mut this.machine.fds; let sv0 = fds.insert_fd(FileDescriptor::new(socketpair_0)); - let sv0 = Scalar::try_from_int(sv0, sv.layout.size).unwrap(); + let sv0 = Scalar::from_int(sv0, sv.layout.size); let sv1 = fds.insert_fd(FileDescriptor::new(socketpair_1)); - let sv1 = Scalar::try_from_int(sv1, sv.layout.size).unwrap(); + let sv1 = Scalar::from_int(sv1, sv.layout.size); this.write_scalar(sv0, &sv)?; this.write_scalar(sv1, &sv.offset(sv.layout.size, sv.layout, this)?)?; diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs index c4ec45e4bbef..03d9fc0a76fe 100644 --- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs +++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs @@ -658,11 +658,32 @@ fn simd_masked_loadstore() { assert_eq!(buf, [2, 3, 4]); } +fn simd_ops_non_pow2() { + // Just a little smoke test for operations on non-power-of-two vectors. + #[repr(simd, packed)] + #[derive(Copy, Clone)] + pub struct SimdPacked([T; N]); + #[repr(simd)] + #[derive(Copy, Clone)] + pub struct SimdPadded([T; N]); + + let x = SimdPacked([1u32; 3]); + let y = SimdPacked([2u32; 3]); + let z = unsafe { intrinsics::simd_add(x, y) }; + assert_eq!({ z.0 }, [3u32; 3]); + + let x = SimdPadded([1u32; 3]); + let y = SimdPadded([2u32; 3]); + let z = unsafe { intrinsics::simd_add(x, y) }; + assert_eq!(z.0, [3u32; 3]); +} + fn main() { simd_mask(); simd_ops_f32(); simd_ops_f64(); simd_ops_i32(); + simd_ops_non_pow2(); simd_cast(); simd_swizzle(); simd_gather_scatter(); diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index 09263dc645e2..89f4d8957c8b 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -3,30 +3,10 @@ use crate::exec::{cmd, CmdBuilder}; use crate::utils::io::{count_files, delete_directory}; use crate::utils::with_log_group; use anyhow::Context; +use build_helper::{LLVM_PGO_CRATES, RUSTC_PGO_CRATES}; use camino::{Utf8Path, Utf8PathBuf}; use humansize::BINARY; -const LLVM_PGO_CRATES: &[&str] = &[ - "syn-1.0.89", - "cargo-0.60.0", - "serde-1.0.136", - "ripgrep-13.0.0", - "regex-1.5.5", - "clap-3.1.6", - "hyper-0.14.18", -]; - -const RUSTC_PGO_CRATES: &[&str] = &[ - "externs", - "ctfe-stress-5", - "cargo-0.60.0", - "token-stream-stress", - "match-stress", - "tuple-stress", - "diesel-1.4.8", - "bitmaps-3.1.0", -]; - fn init_compiler_benchmarks( env: &Environment, profiles: &[&str], diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index b33004974bf3..5c0158d75470 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -1,7 +1,7 @@ use std::path::Path; -use std::process::Command; -use crate::{bin_name, cygpath_windows, env_var, handle_failed_output, is_msvc, is_windows, uname}; +use crate::command::Command; +use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname}; /// Construct a new platform-specific C compiler invocation. /// diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs index 7d9246b52227..d2ebed7ab067 100644 --- a/src/tools/run-make-support/src/clang.rs +++ b/src/tools/run-make-support/src/clang.rs @@ -1,7 +1,7 @@ use std::path::Path; -use std::process::Command; -use crate::{bin_name, env_var, handle_failed_output}; +use crate::command::Command; +use crate::{bin_name, env_var}; /// Construct a new `clang` invocation. `clang` is not always available for all targets. pub fn clang() -> Clang { @@ -68,9 +68,4 @@ impl Clang { self.cmd.arg(format!("-fuse-ld={ld}")); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } diff --git a/src/tools/run-make-support/src/command.rs b/src/tools/run-make-support/src/command.rs new file mode 100644 index 000000000000..b9e56ab632ad --- /dev/null +++ b/src/tools/run-make-support/src/command.rs @@ -0,0 +1,151 @@ +use crate::{assert_not_contains, handle_failed_output}; +use std::ffi::OsStr; +use std::io::Write; +use std::ops::{Deref, DerefMut}; +use std::process::{Command as StdCommand, ExitStatus, Output, Stdio}; + +/// This is a custom command wrapper that simplifies working with commands +/// and makes it easier to ensure that we check the exit status of executed +/// processes. +#[derive(Debug)] +pub struct Command { + cmd: StdCommand, + stdin: Option>, +} + +impl Command { + pub fn new>(program: S) -> Self { + Self { cmd: StdCommand::new(program), stdin: None } + } + + pub fn set_stdin(&mut self, stdin: Box<[u8]>) { + self.stdin = Some(stdin); + } + + /// Run the constructed command and assert that it is successfully run. + #[track_caller] + pub fn run(&mut self) -> CompletedProcess { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.command_output(); + if !output.status().success() { + handle_failed_output(&self, output, caller_line_number); + } + output + } + + /// Run the constructed command and assert that it does not successfully run. + #[track_caller] + pub fn run_fail(&mut self) -> CompletedProcess { + let caller_location = std::panic::Location::caller(); + let caller_line_number = caller_location.line(); + + let output = self.command_output(); + if output.status().success() { + handle_failed_output(&self, output, caller_line_number); + } + output + } + + #[track_caller] + pub(crate) fn command_output(&mut self) -> CompletedProcess { + // let's make sure we piped all the input and outputs + self.cmd.stdin(Stdio::piped()); + self.cmd.stdout(Stdio::piped()); + self.cmd.stderr(Stdio::piped()); + + let output = if let Some(input) = &self.stdin { + let mut child = self.cmd.spawn().unwrap(); + + { + let mut stdin = child.stdin.take().unwrap(); + stdin.write_all(input.as_ref()).unwrap(); + } + + child.wait_with_output().expect("failed to get output of finished process") + } else { + self.cmd.output().expect("failed to get output of finished process") + }; + output.into() + } +} + +impl Deref for Command { + type Target = StdCommand; + + fn deref(&self) -> &Self::Target { + &self.cmd + } +} + +impl DerefMut for Command { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.cmd + } +} + +/// Represents the result of an executed process. +/// The various `assert_` helper methods should preferably be used for +/// checking the contents of stdout/stderr. +pub struct CompletedProcess { + output: Output, +} + +impl CompletedProcess { + pub fn stdout_utf8(&self) -> String { + String::from_utf8(self.output.stdout.clone()).expect("stdout is not valid UTF-8") + } + + pub fn stderr_utf8(&self) -> String { + String::from_utf8(self.output.stderr.clone()).expect("stderr is not valid UTF-8") + } + + pub fn status(&self) -> ExitStatus { + self.output.status + } + + /// Checks that trimmed `stdout` matches trimmed `content`. + #[track_caller] + pub fn assert_stdout_equals>(self, content: S) -> Self { + assert_eq!(self.stdout_utf8().trim(), content.as_ref().trim()); + self + } + + #[track_caller] + pub fn assert_stdout_not_contains>(self, needle: S) -> Self { + assert_not_contains(&self.stdout_utf8(), needle.as_ref()); + self + } + + /// Checks that trimmed `stderr` matches trimmed `content`. + #[track_caller] + pub fn assert_stderr_equals>(self, content: S) -> Self { + assert_eq!(self.stderr_utf8().trim(), content.as_ref().trim()); + self + } + + #[track_caller] + pub fn assert_stderr_contains>(self, needle: S) -> Self { + assert!(self.stderr_utf8().contains(needle.as_ref())); + self + } + + #[track_caller] + pub fn assert_stderr_not_contains>(self, needle: S) -> Self { + assert_not_contains(&self.stdout_utf8(), needle.as_ref()); + self + } + + #[track_caller] + pub fn assert_exit_code(self, code: i32) -> Self { + assert!(self.output.status.code() == Some(code)); + self + } +} + +impl From for CompletedProcess { + fn from(output: Output) -> Self { + Self { output } + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 0d167960c162..cea1313e29d7 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -5,6 +5,7 @@ pub mod cc; pub mod clang; +mod command; pub mod diff; pub mod llvm_readobj; pub mod run; @@ -16,7 +17,6 @@ use std::ffi::OsString; use std::fs; use std::io; use std::path::{Path, PathBuf}; -use std::process::{Command, Output}; pub use gimli; pub use object; @@ -27,7 +27,7 @@ pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; pub use clang::{clang, Clang}; pub use diff::{diff, Diff}; pub use llvm_readobj::{llvm_readobj, LlvmReadobj}; -pub use run::{run, run_fail}; +pub use run::{cmd, run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; @@ -167,13 +167,12 @@ pub fn cygpath_windows>(path: P) -> String { let mut cygpath = Command::new("cygpath"); cygpath.arg("-w"); cygpath.arg(path.as_ref()); - let output = cygpath.output().unwrap(); - if !output.status.success() { + let output = cygpath.command_output(); + if !output.status().success() { handle_failed_output(&cygpath, output, caller_line_number); } - let s = String::from_utf8(output.stdout).unwrap(); // cygpath -w can attach a newline - s.trim().to_string() + output.stdout_utf8().trim().to_string() } /// Run `uname`. This assumes that `uname` is available on the platform! @@ -183,23 +182,23 @@ pub fn uname() -> String { let caller_line_number = caller_location.line(); let mut uname = Command::new("uname"); - let output = uname.output().unwrap(); - if !output.status.success() { + let output = uname.command_output(); + if !output.status().success() { handle_failed_output(&uname, output, caller_line_number); } - String::from_utf8(output.stdout).unwrap() + output.stdout_utf8() } -fn handle_failed_output(cmd: &Command, output: Output, caller_line_number: u32) -> ! { - if output.status.success() { +fn handle_failed_output(cmd: &Command, output: CompletedProcess, caller_line_number: u32) -> ! { + if output.status().success() { eprintln!("command unexpectedly succeeded at line {caller_line_number}"); } else { eprintln!("command failed at line {caller_line_number}"); } eprintln!("{cmd:?}"); - eprintln!("output status: `{}`", output.status); - eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap()); - eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap()); + eprintln!("output status: `{}`", output.status()); + eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8()); + eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8()); std::process::exit(1) } @@ -286,6 +285,7 @@ pub fn read_dir(dir: impl AsRef, callback: F) { } /// Check that `haystack` does not contain `needle`. Panic otherwise. +#[track_caller] pub fn assert_not_contains(haystack: &str, needle: &str) { if haystack.contains(needle) { eprintln!("=== HAYSTACK ==="); @@ -318,38 +318,30 @@ pub fn run_in_tmpdir(callback: F) { } /// Implement common helpers for command wrappers. This assumes that the command wrapper is a struct -/// containing a `cmd: Command` field and a `output` function. The provided helpers are: +/// containing a `cmd: Command` field. The provided helpers are: /// /// 1. Generic argument acceptors: `arg` and `args` (delegated to [`Command`]). These are intended /// to be *fallback* argument acceptors, when specific helpers don't make sense. Prefer to add /// new specific helper methods over relying on these generic argument providers. /// 2. Environment manipulation methods: `env`, `env_remove` and `env_clear`: these delegate to /// methods of the same name on [`Command`]. -/// 3. Output and execution: `output`, `run` and `run_fail` are provided. `output` waits for the -/// command to finish running and returns the process's [`Output`]. `run` and `run_fail` are -/// higher-level convenience methods which waits for the command to finish running and assert -/// that the command successfully ran or failed as expected. Prefer `run` and `run_fail` when -/// possible. +/// 3. Output and execution: `run` and `run_fail` are provided. These are +/// higher-level convenience methods which wait for the command to finish running and assert +/// that the command successfully ran or failed as expected. They return +/// [`CompletedProcess`], which can be used to assert the stdout/stderr/exit code of the executed +/// process. /// /// Example usage: /// /// ```ignore (illustrative) /// struct CommandWrapper { cmd: Command } // <- required `cmd` field /// -/// impl CommandWrapper { -/// /// Get the [`Output`][::std::process::Output] of the finished process. -/// pub fn command_output(&mut self) -> Output { /* ... */ } // <- required `command_output()` method -/// } -/// /// crate::impl_common_helpers!(CommandWrapper); /// /// impl CommandWrapper { /// // ... additional specific helper methods /// } /// ``` -/// -/// [`Command`]: ::std::process::Command -/// [`Output`]: ::std::process::Output macro_rules! impl_common_helpers { ($wrapper: ident) => { impl $wrapper { @@ -412,28 +404,14 @@ macro_rules! impl_common_helpers { /// Run the constructed command and assert that it is successfully run. #[track_caller] - pub fn run(&mut self) -> ::std::process::Output { - let caller_location = ::std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if !output.status.success() { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output + pub fn run(&mut self) -> crate::command::CompletedProcess { + self.cmd.run() } /// Run the constructed command and assert that it does not successfully run. #[track_caller] - pub fn run_fail(&mut self) -> ::std::process::Output { - let caller_location = ::std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if output.status.success() { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output + pub fn run_fail(&mut self) -> crate::command::CompletedProcess { + self.cmd.run_fail() } /// Set the path where the command will be run. @@ -445,4 +423,5 @@ macro_rules! impl_common_helpers { }; } +use crate::command::{Command, CompletedProcess}; pub(crate) use impl_common_helpers; diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs index 77aaadfe18c4..db2f9db6e41f 100644 --- a/src/tools/run-make-support/src/llvm_readobj.rs +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -1,7 +1,7 @@ use std::path::{Path, PathBuf}; -use std::process::Command; -use crate::{env_var, handle_failed_output}; +use crate::command::Command; +use crate::env_var; /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available /// at `$LLVM_BIN_DIR/llvm-readobj`. @@ -39,10 +39,4 @@ impl LlvmReadobj { self.cmd.arg("--file-header"); self } - - /// Get the [`Output`][::std::process::Output] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> ::std::process::Output { - self.cmd.output().expect("failed to get output of finished process") - } } diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index b607c583e328..4a6fd7c432e5 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,12 +1,13 @@ use std::env; +use std::ffi::OsStr; use std::path::{Path, PathBuf}; -use std::process::{Command, Output}; -use crate::{cwd, env_var, is_windows}; +use crate::command::{Command, CompletedProcess}; +use crate::{cwd, env_var, is_windows, set_host_rpath}; use super::handle_failed_output; -fn run_common(name: &str) -> (Command, Output) { +fn run_common(name: &str) -> (Command, CompletedProcess) { let mut bin_path = PathBuf::new(); bin_path.push(cwd()); bin_path.push(name); @@ -33,18 +34,18 @@ fn run_common(name: &str) -> (Command, Output) { cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); } - let output = cmd.output().unwrap(); + let output = cmd.command_output(); (cmd, output) } /// Run a built binary and make sure it succeeds. #[track_caller] -pub fn run(name: &str) -> Output { +pub fn run(name: &str) -> CompletedProcess { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); let (cmd, output) = run_common(name); - if !output.status.success() { + if !output.status().success() { handle_failed_output(&cmd, output, caller_line_number); } output @@ -52,13 +53,21 @@ pub fn run(name: &str) -> Output { /// Run a built binary and make sure it fails. #[track_caller] -pub fn run_fail(name: &str) -> Output { +pub fn run_fail(name: &str) -> CompletedProcess { let caller_location = std::panic::Location::caller(); let caller_line_number = caller_location.line(); let (cmd, output) = run_common(name); - if output.status.success() { + if output.status().success() { handle_failed_output(&cmd, output, caller_line_number); } output } + +/// Create a new custom Command. +/// This should be preferred to creating `std::process::Command` directly. +pub fn cmd>(program: S) -> Command { + let mut command = Command::new(program); + set_host_rpath(&mut command); + command +} diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index a64dd9d30cf5..5ea231442bc2 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -1,9 +1,8 @@ +use command::Command; use std::ffi::{OsStr, OsString}; -use std::io::Write; use std::path::Path; -use std::process::{Command, Output, Stdio}; -use crate::{cwd, env_var, handle_failed_output, set_host_rpath}; +use crate::{command, cwd, env_var, set_host_rpath}; /// Construct a new `rustc` invocation. pub fn rustc() -> Rustc { @@ -19,7 +18,6 @@ pub fn aux_build() -> Rustc { #[derive(Debug)] pub struct Rustc { cmd: Command, - stdin: Option>, } crate::impl_common_helpers!(Rustc); @@ -38,14 +36,14 @@ impl Rustc { /// Construct a new `rustc` invocation. pub fn new() -> Self { let cmd = setup_common(); - Self { cmd, stdin: None } + Self { cmd } } /// Construct a new `rustc` invocation with `aux_build` preset (setting `--crate-type=lib`). pub fn new_aux_build() -> Self { let mut cmd = setup_common(); cmd.arg("--crate-type=lib"); - Self { cmd, stdin: None } + Self { cmd } } // Argument provider methods @@ -109,6 +107,13 @@ impl Rustc { self } + /// Specify path to the output directory. Equivalent to `--out-dir`` in rustc. + pub fn out_dir>(&mut self, path: P) -> &mut Self { + self.cmd.arg("--out-dir"); + self.cmd.arg(path.as_ref()); + self + } + /// This flag defers LTO optimizations to the linker. pub fn linker_plugin_lto(&mut self, option: &str) -> &mut Self { self.cmd.arg(format!("-Clinker-plugin-lto={option}")); @@ -197,7 +202,7 @@ impl Rustc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); self } @@ -213,38 +218,4 @@ impl Rustc { self.cmd.arg(format!("-Clinker={linker}")); self } - - /// Get the [`Output`] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> Output { - // let's make sure we piped all the input and outputs - self.cmd.stdin(Stdio::piped()); - self.cmd.stdout(Stdio::piped()); - self.cmd.stderr(Stdio::piped()); - - if let Some(input) = &self.stdin { - let mut child = self.cmd.spawn().unwrap(); - - { - let mut stdin = child.stdin.take().unwrap(); - stdin.write_all(input.as_ref()).unwrap(); - } - - child.wait_with_output().expect("failed to get output of finished process") - } else { - self.cmd.output().expect("failed to get output of finished process") - } - } - - #[track_caller] - pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if output.status.code().unwrap() != code { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output - } } diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs index 34d32992e65e..39a698a47b43 100644 --- a/src/tools/run-make-support/src/rustdoc.rs +++ b/src/tools/run-make-support/src/rustdoc.rs @@ -1,9 +1,8 @@ use std::ffi::OsStr; -use std::io::Write; use std::path::Path; -use std::process::{Command, Output, Stdio}; -use crate::{env_var, env_var_os, handle_failed_output, set_host_rpath}; +use crate::command::Command; +use crate::{env_var, env_var_os, set_host_rpath}; /// Construct a plain `rustdoc` invocation with no flags set. pub fn bare_rustdoc() -> Rustdoc { @@ -18,7 +17,6 @@ pub fn rustdoc() -> Rustdoc { #[derive(Debug)] pub struct Rustdoc { cmd: Command, - stdin: Option>, } crate::impl_common_helpers!(Rustdoc); @@ -34,7 +32,7 @@ impl Rustdoc { /// Construct a bare `rustdoc` invocation. pub fn bare() -> Self { let cmd = setup_common(); - Self { cmd, stdin: None } + Self { cmd } } /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. @@ -42,7 +40,7 @@ impl Rustdoc { let mut cmd = setup_common(); let target_rpath_dir = env_var_os("TARGET_RPATH_DIR"); cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); - Self { cmd, stdin: None } + Self { cmd } } /// Specify where an external library is located. @@ -88,33 +86,10 @@ impl Rustdoc { /// Specify a stdin input pub fn stdin>(&mut self, input: I) -> &mut Self { - self.cmd.stdin(Stdio::piped()); - self.stdin = Some(input.as_ref().to_vec().into_boxed_slice()); + self.cmd.set_stdin(input.as_ref().to_vec().into_boxed_slice()); self } - /// Get the [`Output`] of the finished process. - #[track_caller] - pub fn command_output(&mut self) -> ::std::process::Output { - // let's make sure we piped all the input and outputs - self.cmd.stdin(Stdio::piped()); - self.cmd.stdout(Stdio::piped()); - self.cmd.stderr(Stdio::piped()); - - if let Some(input) = &self.stdin { - let mut child = self.cmd.spawn().unwrap(); - - { - let mut stdin = child.stdin.take().unwrap(); - stdin.write_all(input.as_ref()).unwrap(); - } - - child.wait_with_output().expect("failed to get output of finished process") - } else { - self.cmd.output().expect("failed to get output of finished process") - } - } - /// Specify the edition year. pub fn edition(&mut self, edition: &str) -> &mut Self { self.cmd.arg("--edition"); @@ -156,16 +131,4 @@ impl Rustdoc { self.cmd.arg(format); self } - - #[track_caller] - pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { - let caller_location = std::panic::Location::caller(); - let caller_line_number = caller_location.line(); - - let output = self.command_output(); - if output.status.code().unwrap() != code { - handle_failed_output(&self.cmd, output, caller_line_number); - } - output - } } diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index a015f96ae51d..babf1abbe64a 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -122,7 +122,6 @@ run-make/link-framework/Makefile run-make/link-path-order/Makefile run-make/linkage-attr-on-static/Makefile run-make/llvm-ident/Makefile -run-make/llvm-outputs/Makefile run-make/long-linker-command-lines-cmd-exe/Makefile run-make/long-linker-command-lines/Makefile run-make/longjmp-across-rust/Makefile diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index efcd2a181ffa..2dd3d17f9e3e 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -27,7 +27,8 @@ const LICENSES: &[&str] = &[ "MIT OR Zlib OR Apache-2.0", // miniz_oxide "MIT", "MIT/Apache-2.0", - "Unicode-DFS-2016", // tinystr and icu4x + "Unicode-3.0", // icu4x + "Unicode-DFS-2016", // tinystr "Unlicense OR MIT", "Unlicense/MIT", "Zlib OR Apache-2.0 OR MIT", // tinyvec @@ -67,6 +68,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>) //("src/tools/miri/test-cargo-miri", &[], None), // FIXME uncomment once all deps are vendored //("src/tools/miri/test_dependencies", &[], None), // FIXME uncomment once all deps are vendored ("src/tools/rust-analyzer", EXCEPTIONS_RUST_ANALYZER, None), + ("src/tools/rustc-perf", EXCEPTIONS_RUSTC_PERF, None), ("src/tools/x", &[], None), // tidy-alphabetical-end ]; @@ -142,6 +144,22 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[ // tidy-alphabetical-end ]; +const EXCEPTIONS_RUSTC_PERF: ExceptionList = &[ + // tidy-alphabetical-start + ("alloc-no-stdlib", "BSD-3-Clause"), + ("alloc-stdlib", "BSD-3-Clause"), + ("brotli", "BSD-3-Clause/MIT"), + ("brotli-decompressor", "BSD-3-Clause/MIT"), + ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"), + ("inferno", "CDDL-1.0"), + ("instant", "BSD-3-Clause"), + ("ring", NON_STANDARD_LICENSE), // see EXCEPTIONS_NON_STANDARD_LICENSE_DEPS for more. + ("ryu", "Apache-2.0 OR BSL-1.0"), + ("snap", "BSD-3-Clause"), + ("subtle", "BSD-3-Clause"), + // tidy-alphabetical-end +]; + const EXCEPTIONS_CRANELIFT: ExceptionList = &[ // tidy-alphabetical-start ("cranelift-bforest", "Apache-2.0 WITH LLVM-exception"), @@ -178,6 +196,20 @@ const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[ ("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptible, but we use it under MIT OR Apache-2.0 ]; +/// Placeholder for non-standard license file. +const NON_STANDARD_LICENSE: &str = "NON_STANDARD_LICENSE"; + +/// These dependencies have non-standard licenses but are genenrally permitted. +const EXCEPTIONS_NON_STANDARD_LICENSE_DEPS: &[&str] = &[ + // `ring` is included because it is an optional dependency of `hyper`, + // which is a training data in rustc-perf for optimized build. + // The license of it is generally `ISC AND MIT AND OpenSSL`, + // though the `package.license` field is not set. + // + // See https://github.com/briansmith/ring/issues/902 + "ring", +]; + /// These are the root crates that are part of the runtime. The licenses for /// these and all their dependencies *must not* be in the exception list. const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"]; @@ -411,32 +443,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-end ]; -// These crates come from ICU4X and are licensed under the unicode license. -// It currently doesn't have an SPDX identifier, so they cannot put one there. -// See https://github.com/unicode-org/icu4x/pull/3875 -// FIXME: This should be removed once ICU4X crates update. -const ICU4X_UNICODE_LICENSE_DEPENDENCIES: &[&str] = &[ - // tidy-alphabetical-start - "icu_list", - "icu_list_data", - "icu_locid", - "icu_locid_transform", - "icu_locid_transform_data", - "icu_provider", - "icu_provider_adapters", - "icu_provider_macros", - "litemap", - "tinystr", - "writeable", - "yoke", - "yoke-derive", - "zerofrom", - "zerofrom-derive", - "zerovec", - "zerovec-derive", - // tidy-alphabetical-end -]; - const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ // tidy-alphabetical-start "ahash", @@ -610,6 +616,11 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba for pkg in metadata.packages.iter().filter(|p| p.name == *name) { match &pkg.license { None => { + if *license == NON_STANDARD_LICENSE + && EXCEPTIONS_NON_STANDARD_LICENSE_DEPS.contains(&pkg.name.as_str()) + { + continue; + } tidy_error!( bad, "dependency exception `{}` does not declare a license expression", @@ -642,10 +653,6 @@ fn check_license_exceptions(metadata: &Metadata, exceptions: &[(&str, &str)], ba let license = match &pkg.license { Some(license) => license, None => { - if ICU4X_UNICODE_LICENSE_DEPENDENCIES.contains(&pkg.name.as_str()) { - // See the comment on ICU4X_UNICODE_LICENSE_DEPENDENCIES. - continue; - } tidy_error!(bad, "dependency `{}` does not define a license expression", pkg.id); continue; } diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 40e75d1d3fac..2c97a39f1008 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -320,7 +320,7 @@ fn install_requirements( } let stat = Command::new(py_path) - .args(["-m", "pip", "install", "--require-hashes", "-r"]) + .args(["-m", "pip", "install", "--quiet", "--require-hashes", "-r"]) .arg(src_reqs_path) .status()?; if !stat.success() { diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index ff71ca537256..2118de5f2041 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -4,7 +4,11 @@ use std::fs; use std::path::Path; /// List of allowed sources for packages. -const ALLOWED_SOURCES: &[&str] = &["\"registry+https://github.com/rust-lang/crates.io-index\""]; +const ALLOWED_SOURCES: &[&str] = &[ + r#""registry+https://github.com/rust-lang/crates.io-index""#, + // This is `rust_team_data` used by `site` in src/tools/rustc-perf, + r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#, +]; /// Checks for external package sources. `root` is the path to the directory that contains the /// workspace `Cargo.toml`. diff --git a/tests/assembly/asm/global_asm.rs b/tests/assembly/asm/global_asm.rs index 8f824563e8ae..22cf4bdb15b7 100644 --- a/tests/assembly/asm/global_asm.rs +++ b/tests/assembly/asm/global_asm.rs @@ -25,9 +25,9 @@ global_asm!("movl ${}, %ecx", const 5, options(att_syntax)); global_asm!("call {}", sym my_func); // CHECK: lea rax, [rip + MY_STATIC] global_asm!("lea rax, [rip + {}]", sym MY_STATIC); -// CHECK: call _RNvCsddMtV7nAi4C_10global_asm6foobar +// CHECK: call _RNvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_10global_asm6foobar global_asm!("call {}", sym foobar); -// CHECK: _RNvCsddMtV7nAi4C_10global_asm6foobar: +// CHECK: _RNvC[[CRATE_IDENT]]_10global_asm6foobar: fn foobar() { loop {} } diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index 93c58c37c287..42ce7679d1ac 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -9,11 +9,11 @@ // CHECK: @STATIC = {{.*}}, align 4 // This checks the constants from inline_enum_const -// CHECK: @alloc_af1f8e8e6f4b341431a1d405e652df2d = {{.*}}, align 2 +// CHECK: @alloc_[[INLINE_ENUM_HASH:[a-f0-9]{32}]] = {{.*}}, align 2 // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used -// CHECK: [[LOW_HIGH:@alloc_[a-f0-9]+]] = {{.*}}, align 4 +// CHECK: [[LOW_HIGH:@alloc_[a-f0-9]{32}]] = {{.*}}, align 4 #[derive(Copy, Clone)] // repr(i16) is required for the {low,high}_align_const test diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs index dfe834433487..a99b3efca415 100644 --- a/tests/codegen/pattern_type_symbols.rs +++ b/tests/codegen/pattern_type_symbols.rs @@ -15,9 +15,9 @@ fn foo() {} pub fn bar() { // CHECK: call pattern_type_symbols::foo:: - // CHECK: call void @_RINvCs3QvG2ESzx2Q_20pattern_type_symbols3foomEB2_ + // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_ foo::(); // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999], [(); true])> - // CHECK: call void @_RINvCs3QvG2ESzx2Q_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_ + // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_ foo::(); } diff --git a/tests/codegen/simd/packed-simd.rs b/tests/codegen/simd/packed-simd.rs index f0911b6e3602..1df09c96e6cc 100644 --- a/tests/codegen/simd/packed-simd.rs +++ b/tests/codegen/simd/packed-simd.rs @@ -9,10 +9,11 @@ use core::intrinsics::simd as intrinsics; use core::{mem, ptr}; // Test codegen for not only "packed" but also "fully aligned" SIMD types, and conversion between -// A repr(packed,simd) type with 3 elements can't exceed its element alignment, -// whereas the same type as repr(simd) will instead have padding. +// them. A repr(packed,simd) type with 3 elements can't exceed its element alignment, whereas the +// same type as repr(simd) will instead have padding. #[repr(simd, packed)] +#[derive(Copy, Clone)] pub struct Simd([T; N]); #[repr(simd)] @@ -28,11 +29,11 @@ fn load(v: Simd) -> FullSimd { } } -// CHECK-LABEL: square_packed +// CHECK-LABEL: square_packed_full // CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align (8|16)]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] // CHECK-SAME: ptr{{[a-z_ ]*}} align 4 #[no_mangle] -pub fn square_packed(x: Simd) -> FullSimd { +pub fn square_packed_full(x: Simd) -> FullSimd { // CHECK-NEXT: start // noopt: alloca [[RET_TYPE]], [[RET_ALIGN]] // CHECK: load <3 x float> @@ -42,3 +43,17 @@ pub fn square_packed(x: Simd) -> FullSimd { // CHECK-NEXT: ret void unsafe { intrinsics::simd_mul(x, x) } } + +// CHECK-LABEL: square_packed +// CHECK-SAME: ptr{{[a-z_ ]*}} sret([[RET_TYPE:[^)]+]]) [[RET_ALIGN:align 4]]{{[^%]*}} [[RET_VREG:%[_0-9]*]] +// CHECK-SAME: ptr{{[a-z_ ]*}} align 4 +#[no_mangle] +pub fn square_packed(x: Simd) -> Simd { + // CHECK-NEXT: start + // CHECK-NEXT: load <3 x float> + // noopt-NEXT: load <3 x float> + // CHECK-NEXT: [[VREG:%[a-z0-9_]+]] = fmul <3 x float> + // CHECK-NEXT: store <3 x float> [[VREG]], ptr [[RET_VREG]], [[RET_ALIGN]] + // CHECK-NEXT: ret void + unsafe { intrinsics::simd_mul(x, x) } +} diff --git a/tests/codegen/virtual-function-elimination.rs b/tests/codegen/virtual-function-elimination.rs index 6c391d9114b4..23d7657baa99 100644 --- a/tests/codegen/virtual-function-elimination.rs +++ b/tests/codegen/virtual-function-elimination.rs @@ -81,7 +81,7 @@ fn taking_u(u: &dyn U) -> i32 { } pub fn taking_v(v: &dyn V) -> i32 { - // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtCs64ITQYi9761_28virtual_function_elimination1V") + // CHECK: @llvm.type.checked.load({{.*}}, i32 24, metadata !"NtC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_28virtual_function_elimination1V") v.public_function() } @@ -96,5 +96,5 @@ pub fn main() { // CHECK: ![[TYPE0]] = !{i64 0, !"[[MANGLED_TYPE0]]"} // CHECK: ![[VCALL_VIS0]] = !{i64 2} // CHECK: ![[TYPE1]] = !{i64 0, !"[[MANGLED_TYPE1]]"} -// CHECK: ![[TYPE2]] = !{i64 0, !"NtCs64ITQYi9761_28virtual_function_elimination1V"} +// CHECK: ![[TYPE2]] = !{i64 0, !"NtC[[CRATE_IDENT]]_28virtual_function_elimination1V"} // CHECK: ![[VCALL_VIS2]] = !{i64 1} diff --git a/tests/crashes/125655.rs b/tests/crashes/125655.rs new file mode 100644 index 000000000000..fbf92ca22be7 --- /dev/null +++ b/tests/crashes/125655.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#125655 + +fn main() { + static foo: dyn Fn() -> u32 = || -> u32 { + ... + 0 + }; +} diff --git a/tests/crashes/125680.rs b/tests/crashes/125680.rs new file mode 100644 index 000000000000..09f4f318bddd --- /dev/null +++ b/tests/crashes/125680.rs @@ -0,0 +1,15 @@ +//@ known-bug: rust-lang/rust#125680 +//@ edition:2021 + +#![feature(generic_const_exprs)] + +use core::fmt::Debug; + +struct Inline +where + [(); std::mem::offset_of!((T,), 0)]:, +{} + +fn main() { + let dst = Inline::::new(0); // BANG! +} diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs new file mode 100644 index 000000000000..86c3b80abab9 --- /dev/null +++ b/tests/crashes/125758.rs @@ -0,0 +1,26 @@ +//@ known-bug: rust-lang/rust#125758 +#![feature(impl_trait_in_assoc_type)] + +trait Trait: Sized { + type Assoc2; +} + +impl Trait for Bar { + type Assoc2 = impl std::fmt::Debug; +} + +struct Foo { + field: ::Assoc2, +} + +enum Bar { + C = 42, + D = 99, +} + +static BAR: u8 = 42; + +static FOO2: (&Foo, &::Assoc2) = + unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; + +fn main() {} diff --git a/tests/crashes/125768.rs b/tests/crashes/125768.rs new file mode 100644 index 000000000000..3c04431baa0a --- /dev/null +++ b/tests/crashes/125768.rs @@ -0,0 +1,15 @@ +//@ known-bug: rust-lang/rust#125768 + +#![feature(generic_const_exprs)] + +struct Outer(); +impl Outer +where + [(); A + (B * 2)]:, +{ + fn o() -> Union {} +} + +fn main() { + Outer::<1, 1>::o(); +} diff --git a/tests/crashes/125769.rs b/tests/crashes/125769.rs new file mode 100644 index 000000000000..da19458f7ca7 --- /dev/null +++ b/tests/crashes/125769.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#125769 + +#![feature(generic_const_exprs)] + +trait Trait {} + +struct HasCastInTraitImpl; +impl Trait for HasCastInTraitImpl {} + +pub fn use_trait_impl() { + fn assert_impl() {} + + assert_impl::>(); +} diff --git a/tests/crashes/125772.rs b/tests/crashes/125772.rs new file mode 100644 index 000000000000..2965cfc9e7c3 --- /dev/null +++ b/tests/crashes/125772.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#125772 +//@ only-x86_64 +#![feature(generic_const_exprs)] + +struct Outer(); +impl Outer +where + [(); A + (B * 2)]:, +{ + fn i() -> Self { + Self + } +} + +fn main() { + Outer::<1, 1>::o(); +} diff --git a/tests/crashes/125799.rs b/tests/crashes/125799.rs new file mode 100644 index 000000000000..62d5438b4e40 --- /dev/null +++ b/tests/crashes/125799.rs @@ -0,0 +1,22 @@ +//@ known-bug: rust-lang/rust#125799 +//@ only-x86_64 + +trait Trait { + type Assoc; +} + +impl Trait for Vec { + type Assoc = (); +} + +impl Trait for Vec {} + +const BAR: as Trait>::Assoc = 3; + +pub fn main() { + let x: isize = 3; + let _ = match x { + BAR => 2, + _ => 3, + }; +} diff --git a/tests/crashes/125801.rs b/tests/crashes/125801.rs new file mode 100644 index 000000000000..aaa76bd0ba69 --- /dev/null +++ b/tests/crashes/125801.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125801 + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait Foo { + type Output; +} + +impl Foo for [u8; 3] { + type Output = [u8; 3]; +} + +static A: <[u8; N] as Foo>::Output = [1, 2, 3]; + +fn main() { + || { + let _ = A[1]; + }; +} diff --git a/tests/crashes/125810.rs b/tests/crashes/125810.rs new file mode 100644 index 000000000000..4a152da8ddf3 --- /dev/null +++ b/tests/crashes/125810.rs @@ -0,0 +1,10 @@ +//@ known-bug: rust-lang/rust#125810 +#![feature(arbitrary_self_types, dispatch_from_dyn)] + +use std::ops::{Deref, DispatchFromDyn}; + +trait Trait + DispatchFromDyn> { + fn MONO_BUF(self: T) -> dyn Trait; +} + +fn main() {} diff --git a/tests/crashes/125811.rs b/tests/crashes/125811.rs new file mode 100644 index 000000000000..eb764e8d1522 --- /dev/null +++ b/tests/crashes/125811.rs @@ -0,0 +1,34 @@ +//@ known-bug: rust-lang/rust#125811 +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable() + where + Dst: BikeshedIntrinsicFrom, + { + } +} + +#[repr(C)] +struct Zst; + +enum V0 { + B(!), +} + +enum V2 { + V = 2, +} + +enum Lopsided { + Smol(Zst), + Lorg(V0), +} + +#[repr(C)] +#[repr(C)] +struct Dst(Lopsided, V2); + +fn should_pad_variants() { + assert::is_transmutable::(); +} diff --git a/tests/crashes/125841.rs b/tests/crashes/125841.rs new file mode 100644 index 000000000000..e2e61071f1df --- /dev/null +++ b/tests/crashes/125841.rs @@ -0,0 +1,14 @@ +//@ known-bug: rust-lang/rust#125841 +#![feature(non_lifetime_binders)] +fn take(id: impl for Fn(T) -> T) { + id(0); + id(""); +} + +fn take2() -> impl for Fn(T) -> T { + |x| x +} + +fn main() { + take(|x| take2) +} diff --git a/tests/crashes/125843.rs b/tests/crashes/125843.rs new file mode 100644 index 000000000000..8b9a3913c7e6 --- /dev/null +++ b/tests/crashes/125843.rs @@ -0,0 +1,4 @@ +//@ known-bug: rust-lang/rust#125843 +#![feature(non_lifetime_binders)] +trait v0<> {} +fn kind :(v3main impl for v0<'_, v2 = impl v0 + '_>) {} diff --git a/tests/crashes/125874.rs b/tests/crashes/125874.rs new file mode 100644 index 000000000000..6a2713cd7c89 --- /dev/null +++ b/tests/crashes/125874.rs @@ -0,0 +1,22 @@ +//@ known-bug: rust-lang/rust#125874 +pub trait A {} + +pub trait Mirror { + type Assoc: ?Sized; +} +impl Mirror for dyn A { + type Assoc = T; +} + +struct Bar { + foo: ::Assoc, +} + +pub fn main() { + let strct = Bar { foo: 3 }; + + match strct { + Bar { foo: 1, .. } => {} + _ => (), + }; +} diff --git a/tests/crashes/125879.rs b/tests/crashes/125879.rs new file mode 100644 index 000000000000..4318842e4551 --- /dev/null +++ b/tests/crashes/125879.rs @@ -0,0 +1,18 @@ +//@ known-bug: rust-lang/rust#125879 +#![feature(inherent_associated_types)] +#![allow(incomplete_features)] + +pub type PubAlias0 = PubTy::PrivAssocTy; + +pub struct PubTy; +impl PubTy { + type PrivAssocTy = (); +} + +pub struct S(pub PubAlias0); + +pub unsafe fn foo(a: S) -> S { + a +} + +fn main() {} diff --git a/tests/crashes/125881.rs b/tests/crashes/125881.rs new file mode 100644 index 000000000000..98331d3c9748 --- /dev/null +++ b/tests/crashes/125881.rs @@ -0,0 +1,8 @@ +//@ known-bug: rust-lang/rust#125881 +#![crate_type = "lib"] +#![feature(transmutability)] +#![feature(unboxed_closures,effects)] + +const fn test() -> impl std::mem::BikeshedIntrinsicFrom() { + || {} +} diff --git a/tests/crashes/125888.rs b/tests/crashes/125888.rs new file mode 100644 index 000000000000..ae8f2d6576b7 --- /dev/null +++ b/tests/crashes/125888.rs @@ -0,0 +1,17 @@ +//@ known-bug: rust-lang/rust#125888 +enum NestedEnum { + First, + Second, +} + +enum Enum { + Variant(*const &'a ()), +} + +fn foo(x: Enum) { + match x { + Enum::Variant(NestedEnum::Second) => {} + } +} + +fn main() {} diff --git a/tests/crashes/125914.rs b/tests/crashes/125914.rs new file mode 100644 index 000000000000..77ccb9fb0978 --- /dev/null +++ b/tests/crashes/125914.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125914 +enum AstKind<'ast> { + ExprInt, +} + +enum Foo { + Bar(isize), + Baz, +} + +enum Other { + Other1(Foo), + Other2(AstKind), +} + +fn main() { + match Other::Other1(Foo::Baz) { + ::Other::Other2(::Foo::Bar(..)) => {} + } +} diff --git a/tests/crashes/125957.rs b/tests/crashes/125957.rs new file mode 100644 index 000000000000..e3abe5262eb9 --- /dev/null +++ b/tests/crashes/125957.rs @@ -0,0 +1,20 @@ +//@ known-bug: rust-lang/rust#125957 +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] +#![feature(associated_const_equality)] + +pub struct Equal(); + +pub enum ParseMode { + Raw, +} +pub trait Parse { + const PARSE_MODE: ParseMode; +} +pub trait RenderRaw: Parse {} + +trait GenericVec { + fn unwrap() -> dyn RenderRaw; +} + +fn main() {} diff --git a/tests/crashes/125992.rs b/tests/crashes/125992.rs new file mode 100644 index 000000000000..d78f28ce6de4 --- /dev/null +++ b/tests/crashes/125992.rs @@ -0,0 +1,19 @@ +//@ known-bug: rust-lang/rust#125992 +//@ compile-flags: -Zpolonius=next + +#![feature(inherent_associated_types)] + +type Function = for<'a> fn(&'a i32) -> S<'a>::P; + +struct S<'a>(&'a ()); + +impl<'a> S { + type P = &'a i32; +} + +fn ret_ref_local<'e>() -> &'e i32 { + let f: Function = |x| x; + + let local = 0; + f(&local) +} diff --git a/tests/mir-opt/building/match/sort_candidates.rs b/tests/mir-opt/building/match/sort_candidates.rs index f207f0b32348..593a975a7a47 100644 --- a/tests/mir-opt/building/match/sort_candidates.rs +++ b/tests/mir-opt/building/match/sort_candidates.rs @@ -5,9 +5,9 @@ fn constant_eq(s: &str, b: bool) -> u32 { // Check that we only test "a" once // CHECK-LABEL: fn constant_eq( - // CHECK: bb0: { - // CHECK: [[a:_.*]] = const "a"; - // CHECK-NOT: {{_.*}} = const "a"; + // CHECK-NOT: const "a" + // CHECK: {{_[0-9]+}} = const "a" as &[u8] (Transmute); + // CHECK-NOT: const "a" match (s, b) { ("a", _) if true => 1, ("b", true) => 2, diff --git a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff b/tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff similarity index 79% rename from tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff rename to tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff index c1529dbee13c..ac33f51984cd 100644 --- a/tests/mir-opt/const_debuginfo.main.ConstDebugInfo.diff +++ b/tests/mir-opt/const_debuginfo.main.SingleUseConsts.diff @@ -1,5 +1,5 @@ -- // MIR for `main` before ConstDebugInfo -+ // MIR for `main` after ConstDebugInfo +- // MIR for `main` before SingleUseConsts ++ // MIR for `main` after SingleUseConsts fn main() -> () { let mut _0: (); @@ -56,39 +56,53 @@ bb0: { nop; - _1 = const 1_u8; +- _1 = const 1_u8; nop; - _2 = const 2_u8; +- _2 = const 2_u8; nop; - _3 = const 3_u8; +- _3 = const 3_u8; ++ nop; ++ nop; ++ nop; StorageLive(_4); StorageLive(_5); StorageLive(_6); - _6 = const 1_u8; +- _6 = const 1_u8; ++ nop; StorageLive(_7); - _7 = const 2_u8; - _5 = const 3_u8; +- _7 = const 2_u8; +- _5 = const 3_u8; ++ nop; ++ nop; StorageDead(_7); StorageDead(_6); StorageLive(_8); - _8 = const 3_u8; - _4 = const 6_u8; +- _8 = const 3_u8; +- _4 = const 6_u8; ++ nop; ++ nop; StorageDead(_8); StorageDead(_5); StorageLive(_9); - _9 = const "hello, world!"; +- _9 = const "hello, world!"; ++ nop; StorageLive(_10); _10 = (const true, const false, const 123_u32); StorageLive(_11); - _11 = const Option::::Some(99_u16); +- _11 = const Option::::Some(99_u16); ++ nop; StorageLive(_12); - _12 = const Point {{ x: 32_u32, y: 32_u32 }}; +- _12 = const Point {{ x: 32_u32, y: 32_u32 }}; ++ nop; StorageLive(_13); nop; - _14 = const 32_u32; +- _14 = const 32_u32; ++ nop; StorageLive(_15); - _15 = const 32_u32; - _13 = const 64_u32; +- _15 = const 32_u32; +- _13 = const 64_u32; ++ nop; ++ nop; StorageDead(_15); nop; _0 = const (); diff --git a/tests/mir-opt/const_debuginfo.rs b/tests/mir-opt/const_debuginfo.rs index b880d7e07a6e..907d7fef0674 100644 --- a/tests/mir-opt/const_debuginfo.rs +++ b/tests/mir-opt/const_debuginfo.rs @@ -1,12 +1,14 @@ -//@ test-mir-pass: ConstDebugInfo +//@ test-mir-pass: SingleUseConsts //@ compile-flags: -C overflow-checks=no -Zmir-enable-passes=+GVN +#![allow(unused)] + struct Point { x: u32, y: u32, } -// EMIT_MIR const_debuginfo.main.ConstDebugInfo.diff +// EMIT_MIR const_debuginfo.main.SingleUseConsts.diff fn main() { // CHECK-LABEL: fn main( // CHECK: debug x => const 1_u8; diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff index 570ec129f06e..b596e25ddfdf 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - _2 = const 1_u32; + nop; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff index 570ec129f06e..b596e25ddfdf 100644 --- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff +++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff @@ -18,7 +18,7 @@ bb0: { StorageLive(_1); StorageLive(_2); - _2 = const 1_u32; + nop; _1 = Un { us: const 1_u32 }; StorageDead(_2); StorageLive(_3); diff --git a/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff new file mode 100644 index 000000000000..6e5bdb16595b --- /dev/null +++ b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-abort.diff @@ -0,0 +1,60 @@ +- // MIR for `casts_before_aggregate_raw_ptr` before GVN ++ // MIR for `casts_before_aggregate_raw_ptr` after GVN + + fn casts_before_aggregate_raw_ptr(_1: *const u32) -> *const [u8] { + debug x => _1; + let mut _0: *const [u8]; + let _2: *const [u8; 4]; + let mut _3: *const u32; + let mut _5: *const [u8; 4]; + let mut _7: *const u8; + let mut _8: *const (); + scope 1 { + debug x => _2; + let _4: *const u8; + scope 2 { + debug x => _4; + let _6: *const (); + scope 3 { + debug x => _6; + } + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = move _3 as *const [u8; 4] (PtrToPtr); ++ _2 = _1 as *const [u8; 4] (PtrToPtr); + StorageDead(_3); +- StorageLive(_4); ++ nop; + StorageLive(_5); + _5 = _2; +- _4 = move _5 as *const u8 (PtrToPtr); ++ _4 = _1 as *const u8 (PtrToPtr); + StorageDead(_5); +- StorageLive(_6); ++ nop; + StorageLive(_7); + _7 = _4; +- _6 = move _7 as *const () (PtrToPtr); ++ _6 = _1 as *const () (PtrToPtr); + StorageDead(_7); + StorageLive(_8); + _8 = _6; +- _0 = *const [u8] from (move _8, const 4_usize); ++ _0 = *const [u8] from (_1, const 4_usize); + StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff new file mode 100644 index 000000000000..6e5bdb16595b --- /dev/null +++ b/tests/mir-opt/gvn.casts_before_aggregate_raw_ptr.GVN.panic-unwind.diff @@ -0,0 +1,60 @@ +- // MIR for `casts_before_aggregate_raw_ptr` before GVN ++ // MIR for `casts_before_aggregate_raw_ptr` after GVN + + fn casts_before_aggregate_raw_ptr(_1: *const u32) -> *const [u8] { + debug x => _1; + let mut _0: *const [u8]; + let _2: *const [u8; 4]; + let mut _3: *const u32; + let mut _5: *const [u8; 4]; + let mut _7: *const u8; + let mut _8: *const (); + scope 1 { + debug x => _2; + let _4: *const u8; + scope 2 { + debug x => _4; + let _6: *const (); + scope 3 { + debug x => _6; + } + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = move _3 as *const [u8; 4] (PtrToPtr); ++ _2 = _1 as *const [u8; 4] (PtrToPtr); + StorageDead(_3); +- StorageLive(_4); ++ nop; + StorageLive(_5); + _5 = _2; +- _4 = move _5 as *const u8 (PtrToPtr); ++ _4 = _1 as *const u8 (PtrToPtr); + StorageDead(_5); +- StorageLive(_6); ++ nop; + StorageLive(_7); + _7 = _4; +- _6 = move _7 as *const () (PtrToPtr); ++ _6 = _1 as *const () (PtrToPtr); + StorageDead(_7); + StorageLive(_8); + _8 = _6; +- _0 = *const [u8] from (move _8, const 4_usize); ++ _0 = *const [u8] from (_1, const 4_usize); + StorageDead(_8); +- StorageDead(_6); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff new file mode 100644 index 000000000000..73dbabb56b35 --- /dev/null +++ b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-abort.diff @@ -0,0 +1,32 @@ +- // MIR for `meta_of_ref_to_slice` before GVN ++ // MIR for `meta_of_ref_to_slice` after GVN + + fn meta_of_ref_to_slice(_1: *const i32) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *const [i32]; + let mut _3: *const i32; + let mut _4: *const [i32]; + scope 1 { + debug ptr => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = *const [i32] from (move _3, const 1_usize); ++ _2 = *const [i32] from (_1, const 1_usize); + StorageDead(_3); + StorageLive(_4); + _4 = _2; +- _0 = PtrMetadata(move _4); ++ _0 = const 1_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff new file mode 100644 index 000000000000..73dbabb56b35 --- /dev/null +++ b/tests/mir-opt/gvn.meta_of_ref_to_slice.GVN.panic-unwind.diff @@ -0,0 +1,32 @@ +- // MIR for `meta_of_ref_to_slice` before GVN ++ // MIR for `meta_of_ref_to_slice` after GVN + + fn meta_of_ref_to_slice(_1: *const i32) -> usize { + debug x => _1; + let mut _0: usize; + let _2: *const [i32]; + let mut _3: *const i32; + let mut _4: *const [i32]; + scope 1 { + debug ptr => _2; + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = _1; +- _2 = *const [i32] from (move _3, const 1_usize); ++ _2 = *const [i32] from (_1, const 1_usize); + StorageDead(_3); + StorageLive(_4); + _4 = _2; +- _0 = PtrMetadata(move _4); ++ _0 = const 1_usize; + StorageDead(_4); +- StorageDead(_2); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs index 315377e4356f..720018f112e5 100644 --- a/tests/mir-opt/gvn.rs +++ b/tests/mir-opt/gvn.rs @@ -783,6 +783,39 @@ fn non_freeze(x: T) { } } +// Check that we can const-prop into `from_raw_parts` +fn slice_const_length(x: &[i32]) -> *const [i32] { + // CHECK-LABEL: fn slice_const_length( + // CHECK: _0 = *const [i32] from ({{_[0-9]+}}, const 123_usize); + let ptr = x.as_ptr(); + let len = 123; + std::intrinsics::aggregate_raw_ptr(ptr, len) +} + +fn meta_of_ref_to_slice(x: *const i32) -> usize { + // CHECK-LABEL: fn meta_of_ref_to_slice + // CHECK: _0 = const 1_usize + let ptr: *const [i32] = std::intrinsics::aggregate_raw_ptr(x, 1); + std::intrinsics::ptr_metadata(ptr) +} + +fn slice_from_raw_parts_as_ptr(x: *const u16, n: usize) -> (*const u16, *const f32) { + // CHECK-LABEL: fn slice_from_raw_parts_as_ptr + // CHECK: _8 = _1 as *const f32 (PtrToPtr); + // CHECK: _0 = (_1, move _8); + let ptr: *const [u16] = std::intrinsics::aggregate_raw_ptr(x, n); + (ptr as *const u16, ptr as *const f32) +} + +fn casts_before_aggregate_raw_ptr(x: *const u32) -> *const [u8] { + // CHECK-LABEL: fn casts_before_aggregate_raw_ptr + // CHECK: _0 = *const [u8] from (_1, const 4_usize); + let x = x as *const [u8; 4]; + let x = x as *const u8; + let x = x as *const (); + std::intrinsics::aggregate_raw_ptr(x, 4) +} + fn main() { subexpression_elimination(2, 4, 5); wrap_unwrap(5); @@ -807,6 +840,9 @@ fn main() { wide_ptr_integer(); borrowed(5); non_freeze(5); + slice_const_length(&[1]); + meta_of_ref_to_slice(&42); + slice_from_raw_parts_as_ptr(&123, 456); } #[inline(never)] @@ -840,3 +876,7 @@ fn identity(x: T) -> T { // EMIT_MIR gvn.wide_ptr_integer.GVN.diff // EMIT_MIR gvn.borrowed.GVN.diff // EMIT_MIR gvn.non_freeze.GVN.diff +// EMIT_MIR gvn.slice_const_length.GVN.diff +// EMIT_MIR gvn.meta_of_ref_to_slice.GVN.diff +// EMIT_MIR gvn.slice_from_raw_parts_as_ptr.GVN.diff +// EMIT_MIR gvn.casts_before_aggregate_raw_ptr.GVN.diff diff --git a/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff b/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff new file mode 100644 index 000000000000..fd5fa035d816 --- /dev/null +++ b/tests/mir-opt/gvn.slice_const_length.GVN.panic-abort.diff @@ -0,0 +1,48 @@ +- // MIR for `slice_const_length` before GVN ++ // MIR for `slice_const_length` after GVN + + fn slice_const_length(_1: &[i32]) -> *const [i32] { + debug x => _1; + let mut _0: *const [i32]; + let _2: *const i32; + let mut _3: &[i32]; + let mut _5: *const i32; + let mut _6: usize; + scope 1 { + debug ptr => _2; + let _4: usize; + scope 2 { + debug len => _4; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = core::slice::::as_ptr(move _3) -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_3); +- StorageLive(_4); ++ nop; + _4 = const 123_usize; + StorageLive(_5); + _5 = _2; + StorageLive(_6); +- _6 = _4; +- _0 = *const [i32] from (move _5, move _6); ++ _6 = const 123_usize; ++ _0 = *const [i32] from (_2, const 123_usize); + StorageDead(_6); + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff new file mode 100644 index 000000000000..98945cf9724d --- /dev/null +++ b/tests/mir-opt/gvn.slice_const_length.GVN.panic-unwind.diff @@ -0,0 +1,48 @@ +- // MIR for `slice_const_length` before GVN ++ // MIR for `slice_const_length` after GVN + + fn slice_const_length(_1: &[i32]) -> *const [i32] { + debug x => _1; + let mut _0: *const [i32]; + let _2: *const i32; + let mut _3: &[i32]; + let mut _5: *const i32; + let mut _6: usize; + scope 1 { + debug ptr => _2; + let _4: usize; + scope 2 { + debug len => _4; + } + } + + bb0: { +- StorageLive(_2); ++ nop; + StorageLive(_3); + _3 = &(*_1); + _2 = core::slice::::as_ptr(move _3) -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_3); +- StorageLive(_4); ++ nop; + _4 = const 123_usize; + StorageLive(_5); + _5 = _2; + StorageLive(_6); +- _6 = _4; +- _0 = *const [i32] from (move _5, move _6); ++ _6 = const 123_usize; ++ _0 = *const [i32] from (_2, const 123_usize); + StorageDead(_6); + StorageDead(_5); +- StorageDead(_4); +- StorageDead(_2); ++ nop; ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff new file mode 100644 index 000000000000..75bcd2a8d72c --- /dev/null +++ b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-abort.diff @@ -0,0 +1,51 @@ +- // MIR for `slice_from_raw_parts_as_ptr` before GVN ++ // MIR for `slice_from_raw_parts_as_ptr` after GVN + + fn slice_from_raw_parts_as_ptr(_1: *const u16, _2: usize) -> (*const u16, *const f32) { + debug x => _1; + debug n => _2; + let mut _0: (*const u16, *const f32); + let _3: *const [u16]; + let mut _4: *const u16; + let mut _5: usize; + let mut _6: *const u16; + let mut _7: *const [u16]; + let mut _8: *const f32; + let mut _9: *const [u16]; + scope 1 { + debug ptr => _3; + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _1; + StorageLive(_5); + _5 = _2; +- _3 = *const [u16] from (move _4, move _5); ++ _3 = *const [u16] from (_1, _2); + StorageDead(_5); + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _7 = _3; +- _6 = move _7 as *const u16 (PtrToPtr); ++ _6 = _1; + StorageDead(_7); + StorageLive(_8); + StorageLive(_9); + _9 = _3; +- _8 = move _9 as *const f32 (PtrToPtr); ++ _8 = _1 as *const f32 (PtrToPtr); + StorageDead(_9); +- _0 = (move _6, move _8); ++ _0 = (_1, move _8); + StorageDead(_8); + StorageDead(_6); +- StorageDead(_3); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff new file mode 100644 index 000000000000..75bcd2a8d72c --- /dev/null +++ b/tests/mir-opt/gvn.slice_from_raw_parts_as_ptr.GVN.panic-unwind.diff @@ -0,0 +1,51 @@ +- // MIR for `slice_from_raw_parts_as_ptr` before GVN ++ // MIR for `slice_from_raw_parts_as_ptr` after GVN + + fn slice_from_raw_parts_as_ptr(_1: *const u16, _2: usize) -> (*const u16, *const f32) { + debug x => _1; + debug n => _2; + let mut _0: (*const u16, *const f32); + let _3: *const [u16]; + let mut _4: *const u16; + let mut _5: usize; + let mut _6: *const u16; + let mut _7: *const [u16]; + let mut _8: *const f32; + let mut _9: *const [u16]; + scope 1 { + debug ptr => _3; + } + + bb0: { +- StorageLive(_3); ++ nop; + StorageLive(_4); + _4 = _1; + StorageLive(_5); + _5 = _2; +- _3 = *const [u16] from (move _4, move _5); ++ _3 = *const [u16] from (_1, _2); + StorageDead(_5); + StorageDead(_4); + StorageLive(_6); + StorageLive(_7); + _7 = _3; +- _6 = move _7 as *const u16 (PtrToPtr); ++ _6 = _1; + StorageDead(_7); + StorageLive(_8); + StorageLive(_9); + _9 = _3; +- _8 = move _9 as *const f32 (PtrToPtr); ++ _8 = _1 as *const f32 (PtrToPtr); + StorageDead(_9); +- _0 = (move _6, move _8); ++ _0 = (_1, move _8); + StorageDead(_8); + StorageDead(_6); +- StorageDead(_3); ++ nop; + return; + } + } + diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff index 24e5587f9632..2ab79cc2a509 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-abort.diff @@ -8,7 +8,7 @@ + let mut _2: bool; + let mut _3: bool; + scope 2 { -+ debug buffer => const inner::promoted[0]; ++ debug buffer => _1; + scope 3 { + debug index => _0; + } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff index 4eb8a5c98473..4d96a8628859 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.panic-unwind.diff @@ -8,7 +8,7 @@ + let mut _2: bool; + let mut _3: bool; + scope 2 { -+ debug buffer => const inner::promoted[0]; ++ debug buffer => _1; + scope 3 { + debug index => _0; + } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index b2539f391d1a..1f88339b5861 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -29,8 +29,8 @@ _3 = &_4; _2 = move _3 as &[T] (PointerCoercion(Unsize)); StorageDead(_3); - _5 = const 3_usize; - _6 = const true; + nop; + nop; goto -> bb2; } diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index ff7f12c093ce..19a581ba3f09 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -29,8 +29,8 @@ _3 = &_4; _2 = move _3 as &[T] (PointerCoercion(Unsize)); StorageDead(_3); - _5 = const 3_usize; - _6 = const true; + nop; + nop; goto -> bb2; } diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff index 17d83752fc13..465cb1a9b1f4 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff @@ -23,16 +23,15 @@ let mut _12: isize; let _13: std::alloc::AllocError; let mut _14: !; - let _15: &str; - let mut _16: &dyn std::fmt::Debug; - let mut _17: &std::alloc::AllocError; + let mut _15: &dyn std::fmt::Debug; + let mut _16: &std::alloc::AllocError; scope 7 { } scope 8 { } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _18: *const [u8]; + let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::::unwrap) { @@ -87,36 +86,33 @@ StorageDead(_8); StorageDead(_7); StorageLive(_12); - StorageLive(_15); _12 = discriminant(_6); switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - _15 = const "called `Result::unwrap()` on an `Err` value"; + StorageLive(_15); StorageLive(_16); - StorageLive(_17); - _17 = &_13; - _16 = move _17 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); - StorageDead(_17); - _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable; + _16 = &_13; + _15 = move _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + StorageDead(_16); + _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_15); StorageDead(_12); StorageDead(_6); -- StorageLive(_18); +- StorageLive(_17); + nop; - _18 = (_5.0: *const [u8]); -- _4 = move _18 as *mut [u8] (PtrToPtr); -- StorageDead(_18); -+ _4 = _18 as *mut [u8] (PtrToPtr); + _17 = (_5.0: *const [u8]); +- _4 = move _17 as *mut [u8] (PtrToPtr); +- StorageDead(_17); ++ _4 = _17 as *mut [u8] (PtrToPtr); + nop; StorageDead(_5); - _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = _18 as *mut u8 (PtrToPtr); ++ _3 = _17 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff index 1cf950402c36..925d8997b8a5 100644 --- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff @@ -23,16 +23,15 @@ let mut _12: isize; let _13: std::alloc::AllocError; let mut _14: !; - let _15: &str; - let mut _16: &dyn std::fmt::Debug; - let mut _17: &std::alloc::AllocError; + let mut _15: &dyn std::fmt::Debug; + let mut _16: &std::alloc::AllocError; scope 7 { } scope 8 { } } scope 9 (inlined NonNull::<[u8]>::as_ptr) { - let mut _18: *const [u8]; + let mut _17: *const [u8]; } } scope 3 (inlined #[track_caller] Option::::unwrap) { @@ -87,36 +86,33 @@ StorageDead(_8); StorageDead(_7); StorageLive(_12); - StorageLive(_15); _12 = discriminant(_6); switchInt(move _12) -> [0: bb6, 1: bb5, otherwise: bb1]; } bb5: { - _15 = const "called `Result::unwrap()` on an `Err` value"; + StorageLive(_15); StorageLive(_16); - StorageLive(_17); - _17 = &_13; - _16 = move _17 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); - StorageDead(_17); - _14 = result::unwrap_failed(move _15, move _16) -> unwind unreachable; + _16 = &_13; + _15 = move _16 as &dyn std::fmt::Debug (PointerCoercion(Unsize)); + StorageDead(_16); + _14 = result::unwrap_failed(const "called `Result::unwrap()` on an `Err` value", move _15) -> unwind unreachable; } bb6: { _5 = move ((_6 as Ok).0: std::ptr::NonNull<[u8]>); - StorageDead(_15); StorageDead(_12); StorageDead(_6); -- StorageLive(_18); +- StorageLive(_17); + nop; - _18 = (_5.0: *const [u8]); -- _4 = move _18 as *mut [u8] (PtrToPtr); -- StorageDead(_18); -+ _4 = _18 as *mut [u8] (PtrToPtr); + _17 = (_5.0: *const [u8]); +- _4 = move _17 as *mut [u8] (PtrToPtr); +- StorageDead(_17); ++ _4 = _17 as *mut [u8] (PtrToPtr); + nop; StorageDead(_5); - _3 = move _4 as *mut u8 (PtrToPtr); -+ _3 = _18 as *mut u8 (PtrToPtr); ++ _3 = _17 as *mut u8 (PtrToPtr); StorageDead(_4); StorageDead(_3); - StorageDead(_1); diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir index 2c6d93e10c11..2f6139712ffc 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir @@ -12,8 +12,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 3 (inlined std::ptr::const_ptr::::add) { } scope 4 (inlined std::ptr::const_ptr::::with_metadata_of::<[u32]>) { - let mut _5: *const (); - let mut _6: usize; + let mut _5: usize; scope 5 (inlined std::ptr::metadata::<[u32]>) { } scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) { @@ -28,11 +27,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); - _5 = _4 as *const () (PtrToPtr); - StorageLive(_6); - _6 = PtrMetadata(_1); - _0 = *const [u32] from (_5, _6); - StorageDead(_6); + _5 = PtrMetadata(_1); + _0 = *const [u32] from (_4, _5); StorageDead(_5); StorageDead(_4); return; diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir index 2c6d93e10c11..2f6139712ffc 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir @@ -12,8 +12,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { scope 3 (inlined std::ptr::const_ptr::::add) { } scope 4 (inlined std::ptr::const_ptr::::with_metadata_of::<[u32]>) { - let mut _5: *const (); - let mut _6: usize; + let mut _5: usize; scope 5 (inlined std::ptr::metadata::<[u32]>) { } scope 6 (inlined std::ptr::from_raw_parts::<[u32], ()>) { @@ -28,11 +27,8 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] { _4 = Offset(_3, _2); StorageDead(_3); StorageLive(_5); - _5 = _4 as *const () (PtrToPtr); - StorageLive(_6); - _6 = PtrMetadata(_1); - _0 = *const [u32] from (_5, _6); - StorageDead(_6); + _5 = PtrMetadata(_1); + _0 = *const [u32] from (_4, _5); StorageDead(_5); StorageDead(_4); return; diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir index 04fb6b838f02..8d47e63eff2a 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir @@ -20,11 +20,13 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { } bb0: { + StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); _0 = _4 as *const u32 (PtrToPtr); + StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir index 04fb6b838f02..8d47e63eff2a 100644 --- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir @@ -20,11 +20,13 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 { } bb0: { + StorageLive(_4); StorageLive(_3); _3 = _1 as *const u8 (PtrToPtr); _4 = Offset(_3, _2); StorageDead(_3); _0 = _4 as *const u32 (PtrToPtr); + StorageDead(_4); return; } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir index d979c5ec1d5a..8f41fb70925f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir @@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; let mut _13: std::iter::Enumerate>; - let mut _14: std::iter::Enumerate>; - let mut _15: &mut std::iter::Enumerate>; - let mut _16: std::option::Option<(usize, &T)>; - let mut _17: isize; - let mut _20: &impl Fn(usize, &T); - let mut _21: (usize, &T); - let _22: (); + let mut _14: &mut std::iter::Enumerate>; + let mut _15: std::option::Option<(usize, &T)>; + let mut _16: isize; + let mut _19: &impl Fn(usize, &T); + let mut _20: (usize, &T); + let _21: (); scope 1 { - debug iter => _14; - let _18: usize; - let _19: &T; + debug iter => _13; + let _17: usize; + let _18: &T; scope 2 { - debug i => _18; - debug x => _19; + debug i => _17; + debug x => _18; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Enumerate::> { iter: _12, count: const 0_usize }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Enumerate::> { iter: _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut _14; - _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind unreachable]; + StorageLive(_14); + _14 = &mut _13; + _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -134,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _18 = (((_16 as Some).0: (usize, &T)).0: usize); - _19 = (((_16 as Some).0: (usize, &T)).1: &T); + _17 = (((_15 as Some).0: (usize, &T)).0: usize); + _18 = (((_15 as Some).0: (usize, &T)).1: &T); + StorageLive(_19); + _19 = &_2; StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (_18, _19); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind unreachable]; + _20 = (_17, _18); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_21); StorageDead(_20); - StorageDead(_16); + StorageDead(_19); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir index 8491c49f7673..17cf305468e8 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Enumerate>; let mut _13: std::iter::Enumerate>; - let mut _14: std::iter::Enumerate>; - let mut _15: &mut std::iter::Enumerate>; - let mut _16: std::option::Option<(usize, &T)>; - let mut _17: isize; - let mut _20: &impl Fn(usize, &T); - let mut _21: (usize, &T); - let _22: (); + let mut _14: &mut std::iter::Enumerate>; + let mut _15: std::option::Option<(usize, &T)>; + let mut _16: isize; + let mut _19: &impl Fn(usize, &T); + let mut _20: (usize, &T); + let _21: (); scope 1 { - debug iter => _14; - let _18: usize; - let _19: &T; + debug iter => _13; + let _17: usize; + let _18: &T; scope 2 { - debug i => _18; - debug x => _19; + debug i => _17; + debug x => _18; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Enumerate::> { iter: _12, count: const 0_usize }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Enumerate::> { iter: _11, count: const 0_usize }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut _14; - _16 = > as Iterator>::next(move _15) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _14 = &mut _13; + _15 = > as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -134,19 +130,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb8: { - _18 = (((_16 as Some).0: (usize, &T)).0: usize); - _19 = (((_16 as Some).0: (usize, &T)).1: &T); + _17 = (((_15 as Some).0: (usize, &T)).0: usize); + _18 = (((_15 as Some).0: (usize, &T)).1: &T); + StorageLive(_19); + _19 = &_2; StorageLive(_20); - _20 = &_2; - StorageLive(_21); - _21 = (_18, _19); - _22 = >::call(move _20, move _21) -> [return: bb9, unwind: bb11]; + _20 = (_17, _18); + _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_21); StorageDead(_20); - StorageDead(_16); + StorageDead(_19); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir index 67dd0c85ea1d..3c1bbdc87424 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); + let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: std::slice::Iter<'_, T>; - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -62,60 +61,57 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - StorageLive(_13); - _13 = _12; + StorageLive(_12); + _12 = _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut _13; - _15 = as Iterator>::next(move _14) -> [return: bb5, unwind unreachable]; + StorageLive(_13); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -124,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); + _16 = ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir index 7c41e9e1f1b7..b2ec1ea7b9f2 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -4,32 +4,31 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); + let mut _11: std::slice::Iter<'_, T>; let mut _12: std::slice::Iter<'_, T>; - let mut _13: std::slice::Iter<'_, T>; - let mut _14: &mut std::slice::Iter<'_, T>; - let mut _15: std::option::Option<&T>; - let mut _16: isize; - let mut _18: &impl Fn(&T); - let mut _19: (&T,); - let _20: (); + let mut _13: &mut std::slice::Iter<'_, T>; + let mut _14: std::option::Option<&T>; + let mut _15: isize; + let mut _17: &impl Fn(&T); + let mut _18: (&T,); + let _19: (); scope 1 { - debug iter => _13; - let _17: &T; + debug iter => _12; + let _16: &T; scope 2 { - debug x => _17; + debug x => _16; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -62,60 +61,57 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - StorageLive(_13); - _13 = _12; + StorageLive(_12); + _12 = _11; goto -> bb4; } bb4: { - StorageLive(_15); StorageLive(_14); - _14 = &mut _13; - _15 = as Iterator>::next(move _14) -> [return: bb5, unwind: bb11]; + StorageLive(_13); + _13 = &mut _12; + _14 = as Iterator>::next(move _13) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_14); - _16 = discriminant(_15); - switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_13); + _15 = discriminant(_14); + switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_15); - StorageDead(_13); + StorageDead(_14); + StorageDead(_12); drop(_2) -> [return: bb7, unwind continue]; } @@ -124,18 +120,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _17 = ((_15 as Some).0: &T); + _16 = ((_14 as Some).0: &T); + StorageLive(_17); + _17 = &_2; StorageLive(_18); - _18 = &_2; - StorageLive(_19); - _19 = (_17,); - _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; + _18 = (_16,); + _19 = >::call(move _17, move _18) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_19); StorageDead(_18); - StorageDead(_15); + StorageDead(_17); + StorageDead(_14); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir index ffeef1e04a15..bf982f076de7 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _14: std::iter::Rev>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _18; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - let mut _15: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Rev::> { iter: _12 }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Rev::> { iter: _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut (_14.0: std::slice::Iter<'_, T>); - _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind unreachable]; + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind unreachable]; } @@ -134,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = ((_16 as Some).0: &T); + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind unreachable]; + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind unreachable]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir index c7cd37afd866..532b81625212 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir @@ -4,35 +4,34 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { debug slice => _1; debug f => _2; let mut _0: (); - let mut _12: std::slice::Iter<'_, T>; + let mut _11: std::slice::Iter<'_, T>; + let mut _12: std::iter::Rev>; let mut _13: std::iter::Rev>; - let mut _14: std::iter::Rev>; - let mut _16: std::option::Option<&T>; - let mut _17: isize; - let mut _19: &impl Fn(&T); - let mut _20: (&T,); - let _21: (); + let mut _15: std::option::Option<&T>; + let mut _16: isize; + let mut _18: &impl Fn(&T); + let mut _19: (&T,); + let _20: (); scope 1 { - debug iter => _14; - let _18: &T; + debug iter => _13; + let _17: &T; scope 2 { - debug x => _18; + debug x => _17; } scope 17 (inlined > as Iterator>::next) { - let mut _15: &mut std::slice::Iter<'_, T>; + let mut _14: &mut std::slice::Iter<'_, T>; } } scope 3 (inlined core::slice::::iter) { scope 4 (inlined std::slice::Iter::<'_, T>::new) { let _3: usize; - let mut _7: bool; + let mut _7: *mut T; let mut _8: *mut T; - let mut _9: *mut T; - let mut _11: *const T; + let mut _10: *const T; scope 5 { let _6: std::ptr::NonNull; scope 6 { - let _10: *const T; + let _9: *const T; scope 7 { } scope 11 (inlined without_provenance::) { @@ -61,7 +60,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb0: { - StorageLive(_12); + StorageLive(_11); StorageLive(_3); StorageLive(_6); StorageLive(_4); @@ -70,62 +69,59 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { _4 = &raw const (*_1); _5 = _4 as *const T (PtrToPtr); _6 = NonNull:: { pointer: _5 }; - StorageLive(_10); - StorageLive(_7); - _7 = const ::IS_ZST; - switchInt(move _7) -> [0: bb1, otherwise: bb2]; + StorageLive(_9); + switchInt(const ::IS_ZST) -> [0: bb1, otherwise: bb2]; } bb1: { - StorageLive(_9); StorageLive(_8); - _8 = _4 as *mut T (PtrToPtr); - _9 = Offset(_8, _3); + StorageLive(_7); + _7 = _4 as *mut T (PtrToPtr); + _8 = Offset(_7, _3); + StorageDead(_7); + _9 = move _8 as *const T (PointerCoercion(MutToConstPointer)); StorageDead(_8); - _10 = move _9 as *const T (PointerCoercion(MutToConstPointer)); - StorageDead(_9); goto -> bb3; } bb2: { - _10 = _3 as *const T (Transmute); + _9 = _3 as *const T (Transmute); goto -> bb3; } bb3: { - StorageDead(_7); - StorageLive(_11); - _11 = _10; - _12 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _11, _marker: const ZeroSized: PhantomData<&T> }; - StorageDead(_11); + StorageLive(_10); + _10 = _9; + _11 = std::slice::Iter::<'_, T> { ptr: _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> }; StorageDead(_10); + StorageDead(_9); StorageDead(_5); StorageDead(_4); StorageDead(_6); StorageDead(_3); - _13 = Rev::> { iter: _12 }; - StorageDead(_12); - StorageLive(_14); - _14 = _13; + _12 = Rev::> { iter: _11 }; + StorageDead(_11); + StorageLive(_13); + _13 = _12; goto -> bb4; } bb4: { - StorageLive(_16); StorageLive(_15); - _15 = &mut (_14.0: std::slice::Iter<'_, T>); - _16 = as DoubleEndedIterator>::next_back(move _15) -> [return: bb5, unwind: bb11]; + StorageLive(_14); + _14 = &mut (_13.0: std::slice::Iter<'_, T>); + _15 = as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11]; } bb5: { - StorageDead(_15); - _17 = discriminant(_16); - switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10]; + StorageDead(_14); + _16 = discriminant(_15); + switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10]; } bb6: { - StorageDead(_16); - StorageDead(_14); + StorageDead(_15); + StorageDead(_13); drop(_2) -> [return: bb7, unwind continue]; } @@ -134,18 +130,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () { } bb8: { - _18 = ((_16 as Some).0: &T); + _17 = ((_15 as Some).0: &T); + StorageLive(_18); + _18 = &_2; StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_18,); - _21 = >::call(move _19, move _20) -> [return: bb9, unwind: bb11]; + _19 = (_17,); + _20 = >::call(move _18, move _19) -> [return: bb9, unwind: bb11]; } bb9: { - StorageDead(_20); StorageDead(_19); - StorageDead(_16); + StorageDead(_18); + StorageDead(_15); goto -> bb4; } diff --git a/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8818c891e94b --- /dev/null +++ b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-abort.diff @@ -0,0 +1,12 @@ +- // MIR for `assign_const_to_return` before SingleUseConsts ++ // MIR for `assign_const_to_return` after SingleUseConsts + + fn assign_const_to_return() -> bool { + let mut _0: bool; + + bb0: { + _0 = const ::ASSOC_BOOL; + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8818c891e94b --- /dev/null +++ b/tests/mir-opt/single_use_consts.assign_const_to_return.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,12 @@ +- // MIR for `assign_const_to_return` before SingleUseConsts ++ // MIR for `assign_const_to_return` after SingleUseConsts + + fn assign_const_to_return() -> bool { + let mut _0: bool; + + bb0: { + _0 = const ::ASSOC_BOOL; + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..468076e5ee3c --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-abort.diff @@ -0,0 +1,31 @@ +- // MIR for `if_const` before SingleUseConsts ++ // MIR for `if_const` after SingleUseConsts + + fn if_const() -> i32 { + let mut _0: i32; + let mut _1: bool; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_BOOL) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 7_i32; + goto -> bb3; + } + + bb2: { + _0 = const 42_i32; + goto -> bb3; + } + + bb3: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..468076e5ee3c --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,31 @@ +- // MIR for `if_const` before SingleUseConsts ++ // MIR for `if_const` after SingleUseConsts + + fn if_const() -> i32 { + let mut _0: i32; + let mut _1: bool; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; +- switchInt(move _1) -> [0: bb2, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_BOOL) -> [0: bb2, otherwise: bb1]; + } + + bb1: { + _0 = const 7_i32; + goto -> bb3; + } + + bb2: { + _0 = const 42_i32; + goto -> bb3; + } + + bb3: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..ad1a2b300f2a --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,46 @@ +- // MIR for `if_const_debug` before SingleUseConsts ++ // MIR for `if_const_debug` after SingleUseConsts + + fn if_const_debug() -> i32 { + let mut _0: i32; + let _1: bool; + let _2: (); + let mut _3: bool; + scope 1 { +- debug my_bool => _1; ++ debug my_bool => const ::ASSOC_BOOL; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_2); + StorageLive(_3); +- _3 = _1; ++ _3 = const ::ASSOC_BOOL; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; + } + + bb2: { + _0 = const 7_i32; + goto -> bb4; + } + + bb3: { + _0 = const 42_i32; + goto -> bb4; + } + + bb4: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..827a292e5d02 --- /dev/null +++ b/tests/mir-opt/single_use_consts.if_const_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,46 @@ +- // MIR for `if_const_debug` before SingleUseConsts ++ // MIR for `if_const_debug` after SingleUseConsts + + fn if_const_debug() -> i32 { + let mut _0: i32; + let _1: bool; + let _2: (); + let mut _3: bool; + scope 1 { +- debug my_bool => _1; ++ debug my_bool => const ::ASSOC_BOOL; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_BOOL; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_2); + StorageLive(_3); +- _3 = _1; ++ _3 = const ::ASSOC_BOOL; + switchInt(move _3) -> [0: bb3, otherwise: bb2]; + } + + bb2: { + _0 = const 7_i32; + goto -> bb4; + } + + bb3: { + _0 = const 42_i32; + goto -> bb4; + } + + bb4: { + StorageDead(_3); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..f7d823af9e3d --- /dev/null +++ b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-abort.diff @@ -0,0 +1,14 @@ +- // MIR for `keep_parameter` before SingleUseConsts ++ // MIR for `keep_parameter` after SingleUseConsts + + fn keep_parameter(_1: i32) -> () { + debug other => _1; + let mut _0: (); + + bb0: { + _1 = const ::ASSOC_INT; + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..f7d823af9e3d --- /dev/null +++ b/tests/mir-opt/single_use_consts.keep_parameter.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,14 @@ +- // MIR for `keep_parameter` before SingleUseConsts ++ // MIR for `keep_parameter` after SingleUseConsts + + fn keep_parameter(_1: i32) -> () { + debug other => _1; + let mut _0: (); + + bb0: { + _1 = const ::ASSOC_INT; + _0 = const (); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8d87438a47ae --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-abort.diff @@ -0,0 +1,36 @@ +- // MIR for `match_const` before SingleUseConsts ++ // MIR for `match_const` after SingleUseConsts + + fn match_const() -> &str { + let mut _0: &str; + let mut _1: i32; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; +- switchInt(_1) -> [7: bb2, 42: bb3, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_INT) -> [7: bb2, 42: bb3, otherwise: bb1]; + } + + bb1: { + _0 = const "world"; + goto -> bb4; + } + + bb2: { + _0 = const "hello"; + goto -> bb4; + } + + bb3: { + _0 = const "towel"; + goto -> bb4; + } + + bb4: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8d87438a47ae --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,36 @@ +- // MIR for `match_const` before SingleUseConsts ++ // MIR for `match_const` after SingleUseConsts + + fn match_const() -> &str { + let mut _0: &str; + let mut _1: i32; + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; +- switchInt(_1) -> [7: bb2, 42: bb3, otherwise: bb1]; ++ nop; ++ switchInt(const ::ASSOC_INT) -> [7: bb2, 42: bb3, otherwise: bb1]; + } + + bb1: { + _0 = const "world"; + goto -> bb4; + } + + bb2: { + _0 = const "hello"; + goto -> bb4; + } + + bb3: { + _0 = const "towel"; + goto -> bb4; + } + + bb4: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..f192f3feb96e --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,47 @@ +- // MIR for `match_const_debug` before SingleUseConsts ++ // MIR for `match_const_debug` after SingleUseConsts + + fn match_const_debug() -> &str { + let mut _0: &str; + let _1: i32; + let _2: (); + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind unreachable]; + } + + bb1: { + StorageDead(_2); +- switchInt(_1) -> [7: bb3, 42: bb4, otherwise: bb2]; ++ switchInt(const ::ASSOC_INT) -> [7: bb3, 42: bb4, otherwise: bb2]; + } + + bb2: { + _0 = const "world"; + goto -> bb5; + } + + bb3: { + _0 = const "hello"; + goto -> bb5; + } + + bb4: { + _0 = const "towel"; + goto -> bb5; + } + + bb5: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..261faf415f3b --- /dev/null +++ b/tests/mir-opt/single_use_consts.match_const_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,47 @@ +- // MIR for `match_const_debug` before SingleUseConsts ++ // MIR for `match_const_debug` after SingleUseConsts + + fn match_const_debug() -> &str { + let mut _0: &str; + let _1: i32; + let _2: (); + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + StorageLive(_2); + _2 = do_whatever() -> [return: bb1, unwind continue]; + } + + bb1: { + StorageDead(_2); +- switchInt(_1) -> [7: bb3, 42: bb4, otherwise: bb2]; ++ switchInt(const ::ASSOC_INT) -> [7: bb3, 42: bb4, otherwise: bb2]; + } + + bb2: { + _0 = const "world"; + goto -> bb5; + } + + bb3: { + _0 = const "hello"; + goto -> bb5; + } + + bb4: { + _0 = const "towel"; + goto -> bb5; + } + + bb5: { + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff new file mode 100644 index 000000000000..8ef94a790a34 --- /dev/null +++ b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-abort.diff @@ -0,0 +1,21 @@ +- // MIR for `never_used_debug` before SingleUseConsts ++ // MIR for `never_used_debug` after SingleUseConsts + + fn never_used_debug() -> () { + let mut _0: (); + let _1: i32; + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + _0 = const (); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff new file mode 100644 index 000000000000..8ef94a790a34 --- /dev/null +++ b/tests/mir-opt/single_use_consts.never_used_debug.SingleUseConsts.panic-unwind.diff @@ -0,0 +1,21 @@ +- // MIR for `never_used_debug` before SingleUseConsts ++ // MIR for `never_used_debug` after SingleUseConsts + + fn never_used_debug() -> () { + let mut _0: (); + let _1: i32; + scope 1 { +- debug my_int => _1; ++ debug my_int => const ::ASSOC_INT; + } + + bb0: { + StorageLive(_1); +- _1 = const ::ASSOC_INT; ++ nop; + _0 = const (); + StorageDead(_1); + return; + } + } + diff --git a/tests/mir-opt/single_use_consts.rs b/tests/mir-opt/single_use_consts.rs new file mode 100644 index 000000000000..ecb602c647a5 --- /dev/null +++ b/tests/mir-opt/single_use_consts.rs @@ -0,0 +1,80 @@ +//@ test-mir-pass: SingleUseConsts +//@ compile-flags: -C debuginfo=full +// EMIT_MIR_FOR_EACH_PANIC_STRATEGY + +trait MyTrait { + const ASSOC_BOOL: bool; + const ASSOC_INT: i32; +} + +// EMIT_MIR single_use_consts.if_const.SingleUseConsts.diff +fn if_const() -> i32 { + // CHECK-LABEL: fn if_const( + // CHECK: switchInt(const ::ASSOC_BOOL) + if T::ASSOC_BOOL { 7 } else { 42 } +} + +// EMIT_MIR single_use_consts.match_const.SingleUseConsts.diff +fn match_const() -> &'static str { + // CHECK-LABEL: fn match_const( + // CHECK: switchInt(const ::ASSOC_INT) + match T::ASSOC_INT { + 7 => "hello", + 42 => "towel", + _ => "world", + } +} + +// EMIT_MIR single_use_consts.if_const_debug.SingleUseConsts.diff +fn if_const_debug() -> i32 { + // CHECK-LABEL: fn if_const_debug( + // CHECK: my_bool => const ::ASSOC_BOOL; + // FIXME: `if` forces a temporary (unlike `match`), so the const isn't direct + // CHECK: _3 = const ::ASSOC_BOOL; + // CHECK: switchInt(move _3) + let my_bool = T::ASSOC_BOOL; + do_whatever(); + if my_bool { 7 } else { 42 } +} + +// EMIT_MIR single_use_consts.match_const_debug.SingleUseConsts.diff +fn match_const_debug() -> &'static str { + // CHECK-LABEL: fn match_const_debug( + // CHECK: my_int => const ::ASSOC_INT; + // CHECK: switchInt(const ::ASSOC_INT) + let my_int = T::ASSOC_INT; + do_whatever(); + match my_int { + 7 => "hello", + 42 => "towel", + _ => "world", + } +} + +// EMIT_MIR single_use_consts.never_used_debug.SingleUseConsts.diff +#[allow(unused_variables)] +fn never_used_debug() { + // CHECK-LABEL: fn never_used_debug( + // CHECK: my_int => const ::ASSOC_INT; + // CHECK-NOT: ASSOC_INT + // CHECK: nop + // CHECK-NOT: ASSOC_INT + let my_int = T::ASSOC_INT; +} + +// EMIT_MIR single_use_consts.assign_const_to_return.SingleUseConsts.diff +fn assign_const_to_return() -> bool { + // CHECK-LABEL: fn assign_const_to_return( + // CHECK: _0 = const ::ASSOC_BOOL; + T::ASSOC_BOOL +} + +// EMIT_MIR single_use_consts.keep_parameter.SingleUseConsts.diff +fn keep_parameter(mut other: i32) { + // CHECK-LABEL: fn keep_parameter( + // CHECK: _1 = const ::ASSOC_INT; + // CHECK: _0 = const (); + other = T::ASSOC_INT; +} + +fn do_whatever() {} diff --git a/tests/run-make-fulldeps/README.md b/tests/run-make-fulldeps/README.md deleted file mode 100644 index dd1788390220..000000000000 --- a/tests/run-make-fulldeps/README.md +++ /dev/null @@ -1,4 +0,0 @@ -If this directory is empty, Git won't create it, and compiletest will complain -that it can't find a nonexistent test suite directory. - -FIXME(#126111): Remove `run-make-fulldeps` from bootstrap. diff --git a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs index b56f8dd7acb2..f913aedcde75 100644 --- a/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs +++ b/tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs @@ -10,14 +10,10 @@ use run_make_support::{aux_build, rustc, source_root}; fn main() { aux_build().input("stable.rs").emit("metadata").run(); - let output = rustc() - .input("main.rs") - .emit("metadata") - .extern_("stable", "libstable.rmeta") - .command_output(); + let output = + rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run(); - let stderr = String::from_utf8_lossy(&output.stderr); let version = std::fs::read_to_string(source_root().join("src/version")).unwrap(); let expected_string = format!("stable since {}", version.trim()); - assert!(stderr.contains(&expected_string)); + output.assert_stderr_contains(expected_string); } diff --git a/tests/run-make/README.md b/tests/run-make/README.md new file mode 100644 index 000000000000..a6c1b4b7db76 --- /dev/null +++ b/tests/run-make/README.md @@ -0,0 +1,43 @@ +# The `run-make` test suite + +The `run-make` test suite contains tests which are the most flexible out of all +the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` +tests can basically contain arbitrary code, and are supported by the +[`run_make_support`] library. + +## Infrastructure + +There are two kinds of run-make tests: + +1. The new `rmake.rs` version: this allows run-make tests to be written in Rust + (with `rmake.rs` as the main test file). +2. The legacy `Makefile` version: this is what run-make tests were written with + before support for `rmake.rs` was introduced. + +The implementation for collecting and building the `rmake.rs` recipes (or +`Makefile`s) are in +[`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), +in `run_rmake_v2_test` and `run_rmake_legacy_test`. + +### Rust-based `run-make` tests: `rmake.rs` + +The setup for the `rmake.rs` version is a 3-stage process: + +1. First, we build the [`run_make_support`] library in bootstrap as a tool lib. +2. Then, we compile the `rmake.rs` "recipe" linking the support library and its + dependencies in, and provide a bunch of env vars. We setup a directory + structure within `build//test/run-make/` + + ``` + / + rmake.exe # recipe binary + rmake_out/ # sources from test sources copied over + ``` + + and copy non-`rmake.rs` input support files over to `rmake_out/`. The + support library is made available as an [*extern prelude*][extern_prelude]. +3. Finally, we run the recipe binary and set `rmake_out/` as the working + directory. + +[`run_make_support`]: ../../src/tools/run-make-support +[extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude diff --git a/tests/run-make/allow-warnings-cmdline-stability/rmake.rs b/tests/run-make/allow-warnings-cmdline-stability/rmake.rs index 8f6fe6bd0b66..22a31266176b 100644 --- a/tests/run-make/allow-warnings-cmdline-stability/rmake.rs +++ b/tests/run-make/allow-warnings-cmdline-stability/rmake.rs @@ -1,11 +1,13 @@ // Test that `-Awarnings` suppresses warnings for unstable APIs. -use run_make_support::{assert_not_contains, rustc}; +use run_make_support::rustc; fn main() { rustc().input("bar.rs").run(); - let output = rustc().input("foo.rs").arg("-Awarnings").run(); - - assert_not_contains(&String::from_utf8(output.stdout).unwrap(), "warning"); - assert_not_contains(&String::from_utf8(output.stderr).unwrap(), "warning"); + rustc() + .input("foo.rs") + .arg("-Awarnings") + .run() + .assert_stdout_not_contains("warning") + .assert_stderr_not_contains("warning"); } diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs index 309d3a04b21c..a2c0ad5f6def 100644 --- a/tests/run-make/compiler-builtins/rmake.rs +++ b/tests/run-make/compiler-builtins/rmake.rs @@ -19,8 +19,7 @@ use run_make_support::object::read::Object; use run_make_support::object::ObjectSection; use run_make_support::object::ObjectSymbol; use run_make_support::object::RelocationTarget; -use run_make_support::set_host_rpath; -use run_make_support::{env_var, object}; +use run_make_support::{cmd, env_var, object}; use std::collections::HashSet; use std::path::PathBuf; @@ -35,7 +34,7 @@ fn main() { let path = env_var("PATH"); let rustc = env_var("RUSTC"); let bootstrap_cargo = env_var("BOOTSTRAP_CARGO"); - let mut cmd = std::process::Command::new(bootstrap_cargo); + let mut cmd = cmd(bootstrap_cargo); cmd.args([ "build", "--manifest-path", @@ -52,10 +51,8 @@ fn main() { // Visual Studio 2022 requires that the LIB env var be set so it can // find the Windows SDK. .env("LIB", std::env::var("LIB").unwrap_or_default()); - set_host_rpath(&mut cmd); - let status = cmd.status().unwrap(); - assert!(status.success()); + cmd.run(); let rlibs_path = target_dir.join(target).join("debug").join("deps"); let compiler_builtins_rlib = std::fs::read_dir(rlibs_path) diff --git a/tests/run-make/const-prop-lint/rmake.rs b/tests/run-make/const-prop-lint/rmake.rs index 6d0069a84d7a..c35294f2f5af 100644 --- a/tests/run-make/const-prop-lint/rmake.rs +++ b/tests/run-make/const-prop-lint/rmake.rs @@ -5,7 +5,7 @@ use std::fs; use run_make_support::{cwd, rustc}; fn main() { - rustc().input("input.rs").run_fail_assert_exit_code(1); + rustc().input("input.rs").run_fail().assert_exit_code(1); for entry in fs::read_dir(cwd()).unwrap() { let entry = entry.unwrap(); diff --git a/tests/run-make/crate-data-smoke/rmake.rs b/tests/run-make/crate-data-smoke/rmake.rs index 86fe5593e661..70f8e46b6d92 100644 --- a/tests/run-make/crate-data-smoke/rmake.rs +++ b/tests/run-make/crate-data-smoke/rmake.rs @@ -1,22 +1,21 @@ -use std::process::Output; - use run_make_support::{bin_name, rust_lib_name, rustc}; -fn compare_stdout>(output: Output, expected: S) { - assert_eq!(String::from_utf8(output.stdout).unwrap().trim(), expected.as_ref()); -} - fn main() { - compare_stdout(rustc().print("crate-name").input("crate.rs").run(), "foo"); - compare_stdout(rustc().print("file-names").input("crate.rs").run(), bin_name("foo")); - compare_stdout( - rustc().print("file-names").crate_type("lib").arg("--test").input("crate.rs").run(), - bin_name("foo"), - ); - compare_stdout( - rustc().print("file-names").arg("--test").input("lib.rs").run(), - bin_name("mylib"), - ); - compare_stdout(rustc().print("file-names").input("lib.rs").run(), rust_lib_name("mylib")); - compare_stdout(rustc().print("file-names").input("rlib.rs").run(), rust_lib_name("mylib")); + rustc().print("crate-name").input("crate.rs").run().assert_stdout_equals("foo"); + rustc().print("file-names").input("crate.rs").run().assert_stdout_equals(bin_name("foo")); + rustc() + .print("file-names") + .crate_type("lib") + .arg("--test") + .input("crate.rs") + .run() + .assert_stdout_equals(bin_name("foo")); + rustc() + .print("file-names") + .arg("--test") + .input("lib.rs") + .run() + .assert_stdout_equals(bin_name("mylib")); + rustc().print("file-names").input("lib.rs").run().assert_stdout_equals(rust_lib_name("mylib")); + rustc().print("file-names").input("rlib.rs").run().assert_stdout_equals(rust_lib_name("mylib")); } diff --git a/tests/run-make/exit-code/rmake.rs b/tests/run-make/exit-code/rmake.rs index 6bf7a232642d..f290554831db 100644 --- a/tests/run-make/exit-code/rmake.rs +++ b/tests/run-make/exit-code/rmake.rs @@ -5,21 +5,22 @@ use run_make_support::{rustc, rustdoc}; fn main() { rustc().arg("success.rs").run(); - rustc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); + rustc().arg("--invalid-arg-foo").run_fail().assert_exit_code(1); - rustc().arg("compile-error.rs").run_fail_assert_exit_code(1); + rustc().arg("compile-error.rs").run_fail().assert_exit_code(1); rustc() .env("RUSTC_ICE", "0") .arg("-Ztreat-err-as-bug") .arg("compile-error.rs") - .run_fail_assert_exit_code(101); + .run_fail() + .assert_exit_code(101); rustdoc().arg("success.rs").output("exit-code").run(); - rustdoc().arg("--invalid-arg-foo").run_fail_assert_exit_code(1); + rustdoc().arg("--invalid-arg-foo").run_fail().assert_exit_code(1); - rustdoc().arg("compile-error.rs").run_fail_assert_exit_code(1); + rustdoc().arg("compile-error.rs").run_fail().assert_exit_code(1); - rustdoc().arg("lint-failure.rs").run_fail_assert_exit_code(1); + rustdoc().arg("lint-failure.rs").run_fail().assert_exit_code(1); } diff --git a/tests/run-make/issue-88756-default-output/output-default.stdout b/tests/run-make/issue-88756-default-output/output-default.stdout index 12c1b389fb34..bc38d9e9dc6b 100644 --- a/tests/run-make/issue-88756-default-output/output-default.stdout +++ b/tests/run-make/issue-88756-default-output/output-default.stdout @@ -157,6 +157,8 @@ Options: Comma separated list of types of output for rustdoc to emit --no-run Compile doctests without running them + --remap-path-prefix FROM=TO + Remap source names in compiler messages --show-type-layout Include the memory layout of types in the docs --nocapture Don't capture stdout and stderr of tests diff --git a/tests/run-make/llvm-outputs/Makefile b/tests/run-make/llvm-outputs/Makefile deleted file mode 100644 index cccf1dd66fb9..000000000000 --- a/tests/run-make/llvm-outputs/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir - echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_bc/ --emit=llvm-bc diff --git a/tests/run-make/llvm-outputs/rmake.rs b/tests/run-make/llvm-outputs/rmake.rs new file mode 100644 index 000000000000..2dc3030ca91b --- /dev/null +++ b/tests/run-make/llvm-outputs/rmake.rs @@ -0,0 +1,20 @@ +// test that directories get created when emitting llvm bitcode and IR + +use run_make_support::{cwd, run_in_tmpdir, rustc}; +use std::path::PathBuf; + +fn main() { + let mut path_bc = PathBuf::new(); + let mut path_ir = PathBuf::new(); + run_in_tmpdir(|| { + let p = cwd(); + path_bc = p.join("nonexistant_dir_bc"); + path_ir = p.join("nonexistant_dir_ir"); + rustc().input("-").stdin("fn main() {}").out_dir(&path_bc).emit("llvm-bc").run(); + rustc().input("-").stdin("fn main() {}").out_dir(&path_ir).emit("llvm-ir").run(); + assert!(path_bc.exists()); + assert!(path_ir.exists()); + }); + assert!(!path_bc.exists()); + assert!(!path_ir.exists()); +} diff --git a/tests/run-make/mixing-formats/rmake.rs b/tests/run-make/mixing-formats/rmake.rs index 444751419d74..9cbff94f6701 100644 --- a/tests/run-make/mixing-formats/rmake.rs +++ b/tests/run-make/mixing-formats/rmake.rs @@ -34,8 +34,8 @@ fn main() { rustc().crate_type("rlib").input("foo.rs").run(); rustc().crate_type("dylib").input("bar1.rs").arg("-Cprefer-dynamic").run(); rustc().crate_type("dylib").input("bar2.rs").arg("-Cprefer-dynamic").run(); - rustc().crate_type("dylib").input("baz2.rs").run_fail_assert_exit_code(1); - rustc().crate_type("bin").input("baz2.rs").run_fail_assert_exit_code(1); + rustc().crate_type("dylib").input("baz2.rs").run_fail().assert_exit_code(1); + rustc().crate_type("bin").input("baz2.rs").run_fail().assert_exit_code(1); }); run_in_tmpdir(|| { rustc().crate_type("rlib").input("foo.rs").run(); diff --git a/tests/run-make/no-input-file/no-input-file.stderr b/tests/run-make/no-input-file/no-input-file.stderr deleted file mode 100644 index b843eb524f3d..000000000000 --- a/tests/run-make/no-input-file/no-input-file.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: no input filename given - diff --git a/tests/run-make/no-input-file/rmake.rs b/tests/run-make/no-input-file/rmake.rs index 15e582311f09..fc558b22fb49 100644 --- a/tests/run-make/no-input-file/rmake.rs +++ b/tests/run-make/no-input-file/rmake.rs @@ -1,7 +1,9 @@ -use run_make_support::{diff, rustc}; +use run_make_support::rustc; fn main() { - let output = rustc().print("crate-name").run_fail_assert_exit_code(1); - - diff().expected_file("no-input-file.stderr").actual_text("output", output.stderr).run(); + rustc() + .print("crate-name") + .run_fail() + .assert_exit_code(1) + .assert_stderr_equals("error: no input filename given"); } diff --git a/tests/run-make/non-unicode-env/rmake.rs b/tests/run-make/non-unicode-env/rmake.rs index a4843a52efd5..ed40d7a6d7f0 100644 --- a/tests/run-make/non-unicode-env/rmake.rs +++ b/tests/run-make/non-unicode-env/rmake.rs @@ -6,7 +6,6 @@ fn main() { #[cfg(windows)] let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]); let output = rustc().input("non_unicode_env.rs").env("NON_UNICODE_VAR", non_unicode).run_fail(); - let actual = std::str::from_utf8(&output.stderr).unwrap(); let expected = std::fs::read_to_string("non_unicode_env.stderr").unwrap(); - assert_eq!(actual, expected); + output.assert_stderr_equals(expected); } diff --git a/tests/run-make/notify-all-emit-artifacts/rmake.rs b/tests/run-make/notify-all-emit-artifacts/rmake.rs index 1c2e08ca8f53..321eda489410 100644 --- a/tests/run-make/notify-all-emit-artifacts/rmake.rs +++ b/tests/run-make/notify-all-emit-artifacts/rmake.rs @@ -19,7 +19,7 @@ fn main() { .error_format("json") .incremental(cwd()) .run(); - let stderr = String::from_utf8_lossy(&output.stderr); + let stderr = output.stderr_utf8(); for file in &["lib.o", "lib.ll", "lib.bc", "lib.s"] { assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); } @@ -35,7 +35,7 @@ fn main() { .error_format("json") .incremental(cwd()) .run(); - let stderr = String::from_utf8_lossy(&output.stderr); + let stderr = output.stderr_utf8(); for file in &["rcgu.o", "rcgu.ll", "rcgu.bc", "rcgu.s"] { assert!(stderr.contains(file), "No {:?} in {:?}", file, stderr); } diff --git a/tests/run-make/print-cfg/rmake.rs b/tests/run-make/print-cfg/rmake.rs index 29cf0ba1b3fd..f382d952db47 100644 --- a/tests/run-make/print-cfg/rmake.rs +++ b/tests/run-make/print-cfg/rmake.rs @@ -83,8 +83,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) { // --print=cfg { let output = rustc().target(target).print("cfg").run(); - - let stdout = String::from_utf8(output.stdout).unwrap(); + let stdout = output.stdout_utf8(); check_(&stdout, includes, disallow); } @@ -95,7 +94,7 @@ fn check(PrintCfg { target, includes, disallow }: PrintCfg) { let mut print_arg = OsString::from("--print=cfg="); print_arg.push(tmp_path.as_os_str()); - let output = rustc().target(target).arg(print_arg).run(); + rustc().target(target).arg(print_arg).run(); let output = std::fs::read_to_string(&tmp_path).unwrap(); diff --git a/tests/run-make/print-check-cfg/rmake.rs b/tests/run-make/print-check-cfg/rmake.rs index a0aa95c8abcf..f4b02b5e265b 100644 --- a/tests/run-make/print-check-cfg/rmake.rs +++ b/tests/run-make/print-check-cfg/rmake.rs @@ -93,7 +93,7 @@ fn check(CheckCfg { args, contains }: CheckCfg) { .args(&*args) .run(); - let stdout = String::from_utf8(output.stdout).unwrap(); + let stdout = output.stdout_utf8(); let mut found = HashSet::::new(); diff --git a/tests/run-make/print-native-static-libs/rmake.rs b/tests/run-make/print-native-static-libs/rmake.rs index edb85d568c67..b4e7c0e17ff8 100644 --- a/tests/run-make/print-native-static-libs/rmake.rs +++ b/tests/run-make/print-native-static-libs/rmake.rs @@ -30,9 +30,7 @@ fn main() { .run(); let mut found_note = false; - for l in output.stderr.lines() { - let l = l.expect("utf-8 string"); - + for l in output.stderr_utf8().lines() { let Some(args) = l.strip_prefix("note: native-static-libs:") else { continue; }; diff --git a/tests/run-make/print-to-output/rmake.rs b/tests/run-make/print-to-output/rmake.rs index b3f77e0633c4..ff5e6cacf4fa 100644 --- a/tests/run-make/print-to-output/rmake.rs +++ b/tests/run-make/print-to-output/rmake.rs @@ -39,11 +39,7 @@ fn check(args: Option) { } // --print={option} - let stdout = { - let output = rustc().target(args.target).print(args.option).run(); - - String::from_utf8(output.stdout).unwrap() - }; + let stdout = rustc().target(args.target).print(args.option).run().stdout_utf8(); // --print={option}=PATH let output = { @@ -51,7 +47,7 @@ fn check(args: Option) { let mut print_arg = OsString::from(format!("--print={}=", args.option)); print_arg.push(tmp_path.as_os_str()); - let _output = rustc().target(args.target).arg(print_arg).run(); + rustc().target(args.target).arg(print_arg).run(); std::fs::read_to_string(&tmp_path).unwrap() }; diff --git a/tests/run-make/run-in-tmpdir-self-test/rmake.rs b/tests/run-make/run-in-tmpdir-self-test/rmake.rs new file mode 100644 index 000000000000..83b99bfe8632 --- /dev/null +++ b/tests/run-make/run-in-tmpdir-self-test/rmake.rs @@ -0,0 +1,38 @@ +//! This is a self-test for the `run_in_tmpdir` helper in the support library. This test tries to +//! check that files and directories created within the temporary directory gets properly cleared +//! when returning from the closure. + +use std::fs; +use std::path::{Path, PathBuf}; + +use run_make_support::{cwd, run_in_tmpdir}; + +fn main() { + let mut file_path = PathBuf::new(); + let mut dir_path = PathBuf::new(); + let mut readonly_file_path = PathBuf::new(); + let test_cwd = cwd(); + run_in_tmpdir(|| { + assert_ne!(test_cwd, cwd(), "test cwd should not be the same as tmpdir cwd"); + + file_path = cwd().join("foo.txt"); + fs::write(&file_path, "hi").unwrap(); + + dir_path = cwd().join("bar"); + fs::create_dir_all(&dir_path).unwrap(); + + readonly_file_path = cwd().join("readonly-file.txt"); + fs::write(&readonly_file_path, "owo").unwrap(); + let mut perms = fs::metadata(&readonly_file_path).unwrap().permissions(); + perms.set_readonly(true); + fs::set_permissions(&mut readonly_file_path, perms).unwrap(); + + assert!(file_path.exists()); + assert!(dir_path.exists()); + assert!(readonly_file_path.exists()); + }); + assert!(!file_path.exists()); + assert!(!dir_path.exists()); + assert!(!readonly_file_path.exists()); + assert_eq!(test_cwd, cwd(), "test cwd is not correctly restored"); +} diff --git a/tests/run-make/rust-lld-by-default/rmake.rs b/tests/run-make/rust-lld-by-default/rmake.rs index 8ab16394a915..5b065f86f53f 100644 --- a/tests/run-make/rust-lld-by-default/rmake.rs +++ b/tests/run-make/rust-lld-by-default/rmake.rs @@ -17,9 +17,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // But it can still be disabled by turning the linker feature off. @@ -30,14 +30,13 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index e6c4a321d000..f3dc2275f625 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -23,9 +23,9 @@ fn main() { .input("lib.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // But it can also be disabled via linker features. @@ -38,14 +38,13 @@ fn main() { .input("lib.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index a74e858045d4..3eb60367c7f9 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -21,9 +21,9 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // It should not be used when we explictly opt-out of lld. @@ -34,9 +34,9 @@ fn main() { .input("main.rs") .run(); assert!( - !find_lld_version_in_logs(&output), + !find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should not be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); // While we're here, also check that the last linker feature flag "wins" when passed multiple @@ -52,14 +52,13 @@ fn main() { .input("main.rs") .run(); assert!( - find_lld_version_in_logs(&output), + find_lld_version_in_logs(output.stderr_utf8()), "the LLD version string should be present in the output logs:\n{}", - std::str::from_utf8(&output.stderr).unwrap() + output.stderr_utf8() ); } -fn find_lld_version_in_logs(output: &Output) -> bool { +fn find_lld_version_in_logs(stderr: String) -> bool { let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); - let stderr = std::str::from_utf8(&output.stderr).unwrap(); stderr.lines().any(|line| lld_version_re.is_match(line.trim())) } diff --git a/tests/run-make/rustdoc-error-lines/rmake.rs b/tests/run-make/rustdoc-error-lines/rmake.rs index db6e28e4feb7..ea5ec2faed95 100644 --- a/tests/run-make/rustdoc-error-lines/rmake.rs +++ b/tests/run-make/rustdoc-error-lines/rmake.rs @@ -4,9 +4,7 @@ use run_make_support::rustdoc; fn main() { - let output = - String::from_utf8(rustdoc().input("input.rs").arg("--test").command_output().stdout) - .unwrap(); + let output = rustdoc().input("input.rs").arg("--test").run_fail().stdout_utf8(); let should_contain = &[ "input.rs - foo (line 5)", diff --git a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs index a6d08f28cda3..c9650def347d 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs +++ b/tests/run-make/rustdoc-scrape-examples-macros/rmake.rs @@ -8,17 +8,14 @@ fn main() { let proc_crate_name = "foobar_macro"; let crate_name = "foobar"; - let dylib_name = String::from_utf8( - rustc() - .crate_name(proc_crate_name) - .crate_type("dylib") - .arg("--print") - .arg("file-names") - .arg("-") - .command_output() - .stdout, - ) - .unwrap(); + let dylib_name = rustc() + .crate_name(proc_crate_name) + .crate_type("dylib") + .arg("--print") + .arg("file-names") + .arg("-") + .run() + .stdout_utf8(); rustc() .input("src/proc.rs") diff --git a/tests/run-make/rustdoc-shared-flags/rmake.rs b/tests/run-make/rustdoc-shared-flags/rmake.rs index 2db613f78176..d9a16d78a342 100644 --- a/tests/run-make/rustdoc-shared-flags/rmake.rs +++ b/tests/run-make/rustdoc-shared-flags/rmake.rs @@ -1,8 +1,8 @@ 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(); + let rustc_output = rustc().args(args).run().stdout_utf8(); + let rustdoc_output = rustdoc().args(args).run().stdout_utf8(); Diff::new().expected_text("rustc", rustc_output).actual_text("rustdoc", rustdoc_output).run(); } diff --git a/tests/run-make/stdin-rustc/rmake.rs b/tests/run-make/stdin-rustc/rmake.rs index 1869b1dcb8c0..d599f813563c 100644 --- a/tests/run-make/stdin-rustc/rmake.rs +++ b/tests/run-make/stdin-rustc/rmake.rs @@ -21,7 +21,7 @@ fn main() { ); // echo $NOT_UTF8 | rustc - - let output = rustc().arg("-").stdin(NOT_UTF8).run_fail(); - let stderr = String::from_utf8(output.stderr).unwrap(); - assert!(stderr.contains("error: couldn't read from stdin, as it did not contain valid UTF-8")); + rustc().arg("-").stdin(NOT_UTF8).run_fail().assert_stderr_contains( + "error: couldn't read from stdin, as it did not contain valid UTF-8", + ); } diff --git a/tests/rustdoc-js/underscoredtype.js b/tests/rustdoc-js/underscoredtype.js new file mode 100644 index 000000000000..06e3b07b0960 --- /dev/null +++ b/tests/rustdoc-js/underscoredtype.js @@ -0,0 +1,62 @@ +const EXPECTED = [ + { + 'query': 'pid_t', + 'correction': null, + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'pidt', + 'correction': 'pid_t', + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'unix::pid_t', + 'correction': null, + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, + { + 'query': 'unix::pidt', + 'correction': 'pid_t', + 'proposeCorrectionFrom': null, + 'proposeCorrectionTo': null, + 'others': [ + { 'path': 'underscoredtype::unix', 'name': 'pid_t' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'set_pid' }, + ], + 'returned': [ + { 'path': 'underscoredtype::unix', 'name': 'get_pid' }, + ], + }, +]; diff --git a/tests/rustdoc-js/underscoredtype.rs b/tests/rustdoc-js/underscoredtype.rs new file mode 100644 index 000000000000..83c532cf855d --- /dev/null +++ b/tests/rustdoc-js/underscoredtype.rs @@ -0,0 +1,8 @@ +pub mod unix { + #[allow(non_camel_case_types)] + pub type pid_t = i32; + pub fn get_pid() -> pid_t { + 0 + } + pub fn set_pid(_: pid_t) {} +} diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs new file mode 100644 index 000000000000..2b220370d77a --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.rs @@ -0,0 +1,14 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +//@ normalize-stdout-test "exit (status|code): 101" -> "exit status: 101" + +// doctest fails at runtime +/// ``` +/// panic!("oh no"); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout new file mode 100644 index 000000000000..2102e2c38918 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-failed-doctest-output.stdout @@ -0,0 +1,21 @@ + +running 1 test +test remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) stdout ---- +Test executable failed (exit status: 101). + +stderr: +thread 'main' panicked at remapped_path/remap-path-prefix-failed-doctest-output.rs:3:1: +oh no +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + + +failures: + remapped_path/remap-path-prefix-failed-doctest-output.rs - SomeStruct (line 11) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs new file mode 100644 index 000000000000..2e023e32d7a7 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.rs @@ -0,0 +1,13 @@ +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ failure-status: 101 +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ rustc-env:RUST_BACKTRACE=0 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest fails to compile +/// ``` +/// this is not real code +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout new file mode 100644 index 000000000000..a05b51699894 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-invalid-doctest.stdout @@ -0,0 +1,22 @@ + +running 1 test +test remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) ... FAILED + +failures: + +---- remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) stdout ---- +error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `is` + --> remapped_path/remap-path-prefix-invalid-doctest.rs:11:6 + | +LL | this is not real code + | ^^ expected one of 8 possible tokens + +error: aborting due to 1 previous error + +Couldn't compile the test. + +failures: + remapped_path/remap-path-prefix-invalid-doctest.rs - SomeStruct (line 10) + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs new file mode 100644 index 000000000000..c58f3faeb532 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.rs @@ -0,0 +1,14 @@ +//@ check-pass +//@ check-run-results + +// FIXME: if/when the output of the test harness can be tested on its own, this test should be +// adapted to use that, and that normalize line can go away + +//@ compile-flags:--test -Z unstable-options --remap-path-prefix={{src-base}}=remapped_path --test-args --test-threads=1 +//@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" + +// doctest passes at runtime +/// ``` +/// assert!(true); +/// ``` +pub struct SomeStruct; diff --git a/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout new file mode 100644 index 000000000000..8ffb56948856 --- /dev/null +++ b/tests/rustdoc-ui/remap-path-prefix-passed-doctest-output.stdout @@ -0,0 +1,6 @@ + +running 1 test +test remapped_path/remap-path-prefix-passed-doctest-output.rs - SomeStruct (line 11) ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME + diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr index 1f1e303ea4c6..4c165ff619a3 100644 --- a/tests/ui/async-await/coroutine-desc.stderr +++ b/tests/ui/async-await/coroutine-desc.stderr @@ -10,6 +10,8 @@ LL | fun(async {}, async {}); | = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}` found `async` block `{async block@$DIR/coroutine-desc.rs:10:19: 10:27}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object note: function defined here --> $DIR/coroutine-desc.rs:8:4 | @@ -51,6 +53,8 @@ LL | fun((async || {})(), (async || {})()); | = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}` found `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:36: 14:38}` + = note: no two async blocks, even if identical, have the same type + = help: consider pinning your async block and casting it to a trait object note: function defined here --> $DIR/coroutine-desc.rs:8:4 | diff --git a/tests/ui/feature-gates/feature-gate-extern_prelude.rs b/tests/ui/feature-gates/feature-gate-extern_prelude.rs deleted file mode 100644 index 237099e79010..000000000000 --- a/tests/ui/feature-gates/feature-gate-extern_prelude.rs +++ /dev/null @@ -1 +0,0 @@ -can-only-test-this-in-run-make-fulldeps //~ ERROR expected one of `!` or `::`, found `-` diff --git a/tests/ui/feature-gates/feature-gate-extern_prelude.stderr b/tests/ui/feature-gates/feature-gate-extern_prelude.stderr deleted file mode 100644 index 3b0ffae86965..000000000000 --- a/tests/ui/feature-gates/feature-gate-extern_prelude.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected one of `!` or `::`, found `-` - --> $DIR/feature-gate-extern_prelude.rs:1:4 - | -LL | can-only-test-this-in-run-make-fulldeps - | ^ expected one of `!` or `::` - -error: aborting due to 1 previous error - diff --git a/tests/ui/feature-gates/feature-gate-offset-of-slice.rs b/tests/ui/feature-gates/feature-gate-offset-of-slice.rs new file mode 100644 index 000000000000..23e8668bc685 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-offset-of-slice.rs @@ -0,0 +1,26 @@ +use std::mem::offset_of; + +struct S { + a: u8, + b: (u8, u8), + c: [i32], +} + +struct T { + x: i32, + y: S, +} + +type Tup = (i32, [i32]); + +fn main() { + offset_of!(S, c); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} + +fn other() { + offset_of!(T, y); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} + +fn tuple() { + offset_of!(Tup, 1); //~ ERROR size for values of type `[i32]` cannot be known at compilation time +} diff --git a/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr b/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr new file mode 100644 index 000000000000..5cf34a897f4d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-offset-of-slice.stderr @@ -0,0 +1,35 @@ +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:17:5 + | +LL | offset_of!(S, c); + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:21:5 + | +LL | offset_of!(T, y); + | ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `S`, the trait `Sized` is not implemented for `[i32]`, which is required by `S: Sized` +note: required because it appears within the type `S` + --> $DIR/feature-gate-offset-of-slice.rs:3:8 + | +LL | struct S { + | ^ + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `[i32]` cannot be known at compilation time + --> $DIR/feature-gate-offset-of-slice.rs:25:5 + | +LL | offset_of!(Tup, 1); + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[i32]` + = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr new file mode 100644 index 000000000000..14a3d5e178d4 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.next.stderr @@ -0,0 +1,9 @@ +error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` + --> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50 + | +LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); + | ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: >::Assoc` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs new file mode 100644 index 000000000000..10dbc2a4a825 --- /dev/null +++ b/tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs @@ -0,0 +1,30 @@ +//@ revisions: current next +//@[current] check-pass +//@[next] compile-flags: -Znext-solver +//@[next] check-fail +//@ ignore-compare-mode-next-solver (explicit revisions) + +/// This triggers an ICE with (and without) `--emit metadata` using the old +/// trait solver: +/// ``` +/// rustc +nightly-2023-01-09 \ +/// tests/ui/higher-ranked/trait-bounds/rigid-equate-projections-in-higher-ranked-fn-signature.rs +/// ``` +/// The ICE was unknowingly fixed by +/// in `nightly-2023-01-10`. +/// This is a regression test for that fixed ICE. For the next solver we simply +/// make sure there is a compiler error. + +trait Trait<'a> { + type Assoc; +} + +fn foo Trait<'a>>() -> for<'a> fn(>::Assoc) { + todo!() +} + +fn bar Trait<'a>>() { + let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::(); //[next]~ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs index 016ebfadd142..5ae15f323577 100644 --- a/tests/ui/offset-of/offset-of-dst-field.rs +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -49,3 +49,7 @@ fn delta() { fn generic_with_maybe_sized() -> usize { offset_of!(Delta, z) //~ ERROR the size for values of type } + +fn illformed_tuple() { + offset_of!(([u8], u8), 1); //~ ERROR the size for values of type +} diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr index adfd16c6f2b9..bcfe796897e0 100644 --- a/tests/ui/offset-of/offset-of-dst-field.stderr +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -81,6 +81,15 @@ LL - fn generic_with_maybe_sized() -> usize { LL + fn generic_with_maybe_sized() -> usize { | -error: aborting due to 8 previous errors +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:54:16 + | +LL | offset_of!(([u8], u8), 1); + | ^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-slice.rs b/tests/ui/offset-of/offset-of-slice.rs new file mode 100644 index 000000000000..a0fe3198f686 --- /dev/null +++ b/tests/ui/offset-of/offset-of-slice.rs @@ -0,0 +1,26 @@ +//@run-pass +#![feature(offset_of_slice, offset_of_nested)] + +use std::mem::offset_of; + +#[repr(C)] +struct S { + a: u8, + b: (u8, u8), + c: [i32], +} + +#[repr(C)] +struct T { + x: i8, + y: S, +} + +type Tup = (i16, [i32]); + +fn main() { + assert_eq!(offset_of!(S, c), 4); + assert_eq!(offset_of!(T, y), 4); + assert_eq!(offset_of!(T, y.c), 8); + assert_eq!(offset_of!(Tup, 1), 4); +} diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs new file mode 100644 index 000000000000..efa296db47cf --- /dev/null +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.rs @@ -0,0 +1,11 @@ +// Regression test for ICE #125876 + +fn main() { + std::ptr::from_ref(num).cast_mut().as_deref(); + //~^ ERROR cannot find value `num` in this scope + //~| ERROR no method named `as_deref` found for raw pointer `*mut _` in the current scope + //~| WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + //~| WARN type annotations needed + //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! +} diff --git a/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr new file mode 100644 index 000000000000..d610a3b7cadd --- /dev/null +++ b/tests/ui/suggestions/ice-unwrap-probe-many-result-125876.stderr @@ -0,0 +1,40 @@ +error[E0425]: cannot find value `num` in this scope + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:24 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^ not found in this scope + +warning: type annotations needed + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:29 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #46906 + = note: `#[warn(tyvar_behind_raw_pointer)]` on by default + +warning: type annotations needed + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #46906 + +error[E0599]: no method named `as_deref` found for raw pointer `*mut _` in the current scope + --> $DIR/ice-unwrap-probe-many-result-125876.rs:4:40 + | +LL | std::ptr::from_ref(num).cast_mut().as_deref(); + | ^^^^^^^^ + | +help: there is a method `as_ref` with a similar name + | +LL | std::ptr::from_ref(num).cast_mut().as_ref(); + | ~~~~~~ + +error: aborting due to 2 previous errors; 2 warnings emitted + +Some errors have detailed explanations: E0425, E0599. +For more information about an error, try `rustc --explain E0425`. diff --git a/triagebot.toml b/triagebot.toml index 55f63ef2567c..3abff0f1c784 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -429,6 +429,12 @@ trigger_files = [ "tests/ui/stack-protector" ] +[autolabel."A-run-make"] +trigger_files = [ + "tests/run-make", + "src/tools/run-make-support" +] + [notify-zulip."I-prioritize"] zulip_stream = 245100 # #t-compiler/wg-prioritization/alerts topic = "#{number} {title}" @@ -684,7 +690,13 @@ message = "Some changes occurred in GUI tests." cc = ["@GuillaumeGomez"] [mentions."tests/run-make/"] -message = "Some changes occurred in run-make tests." +message = """ +This PR modifies `tests/run-make/`. If this PR is trying to port a Makefile +run-make test to use rmake.rs, please update the +[run-make port tracking issue](https://github.com/rust-lang/rust/issues/121876) +so we can track our progress. You can either modify the tracking issue +directly, or you can comment on the tracking issue and link this PR. +""" cc = ["@jieyouxu"] [mentions."src/librustdoc/html/static/css/themes/ayu.css"]