diff options
779 files changed, 8591 insertions, 6736 deletions
diff --git a/.editorconfig b/.editorconfig index 03aab32bfc6..d065fa46469 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,6 @@ trim_trailing_whitespace = false [*.yml] indent_size = 2 + +[Makefile] +indent_style = tab diff --git a/.github/ISSUE_TEMPLATE/library_tracking_issue.md b/.github/ISSUE_TEMPLATE/library_tracking_issue.md index 91c06402ca1..934312662be 100644 --- a/.github/ISSUE_TEMPLATE/library_tracking_issue.md +++ b/.github/ISSUE_TEMPLATE/library_tracking_issue.md @@ -12,7 +12,7 @@ Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that -case, you can use use `issue = "none"` in your initial implementation PR. The +case, you can use `issue = "none"` in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be added without an RFC. --> @@ -65,7 +65,7 @@ the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final comment period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in -that period of 10 days, a stabilzation PR can be opened by anyone. +that period of 10 days, a stabilization PR can be opened by anyone. --> ### Unresolved Questions diff --git a/Cargo.lock b/Cargo.lock index da2e483fe61..5ef801cb623 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,12 +4,12 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "compiler_builtins", - "gimli", + "gimli 0.27.2", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] @@ -79,6 +79,15 @@ dependencies = [ ] [[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] name = "annotate-snippets" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -149,7 +158,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0639441fd17a3197d1cbca8dc8768cc172a63b64b4bb6c372e8f41ed0acc9bb" dependencies = [ - "object 0.30.1", + "object", ] [[package]] @@ -215,16 +224,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.29.0", + "object", "rustc-demangle", ] @@ -307,6 +316,12 @@ dependencies = [ ] [[package]] +name = "bumpalo" +version = "3.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" + +[[package]] name = "bytecount" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -456,15 +471,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "libc", + "iana-time-zone", "num-integer", "num-traits", "serde", - "time", "winapi", ] @@ -638,6 +652,16 @@ dependencies = [ ] [[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] name = "collect-license-metadata" version = "0.1.0" dependencies = [ @@ -717,7 +741,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows", + "windows 0.46.0", ] [[package]] @@ -773,6 +797,12 @@ dependencies = [ ] [[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] name = "coverage_test_macros" version = "0.0.0" @@ -888,6 +918,50 @@ dependencies = [ ] [[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.8", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.8", +] + +[[package]] name = "datafrog" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1187,13 +1261,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" [[package]] name = "flate2" -version = "1.0.23" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ - "cfg-if", "crc32fast", - "libc", "miniz_oxide", ] @@ -1409,12 +1481,20 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" dependencies = [ - "compiler_builtins", "fallible-iterator", "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +dependencies = [ + "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", - "stable_deref_trait", ] [[package]] @@ -1550,6 +1630,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] name = "icu_list" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1773,6 +1877,15 @@ dependencies = [ ] [[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] name = "jsondocck" version = "0.1.0" dependencies = [ @@ -1869,9 +1982,9 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "libz-sys" -version = "1.1.3" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" dependencies = [ "cc", "libc", @@ -1880,6 +1993,15 @@ dependencies = [ ] [[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + +[[package]] name = "linkchecker" version = "0.1.0" dependencies = [ @@ -2098,9 +2220,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", "compiler_builtins", @@ -2202,27 +2324,18 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" -dependencies = [ - "compiler_builtins", - "memchr", - "rustc-std-workspace-alloc", - "rustc-std-workspace-core", -] - -[[package]] -name = "object" version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d864c91689fdc196779b98dba0aceac6118594c2df6ee5d943eb6a8df4d107a" dependencies = [ + "compiler_builtins", "crc32fast", "flate2", "hashbrown 0.13.1", "indexmap", "memchr", + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", ] [[package]] @@ -2941,6 +3054,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -2964,6 +3078,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_macros", "rustc_parse", "rustc_session", @@ -2991,6 +3106,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_macros", "rustc_serialize", @@ -3018,6 +3134,7 @@ dependencies = [ "polonius-engine", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -3047,6 +3164,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_lint_defs", "rustc_macros", @@ -3068,13 +3186,14 @@ dependencies = [ "cstr", "libc", "measureme", - "object 0.30.1", + "object", "rustc-demangle", "rustc_ast", "rustc_attr", "rustc_codegen_ssa", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_index", @@ -3104,7 +3223,7 @@ dependencies = [ "itertools", "jobserver", "libc", - "object 0.30.1", + "object", "pathdiff", "regex", "rustc_arena", @@ -3112,6 +3231,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_incremental", @@ -3144,6 +3264,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -3187,7 +3308,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -3217,6 +3338,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", @@ -3246,7 +3368,7 @@ dependencies = [ "rustc_ty_utils", "serde_json", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -3265,6 +3387,7 @@ dependencies = [ "intl-memoizer", "rustc_baked_icu_data", "rustc_data_structures", + "rustc_fluent_macro", "rustc_macros", "rustc_serialize", "rustc_span", @@ -3281,6 +3404,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_error_messages", + "rustc_fluent_macro", "rustc_hir", "rustc_lint_defs", "rustc_macros", @@ -3294,7 +3418,7 @@ dependencies = [ "termize", "tracing", "unicode-width", - "windows", + "windows 0.46.0", ] [[package]] @@ -3309,6 +3433,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_lint_defs", "rustc_macros", @@ -3330,6 +3455,19 @@ dependencies = [ ] [[package]] +name = "rustc_fluent_macro" +version = "0.1.0" +dependencies = [ + "annotate-snippets", + "fluent-bundle", + "fluent-syntax", + "proc-macro2", + "quote", + "syn 2.0.8", + "unic-langid", +] + +[[package]] name = "rustc_fs_util" version = "0.0.0" @@ -3365,6 +3503,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -3399,6 +3538,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_hir_analysis", @@ -3426,6 +3566,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_fs_util", "rustc_graphviz", "rustc_hir", @@ -3454,6 +3595,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -3484,6 +3626,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_expand", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_analysis", @@ -3533,6 +3676,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -3586,14 +3730,10 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ - "annotate-snippets", - "fluent-bundle", - "fluent-syntax", "proc-macro2", "quote", "syn 2.0.8", "synstructure 0.13.0", - "unic-langid", ] [[package]] @@ -3609,6 +3749,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_hir_pretty", @@ -3646,6 +3787,7 @@ dependencies = [ "rustc_error_messages", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -3671,6 +3813,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -3694,6 +3837,7 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", "rustc_index", @@ -3737,6 +3881,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -3760,6 +3905,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_lexer", "rustc_macros", "rustc_session", @@ -3790,6 +3936,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_lexer", @@ -3810,6 +3957,7 @@ dependencies = [ "libloading", "rustc_ast", "rustc_errors", + "rustc_fluent_macro", "rustc_lint", "rustc_macros", "rustc_metadata", @@ -3825,6 +3973,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_hir_analysis", "rustc_macros", @@ -3866,6 +4015,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -3893,6 +4043,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -3926,6 +4077,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_fluent_macro", "rustc_fs_util", "rustc_hir", "rustc_index", @@ -3937,7 +4089,7 @@ dependencies = [ "smallvec", "termize", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -3977,6 +4129,7 @@ dependencies = [ "rustc-demangle", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_macros", "rustc_middle", @@ -4019,6 +4172,7 @@ dependencies = [ "rustc_attr", "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -4076,6 +4230,7 @@ version = "0.0.0" dependencies = [ "rustc_data_structures", "rustc_errors", + "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_infer", @@ -4263,6 +4418,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + +[[package]] name = "self_cell" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4400,9 +4561,9 @@ dependencies = [ [[package]] name = "spdx-rs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c02f6eb7e7b4100c272f685a9ccaccaab302324e8c7ec3e2ee72340fb29ff3" +checksum = "6b1ec09829bf2d82c175c121b20de11ffab2def83bd55979002099b1f9956c9b" dependencies = [ "chrono", "log", @@ -4455,7 +4616,7 @@ dependencies = [ "hermit-abi 0.3.0", "libc", "miniz_oxide", - "object 0.29.0", + "object", "panic_abort", "panic_unwind", "profiler_builtins", @@ -4723,9 +4884,9 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da8fbf660a019b6bf11ea95762041464aa9099cc293b6a66d77cea5107619671" dependencies = [ - "gimli", + "gimli 0.26.2", "hashbrown 0.12.3", - "object 0.30.1", + "object", "tracing", ] @@ -4767,16 +4928,6 @@ name = "tier-check" version = "0.1.0" [[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] name = "tinystr" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5200,9 +5351,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "0.8.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" dependencies = [ "getrandom", ] @@ -5248,6 +5399,60 @@ dependencies = [ ] [[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.102", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.102", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] name = "winapi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5284,7 +5489,16 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -5293,13 +5507,13 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -5308,7 +5522,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", ] [[package]] @@ -5317,13 +5531,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -5333,42 +5562,84 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] name = "writeable" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/README.md b/README.md index c19e129a920..41b135972af 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Read ["Installation"] from [The Book]. The Rust build system uses a Python script called `x.py` to build the compiler, which manages the bootstrapping process. It lives at the root of the project. +It also uses a file named `config.toml` to determine various configuration settings for the build. +You can see a full list of options in `config.example.toml`. The `x.py` command can be run directly on most Unix systems in the following format: @@ -85,6 +87,8 @@ See [the rustc-dev-guide for more info][sysllvm]. ### Building on a Unix-like system +#### Build steps + 1. Clone the [source] with `git`: ```sh @@ -96,18 +100,13 @@ See [the rustc-dev-guide for more info][sysllvm]. 2. Configure the build settings: - The Rust build system uses a file named `config.toml` in the root of the - source tree to determine various configuration settings for the build. - Set up the defaults intended for distros to get started. You can see a full - list of options in `config.example.toml`. - ```sh - printf 'profile = "user" \nchangelog-seen = 2 \n' > config.toml + ./configure ``` If you plan to use `x.py install` to create an installation, it is recommended that you set the `prefix` value in the `[install]` section to a - directory. + directory: `./configure --set install.prefix=<path>` 3. Build and install: @@ -117,12 +116,25 @@ See [the rustc-dev-guide for more info][sysllvm]. When complete, `./x.py install` will place several programs into `$PREFIX/bin`: `rustc`, the Rust compiler, and `rustdoc`, the - API-documentation tool. If you've set `profile = "user"` or - `build.extended = true`, it will also include [Cargo], Rust's package - manager. + API-documentation tool. By default, it will also include [Cargo], Rust's package manager. + You can disable this behavior by passing `--set build.extended=false` to `./configure`. [Cargo]: https://github.com/rust-lang/cargo +#### Configure and Make + +This project provides a configure script and makefile (the latter of which just invokes `x.py`). +`./configure` is the recommended way to programatically generate a `config.toml`. `make` is not +recommended (we suggest using `x.py` directly), but it is supported and we try not to break it +unnecessarily. + +```sh +./configure +make && sudo make install +``` + +`configure` generates a `config.toml` which can also be used with normal `x.py` invocations. + ### Building on Windows On Windows, we suggest using [winget] to install dependencies by running the @@ -186,7 +198,7 @@ toolchain. 4. Navigate to Rust's source code (or clone it), then build it: ```sh - ./x.py build && ./x.py install + python x.py setup user && python x.py build && python x.py install ``` #### MSVC @@ -204,6 +216,7 @@ With these dependencies installed, you can build the compiler in a `cmd.exe` shell with: ```sh +python x.py setup user python x.py build ``` @@ -232,21 +245,7 @@ Windows build triples are: The build triple can be specified by either specifying `--build=<triple>` when invoking `x.py` commands, or by creating a `config.toml` file (as described in -[Installing from Source](#installing-from-source)), and modifying the `build` -option under the `[build]` section. - -### Configure and Make - -While it's not the recommended build system, this project also provides a -configure script and makefile (the latter of which just invokes `x.py`). - -```sh -./configure -make && sudo make install -``` - -`configure` generates a `config.toml` which can also be used with normal `x.py` -invocations. +[Building on a Unix-like system](#building-on-a-unix-like-system)), and passing `--set build.build=<triple>` to `./configure`. ## Building Documentation diff --git a/RELEASES.md b/RELEASES.md index b89178a6f68..e72905c15bd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -88,7 +88,11 @@ Compatibility Notes - [When `default-features` is set to false of a workspace dependency, and an inherited dependency of a member has `default-features = true`, Cargo will enable default features of that dependency.](https://github.com/rust-lang/cargo/pull/11409/) - [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/) - [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/) - +- [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886) + If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By + default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the + list. + <a id="1.69.0-Internal-Changes"></a> Internal Changes @@ -963,7 +967,7 @@ Compatibility Notes - [rustdoc: doctests are now run on unexported `macro_rules!` macros, matching other private items][96630] - [rustdoc: Remove .woff font files][96279] - [Enforce Copy bounds for repeat elements while considering lifetimes][95819] -- [Windows: Fix potentinal unsoundness by aborting if `File` reads or writes cannot +- [Windows: Fix potential unsoundness by aborting if `File` reads or writes cannot complete synchronously][95469]. Internal Changes @@ -1794,10 +1798,10 @@ Libraries - [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744] - [`impl From<[(K, V); N]>` for all collections.][rust#84111] - [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363] -- [Treat invalid environment variable names as non-existent.][rust#86183] +- [Treat invalid environment variable names as nonexistent.][rust#86183] Previously, the environment functions would panic if given a variable name with an internal null character or equal sign (`=`). Now, these functions will - just treat such names as non-existent variables, since the OS cannot represent + just treat such names as nonexistent variables, since the OS cannot represent the existence of a variable with such a name. Stabilised APIs @@ -1990,7 +1994,7 @@ Compatibility Notes kinds of errors could be categorised [into newer more specific `ErrorKind` variants][79965], and that they do not represent a user error. - [Using environment variable names with `process::Command` on Windows now - behaves as expected.][85270] Previously using envionment variables with + behaves as expected.][85270] Previously using environment variables with `Command` would cause them to be ASCII-uppercased. - [Rustdoc will now warn on using rustdoc lints that aren't prefixed with `rustdoc::`][86849] @@ -6367,7 +6371,7 @@ eg. `static MINUTE: Duration = Duration::from_secs(60);` Cargo ----- -- [`cargo new` no longer removes `rust` or `rs` prefixs/suffixs.][cargo/5013] +- [`cargo new` no longer removes `rust` or `rs` prefixes/suffixes.][cargo/5013] - [`cargo new` now defaults to creating a binary crate, instead of a library crate.][cargo/5029] diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ab0409efb3b..1e4d3ba47f4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1271,6 +1271,7 @@ impl Expr { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf, ExprKind::MacCall(..) => ExprPrecedence::Mac, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, @@ -1469,6 +1470,9 @@ pub enum ExprKind { /// Output of the `asm!()` macro. InlineAsm(P<InlineAsm>), + /// Output of the `offset_of!()` macro. + OffsetOf(P<Ty>, P<[Ident]>), + /// A macro invocation; pre-expansion. MacCall(P<MacCall>), diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 23c32fa96ca..b07ed1d1c74 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -10,7 +10,6 @@ )] #![feature(associated_type_bounds)] #![feature(box_patterns)] -#![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(if_let_guard)] #![feature(let_chains)] diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 694d31d8f1f..99f1f4bd968 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1456,6 +1456,12 @@ pub fn noop_visit_expr<T: MutVisitor>( } ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), + ExprKind::OffsetOf(container, fields) => { + vis.visit_ty(container); + for field in fields.iter_mut() { + vis.visit_ident(field); + } + } ExprKind::MacCall(mac) => vis.visit_mac_call(mac), ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = se.deref_mut(); diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs index 4b2850336a0..0140fb752bf 100644 --- a/compiler/rustc_ast/src/ptr.rs +++ b/compiler/rustc_ast/src/ptr.rs @@ -126,7 +126,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> { } impl<T> P<[T]> { - pub const fn new() -> P<[T]> { + // FIXME(const-hack) make this const again + pub fn new() -> P<[T]> { P { ptr: Box::default() } } diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index 3893875e9a4..24b4bd8623f 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -269,6 +269,7 @@ pub enum ExprPrecedence { Index, Try, InlineAsm, + OffsetOf, Mac, FormatArgs, @@ -335,7 +336,8 @@ impl ExprPrecedence { | ExprPrecedence::Try | ExprPrecedence::InlineAsm | ExprPrecedence::Mac - | ExprPrecedence::FormatArgs => PREC_POSTFIX, + | ExprPrecedence::FormatArgs + | ExprPrecedence::OffsetOf => PREC_POSTFIX, // Never need parens ExprPrecedence::Array diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ac9b321b71c..8a6b5d5c905 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -909,6 +909,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression), ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm), ExprKind::FormatArgs(f) => visitor.visit_format_args(f), + ExprKind::OffsetOf(container, fields) => { + visitor.visit_ty(container); + for &field in fields { + visitor.visit_ident(field); + } + } ExprKind::Yield(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index eb2e82d7988..6b0da256505 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_middle = { path = "../rustc_middle" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 0d212b3e130..6863100d9ba 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -289,6 +289,13 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm)) } ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt), + ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf( + self.lower_ty( + container, + &mut ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf), + ), + self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))), + ), ExprKind::Struct(se) => { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index c41bdc44093..ccf481cb9b3 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -220,19 +220,19 @@ fn make_argument<'hir>( /// Generates: /// /// ```text -/// <core::fmt::rt::v1::Count>::Is(…) +/// <core::fmt::rt::Count>::Is(…) /// ``` /// /// or /// /// ```text -/// <core::fmt::rt::v1::Count>::Param(…) +/// <core::fmt::rt::Count>::Param(…) /// ``` /// /// or /// /// ```text -/// <core::fmt::rt::v1::Count>::Implied +/// <core::fmt::rt::Count>::Implied /// ``` fn make_count<'hir>( ctx: &mut LoweringContext<'_, 'hir>, @@ -278,13 +278,13 @@ fn make_count<'hir>( /// Generates /// /// ```text -/// <core::fmt::rt::v1::Argument::new( +/// <core::fmt::rt::Placeholder::new( /// …usize, // position /// '…', // fill -/// <core::fmt::rt::v1::Alignment>::…, // alignment +/// <core::fmt::rt::Alignment>::…, // alignment /// …u32, // flags -/// <core::fmt::rt::v1::Count::…>, // width -/// <core::fmt::rt::v1::Count::…>, // precision +/// <core::fmt::rt::Count::…>, // width +/// <core::fmt::rt::Count::…>, // precision /// ) /// ``` fn make_format_spec<'hir>( diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 08e7a4dfe5d..9fac4ffaf1c 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -443,7 +443,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacroDef(MacroDef { body, macro_rules }) => { let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); - hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind) + let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); + hir::ItemKind::Macro(macro_def, macro_kind) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 537c2a06183..c969d709608 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -55,13 +55,13 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{ DiagnosticArgFromDisplay, DiagnosticMessage, Handler, StashKey, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexSlice, IndexVec}; -use rustc_macros::fluent_messages; use rustc_middle::{ span_bug, ty::{ResolverAstLowering, TyCtxt}, @@ -283,6 +283,7 @@ enum ImplTraitPosition { FieldTy, Cast, ImplSelf, + OffsetOf, } impl std::fmt::Display for ImplTraitPosition { @@ -313,6 +314,7 @@ impl std::fmt::Display for ImplTraitPosition { ImplTraitPosition::FieldTy => "field types", ImplTraitPosition::Cast => "cast types", ImplTraitPosition::ImplSelf => "impl headers", + ImplTraitPosition::OffsetOf => "`offset_of!` params", }; write!(f, "{name}") diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 8bd212073a6..eb736123520 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -12,6 +12,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_macros = { path = "../rustc_macros" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index e2c666604b3..7db413c5bbd 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -13,7 +13,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod ast_validation; mod errors; diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 776bf54244e..aeb0c762020 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -549,6 +549,26 @@ impl<'a> State<'a> { self.end(); self.pclose(); } + ast::ExprKind::OffsetOf(container, fields) => { + // FIXME: This should have its own syntax, distinct from a macro invocation. + self.word("offset_of!"); + self.popen(); + self.rbox(0, Inconsistent); + self.print_type(container); + self.word(","); + self.space(); + + if let Some((&first, rest)) = fields.split_first() { + self.print_ident(first); + + for &field in rest { + self.word("."); + self.print_ident(field); + } + } + + self.end(); + } ast::ExprKind::MacCall(m) => self.print_mac(m), ast::ExprKind::Paren(e) => { self.popen(); diff --git a/compiler/rustc_attr/Cargo.toml b/compiler/rustc_attr/Cargo.toml index 6349ddf31d1..2c4c3a0c263 100644 --- a/compiler/rustc_attr/Cargo.toml +++ b/compiler/rustc_attr/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_serialize = { path = "../rustc_serialize" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_span = { path = "../rustc_span" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_feature = { path = "../rustc_feature" } diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 49818c14f27..cfed2acfb3a 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -12,7 +12,7 @@ extern crate rustc_macros; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod builtin; mod session_diagnostics; diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index e0bb87336e5..56a9deb6aab 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -15,6 +15,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_lexer = { path = "../rustc_lexer" } diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index 2bbb9618dbf..acca1a1477f 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -469,6 +469,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { } #[rustc_lint_diagnostics] + #[track_caller] pub(crate) fn struct_span_err_with_code<S: Into<MultiSpan>>( &self, sp: S, diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index cb1a6522223..cd200aaa277 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_index::vec::IndexSlice; use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_middle::mir::Body; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::TyCtxt; pub use super::{ facts::{AllFacts as PoloniusInput, RustcFacts}, @@ -28,12 +28,9 @@ pub use super::{ /// that shows how to do this at `tests/run-make/obtain-borrowck/`. /// /// * Polonius is highly unstable, so expect regular changes in its signature or other details. -pub fn get_body_with_borrowck_facts( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> BodyWithBorrowckFacts<'_> { +pub fn get_body_with_borrowck_facts(tcx: TyCtxt<'_>, def: LocalDefId) -> BodyWithBorrowckFacts<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build(); + let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def)).build(); let input_body: &Body<'_> = &input_body.borrow(); let promoted: &IndexSlice<_, _> = &promoted.borrow(); *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 9e9f0b4b4ad..6259722b694 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -52,12 +52,16 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) | + // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not + // contain dangling references. + PlaceContext::NonUse(NonUseContext::PlaceMention) | + PlaceContext::NonUse(NonUseContext::AscribeUserTy) | + PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) | - PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => Some(DefUse::Use), @@ -72,8 +76,6 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> { PlaceContext::MutatingUse(MutatingUseContext::Drop) => Some(DefUse::Drop), - // This statement exists to help unsafeck. It does not require the place to be live. - PlaceContext::NonUse(NonUseContext::PlaceMention) => None, // Debug info is neither def nor use. PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index a4a3c738f47..8dd03aaa72d 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1,3 +1,5 @@ +use std::iter; + use either::Either; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexSet; @@ -8,8 +10,8 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; +use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, @@ -21,16 +23,14 @@ use rustc_middle::util::CallKind; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; -use rustc_span::symbol::{kw, sym}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; use crate::borrow_set::TwoPhaseActivation; use crate::borrowck_errors; - use crate::diagnostics::conflict_errors::StorageDeadOrDrop::LocalStorageDead; -use crate::diagnostics::mutability_errors::mut_borrow_of_mutable_ref; use crate::diagnostics::{find_all_local_uses, CapturedMessageOpt}; use crate::{ borrow_set::BorrowData, diagnostics::Instance, prefixes::IsPrefixOf, @@ -642,11 +642,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { return false; }; - // Regions are already solved, so we must use a fresh InferCtxt, - // but the type has region variables, so erase those. - tcx.infer_ctxt() - .build() - .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env) + self.infcx + .type_implements_trait(default_trait, [ty], param_env) .must_apply_modulo_regions() }; @@ -739,13 +736,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - if let Some(clone_trait_def) = tcx.lang_items().clone_trait() - && infcx + && self.infcx .type_implements_trait( clone_trait_def, - [tcx.erase_regions(ty)], + [ty], self.param_env, ) .must_apply_modulo_regions() @@ -769,12 +764,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|def_id| tcx.hir().get_generics(def_id)) else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new(&self.infcx); let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::misc(span, self.mir_def_id()); - ocx.register_bound(cause, self.param_env, infcx.tcx.erase_regions(ty), copy_did); + ocx.register_bound(cause, self.param_env, ty, copy_did); let errors = ocx.select_all_or_error(); // Only emit suggestion if all required predicates are on generic @@ -959,7 +953,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &msg_borrow, None, ); - self.suggest_binding_for_closure_capture_self( + self.suggest_binding_for_closure_capture_self(&mut err, &issued_spans); + self.suggest_using_closure_argument_instead_of_capture( &mut err, issued_borrow.borrowed_place, &issued_spans, @@ -982,6 +977,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { place, issued_borrow.borrowed_place, ); + self.suggest_using_closure_argument_instead_of_capture( + &mut err, + issued_borrow.borrowed_place, + &issued_spans, + ); err } @@ -1268,22 +1268,160 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - fn suggest_binding_for_closure_capture_self( + /// Suggest using closure argument instead of capture. + /// + /// For example: + /// ```ignore (illustrative) + /// struct S; + /// + /// impl S { + /// fn call(&mut self, f: impl Fn(&mut Self)) { /* ... */ } + /// fn x(&self) {} + /// } + /// + /// let mut v = S; + /// v.call(|this: &mut S| v.x()); + /// // ^\ ^-- help: try using the closure argument: `this` + /// // *-- error: cannot borrow `v` as mutable because it is also borrowed as immutable + /// ``` + fn suggest_using_closure_argument_instead_of_capture( &self, err: &mut Diagnostic, borrowed_place: Place<'tcx>, issued_spans: &UseSpans<'tcx>, ) { - let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; - let hir = self.infcx.tcx.hir(); + let &UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; + let tcx = self.infcx.tcx; + let hir = tcx.hir(); - // check whether the borrowed place is capturing `self` by mut reference + // Get the type of the local that we are trying to borrow let local = borrowed_place.local; - let Some(_) = self - .body - .local_decls - .get(local) - .map(|l| mut_borrow_of_mutable_ref(l, self.local_names[local])) else { return }; + let local_ty = self.body.local_decls[local].ty; + + // Get the body the error happens in + let Some(body_id) = hir.get(self.mir_hir_id()).body_id() else { return }; + + let body_expr = hir.body(body_id).value; + + struct ClosureFinder<'hir> { + hir: rustc_middle::hir::map::Map<'hir>, + borrow_span: Span, + res: Option<(&'hir hir::Expr<'hir>, &'hir hir::Closure<'hir>)>, + /// The path expression with the `borrow_span` span + error_path: Option<(&'hir hir::Expr<'hir>, &'hir hir::QPath<'hir>)>, + } + impl<'hir> Visitor<'hir> for ClosureFinder<'hir> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.hir + } + + fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { + if let hir::ExprKind::Path(qpath) = &ex.kind + && ex.span == self.borrow_span + { + self.error_path = Some((ex, qpath)); + } + + if let hir::ExprKind::Closure(closure) = ex.kind + && ex.span.contains(self.borrow_span) + // To support cases like `|| { v.call(|this| v.get()) }` + // FIXME: actually support such cases (need to figure out how to move from the capture place to original local) + && self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span)) + { + self.res = Some((ex, closure)); + } + + hir::intravisit::walk_expr(self, ex); + } + } + + // Find the closure that most tightly wraps `capture_kind_span` + let mut finder = + ClosureFinder { hir, borrow_span: capture_kind_span, res: None, error_path: None }; + finder.visit_expr(body_expr); + let Some((closure_expr, closure)) = finder.res else { return }; + + let typeck_results = tcx.typeck(self.mir_def_id()); + + // Check that the parent of the closure is a method call, + // with receiver matching with local's type (modulo refs) + let parent = hir.parent_id(closure_expr.hir_id); + if let hir::Node::Expr(parent) = hir.get(parent) { + if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind { + let recv_ty = typeck_results.expr_ty(recv); + + if recv_ty.peel_refs() != local_ty { + return; + } + } + } + + // Get closure's arguments + let ty::Closure(_, substs) = typeck_results.expr_ty(closure_expr).kind() else { unreachable!() }; + let sig = substs.as_closure().sig(); + let tupled_params = + tcx.erase_late_bound_regions(sig.inputs().iter().next().unwrap().map_bound(|&b| b)); + let ty::Tuple(params) = tupled_params.kind() else { return }; + + // Find the first argument with a matching type, get its name + let Some((_, this_name)) = params + .iter() + .zip(hir.body_param_names(closure.body)) + .find(|(param_ty, name)|{ + // FIXME: also support deref for stuff like `Rc` arguments + param_ty.peel_refs() == local_ty && name != &Ident::empty() + }) + else { return }; + + let spans; + if let Some((_path_expr, qpath)) = finder.error_path + && let hir::QPath::Resolved(_, path) = qpath + && let hir::def::Res::Local(local_id) = path.res + { + // Find all references to the problematic variable in this closure body + + struct VariableUseFinder { + local_id: hir::HirId, + spans: Vec<Span>, + } + impl<'hir> Visitor<'hir> for VariableUseFinder { + fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) { + if let hir::ExprKind::Path(qpath) = &ex.kind + && let hir::QPath::Resolved(_, path) = qpath + && let hir::def::Res::Local(local_id) = path.res + && local_id == self.local_id + { + self.spans.push(ex.span); + } + + hir::intravisit::walk_expr(self, ex); + } + } + + let mut finder = VariableUseFinder { local_id, spans: Vec::new() }; + finder.visit_expr(hir.body(closure.body).value); + + spans = finder.spans; + } else { + spans = vec![capture_kind_span]; + } + + err.multipart_suggestion( + "try using the closure argument", + iter::zip(spans, iter::repeat(this_name.to_string())).collect(), + Applicability::MaybeIncorrect, + ); + } + + fn suggest_binding_for_closure_capture_self( + &self, + err: &mut Diagnostic, + issued_spans: &UseSpans<'tcx>, + ) { + let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; + let hir = self.infcx.tcx.hir(); struct ExpressionFinder<'hir> { capture_span: Span, @@ -2074,7 +2212,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; - let return_ty = tcx.erase_regions(return_ty); // to avoid panics if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4a85df9f8c0..299d04c4fb6 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::GeneratorKind; use rustc_index::vec::IndexSlice; -use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; +use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, @@ -1042,15 +1042,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { let ty = moved_place.ty(self.body, tcx).ty; let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { - Some(def_id) => { - let infcx = self.infcx.tcx.infer_ctxt().build(); - type_known_to_meet_bound_modulo_regions( - &infcx, - self.param_env, - tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.erase_regions(ty)), - def_id, - ) - } + Some(def_id) => type_known_to_meet_bound_modulo_regions( + &self.infcx, + self.param_env, + tcx.mk_imm_ref(tcx.lifetimes.re_erased, ty), + def_id, + ), _ => false, }; if suggest { @@ -1094,20 +1091,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { is_partial, is_loop_message, }); - let infcx = tcx.infer_ctxt().build(); // Erase and shadow everything that could be passed to the new infcx. - let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty); - let method_substs = tcx.erase_regions(method_substs); + let ty = moved_place.ty(self.body, tcx).ty; if let ty::Adt(def, substs) = ty.kind() && Some(def.did()) == tcx.lang_items().pin_type() && let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind() - && let self_ty = infcx.instantiate_binder_with_fresh_vars( + && let self_ty = self.infcx.instantiate_binder_with_fresh_vars( fn_call_span, LateBoundRegionConversionTime::FnCall, tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), ) - && infcx.can_eq(self.param_env, ty, self_ty) + && self.infcx.can_eq(self.param_env, ty, self_ty) { err.eager_subdiagnostic( &self.infcx.tcx.sess.parse_sess.span_diagnostic, @@ -1123,7 +1118,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.param_env, ty::Binder::dummy(trait_ref), ) - && infcx.predicate_must_hold_modulo_regions(&o) + && self.infcx.predicate_must_hold_modulo_regions(&o) { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 498d254da65..06986f848bf 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -79,7 +79,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index fdd82c7e3b2..73ecd99c04a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -20,6 +20,7 @@ extern crate tracing; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; @@ -27,7 +28,6 @@ use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::{ DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; -use rustc_macros::fluent_messages; use rustc_middle::mir::{ traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, @@ -119,24 +119,12 @@ impl<'tcx> TyCtxtConsts<'tcx> { } pub fn provide(providers: &mut Providers) { - *providers = Providers { - mir_borrowck: |tcx, did| { - if let Some(def) = ty::WithOptConstParam::try_lookup(did, tcx) { - tcx.mir_borrowck_const_arg(def) - } else { - mir_borrowck(tcx, ty::WithOptConstParam::unknown(did)) - } - }, - mir_borrowck_const_arg: |tcx, (did, param_did)| { - mir_borrowck(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, - ..*providers - }; + *providers = Providers { mir_borrowck, ..*providers }; } -fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &BorrowCheckResult<'_> { +fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id())); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); if input_body.borrow().should_skip() { debug!("Skipping borrowck because of injected body"); @@ -150,7 +138,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor return tcx.arena.alloc(result); } - let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner; + let hir_owner = tcx.hir().local_def_id_to_hir_id(def).owner; let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build(); @@ -167,19 +155,19 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor /// If `return_body_with_facts` is true, then return the body with non-erased /// region ids on which the borrow checking was performed together with Polonius /// facts. -#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.with_opt_param().as_local().unwrap()), level = "debug")] +#[instrument(skip(infcx, input_body, input_promoted), fields(id=?input_body.source.def_id()), level = "debug")] fn do_mir_borrowck<'tcx>( infcx: &InferCtxt<'tcx>, input_body: &Body<'tcx>, input_promoted: &IndexSlice<Promoted, Body<'tcx>>, return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { - let def = input_body.source.with_opt_param().as_local().unwrap(); + let def = input_body.source.def_id().expect_local(); debug!(?def); let tcx = infcx.tcx; let infcx = BorrowckInferCtxt::new(infcx); - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); for var_debug_info in &input_body.var_debug_info { @@ -207,7 +195,7 @@ fn do_mir_borrowck<'tcx>( errors.set_tainted_by_errors(e); } let upvars: Vec<_> = tcx - .closure_captures(def.did) + .closure_captures(def) .iter() .map(|&captured_place| { let capture = captured_place.info.capture_kind; @@ -249,7 +237,7 @@ fn do_mir_borrowck<'tcx>( .iterate_to_fixpoint() .into_results_cursor(&body); - let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def.did).is_fn_or_closure(); + let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(def).is_fn_or_closure(); let borrow_set = Rc::new(BorrowSet::build(tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); @@ -677,7 +665,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 73b8765e57d..5e55e1128e8 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -61,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>( body: &mut Body<'tcx>, promoted: &mut IndexSlice<Promoted, Body<'tcx>>, ) -> UniversalRegions<'tcx> { - let def = body.source.with_opt_param().as_local().unwrap(); + let def = body.source.def_id().expect_local(); debug!(?def); @@ -235,7 +235,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. - let var_origins = infcx.take_region_var_origins(); + let var_origins = infcx.get_region_var_origins(); let MirTypeckRegionConstraints { placeholder_indices, placeholder_index_to_region: _, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 375eca1b29d..7cb0cec82c7 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -394,7 +394,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { self.cx.ascribe_user_type( constant.literal.ty(), UserType::TypeOf( - uv.def.did, + uv.def, UserSubsts { substs: uv.substs, user_self_ty: None }, ), locations.span(&self.cx.body), @@ -1766,7 +1766,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { let tcx = self.tcx(); - let def_id = uv.def.def_id_for_type_of(); + let def_id = uv.def; if tcx.def_kind(def_id) == DefKind::InlineConst { let def_id = def_id.expect_local(); let predicates = @@ -2306,7 +2306,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::AddressOf(..) | Rvalue::ThreadLocalRef(..) | Rvalue::Len(..) - | Rvalue::Discriminant(..) => {} + | Rvalue::Discriminant(..) + | Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {} } } diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 74241f722a6..ef37c01cef8 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -226,7 +226,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// known between those regions. pub fn new( infcx: &BorrowckInferCtxt<'_, 'tcx>, - mir_def: ty::WithOptConstParam<LocalDefId>, + mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, ) -> Self { UniversalRegionsBuilder { infcx, mir_def, param_env }.build() @@ -388,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> { struct UniversalRegionsBuilder<'cx, 'tcx> { infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, - mir_def: ty::WithOptConstParam<LocalDefId>, + mir_def: LocalDefId, param_env: ty::ParamEnv<'tcx>, } @@ -417,12 +417,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let mut indices = self.compute_indices(fr_static, defining_ty); debug!("build: indices={:?}", indices); - let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); // If this is a 'root' body (not a closure/generator/inline const), then // there are no extern regions, so the local regions start at the same // position as the (empty) sub-list of extern regions - let first_local_index = if self.mir_def.did.to_def_id() == typeck_root_def_id { + let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { first_extern_index } else { // If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing @@ -433,7 +433,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // } for_each_late_bound_region_in_recursive_scope( self.infcx.tcx, - self.infcx.tcx.local_parent(self.mir_def.did), + self.infcx.tcx.local_parent(self.mir_def), |r| { debug!(?r); if !indices.indices.contains_key(&r) { @@ -462,13 +462,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars( FR, - self.mir_def.did, + self.mir_def, bound_inputs_and_output, &mut indices, ); // Converse of above, if this is a function/closure then the late-bound regions declared on its // signature are local. - for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| { + for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| { debug!(?r); if !indices.indices.contains_key(&r) { let region_vid = { @@ -492,7 +492,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { if self.infcx.tcx.fn_sig(def_id).skip_binder().c_variadic() { let va_list_did = self.infcx.tcx.require_lang_item( LangItem::VaList, - Some(self.infcx.tcx.def_span(self.mir_def.did)), + Some(self.infcx.tcx.def_span(self.mir_def)), ); let reg_vid = self @@ -544,11 +544,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { /// see `DefiningTy` for details. fn defining_ty(&self) -> DefiningTy<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); - match tcx.hir().body_owner_kind(self.mir_def.did) { + match tcx.hir().body_owner_kind(self.mir_def) { BodyOwnerKind::Closure | BodyOwnerKind::Fn => { - let defining_ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); + let defining_ty = tcx.type_of(self.mir_def).subst_identity(); debug!("defining_ty (pre-replacement): {:?}", defining_ty); @@ -562,9 +562,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } ty::FnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs), _ => span_bug!( - tcx.def_span(self.mir_def.did), + tcx.def_span(self.mir_def), "expected defining type for `{:?}`: `{:?}`", - self.mir_def.did, + self.mir_def, defining_ty ), } @@ -572,10 +572,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { BodyOwnerKind::Const | BodyOwnerKind::Static(..) => { let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); - if self.mir_def.did.to_def_id() == typeck_root_def_id { + if self.mir_def.to_def_id() == typeck_root_def_id { let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, identity_substs); - DefiningTy::Const(self.mir_def.did.to_def_id(), substs) + DefiningTy::Const(self.mir_def.to_def_id(), substs) } else { // FIXME this line creates a dependency between borrowck and typeck. // @@ -587,15 +587,15 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { // below), so that `type_of(inline_const_def_id).substs(substs)` uses the // proper type with NLL infer vars. let ty = tcx - .typeck(self.mir_def.did) - .node_type(tcx.local_def_id_to_hir_id(self.mir_def.did)); + .typeck(self.mir_def) + .node_type(tcx.local_def_id_to_hir_id(self.mir_def)); let substs = InlineConstSubsts::new( tcx, InlineConstSubstsParts { parent_substs: identity_substs, ty }, ) .substs; let substs = self.infcx.replace_free_regions_with_nll_infer_vars(FR, substs); - DefiningTy::InlineConst(self.mir_def.did.to_def_id(), substs) + DefiningTy::InlineConst(self.mir_def.to_def_id(), substs) } } } @@ -611,7 +611,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { defining_ty: DefiningTy<'tcx>, ) -> UniversalRegionIndices<'tcx> { let tcx = self.infcx.tcx; - let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.did.to_def_id()); + let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id()); let identity_substs = InternalSubsts::identity_for_item(tcx, typeck_root_def_id); let fr_substs = match defining_ty { DefiningTy::Closure(_, substs) @@ -647,7 +647,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let tcx = self.infcx.tcx; match defining_ty { DefiningTy::Closure(def_id, substs) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let closure_sig = substs.as_closure().sig(); let inputs_and_output = closure_sig.inputs_and_output(); let bound_vars = tcx.mk_bound_variable_kinds_from_iter( @@ -682,7 +682,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { } DefiningTy::Generator(def_id, substs, movability) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let resume_ty = substs.as_generator().resume_ty(); let output = substs.as_generator().return_ty(); let generator_ty = tcx.mk_generator(def_id, substs, movability); @@ -700,14 +700,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { DefiningTy::Const(def_id, _) => { // For a constant body, there are no inputs, and one // "output" (the type of the constant). - assert_eq!(self.mir_def.did.to_def_id(), def_id); - let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); + assert_eq!(self.mir_def.to_def_id(), def_id); + let ty = tcx.type_of(self.mir_def).subst_identity(); let ty = indices.fold_to_region_vids(tcx, ty); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } DefiningTy::InlineConst(def_id, substs) => { - assert_eq!(self.mir_def.did.to_def_id(), def_id); + assert_eq!(self.mir_def.to_def_id(), def_id); let ty = substs.as_inline_const().ty(); ty::Binder::dummy(tcx.mk_type_list(&[ty])) } diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 336e14ef966..5f6441660e3 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -17,6 +17,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_parse_format = { path = "../rustc_parse_format" } rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 83dc1ac50e5..ee2aca6fc93 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -4,8 +4,6 @@ builtin_macros_requires_cfg_pattern = builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern -builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function - builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument .label = boolean expression required @@ -149,3 +147,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n -> [one] argument *[more] arguments } in format string, but {$desc} +builtin_macros_offset_of_expected_field = expected field + +builtin_macros_offset_of_expected_two_args = expected 2 arguments diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs deleted file mode 100644 index 82bae9157e7..00000000000 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ /dev/null @@ -1,97 +0,0 @@ -use crate::errors; -use crate::util::check_builtin_macro_attribute; - -use rustc_ast::ptr::P; -use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind}; -use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe}; -use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::Span; -use thin_vec::{thin_vec, ThinVec}; - -pub fn expand( - ecx: &mut ExtCtxt<'_>, - _span: Span, - meta_item: &ast::MetaItem, - item: Annotatable, -) -> Vec<Annotatable> { - check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler); - - let orig_item = item.clone(); - - // Allow using `#[alloc_error_handler]` on an item statement - // FIXME - if we get deref patterns, use them to reduce duplication here - let (item, is_stmt, sig_span) = - if let Annotatable::Item(item) = &item - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else if let Annotatable::Stmt(stmt) = &item - && let StmtKind::Item(item) = &stmt.kind - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else { - ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() }); - return vec![orig_item]; - }; - - // Generate a bunch of new items using the AllocFnFactory - let span = ecx.with_def_site_ctxt(item.span); - - // Generate item statements for the allocator methods. - let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)]; - - // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); - let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); - let const_item = if is_stmt { - Annotatable::Stmt(P(ecx.stmt_item(span, const_item))) - } else { - Annotatable::Item(const_item) - }; - - // Return the original item and the new methods. - vec![orig_item, const_item] -} - -// #[rustc_std_internal_symbol] -// unsafe fn __rg_oom(size: usize, align: usize) -> ! { -// handler(core::alloc::Layout::from_size_align_unchecked(size, align)) -// } -fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { - let usize = cx.path_ident(span, Ident::new(sym::usize, span)); - let ty_usize = cx.ty_path(usize); - let size = Ident::from_str_and_span("size", span); - let align = Ident::from_str_and_span("align", span); - - let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); - let layout_new = cx.expr_path(cx.path(span, layout_new)); - let layout = cx.expr_call( - span, - layout_new, - thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)], - ); - - let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]); - - let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never)); - let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)]; - let decl = cx.fn_decl(params, never); - let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() }; - let sig = FnSig { decl, header, span: span }; - - let body = Some(cx.block_expr(call)); - let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Final, - sig, - generics: Generics::default(), - body, - })); - - let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; - - let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind); - cx.stmt_item(sig_span, item) -} diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index c9e3cd486f8..090e00616fb 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -301,6 +301,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::If(_, _, _) | ExprKind::IncludedBytes(..) | ExprKind::InlineAsm(_) + | ExprKind::OffsetOf(_, _) | ExprKind::Let(_, _, _) | ExprKind::Lit(_) | ExprKind::Loop(_, _, _) diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 630f9b87bc3..bf0ac3f0ee3 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -20,13 +20,6 @@ pub(crate) struct OneCfgPattern { } #[derive(Diagnostic)] -#[diag(builtin_macros_alloc_error_must_be_fn)] -pub(crate) struct AllocErrorMustBeFn { - #[primary_span] - pub(crate) span: Span, -} - -#[derive(Diagnostic)] #[diag(builtin_macros_assert_requires_boolean)] pub(crate) struct AssertRequiresBoolean { #[primary_span] diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 37fbd03a6a2..b6170161d6b 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -24,10 +24,9 @@ use crate::deriving::*; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_span::symbol::sym; -mod alloc_error_handler; mod assert; mod cfg; mod cfg_accessible; @@ -45,6 +44,7 @@ mod format; mod format_foreign; mod global_allocator; mod log_syntax; +mod offset_of; mod source_util; mod test; mod trace_macros; @@ -92,6 +92,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { line: source_util::expand_line, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, + offset_of: offset_of::expand_offset_of, option_env: env::expand_option_env, core_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic, @@ -102,7 +103,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } register_attr! { - alloc_error_handler: alloc_error_handler::expand, bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs new file mode 100644 index 00000000000..0ef3e000e41 --- /dev/null +++ b/compiler/rustc_builtin_macros/src/offset_of.rs @@ -0,0 +1,99 @@ +use rustc_ast as ast; +use rustc_ast::ptr::P; +use rustc_ast::token; +use rustc_ast::tokenstream::TokenStream; +use rustc_errors::PResult; +use rustc_expand::base::{self, *}; +use rustc_macros::Diagnostic; +use rustc_parse::parser::Parser; +use rustc_span::{symbol::Ident, Span}; + +#[derive(Diagnostic)] +#[diag(builtin_macros_offset_of_expected_field)] +struct ExpectedField { + #[primary_span] + span: Span, +} + +#[derive(Diagnostic)] +#[diag(builtin_macros_offset_of_expected_two_args)] +struct ExpectedTwoArgs { + #[primary_span] + span: Span, +} + +fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> { + let token = p.token.uninterpolate(); + let field = match token.kind { + token::Ident(name, _) => Ident::new(name, token.span), + token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => { + Ident::new(symbol, token.span) + } + _ => return Err(cx.create_err(ExpectedField { span: p.token.span })), + }; + + p.bump(); + + Ok(field) +} + +fn parse_args<'a>( + cx: &mut ExtCtxt<'a>, + sp: Span, + tts: TokenStream, +) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> { + let mut p = cx.new_parser_from_tts(tts); + + let container = p.parse_ty()?; + + p.expect(&token::Comma)?; + + if p.eat(&token::Eof) { + return Err(cx.create_err(ExpectedTwoArgs { span: sp })); + } + + let mut fields = Vec::new(); + + loop { + let field = parse_field(cx, &mut p)?; + fields.push(field); + + if p.eat(&token::Dot) { + continue; + } + + p.eat(&token::Comma); + + if !p.eat(&token::Eof) { + return Err(cx.create_err(ExpectedTwoArgs { span: sp })); + } + + break; + } + + Ok((container, fields.into())) +} + +pub fn expand_offset_of<'cx>( + cx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> Box<dyn base::MacResult + 'cx> { + match parse_args(cx, sp, tts) { + Ok((container, fields)) => { + let expr = P(ast::Expr { + id: ast::DUMMY_NODE_ID, + kind: ast::ExprKind::OffsetOf(container, fields), + span: sp, + attrs: ast::AttrVec::new(), + tokens: None, + }); + + MacEager::expr(expr) + } + Err(mut err) => { + err.emit(); + DummyResult::any(sp) + } + } +} diff --git a/compiler/rustc_codegen_cranelift/example/alloc_example.rs b/compiler/rustc_codegen_cranelift/example/alloc_example.rs index 4ede2fe4efe..e39c3272958 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_example.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, core_intrinsics, alloc_error_handler)] +#![feature(start, core_intrinsics)] #![no_std] extern crate alloc; @@ -22,11 +22,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[alloc_error_handler] -fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { - core::intrinsics::abort(); -} - #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { let world: Box<&str> = Box::new("Hello World!\0"); diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 2c246ceb37d..9fb8079a21f 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -6,7 +6,6 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; -use rustc_span::symbol::sym; /// Returns whether an allocator shim was created pub(crate) fn codegen( @@ -15,13 +14,7 @@ pub(crate) fn codegen( unwind_context: &mut UnwindContext, ) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - module, - unwind_context, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + codegen_inner(module, unwind_context, kind, tcx.sess.opts.unstable_opts.oom); true } @@ -29,7 +22,6 @@ fn codegen_inner( module: &mut impl Module, unwind_context: &mut UnwindContext, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); @@ -71,19 +63,6 @@ fn codegen_inner( ); } - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - unwind_context, - sig, - "__rust_alloc_error_handler", - &alloc_error_handler_kind.fn_name(sym::oom), - ); - let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); let mut data_ctx = DataContext::new(); data_ctx.set_align(1); diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index f5301f9f7f1..f481290583e 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -781,12 +781,15 @@ fn codegen_stmt<'tcx>( let operand = operand.load_scalar(fx); lval.write_cvalue(fx, CValue::by_val(operand, box_layout)); } - Rvalue::NullaryOp(null_op, ty) => { + Rvalue::NullaryOp(ref null_op, ty) => { assert!(lval.layout().ty.is_sized(fx.tcx, ParamEnv::reveal_all())); let layout = fx.layout_of(fx.monomorphize(ty)); let val = match null_op { NullOp::SizeOf => layout.size.bytes(), NullOp::AlignOf => layout.align.abi.bytes(), + NullOp::OffsetOf(fields) => { + layout.offset_of_subfield(fx, fields.iter().map(|f| f.index())).bytes() + } }; let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into()); lval.write_cvalue(fx, val); diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index e87f4e25891..aacf37bb5b7 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -91,7 +91,7 @@ pub(crate) fn eval_mir_constant<'tcx>( ), }, ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _) - if fx.tcx.is_static(def.did) => + if fx.tcx.is_static(def) => { span_bug!(constant.span, "MIR constant refers to static"); } diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs index 754e7931412..faff1dca23f 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_example.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, core_intrinsics, alloc_error_handler, lang_items)] +#![feature(start, core_intrinsics, lang_items)] #![no_std] extern crate alloc; @@ -21,11 +21,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[alloc_error_handler] -fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { - core::intrinsics::abort(); -} - #[lang = "eh_personality"] fn eh_personality() -> ! { loop {} diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 4bad33ee879..e90db44ece1 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -5,11 +5,10 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; -use rustc_span::symbol::sym; use crate::GccContext; -pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind) { let context = &mods.context; let usize = match tcx.sess.target.pointer_width { @@ -87,37 +86,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 } - let types = [usize, usize]; - let name = "__rust_alloc_error_handler".to_string(); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let func = context.new_function(None, FunctionType::Exported, void, &args, name, false); - - if tcx.sess.target.default_hidden_visibility { - #[cfg(feature="master")] - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - } - - let callee = alloc_error_handler_kind.fn_name(sym::oom); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let callee = context.new_function(None, FunctionType::Extern, void, &args, callee, false); - #[cfg(feature="master")] - callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - - let block = func.new_block("entry"); - - let args = args - .iter() - .enumerate() - .map(|(i, _)| func.get_param(i as i32).to_rvalue()) - .collect::<Vec<_>>(); - let _ret = context.new_call(None, callee, &args); - //llvm::LLVMSetTailCall(ret, True); - block.end_with_void_return(None); - let name = OomStrategy::SYMBOL.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); let value = tcx.sess.opts.unstable_opts.oom.should_panic(); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 0b661505acc..1a20dbcebd4 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -27,6 +27,7 @@ extern crate rustc_attr; extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_hir; extern crate rustc_macros; extern crate rustc_metadata; @@ -76,7 +77,7 @@ use rustc_codegen_ssa::target_features::supported_target_features; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; @@ -162,11 +163,11 @@ impl CodegenBackend for GccCodegenBackend { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind) -> Self::Module { let mut mods = GccContext { context: Context::default(), }; - unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); } + unsafe { allocator::codegen(tcx, &mut mods, module_name, kind); } mods } diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index a7ba2f8b695..bdea565a5a6 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -22,6 +22,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 668d9292705..fc9251dda82 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -4,7 +4,6 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; -use rustc_span::symbol::sym; use crate::debuginfo; use crate::llvm::{self, False, True}; @@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen( module_llvm: &mut ModuleLlvm, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) { let llcx = &*module_llvm.llcx; let llmod = module_llvm.llmod(); @@ -100,52 +98,6 @@ pub(crate) unsafe fn codegen( llvm::LLVMDisposeBuilder(llbuilder); } - // rust alloc error handler - let args = [usize, usize]; // size, align - - let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False); - let name = "__rust_alloc_error_handler"; - let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty); - // -> ! DIFlagNoReturn - let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); - - if tcx.sess.target.default_hidden_visibility { - llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); - } - if tcx.sess.must_emit_unwind_tables() { - let uwtable = attributes::uwtable_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } - - let callee = alloc_error_handler_kind.fn_name(sym::oom); - let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty); - // -> ! DIFlagNoReturn - attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); - llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); - - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); - - let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); - llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) - .collect::<Vec<_>>(); - let ret = llvm::LLVMRustBuildCall( - llbuilder, - ty, - callee, - args.as_ptr(), - args.len() as c_uint, - [].as_ptr(), - 0 as c_uint, - ); - llvm::LLVMSetTailCall(ret, True); - llvm::LLVMBuildRetVoid(llbuilder); - llvm::LLVMDisposeBuilder(llbuilder); - // __rust_alloc_error_handler_should_panic let name = OomStrategy::SYMBOL; let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 21a0a60b012..25fe3cb265d 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -29,7 +29,6 @@ use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{ self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility, }; @@ -1182,12 +1181,12 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( let names = get_parameter_names(cx, generics); let template_params: SmallVec<_> = iter::zip(substs, names) .filter_map(|(kind, name)| { - if let GenericArgKind::Type(ty) = kind.unpack() { + kind.as_type().map(|ty| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_di_node = type_di_node(cx, actual_type); let name = name.as_str(); - Some(unsafe { + unsafe { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), None, @@ -1195,10 +1194,8 @@ fn build_generic_type_param_di_nodes<'ll, 'tcx>( name.len(), actual_type_di_node, ) - }) - } else { - None - } + } + }) }) .collect(); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 56844c7951f..dfc226db57b 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -27,7 +27,7 @@ use rustc_hir::def_id::{DefId, DefIdMap}; use rustc_index::vec::IndexVec; use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; +use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; @@ -461,12 +461,12 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { let names = get_parameter_names(cx, generics); iter::zip(substs, names) .filter_map(|(kind, name)| { - if let GenericArgKind::Type(ty) = kind.unpack() { + kind.as_type().map(|ty| { let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty); let actual_type_metadata = type_di_node(cx, actual_type); let name = name.as_str(); - Some(unsafe { + unsafe { Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(cx), None, @@ -474,10 +474,8 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { name.len(), actual_type_metadata, )) - }) - } else { - None - } + } + }) }) .collect() } else { diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 4926f4e50c4..00b2dc1287a 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -34,7 +34,7 @@ use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::{CodegenResults, CompiledModule}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::query::Providers; @@ -115,11 +115,10 @@ impl ExtraBackendMethods for LlvmCodegenBackend { tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) -> ModuleLlvm { let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut module_llvm, module_name, kind); } module_llvm } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 09f3fe02165..c95148013eb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -552,6 +552,7 @@ pub enum ArchiveKind { K_BSD, K_DARWIN, K_COFF, + K_AIXBIG, } // LLVMRustThinLTOData diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index f820e752371..4f5cc575da6 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -137,6 +137,7 @@ impl FromStr for ArchiveKind { "bsd" => Ok(ArchiveKind::K_BSD), "darwin" => Ok(ArchiveKind::K_DARWIN), "coff" => Ok(ArchiveKind::K_COFF), + "aix_big" => Ok(ArchiveKind::K_AIXBIG), _ => Err(()), } } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index c55991e00d3..bd1ac6b7bad 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" test = false [dependencies] -ar_archive_writer = "0.1.1" +ar_archive_writer = "0.1.3" bitflags = "1.2.1" cc = "1.0.69" itertools = "0.10.1" @@ -29,6 +29,7 @@ rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } rustc_type_ir = { path = "../rustc_type_ir" } rustc_attr = { path = "../rustc_attr" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index 66ec8f5f57d..1c464b3eca4 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -233,6 +233,7 @@ impl<'a> ArArchiveBuilder<'a> { "bsd" => ArchiveKind::Bsd, "darwin" => ArchiveKind::Darwin, "coff" => ArchiveKind::Coff, + "aix_big" => ArchiveKind::AixBig, kind => { self.sess.emit_fatal(UnknownArchiveKind { kind }); } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d0fd3cd7666..bda0cf764e5 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -219,7 +219,7 @@ fn exported_symbols_provider_local( for symbol_name in ALLOCATOR_METHODS .iter() .map(|method| format!("__rust_{}", method.name)) - .chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()]) + .chain([OomStrategy::SYMBOL.to_string()]) { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); @@ -333,7 +333,7 @@ fn exported_symbols_provider_local( match *mono_item { MonoItem::Fn(Instance { def: InstanceDef::Item(def), substs }) => { if substs.non_erasable_generics().next().is_some() { - let symbol = ExportedSymbol::Generic(def.did, substs); + let symbol = ExportedSymbol::Generic(def, substs); symbols.push(( symbol, SymbolExportInfo { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c5ca7936a2b..3e9d29df02c 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -635,16 +635,9 @@ pub fn codegen_crate<B: ExtraBackendMethods>( if let Some(kind) = allocator_kind_for_codegen(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); - let module_llvm = tcx.sess.time("write_allocator_module", || { - backend.codegen_allocator( - tcx, - &llmod_id, - kind, - // If allocator_kind is Some then alloc_error_handler_kind must - // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), - ) - }); + let module_llvm = tcx + .sess + .time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id, kind)); ongoing_codegen.submit_pre_codegened_module_to_llvm( tcx, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 0ab12314b3c..26d55618b49 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -25,8 +25,8 @@ use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def_id::CrateNum; -use rustc_macros::fluent_messages; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs index 2421acab471..81b49afb883 100644 --- a/compiler/rustc_codegen_ssa/src/meth.rs +++ b/compiler/rustc_codegen_ssa/src/meth.rs @@ -67,10 +67,10 @@ impl<'a, 'tcx> VirtualIndex { /// ref of the type. fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> { for arg in ty.peel_refs().walk() { - if let GenericArgKind::Type(ty) = arg.unpack() { - if let ty::Dynamic(data, _, _) = ty.kind() { - return data.principal().expect("expected principal trait object"); - } + if let GenericArgKind::Type(ty) = arg.unpack() + && let ty::Dynamic(data, _, _) = ty.kind() + { + return data.principal().expect("expected principal trait object"); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d049bafb821..b67230cf498 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -494,6 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { + self.set_debug_loc(bx, var.source_info); let base = Self::spill_operand_to_stack( &operand, Some(var.name.to_string()), diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d88226f5db0..94de19a9c29 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::Operand; use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; +use rustc_session::config::OptLevel; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_target::abi::{self, FIRST_VARIANT}; @@ -231,10 +232,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { (ScalarOrZst::Scalar(in_scalar), ScalarOrZst::Scalar(out_scalar)) if in_scalar.size(self.cx) == out_scalar.size(self.cx) => { + let operand_bty = bx.backend_type(operand.layout); let cast_bty = bx.backend_type(cast); - Some(OperandValue::Immediate( - self.transmute_immediate(bx, imm, in_scalar, out_scalar, cast_bty), - )) + Some(OperandValue::Immediate(self.transmute_immediate( + bx, + imm, + in_scalar, + operand_bty, + out_scalar, + cast_bty, + ))) } _ => None, } @@ -250,11 +257,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { && in_a.size(self.cx) == out_a.size(self.cx) && in_b.size(self.cx) == out_b.size(self.cx) { + let in_a_ibty = bx.scalar_pair_element_backend_type(operand.layout, 0, false); + let in_b_ibty = bx.scalar_pair_element_backend_type(operand.layout, 1, false); let out_a_ibty = bx.scalar_pair_element_backend_type(cast, 0, false); let out_b_ibty = bx.scalar_pair_element_backend_type(cast, 1, false); Some(OperandValue::Pair( - self.transmute_immediate(bx, imm_a, in_a, out_a, out_a_ibty), - self.transmute_immediate(bx, imm_b, in_b, out_b, out_b_ibty), + self.transmute_immediate(bx, imm_a, in_a, in_a_ibty, out_a, out_a_ibty), + self.transmute_immediate(bx, imm_b, in_b, in_b_ibty, out_b, out_b_ibty), )) } else { None @@ -273,6 +282,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx: &mut Bx, mut imm: Bx::Value, from_scalar: abi::Scalar, + from_backend_ty: Bx::Type, to_scalar: abi::Scalar, to_backend_ty: Bx::Type, ) -> Bx::Value { @@ -280,6 +290,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { use abi::Primitive::*; imm = bx.from_immediate(imm); + + // When scalars are passed by value, there's no metadata recording their + // valid ranges. For example, `char`s are passed as just `i32`, with no + // way for LLVM to know that they're 0x10FFFF at most. Thus we assume + // the range of the input value too, not just the output range. + self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty); + imm = match (from_scalar.primitive(), to_scalar.primitive()) { (Int(..) | F32 | F64, Int(..) | F32 | F64) => bx.bitcast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), @@ -294,10 +311,55 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.bitcast(int_imm, to_backend_ty) } }; + self.assume_scalar_range(bx, imm, to_scalar, to_backend_ty); imm = bx.to_immediate_scalar(imm, to_scalar); imm } + fn assume_scalar_range( + &self, + bx: &mut Bx, + imm: Bx::Value, + scalar: abi::Scalar, + backend_ty: Bx::Type, + ) { + if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less) + // For now, the critical niches are all over `Int`eger values. + // Should floating-point values or pointers ever get more complex + // niches, then this code will probably want to handle them too. + || !matches!(scalar.primitive(), abi::Primitive::Int(..)) + || scalar.is_always_valid(self.cx) + { + return; + } + + let abi::WrappingRange { start, end } = scalar.valid_range(self.cx); + + if start <= end { + if start > 0 { + let low = bx.const_uint_big(backend_ty, start); + let cmp = bx.icmp(IntPredicate::IntUGE, imm, low); + bx.assume(cmp); + } + + let type_max = scalar.size(self.cx).unsigned_int_max(); + if end < type_max { + let high = bx.const_uint_big(backend_ty, end); + let cmp = bx.icmp(IntPredicate::IntULE, imm, high); + bx.assume(cmp); + } + } else { + let low = bx.const_uint_big(backend_ty, start); + let cmp_low = bx.icmp(IntPredicate::IntUGE, imm, low); + + let high = bx.const_uint_big(backend_ty, end); + let cmp_high = bx.icmp(IntPredicate::IntULE, imm, high); + + let or = bx.or(cmp_low, cmp_high); + bx.assume(or); + } + } + pub fn codegen_rvalue_unsized( &mut self, bx: &mut Bx, @@ -604,13 +666,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } - mir::Rvalue::NullaryOp(null_op, ty) => { + mir::Rvalue::NullaryOp(ref null_op, ty) => { let ty = self.monomorphize(ty); assert!(bx.cx().type_is_sized(ty)); let layout = bx.cx().layout_of(ty); let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), + mir::NullOp::OffsetOf(fields) => { + layout.offset_of_subfield(bx.cx(), fields.iter().map(|f| f.index())).bytes() + } }; let val = bx.cx().const_usize(val); let tcx = self.cx.tcx(); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 64bebe50ddb..2e88b7ce219 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -123,7 +123,6 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) -> Self::Module; /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index 98ac36c1ced..74030a43c50 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -14,6 +14,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 4bd6fe19931..99f180f475d 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -296,12 +296,12 @@ pub fn eval_to_allocation_raw_provider<'tcx>( } let cid = key.value; - let def = cid.instance.def.with_opt_param(); - let is_static = tcx.is_static(def.did); + let def = cid.instance.def.def_id(); + let is_static = tcx.is_static(def); let mut ecx = InterpCx::new( tcx, - tcx.def_span(def.did), + tcx.def_span(def), key.param_env, // Statics (and promoteds inside statics) may access other statics, because unlike consts // they do not have to behave "as if" they were evaluated at runtime. diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index a5dfd1072f0..814b67b46ec 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -375,9 +375,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { match instance { ty::InstanceDef::Item(def) => { - if ecx.tcx.is_ctfe_mir_available(def.did) { - Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def)) - } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst { + if ecx.tcx.is_ctfe_mir_available(def) { + Ok(ecx.tcx.mir_for_ctfe(def)) + } else if ecx.tcx.def_kind(def) == DefKind::AssocConst { let guar = ecx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", @@ -386,7 +386,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, // so this should be unreachable. - let path = ecx.tcx.def_path_str(def.did); + let path = ecx.tcx.def_path_str(def); bug!("trying to call extern function `{path}` at compile-time"); } } @@ -410,9 +410,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, // Execution might have wandered off into other crates, so we cannot do a stability- // sensitive check here. But we can at least rule out functions that are not const // at all. - if !ecx.tcx.is_const_fn_raw(def.did) { + if !ecx.tcx.is_const_fn_raw(def) { // allow calling functions inside a trait marked with #[const_trait]. - if !ecx.tcx.is_const_default_method(def.did) { + if !ecx.tcx.is_const_default_method(def) { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index b5b5cc4f196..6030498e946 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -461,10 +461,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { instance: ty::InstanceDef<'tcx>, promoted: Option<mir::Promoted>, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { - let def = instance.with_opt_param(); trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); let body = if let Some(promoted) = promoted { - &self.tcx.promoted_mir_opt_const_arg(def)[promoted] + let def = instance.def_id(); + &self.tcx.promoted_mir(def)[promoted] } else { M::load_mir(self, instance)? }; @@ -502,13 +502,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// The `substs` are assumed to already be in our interpreter "universe" (param_env). pub(super) fn resolve( &self, - def: ty::WithOptConstParam<DefId>, + def: DefId, substs: SubstsRef<'tcx>, ) -> InterpResult<'tcx, ty::Instance<'tcx>> { trace!("resolve: {:?}, {:#?}", def, substs); trace!("param_env: {:#?}", self.param_env); trace!("substs: {:#?}", substs); - match ty::Instance::resolve_opt_const_arg(*self.tcx, self.param_env, def, substs) { + match ty::Instance::resolve(*self.tcx, self.param_env, def, substs) { Ok(Some(instance)) => Ok(instance), Ok(None) => throw_inval!(TooGeneric), diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 9a366364e76..319b80d66e1 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -113,8 +113,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, - // Statements we do not track. - PlaceMention(..) | AscribeUserType(..) => {} + // Evaluate the place expression, without reading from it. + PlaceMention(box place) => { + let _ = self.eval_place(*place)?; + } + + // This exists purely to guide borrowck lifetime inference, and does not have + // an operational effect. + AscribeUserType(..) => {} // Currently, Miri discards Coverage statements. Coverage statements are only injected // via an optional compile time MIR pass and have no side effects. Since Coverage @@ -280,20 +286,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.write_immediate(*val, &dest)?; } - NullaryOp(null_op, ty) => { + NullaryOp(ref null_op, ty) => { let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?; let layout = self.layout_of(ty)?; - if layout.is_unsized() { + if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op && layout.is_unsized() { // FIXME: This should be a span_bug (#80742) self.tcx.sess.delay_span_bug( self.frame().current_span(), - &format!("Nullary MIR operator called for unsized type {}", ty), + &format!("{null_op:?} MIR operator called for unsized type {ty}"), ); throw_inval!(SizeOfUnsizedType(ty)); } let val = match null_op { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), + mir::NullOp::OffsetOf(fields) => { + layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes() + } }; self.write_scalar(Scalar::from_target_usize(val, self), &dest)?; } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index a07702f7d9b..df387920010 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -83,8 +83,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (fn_val, self.fn_abi_of_fn_ptr(fn_sig_binder, extra_args)?, false) } ty::FnDef(def_id, substs) => { - let instance = - self.resolve(ty::WithOptConstParam::unknown(def_id), substs)?; + let instance = self.resolve(def_id, substs)?; ( FnVal::Instance(instance), self.fn_abi_of_instance(instance, extra_args)?, diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index bf2b4ee69ab..7cb19744987 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -36,7 +36,7 @@ where ty::Closure(def_id, substs) | ty::Generator(def_id, substs, ..) | ty::FnDef(def_id, substs) => { - let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)); + let instance = ty::InstanceDef::Item(def_id); let unused_params = self.tcx.unused_generic_params(instance); for (index, subst) in substs.into_iter().enumerate() { let index = index diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 5ab389d04c7..1b66eca97a5 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -34,7 +34,7 @@ pub mod transform; pub mod util; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty; use rustc_middle::ty::query::Providers; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 9dad9479053..696c4517700 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -558,7 +558,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::Cast(_, _, _) => {} - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {} Rvalue::ShallowInitBox(_, _) => {} Rvalue::UnaryOp(_, operand) => { @@ -874,7 +874,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { debug!("Resolving ({:?}) -> {:?}", callee, instance); if let Ok(Some(func)) = instance { if let InstanceDef::Item(def) = func.def { - callee = def.did; + callee = def; } } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 4fe842856aa..6c11edb742c 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -610,10 +610,11 @@ pub struct RawPtrComparison; impl<'tcx> NonConstOp<'tcx> for RawPtrComparison { fn build_error( &self, - _: &ConstCx<'_, 'tcx>, + ccx: &ConstCx<'_, 'tcx>, span: Span, ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> { - span_bug!(span, "raw ptr comparison should already be caught in the trait system"); + // FIXME(const_trait_impl): revert to span_bug? + ccx.tcx.sess.create_err(errors::RawPtrComparisonErr { span }) } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 6758cba2eed..bf688f2b34e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -364,9 +364,8 @@ where assert!(promoted.is_none() || Q::ALLOW_PROMOTED); // Don't peek inside trait associated constants. - if promoted.is_none() && cx.tcx.trait_of_item(def.did).is_none() { - assert_eq!(def.const_param_did, None, "expected associated const: {def:?}"); - let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def.did); + if promoted.is_none() && cx.tcx.trait_of_item(def).is_none() { + let qualifs = cx.tcx.at(constant.span).mir_const_qualif(def); if !Q::in_qualifs(&qualifs) { return false; diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 7919aed097a..e978e344283 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -514,6 +514,7 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::NullaryOp(op, _) => match op { NullOp::SizeOf => {} NullOp::AlignOf => {} + NullOp::OffsetOf(_) => {} }, Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable), @@ -828,7 +829,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Body<'tcx> { - let def = self.source.source.with_opt_param(); + let def = self.source.source.def_id(); let mut rvalue = { let promoted = &mut self.promoted; let promoted_id = Promoted::new(next_promoted_id); @@ -836,7 +837,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut promoted_operand = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new(ty, span); - let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def.did)); + let substs = tcx.erase_regions(InternalSubsts::identity_for_item(tcx, def)); let uneval = mir::UnevaluatedConst { def, substs, promoted: Some(promoted_id) }; Operand::Constant(Box::new(Constant { diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 8aee019e994..b8809d29c77 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -8,9 +8,10 @@ use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{ traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location, - MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem, - RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, - TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, START_BLOCK, + MirPass, MirPhase, NonDivergingIntrinsic, NullOp, Operand, Place, PlaceElem, PlaceRef, + ProjectionElem, RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, + Terminator, TerminatorKind, UnOp, UnwindAction, VarDebugInfo, VarDebugInfoContents, + START_BLOCK, }; use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; @@ -711,10 +712,54 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } + Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => { + let fail_out_of_bounds = |this: &Self, location, field, ty| { + this.fail(location, format!("Out of bounds field {field:?} for {ty:?}")); + }; + + let mut current_ty = *container; + + for field in fields.iter() { + match current_ty.kind() { + ty::Tuple(fields) => { + let Some(&f_ty) = fields.get(field.as_usize()) else { + fail_out_of_bounds(self, location, field, current_ty); + return; + }; + + current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + } + ty::Adt(adt_def, substs) => { + if adt_def.is_enum() { + self.fail( + location, + format!("Cannot get field offset from enum {current_ty:?}"), + ); + return; + } + + let Some(field) = adt_def.non_enum_variant().fields.get(field) else { + fail_out_of_bounds(self, location, field, current_ty); + return; + }; + + let f_ty = field.ty(self.tcx, substs); + current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); + } + _ => { + self.fail( + location, + format!("Cannot get field offset from non-adt type {current_ty:?}"), + ); + return; + } + } + } + } Rvalue::Repeat(_, _) | Rvalue::ThreadLocalRef(_) | Rvalue::AddressOf(_, _) - | Rvalue::NullaryOp(_, _) + | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::Discriminant(_) => {} } self.super_rvalue(rvalue, location); @@ -757,14 +802,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } - StatementKind::PlaceMention(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { - self.fail( - location, - "`PlaceMention` should have been removed after drop lowering phase", - ); - } - } StatementKind::AscribeUserType(..) => { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( @@ -874,6 +911,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { StatementKind::StorageDead(_) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(..) | StatementKind::Nop => {} } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 405ae99395b..426d2c4034b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -35,6 +35,7 @@ #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +#![deny(unsafe_op_in_unsafe_fn)] #[macro_use] extern crate tracing; diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs index ef37a606f31..ca908671ae5 100644 --- a/compiler/rustc_data_structures/src/memmap.rs +++ b/compiler/rustc_data_structures/src/memmap.rs @@ -13,7 +13,8 @@ pub struct Mmap(Vec<u8>); impl Mmap { #[inline] pub unsafe fn map(file: File) -> io::Result<Self> { - memmap2::Mmap::map(&file).map(Mmap) + // Safety: this is in fact not safe. + unsafe { memmap2::Mmap::map(&file).map(Mmap) } } } diff --git a/compiler/rustc_data_structures/src/sip128.rs b/compiler/rustc_data_structures/src/sip128.rs index d849fe0373f..4a0ed87f77c 100644 --- a/compiler/rustc_data_structures/src/sip128.rs +++ b/compiler/rustc_data_structures/src/sip128.rs @@ -96,28 +96,30 @@ macro_rules! compress { unsafe fn copy_nonoverlapping_small(src: *const u8, dst: *mut u8, count: usize) { debug_assert!(count <= 8); - if count == 8 { - ptr::copy_nonoverlapping(src, dst, 8); - return; - } + unsafe { + if count == 8 { + ptr::copy_nonoverlapping(src, dst, 8); + return; + } - let mut i = 0; - if i + 3 < count { - ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4); - i += 4; - } + let mut i = 0; + if i + 3 < count { + ptr::copy_nonoverlapping(src.add(i), dst.add(i), 4); + i += 4; + } - if i + 1 < count { - ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2); - i += 2 - } + if i + 1 < count { + ptr::copy_nonoverlapping(src.add(i), dst.add(i), 2); + i += 2 + } - if i < count { - *dst.add(i) = *src.add(i); - i += 1; - } + if i < count { + *dst.add(i) = *src.add(i); + i += 1; + } - debug_assert_eq!(i, count); + debug_assert_eq!(i, count); + } } // # Implementation @@ -232,38 +234,40 @@ impl SipHasher128 { // overflow) if it wasn't already. #[inline(never)] unsafe fn short_write_process_buffer<const LEN: usize>(&mut self, bytes: [u8; LEN]) { - let nbuf = self.nbuf; - debug_assert!(LEN <= 8); - debug_assert!(nbuf < BUFFER_SIZE); - debug_assert!(nbuf + LEN >= BUFFER_SIZE); - debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE); + unsafe { + let nbuf = self.nbuf; + debug_assert!(LEN <= 8); + debug_assert!(nbuf < BUFFER_SIZE); + debug_assert!(nbuf + LEN >= BUFFER_SIZE); + debug_assert!(nbuf + LEN < BUFFER_WITH_SPILL_SIZE); + + // Copy first part of input into end of buffer, possibly into spill + // element. The memcpy call is optimized away because the size is known. + let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); + ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN); + + // Process buffer. + for i in 0..BUFFER_CAPACITY { + let elem = self.buf.get_unchecked(i).assume_init().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + } - // Copy first part of input into end of buffer, possibly into spill - // element. The memcpy call is optimized away because the size is known. - let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); - ptr::copy_nonoverlapping(bytes.as_ptr(), dst, LEN); - - // Process buffer. - for i in 0..BUFFER_CAPACITY { - let elem = self.buf.get_unchecked(i).assume_init().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; + // Copy remaining input into start of buffer by copying LEN - 1 + // elements from spill (at most LEN - 1 bytes could have overflowed + // into the spill). The memcpy call is optimized away because the size + // is known. And the whole copy is optimized away for LEN == 1. + let dst = self.buf.as_mut_ptr() as *mut u8; + let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; + ptr::copy_nonoverlapping(src, dst, LEN - 1); + + // This function should only be called when the write fills the buffer. + // Therefore, when LEN == 1, the new `self.nbuf` must be zero. + // LEN is statically known, so the branch is optimized away. + self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE }; + self.processed += BUFFER_SIZE; } - - // Copy remaining input into start of buffer by copying LEN - 1 - // elements from spill (at most LEN - 1 bytes could have overflowed - // into the spill). The memcpy call is optimized away because the size - // is known. And the whole copy is optimized away for LEN == 1. - let dst = self.buf.as_mut_ptr() as *mut u8; - let src = self.buf.get_unchecked(BUFFER_SPILL_INDEX) as *const _ as *const u8; - ptr::copy_nonoverlapping(src, dst, LEN - 1); - - // This function should only be called when the write fills the buffer. - // Therefore, when LEN == 1, the new `self.nbuf` must be zero. - // LEN is statically known, so the branch is optimized away. - self.nbuf = if LEN == 1 { 0 } else { nbuf + LEN - BUFFER_SIZE }; - self.processed += BUFFER_SIZE; } // A write function for byte slices. @@ -301,57 +305,59 @@ impl SipHasher128 { // containing the byte offset `self.nbuf`. #[inline(never)] unsafe fn slice_write_process_buffer(&mut self, msg: &[u8]) { - let length = msg.len(); - let nbuf = self.nbuf; - debug_assert!(nbuf < BUFFER_SIZE); - debug_assert!(nbuf + length >= BUFFER_SIZE); - - // Always copy first part of input into current element of buffer. - // This function should only be called when the write fills the buffer, - // so we know that there is enough input to fill the current element. - let valid_in_elem = nbuf % ELEM_SIZE; - let needed_in_elem = ELEM_SIZE - valid_in_elem; - - let src = msg.as_ptr(); - let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); - copy_nonoverlapping_small(src, dst, needed_in_elem); - - // Process buffer. + unsafe { + let length = msg.len(); + let nbuf = self.nbuf; + debug_assert!(nbuf < BUFFER_SIZE); + debug_assert!(nbuf + length >= BUFFER_SIZE); + + // Always copy first part of input into current element of buffer. + // This function should only be called when the write fills the buffer, + // so we know that there is enough input to fill the current element. + let valid_in_elem = nbuf % ELEM_SIZE; + let needed_in_elem = ELEM_SIZE - valid_in_elem; + + let src = msg.as_ptr(); + let dst = (self.buf.as_mut_ptr() as *mut u8).add(nbuf); + copy_nonoverlapping_small(src, dst, needed_in_elem); + + // Process buffer. + + // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) / + // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0. + // We know that is true, because last step ensured we have a full + // element in the buffer. + let last = nbuf / ELEM_SIZE + 1; + + for i in 0..last { + let elem = self.buf.get_unchecked(i).assume_init().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + } - // Using `nbuf / ELEM_SIZE + 1` rather than `(nbuf + needed_in_elem) / - // ELEM_SIZE` to show the compiler that this loop's upper bound is > 0. - // We know that is true, because last step ensured we have a full - // element in the buffer. - let last = nbuf / ELEM_SIZE + 1; + // Process the remaining element-sized chunks of input. + let mut processed = needed_in_elem; + let input_left = length - processed; + let elems_left = input_left / ELEM_SIZE; + let extra_bytes_left = input_left % ELEM_SIZE; + + for _ in 0..elems_left { + let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le(); + self.state.v3 ^= elem; + Sip13Rounds::c_rounds(&mut self.state); + self.state.v0 ^= elem; + processed += ELEM_SIZE; + } - for i in 0..last { - let elem = self.buf.get_unchecked(i).assume_init().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; - } + // Copy remaining input into start of buffer. + let src = msg.as_ptr().add(processed); + let dst = self.buf.as_mut_ptr() as *mut u8; + copy_nonoverlapping_small(src, dst, extra_bytes_left); - // Process the remaining element-sized chunks of input. - let mut processed = needed_in_elem; - let input_left = length - processed; - let elems_left = input_left / ELEM_SIZE; - let extra_bytes_left = input_left % ELEM_SIZE; - - for _ in 0..elems_left { - let elem = (msg.as_ptr().add(processed) as *const u64).read_unaligned().to_le(); - self.state.v3 ^= elem; - Sip13Rounds::c_rounds(&mut self.state); - self.state.v0 ^= elem; - processed += ELEM_SIZE; + self.nbuf = extra_bytes_left; + self.processed += nbuf + processed; } - - // Copy remaining input into start of buffer. - let src = msg.as_ptr().add(processed); - let dst = self.buf.as_mut_ptr() as *mut u8; - copy_nonoverlapping_small(src, dst, extra_bytes_left); - - self.nbuf = extra_bytes_left; - self.processed += nbuf + processed; } #[inline] diff --git a/compiler/rustc_data_structures/src/tagged_ptr.rs b/compiler/rustc_data_structures/src/tagged_ptr.rs index c26bffac678..8568aac67c0 100644 --- a/compiler/rustc_data_structures/src/tagged_ptr.rs +++ b/compiler/rustc_data_structures/src/tagged_ptr.rs @@ -153,7 +153,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> { #[inline] unsafe fn from_ptr(ptr: NonNull<T>) -> Self { // Safety: `ptr` comes from `into_ptr` which calls `Box::into_raw` - Box::from_raw(ptr.as_ptr()) + unsafe { Box::from_raw(ptr.as_ptr()) } } } @@ -169,7 +169,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> { #[inline] unsafe fn from_ptr(ptr: NonNull<T>) -> Self { // Safety: `ptr` comes from `into_ptr` which calls `Rc::into_raw` - Rc::from_raw(ptr.as_ptr()) + unsafe { Rc::from_raw(ptr.as_ptr()) } } } @@ -185,7 +185,7 @@ unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> { #[inline] unsafe fn from_ptr(ptr: NonNull<T>) -> Self { // Safety: `ptr` comes from `into_ptr` which calls `Arc::into_raw` - Arc::from_raw(ptr.as_ptr()) + unsafe { Arc::from_raw(ptr.as_ptr()) } } } @@ -201,7 +201,7 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T { unsafe fn from_ptr(ptr: NonNull<T>) -> Self { // Safety: // `ptr` comes from `into_ptr` which gets the pointer from a reference - ptr.as_ref() + unsafe { ptr.as_ref() } } } @@ -217,7 +217,7 @@ unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T { unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self { // Safety: // `ptr` comes from `into_ptr` which gets the pointer from a reference - ptr.as_mut() + unsafe { ptr.as_mut() } } } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index 73a1f79a020..cc4c5a0cacd 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -18,6 +18,7 @@ rustc_const_eval = { path = "../rustc_const_eval" } rustc_error_messages = { path = "../rustc_error_messages" } rustc_expand = { path = "../rustc_expand" } rustc_hir_typeck = { path = "../rustc_hir_typeck" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_incremental = { path = "../rustc_incremental" } rustc_infer = { path = "../rustc_infer" } rustc_mir_build = { path = "../rustc_mir_build" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index b9f0e756e65..1a80b4fc314 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -28,10 +28,10 @@ use rustc_errors::{ DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl, }; use rustc_feature::find_gated_cfg; +use rustc_fluent_macro::fluent_messages; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; -use rustc_macros::fluent_messages; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 446c6832cb7..ee64b18d3f6 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -488,12 +488,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR tree"); for did in tcx.hir().body_owners() { - let _ = writeln!( - out, - "{:?}:\n{}\n", - did, - tcx.thir_tree(ty::WithOptConstParam::unknown(did)) - ); + let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did)); } out } @@ -503,12 +498,7 @@ fn print_with_analysis(tcx: TyCtxt<'_>, ppm: PpMode) -> Result<(), ErrorGuarante abort_on_err(rustc_hir_analysis::check_crate(tcx), tcx.sess); debug!("pretty printing THIR flat"); for did in tcx.hir().body_owners() { - let _ = writeln!( - out, - "{:?}:\n{}\n", - did, - tcx.thir_flat(ty::WithOptConstParam::unknown(did)) - ); + let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did)); } out } diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 27783d60be4..481c94266f2 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -11,6 +11,7 @@ fluent-syntax = "0.11" intl-memoizer = "0.5.1" rustc_baked_icu_data = { path = "../rustc_baked_icu_data" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6f319b96f2f..88d94c93bf5 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -12,7 +12,8 @@ use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker}; use rustc_data_structures::sync::Lrc; -use rustc_macros::{fluent_messages, Decodable, Encodable}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Decodable, Encodable}; use rustc_span::Span; use std::borrow::Cow; use std::error::Error; diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index e1ead08ea66..46ace8eb2dd 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -10,6 +10,7 @@ tracing = "0.1" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_error_messages = { path = "../rustc_error_messages" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 8c76d5e010f..2498ae2b7bc 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -1336,6 +1336,7 @@ impl EmitterWriter { // see? for (text, style) in msg.iter() { let text = self.translate_message(text, args).map_err(Report::new).unwrap(); + let text = &normalize_whitespace(&text); let lines = text.split('\n').collect::<Vec<_>>(); if lines.len() > 1 { for (i, line) in lines.iter().enumerate() { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 26791304ef1..b65a636d770 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -38,8 +38,8 @@ pub use rustc_error_messages::{ fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; pub use rustc_lint_defs::{pluralize, Applicability}; -use rustc_macros::fluent_messages; use rustc_span::source_map::SourceMap; pub use rustc_span::ErrorGuaranteed; use rustc_span::{Loc, Span}; diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index c971714e05b..2dae0e3f53c 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -16,6 +16,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index ced7531c3fe..83a5043b0aa 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -21,7 +21,7 @@ extern crate tracing; extern crate proc_macro as pm; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod placeholders; mod proc_macro_server; diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 341ae18541b..1e7d07bc22d 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -18,7 +18,7 @@ use rustc_span::def_id::CrateNum; use rustc_span::symbol::{self, sym, Symbol}; use rustc_span::{BytePos, FileName, Pos, SourceFile, Span}; use smallvec::{smallvec, SmallVec}; -use std::ops::Bound; +use std::ops::{Bound, Range}; trait FromInternal<T> { fn from_internal(x: T) -> Self; @@ -634,6 +634,15 @@ impl server::Span for Rustc<'_, '_> { span.source_callsite() } + fn byte_range(&mut self, span: Self::Span) -> Range<usize> { + let source_map = self.sess().source_map(); + + let relative_start_pos = source_map.lookup_byte_offset(span.lo()).pos; + let relative_end_pos = source_map.lookup_byte_offset(span.hi()).pos; + + Range { start: relative_start_pos.0 as usize, end: relative_end_pos.0 as usize } + } + fn start(&mut self, span: Self::Span) -> LineColumn { let loc = self.sess().source_map().lookup_char_pos(span.lo()); LineColumn { line: loc.line, column: loc.col.to_usize() } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 48f5bd1cb50..594e6cca912 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -291,8 +291,6 @@ declare_features! ( (active, abi_x86_interrupt, "1.17.0", Some(40180), None), /// Allows additional const parameter types, such as `&'static str` or user defined types (incomplete, adt_const_params, "1.56.0", Some(95174), None), - /// Allows defining an `#[alloc_error_handler]`. - (active, alloc_error_handler, "1.29.0", Some(51540), None), /// Allows trait methods with arbitrary self types. (active, arbitrary_self_types, "1.23.0", Some(44874), None), /// Allows using `const` operands in inline assembly. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 876a31abdf8..c978d6472c8 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -47,6 +47,8 @@ declare_features! ( (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), + /// Allows defining an `#[alloc_error_handler]`. + (removed, alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(51540), None, Some("now handled by panic handler")), (removed, allocator, "1.0.0", None, None, None), /// Allows a test to fail without failing the whole suite. (removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")), diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml new file mode 100644 index 00000000000..f5a6585b5c6 --- /dev/null +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rustc_fluent_macro" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +annotate-snippets = "0.9" +fluent-bundle = "0.15.2" +fluent-syntax = "0.11" +syn = { version = "2", features = ["full"] } +proc-macro2 = "1" +quote = "1" +unic-langid = { version = "0.9.0", features = ["macros"] } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs index 607d51f5608..9dffc9a7645 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_fluent_macro/src/fluent.rs @@ -68,7 +68,7 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream { .into() } -/// See [rustc_macros::fluent_messages]. +/// See [rustc_fluent_macro::fluent_messages]. pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let crate_name = std::env::var("CARGO_PKG_NAME") // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs new file mode 100644 index 00000000000..a01643cd67d --- /dev/null +++ b/compiler/rustc_fluent_macro/src/lib.rs @@ -0,0 +1,64 @@ +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(proc_macro_diagnostic)] +#![feature(proc_macro_span)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] +#![allow(rustc::default_hash_types)] + +use proc_macro::TokenStream; + +mod fluent; + +/// Implements the `fluent_messages` macro, which performs compile-time validation of the +/// compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same +/// messages) and generates constants that make using those messages in diagnostics more ergonomic. +/// +/// For example, given the following invocation of the macro.. +/// +/// ```ignore (rust) +/// fluent_messages! { "./typeck.ftl" } +/// ``` +/// ..where `typeck.ftl` has the following contents.. +/// +/// ```fluent +/// typeck_field_multiply_specified_in_initializer = +/// field `{$ident}` specified more than once +/// .label = used more than once +/// .label_previous_use = first use of `{$ident}` +/// ``` +/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and +/// will generate the following code: +/// +/// ```ignore (rust) +/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); +/// +/// mod fluent_generated { +/// mod typeck { +/// pub const field_multiply_specified_in_initializer: DiagnosticMessage = +/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer"); +/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage = +/// DiagnosticMessage::fluent_attr( +/// "typeck_field_multiply_specified_in_initializer", +/// "previous_use_label" +/// ); +/// } +/// } +/// ``` +/// When emitting a diagnostic, the generated constants can be used as follows: +/// +/// ```ignore (rust) +/// let mut err = sess.struct_span_err( +/// span, +/// fluent::typeck::field_multiply_specified_in_initializer +/// ); +/// err.span_default_label(span); +/// err.span_label( +/// previous_use_span, +/// fluent::typeck::field_multiply_specified_in_initializer_label_previous_use +/// ); +/// err.emit(); +/// ``` +#[proc_macro] +pub fn fluent_messages(input: TokenStream) -> TokenStream { + fluent::fluent_messages(input) +} diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 3e5b3c498ee..e213623e06d 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,57 +1,17 @@ /// This higher-order macro declares a list of types which can be allocated by `Arena`. -/// -/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`, -/// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. +/// Note that all `Copy` types can be allocated by default and need not be specified here. #[macro_export] macro_rules! arena_types { ($macro:path) => ( $macro!([ // HIR types [] hir_krate: rustc_hir::Crate<'tcx>, - [] arm: rustc_hir::Arm<'tcx>, - [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, - [] closure: rustc_hir::Closure<'tcx>, - [] block: rustc_hir::Block<'tcx>, - [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, - [] body: rustc_hir::Body<'tcx>, - [] generics: rustc_hir::Generics<'tcx>, - [] generic_arg: rustc_hir::GenericArg<'tcx>, - [] generic_args: rustc_hir::GenericArgs<'tcx>, - [] generic_bound: rustc_hir::GenericBound<'tcx>, - [] generic_param: rustc_hir::GenericParam<'tcx>, - [] expr: rustc_hir::Expr<'tcx>, - [] impl_: rustc_hir::Impl<'tcx>, - [] let_expr: rustc_hir::Let<'tcx>, - [] expr_field: rustc_hir::ExprField<'tcx>, - [] pat_field: rustc_hir::PatField<'tcx>, - [] fn_decl: rustc_hir::FnDecl<'tcx>, - [] foreign_item: rustc_hir::ForeignItem<'tcx>, - [] foreign_item_ref: rustc_hir::ForeignItemRef, - [] impl_item: rustc_hir::ImplItem<'tcx>, - [] impl_item_ref: rustc_hir::ImplItemRef, - [] item: rustc_hir::Item<'tcx>, - [] inline_asm: rustc_hir::InlineAsm<'tcx>, - [] local: rustc_hir::Local<'tcx>, - [] mod_: rustc_hir::Mod<'tcx>, [] owner_info: rustc_hir::OwnerInfo<'tcx>, - [] param: rustc_hir::Param<'tcx>, - [] pat: rustc_hir::Pat<'tcx>, - [] path: rustc_hir::Path<'tcx>, [] use_path: rustc_hir::UsePath<'tcx>, - [] path_segment: rustc_hir::PathSegment<'tcx>, - [] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>, - [] qpath: rustc_hir::QPath<'tcx>, - [] stmt: rustc_hir::Stmt<'tcx>, - [] field_def: rustc_hir::FieldDef<'tcx>, - [] trait_item: rustc_hir::TraitItem<'tcx>, - [] trait_item_ref: rustc_hir::TraitItemRef, - [] ty: rustc_hir::Ty<'tcx>, - [] type_binding: rustc_hir::TypeBinding<'tcx>, - [] variant: rustc_hir::Variant<'tcx>, - [] where_predicate: rustc_hir::WherePredicate<'tcx>, [] lit: rustc_hir::Lit, + [] macro_def: rustc_ast::MacroDef, ]); ) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index fb0c087bfb4..68db8f3e272 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -182,7 +182,7 @@ impl Lifetime { /// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Path<'hir, R = Res> { pub span: Span, /// The resolution for the path. @@ -202,7 +202,7 @@ impl Path<'_> { /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, @@ -243,13 +243,13 @@ impl<'hir> PathSegment<'hir> { } } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct ConstArg { pub value: AnonConst, pub span: Span, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { pub hir_id: HirId, pub span: Span, @@ -261,7 +261,7 @@ impl InferArg { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericArg<'hir> { Lifetime(&'hir Lifetime), Type(&'hir Ty<'hir>), @@ -318,7 +318,7 @@ impl GenericArg<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericArgs<'hir> { /// The generic arguments for this path segment. pub args: &'hir [GenericArg<'hir>], @@ -447,7 +447,7 @@ pub enum TraitBoundModifier { /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` @@ -488,7 +488,7 @@ pub enum LifetimeParamKind { Error, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericParamKind<'hir> { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime { @@ -505,7 +505,7 @@ pub enum GenericParamKind<'hir> { }, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericParam<'hir> { pub hir_id: HirId, pub def_id: LocalDefId, @@ -557,7 +557,7 @@ pub struct GenericParamCount { /// Represents lifetimes and type parameters attached to a declaration /// of a function, enum, trait, etc. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Generics<'hir> { pub params: &'hir [GenericParam<'hir>], pub predicates: &'hir [WherePredicate<'hir>], @@ -729,7 +729,7 @@ impl<'hir> Generics<'hir> { } /// A single predicate in a where-clause. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum WherePredicate<'hir> { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), @@ -773,7 +773,7 @@ pub enum PredicateOrigin { } /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereBoundPredicate<'hir> { pub hir_id: HirId, pub span: Span, @@ -795,7 +795,7 @@ impl<'hir> WhereBoundPredicate<'hir> { } /// A lifetime predicate (e.g., `'a: 'b + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereRegionPredicate<'hir> { pub span: Span, pub in_where_clause: bool, @@ -811,7 +811,7 @@ impl<'hir> WhereRegionPredicate<'hir> { } /// An equality predicate (e.g., `T = int`); currently unsupported. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { pub span: Span, pub lhs_ty: &'hir Ty<'hir>, @@ -821,7 +821,7 @@ pub struct WhereEqPredicate<'hir> { /// HIR node coupled with its parent's id in the same HIR owner. /// /// The parent is trash when the node is a HIR owner. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ParentedNode<'tcx> { pub parent: ItemLocalId, pub node: Node<'tcx>, @@ -959,7 +959,7 @@ pub struct Crate<'hir> { pub opt_hir_hash: Option<Fingerprint>, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Closure<'hir> { pub def_id: LocalDefId, pub binder: ClosureBinder, @@ -978,7 +978,7 @@ pub struct Closure<'hir> { /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Block<'hir> { /// Statements in a block. pub stmts: &'hir [Stmt<'hir>], @@ -1006,7 +1006,7 @@ impl<'hir> Block<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Pat<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1085,7 +1085,7 @@ impl<'hir> Pat<'hir> { /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` /// are treated the same as` x: x, y: ref y, z: ref mut z`, /// except `is_shorthand` is true. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PatField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1141,7 +1141,7 @@ impl fmt::Debug for DotDotPos { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum PatKind<'hir> { /// Represents a wildcard pattern (i.e., `_`). Wild, @@ -1351,7 +1351,7 @@ impl UnOp { } /// A statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Stmt<'hir> { pub hir_id: HirId, pub kind: StmtKind<'hir>, @@ -1359,7 +1359,7 @@ pub struct Stmt<'hir> { } /// The contents of a statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum StmtKind<'hir> { /// A local (`let`) binding. Local(&'hir Local<'hir>), @@ -1375,7 +1375,7 @@ pub enum StmtKind<'hir> { } /// Represents a `let` statement (i.e., `let <pat>:<ty> = <init>;`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Local<'hir> { pub pat: &'hir Pat<'hir>, /// Type annotation, if any (otherwise the type will be inferred). @@ -1393,7 +1393,7 @@ pub struct Local<'hir> { /// Represents a single arm of a `match` expression, e.g. /// `<pat> (if <guard>) => <body>`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Arm<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1411,7 +1411,7 @@ pub struct Arm<'hir> { /// /// In an if-let, imagine it as `if (let <pat> = <expr>) { ... }`; in a let-else, it is part of the /// desugaring to if-let. Only let-else supports the type annotation at present. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Let<'hir> { pub hir_id: HirId, pub span: Span, @@ -1420,7 +1420,7 @@ pub struct Let<'hir> { pub init: &'hir Expr<'hir>, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), IfLet(&'hir Let<'hir>), @@ -1440,7 +1440,7 @@ impl<'hir> Guard<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ExprField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1488,7 +1488,7 @@ pub struct BodyId { /// /// All bodies have an **owner**, which can be accessed via the HIR /// map using `body_owner_def_id()`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Body<'hir> { pub params: &'hir [Param<'hir>], pub value: &'hir Expr<'hir>, @@ -1679,7 +1679,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1715,6 +1715,7 @@ impl Expr<'_> { ExprKind::Continue(..) => ExprPrecedence::Continue, ExprKind::Ret(..) => ExprPrecedence::Ret, ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm, + ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf, ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, ExprKind::Yield(..) => ExprPrecedence::Yield, @@ -1774,6 +1775,7 @@ impl Expr<'_> { | ExprKind::Loop(..) | ExprKind::Assign(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::AssignOp(..) | ExprKind::Lit(_) | ExprKind::ConstBlock(..) @@ -1818,7 +1820,7 @@ impl Expr<'_> { pub fn can_have_side_effects(&self) -> bool { match self.peel_drop_temps().kind { - ExprKind::Path(_) | ExprKind::Lit(_) => false, + ExprKind::Path(_) | ExprKind::Lit(_) | ExprKind::OffsetOf(..) => false, ExprKind::Type(base, _) | ExprKind::Unary(_, base) | ExprKind::Field(base, _) @@ -1920,7 +1922,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ExprKind<'hir> { /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), @@ -1960,7 +1962,7 @@ pub enum ExprKind<'hir> { Lit(&'hir Lit), /// A cast (e.g., `foo as f64`). Cast(&'hir Expr<'hir>, &'hir Ty<'hir>), - /// A type reference (e.g., `Foo`). + /// A type ascription (e.g., `x: Foo`). See RFC 3307. Type(&'hir Expr<'hir>, &'hir Ty<'hir>), /// Wraps the expression in a terminating scope. /// This makes it semantically equivalent to `{ let _t = expr; _t }`. @@ -2022,6 +2024,9 @@ pub enum ExprKind<'hir> { /// Inline assembly (from `asm!`), with its outputs and inputs. InlineAsm(&'hir InlineAsm<'hir>), + /// Field offset (`offset_of!`) + OffsetOf(&'hir Ty<'hir>, &'hir [Ident]), + /// A struct or struct-like variant literal expression. /// /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`, @@ -2046,7 +2051,7 @@ pub enum ExprKind<'hir> { /// To resolve the path to a `DefId`, call [`qpath_res`]. /// /// [`qpath_res`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum QPath<'hir> { /// Path to a definition, optionally "fully-qualified" with a `Self` /// type, if the path points to an associated item in a trait. @@ -2238,7 +2243,7 @@ impl From<GeneratorKind> for YieldSource { // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct MutTy<'hir> { pub ty: &'hir Ty<'hir>, pub mutbl: Mutability, @@ -2246,7 +2251,7 @@ pub struct MutTy<'hir> { /// Represents a function's signature in a trait declaration, /// trait implementation, or a free function. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnSig<'hir> { pub header: FnHeader, pub decl: &'hir FnDecl<'hir>, @@ -2273,7 +2278,7 @@ impl TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2322,7 +2327,7 @@ impl<'hir> TraitItem<'hir> { } /// Represents a trait method's body (or just argument names). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub enum TraitFn<'hir> { /// No default body in the trait, just a signature. Required(&'hir [Ident]), @@ -2332,7 +2337,7 @@ pub enum TraitFn<'hir> { } /// Represents a trait method or associated constant or type -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(&'hir Ty<'hir>, Option<BodyId>), @@ -2360,7 +2365,7 @@ impl ImplItemId { } /// Represents anything within an `impl` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2410,7 +2415,7 @@ impl<'hir> ImplItem<'hir> { } /// Represents various kinds of content within an `impl`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. @@ -2439,7 +2444,7 @@ pub const FN_OUTPUT_NAME: Symbol = sym::Output; /// Binding(...), /// } /// ``` -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TypeBinding<'hir> { pub hir_id: HirId, pub ident: Ident, @@ -2448,7 +2453,7 @@ pub struct TypeBinding<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Term<'hir> { Ty(&'hir Ty<'hir>), Const(AnonConst), @@ -2467,7 +2472,7 @@ impl<'hir> From<AnonConst> for Term<'hir> { } // Represents the two kinds of type bindings. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TypeBindingKind<'hir> { /// E.g., `Foo<Bar: Send>`. Constraint { bounds: &'hir [GenericBound<'hir>] }, @@ -2490,7 +2495,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2635,7 +2640,7 @@ impl PrimTy { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct BareFnTy<'hir> { pub unsafety: Unsafety, pub abi: Abi, @@ -2644,7 +2649,7 @@ pub struct BareFnTy<'hir> { pub param_names: &'hir [Ident], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, @@ -2664,7 +2669,7 @@ pub enum OpaqueTyOrigin { } /// The various kinds of types recognized by the compiler. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyKind<'hir> { /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), @@ -2704,7 +2709,7 @@ pub enum TyKind<'hir> { Err(rustc_span::ErrorGuaranteed), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, @@ -2757,7 +2762,7 @@ impl<'hir> InlineAsmOperand<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct InlineAsm<'hir> { pub template: &'hir [InlineAsmTemplatePiece], pub template_strs: &'hir [(Symbol, Option<Symbol>, Span)], @@ -2767,7 +2772,7 @@ pub struct InlineAsm<'hir> { } /// Represents a parameter in a function header. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Param<'hir> { pub hir_id: HirId, pub pat: &'hir Pat<'hir>, @@ -2776,7 +2781,7 @@ pub struct Param<'hir> { } /// Represents the header (not the body) of a function declaration. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnDecl<'hir> { /// The types of the function's parameters. /// @@ -2849,7 +2854,7 @@ impl Defaultness { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum FnRetTy<'hir> { /// Return type is not specified. /// @@ -2882,7 +2887,7 @@ pub enum ClosureBinder { For { span: Span }, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct Mod<'hir> { pub spans: ModSpans, pub item_ids: &'hir [ItemId], @@ -2897,12 +2902,12 @@ pub struct ModSpans { pub inject_use_span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct EnumDef<'hir> { pub variants: &'hir [Variant<'hir>], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Variant<'hir> { /// Name of the variant. pub ident: Ident, @@ -2939,7 +2944,7 @@ pub enum UseKind { /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct TraitRef<'hir> { pub path: &'hir Path<'hir>, // Don't hash the `ref_id`. It is tracked via the thing it is used to access. @@ -2958,7 +2963,7 @@ impl TraitRef<'_> { } } -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], @@ -2969,7 +2974,7 @@ pub struct PolyTraitRef<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FieldDef<'hir> { pub span: Span, pub vis_span: Span, @@ -2988,7 +2993,7 @@ impl FieldDef<'_> { } /// Fields and constructor IDs of enum variants and structs. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum VariantData<'hir> { /// A struct variant. /// @@ -3058,7 +3063,7 @@ impl ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Item<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -3266,7 +3271,7 @@ impl FnHeader { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// @@ -3287,7 +3292,7 @@ pub enum ItemKind<'hir> { /// A function declaration. Fn(FnSig<'hir>, &'hir Generics<'hir>, BodyId), /// A MBE macro definition (`macro_rules!` or `macro`). - Macro(ast::MacroDef, MacroKind), + Macro(&'hir ast::MacroDef, MacroKind), /// A module. Mod(&'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. @@ -3313,7 +3318,7 @@ pub enum ItemKind<'hir> { Impl(&'hir Impl<'hir>), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { pub unsafety: Unsafety, pub polarity: ImplPolarity, @@ -3376,7 +3381,7 @@ impl ItemKind<'_> { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItemRef { pub id: TraitItemId, pub ident: Ident, @@ -3390,7 +3395,7 @@ pub struct TraitItemRef { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItemRef { pub id: ImplItemId, pub ident: Ident, @@ -3429,14 +3434,14 @@ impl ForeignItemId { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItemRef { pub id: ForeignItemId, pub ident: Ident, pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItem<'hir> { pub ident: Ident, pub kind: ForeignItemKind<'hir>, @@ -3458,7 +3463,7 @@ impl ForeignItem<'_> { } /// An item within an `extern` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ForeignItemKind<'hir> { /// A foreign function. Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>), @@ -3478,7 +3483,7 @@ pub struct Upvar { // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and // has length > 0 if the trait is found through an chain of imports, starting with the // import/use statement in the scope where the trait is used. -#[derive(Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Encodable, Decodable, Debug, Clone, HashStable_Generic)] pub struct TraitCandidate { pub def_id: DefId, pub import_ids: SmallVec<[LocalDefId; 1]>, @@ -3529,12 +3534,20 @@ impl<'hir> OwnerNode<'hir> { pub fn body_id(&self) -> Option<BodyId> { match self { - OwnerNode::TraitItem(TraitItem { - kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)), + OwnerNode::Item(Item { + kind: + ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body), .. }) - | OwnerNode::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. }) - | OwnerNode::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id), + | OwnerNode::TraitItem(TraitItem { + kind: + TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + .. + }) + | OwnerNode::ImplItem(ImplItem { + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), + .. + }) => Some(*body), _ => None, } } @@ -3729,12 +3742,27 @@ impl<'hir> Node<'hir> { pub fn body_id(&self) -> Option<BodyId> { match self { - Node::TraitItem(TraitItem { - kind: TraitItemKind::Fn(_, TraitFn::Provided(body_id)), + Node::Item(Item { + kind: + ItemKind::Static(_, _, body) | ItemKind::Const(_, body) | ItemKind::Fn(_, _, body), + .. + }) + | Node::TraitItem(TraitItem { + kind: + TraitItemKind::Fn(_, TraitFn::Provided(body)) | TraitItemKind::Const(_, Some(body)), + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(_, body) | ImplItemKind::Const(_, body), .. }) - | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. }) - | Node::Item(Item { kind: ItemKind::Fn(.., body_id), .. }) => Some(*body_id), + | Node::Expr(Expr { + kind: + ExprKind::ConstBlock(AnonConst { body, .. }) + | ExprKind::Closure(Closure { body, .. }) + | ExprKind::Repeat(_, ArrayLen::Body(AnonConst { body, .. })), + .. + }) => Some(*body), _ => None, } } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 234256ab553..df0047d82e1 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -786,6 +786,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::InlineAsm(ref asm) => { visitor.visit_inline_asm(asm, expression.hir_id); } + ExprKind::OffsetOf(ref container, ref fields) => { + visitor.visit_ty(container); + walk_list!(visitor, visit_ident, fields.iter().copied()); + } ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); } diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index a64466884d8..f56cedebfb0 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -15,6 +15,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_session = { path = "../rustc_session" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 7eb12d380a7..992316edb63 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -447,14 +447,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { handle_ty_args(has_default, &inf.to_ty()) } (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => { - ty::Const::from_opt_const_arg_anon_const( - tcx, - ty::WithOptConstParam { - did: ct.value.def_id, - const_param_did: Some(param.def_id), - }, - ) - .into() + let did = ct.value.def_id; + tcx.feed_anon_const_type(did, tcx.type_of(param.def_id)); + ty::Const::from_anon_const(tcx, did).into() } (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => { let ty = tcx diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0c54fd70c9b..ad2624a5d2d 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -494,7 +494,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { debug!( "check_item_type(it.def_id={:?}, it.name={})", id.owner_id, - tcx.def_path_str(id.owner_id.to_def_id()) + tcx.def_path_str(id.owner_id) ); let _indenter = indenter(); match tcx.def_kind(id.owner_id) { @@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>( if !missing_items.is_empty() { let full_impl_span = tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id)); - missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span); + missing_items_err(tcx, impl_id, &missing_items, full_impl_span); } if let Some(missing_items) = must_implement_one_of { diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 854974d1605..0fcbaa2efab 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -198,7 +198,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()), sym::forget => (1, vec![param(0)], tcx.mk_unit()), - sym::transmute => (2, vec![param(0)], param(1)), + sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)), sym::prefetch_read_data | sym::prefetch_write_data | sym::prefetch_read_instruction diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8fe4c44fca4..4b3f3cf169d 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp fn missing_items_err( tcx: TyCtxt<'_>, - impl_span: Span, + impl_def_id: LocalDefId, missing_items: &[ty::AssocItem], full_impl_span: Span, ) { @@ -211,6 +211,7 @@ fn missing_items_err( .collect::<Vec<_>>() .join("`, `"); + let impl_span = tcx.def_span(impl_def_id); let mut err = struct_span_err!( tcx.sess, impl_span, @@ -229,7 +230,11 @@ fn missing_items_err( tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new()); for &trait_item in missing_items { - let snippet = suggestion_signature(trait_item, tcx); + let snippet = suggestion_signature( + tcx, + trait_item, + tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(), + ); let code = format!("{}{}\n{}", padding, snippet, padding); let msg = format!("implement the missing item: `{snippet}`"); let appl = Applicability::HasPlaceholders; @@ -301,11 +306,11 @@ fn default_body_is_unstable( /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions. fn bounds_from_generic_predicates<'tcx>( tcx: TyCtxt<'tcx>, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>, ) -> (String, String) { let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default(); let mut projections = vec![]; - for (predicate, _) in predicates.predicates { + for (predicate, _) in predicates { debug!("predicate {:?}", predicate); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { @@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>( tcx: TyCtxt<'tcx>, sig: ty::FnSig<'tcx>, ident: Ident, - predicates: ty::GenericPredicates<'tcx>, + predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>, assoc: ty::AssocItem, ) -> String { let args = sig @@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { /// Return placeholder code for the given associated item. /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a /// structured suggestion. -fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { +fn suggestion_signature<'tcx>( + tcx: TyCtxt<'tcx>, + assoc: ty::AssocItem, + impl_trait_ref: ty::TraitRef<'tcx>, +) -> String { + let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto( + tcx, + assoc.container_id(tcx), + impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs, + ); + match assoc.kind { ty::AssocKind::Fn => { // We skip the binder here because the binder would deanonymize all @@ -445,16 +460,22 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String { // regions just fine, showing `fn(&MyType)`. fn_sig_suggestion( tcx, - tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(), + tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(), assoc.ident(tcx), - tcx.predicates_of(assoc.def_id), + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), assoc, ) } - ty::AssocKind::Type => format!("type {} = Type;", assoc.name), + ty::AssocKind::Type => { + let (generics, where_clauses) = bounds_from_generic_predicates( + tcx, + tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs), + ); + format!("type {}{generics} = /* Type */{where_clauses};", assoc.name) + } ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).subst_identity(); - let val = ty_kind_suggestion(ty).unwrap_or("value"); + let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); format!("const {}: {} = {};", assoc.name, ty, val) } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 53197bc8491..b2ebbf993a1 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -155,7 +155,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { @@ -251,7 +251,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 465e787c92a..ac393ee15a6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -22,7 +22,7 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef< debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, - tcx.def_path_str(impl_def_id.to_def_id()) + tcx.def_path_str(impl_def_id) ); // Skip impls where one of the self type is an error type. diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 7c07a1ebaec..9fe0c07814e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -55,7 +55,6 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) { pub fn provide(providers: &mut Providers) { resolve_bound_vars::provide(providers); *providers = Providers { - opt_const_param_of: type_of::opt_const_param_of, type_of: type_of::type_of, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, @@ -1147,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(ty); + let mut diag = bad_placeholder(tcx, visitor.0, "return type"); let ret_ty = fn_sig.output(); + // Don't leak types into signatures unless they're nameable! + // For example, if a function returns itself, we don't want that + // recursive function definition to leak out into the fn sig. + let mut should_recover = false; + if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) { diag.span_suggestion( ty.span, @@ -1156,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( ret_ty, Applicability::MachineApplicable, ); - } else if matches!(ret_ty.kind(), ty::FnDef(..)) - && let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false) - { - diag.span_suggestion( - ty.span, - "replace with the correct return type", - fn_sig, - Applicability::MachineApplicable, - ); + should_recover = true; } else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) { diag.span_suggestion( ty.span, @@ -1182,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>( https://doc.rust-lang.org/book/ch13-01-closures.html", ); } - diag.emit(); - ty::Binder::dummy(fn_sig) + let guar = diag.emit(); + + if should_recover { + ty::Binder::dummy(fn_sig) + } else { + ty::Binder::dummy(tcx.mk_fn_sig( + fn_sig.inputs().iter().copied(), + tcx.ty_error(guar), + fn_sig.c_variadic, + fn_sig.unsafety, + fn_sig.abi, + )) + } } None => icx.astconv().ty_of_fn( hir_id, diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index f82fad47422..d7d509e5394 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -1,6 +1,6 @@ use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirId, Node}; @@ -16,22 +16,81 @@ use super::ItemCtxt; use super::{bad_placeholder, is_suggestable_infer_ty}; use crate::errors::UnconstrainedOpaqueType; -/// Computes the relevant generic parameter for a potential generic const argument. -/// -/// This should be called using the query `tcx.opt_const_param_of`. -pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> { +fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> { use hir::*; let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - match tcx.hir().get(hir_id) { - Node::AnonConst(_) => (), - _ => return None, - }; + let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() }; let parent_node_id = tcx.hir().parent_id(hir_id); let parent_node = tcx.hir().get(parent_node_id); let (generics, arg_idx) = match parent_node { + // Easy case: arrays repeat expressions. + Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. }) + | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id() == hir_id => + { + return tcx.types.usize + } + Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => { + return tcx.typeck(def_id).node_type(e.hir_id) + } + Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. }) + if anon_const.hir_id == hir_id => + { + let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); + return substs.as_inline_const().ty() + } + Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) + | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) + if asm.operands.iter().any(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, + _ => false, + }) => + { + return tcx.typeck(def_id).node_type(hir_id) + } + Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { + return tcx + .adt_def(tcx.hir().get_parent_item(hir_id)) + .repr() + .discr_type() + .to_ty(tcx) + } + Node::GenericParam(&GenericParam { + def_id: param_def_id, + kind: GenericParamKind::Const { default: Some(ct), .. }, + .. + }) if ct.hir_id == hir_id => { + return tcx.type_of(param_def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } + + Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) + if let Node::TraitRef(trait_ref) = tcx.hir().get( + tcx.hir().parent_id(binding_id) + ) => + { + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), + ); + return if let Some(assoc_item) = assoc_item { + tcx.type_of(assoc_item.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic") + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait") + } + } + // This match arm is for when the def_id appears in a GAT whose // path can't be resolved without typechecking e.g. // @@ -86,11 +145,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< (generics, arg_index) } else { // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "unexpected non-GAT usage of an anon const", ); - return None; } } Node::Expr(&Expr { @@ -103,7 +161,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< // This may fail in case the method/path does not actually exist. // As there is no relevant param for `def_id`, we simply return // `None` here. - let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?; + let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("unable to find type-dependent def for {:?}", parent_node_id), + ); + }; let idx = segment .args .and_then(|args| { @@ -140,19 +203,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) { path } else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unable to find const parent for {} in pat {:?}", hir_id, pat), ); - return None; } } _ => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unexpected const parent path {:?}", parent_node), ); - return None; } }; @@ -171,32 +232,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< .position(|ct| ct.hir_id == hir_id) .map(|idx| (idx, seg))) }) else { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), "no arg matching AnonConst in path", ); - return None; }; let generics = match tcx.res_generics_def_id(segment.res) { Some(def_id) => tcx.generics_of(def_id), None => { - tcx.sess.delay_span_bug( + return tcx.ty_error_with_message( tcx.def_span(def_id), &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path), ); - return None; } }; (generics, arg_index) } - _ => return None, + + _ => return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("unexpected const parent in type_of(): {parent_node:?}"), + ), }; debug!(?parent_node); debug!(?generics, ?arg_idx); - generics + if let Some(param_def_id) = generics .params .iter() .filter(|param| param.kind.is_ty_or_const()) @@ -211,6 +274,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< } _ => None, }) + { + tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic") + } else { + return tcx.ty_error_with_message( + tcx.def_span(def_id), + &format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"), + ); + } } fn get_path_containing_arg_in_pat<'hir>( @@ -415,143 +486,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty tcx.typeck(def_id).node_type(hir_id) } - Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => { - // We defer to `type_of` of the corresponding parameter - // for generic arguments. - tcx.type_of(param).subst_identity() - } - - Node::AnonConst(_) => { - let parent_node = tcx.hir().get_parent(hir_id); - match parent_node { - Node::Ty(Ty { kind: TyKind::Array(_, constant), .. }) - | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. }) - if constant.hir_id() == hir_id => - { - tcx.types.usize - } - Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => { - tcx.typeck(def_id).node_type(e.hir_id) - } - - Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. }) - if anon_const.hir_id == hir_id => - { - let substs = InternalSubsts::identity_for_item(tcx, def_id); - substs.as_inline_const().ty() - } - - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { - anon_const.hir_id == hir_id - } - _ => false, - }) => - { - tcx.typeck(def_id).node_type(hir_id) - } - - Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => { - tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - kind: TypeBindingKind::Equality { term: Term::Const(e) }, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && e.hir_id == hir_id => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - ty::AssocKind::Const, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find associated const on trait", - ) - } - } - - Node::TypeBinding(TypeBinding { - hir_id: binding_id, - gen_args, - kind, - ident, - .. - }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id) - && let Some((idx, _)) = - gen_args.args.iter().enumerate().find(|(_, arg)| { - if let GenericArg::Const(ct) = arg { - ct.value.hir_id == hir_id - } else { - false - } - }) => - { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait")); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, - *ident, - match kind { - // I think `<A: T>` type bindings requires that `A` is a type - TypeBindingKind::Constraint { .. } - | TypeBindingKind::Equality { term: Term::Ty(..) } => { - ty::AssocKind::Type - } - TypeBindingKind::Equality { term: Term::Const(..) } => { - ty::AssocKind::Const - } - }, - def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item - && let param = &tcx.generics_of(assoc_item.def_id).params[idx] - && matches!(param.kind, ty::GenericParamDefKind::Const { .. }) - { - tcx.type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic") - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find const param on associated item", - ) - } - } - - Node::GenericParam(&GenericParam { - def_id: param_def_id, - kind: GenericParamKind::Const { default: Some(ct), .. }, - .. - }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(), - - x => tcx.ty_error_with_message( - DUMMY_SP, - &format!("unexpected const parent in type_of(): {x:?}"), - ), - } - } + Node::AnonConst(_) => anon_const_type_of(tcx, def_id), Node::GenericParam(param) => match ¶m.kind { GenericParamKind::Type { default: Some(ty), .. } diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 27e56180349..a4b797f77f7 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -99,10 +99,10 @@ mod variance; use rustc_errors::ErrorGuaranteed; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::TyCtxtInferExt; -use rustc_macros::fluent_messages; use rustc_middle::middle; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -496,8 +496,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module)) }); - tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(())); - check_unused::check_crate(tcx); check_for_entry_fn(tcx); diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 408bec71ee0..6f0afae1b4c 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn build_constraints_for_item(&mut self, def_id: LocalDefId) { let tcx = self.tcx(); - debug!("build_constraints_for_item({})", tcx.def_path_str(def_id.to_def_id())); + debug!("build_constraints_for_item({})", tcx.def_path_str(def_id)); // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(def_id).count() == 0 { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 74f5b359021..2db4f1e50d4 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1551,6 +1551,23 @@ impl<'a> State<'a> { self.word("asm!"); self.print_inline_asm(asm); } + hir::ExprKind::OffsetOf(container, ref fields) => { + self.word("offset_of!("); + self.print_type(container); + self.word(","); + self.space(); + + if let Some((&first, rest)) = fields.split_first() { + self.print_ident(first); + + for &field in rest { + self.word("."); + self.print_ident(field); + } + } + + self.word(")"); + } hir::ExprKind::Yield(expr, _) => { self.word_space("yield"); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 093f9bb8448..13e1ea31c4d 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_graphviz = { path = "../rustc_graphviz" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 2c537bf4064..6d40df7d0cc 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -3,21 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer = .label = used more than once .previous_use_label = first use of `{$ident}` -hir_typeck_copy_impl_on_type_with_dtor = - the trait `Copy` cannot be implemented for this type; the type has a destructor - .label = `Copy` not allowed on types with destructors - -hir_typeck_multiple_relaxed_default_bounds = - type parameter has more than one relaxed default bound, only one is supported - -hir_typeck_copy_impl_on_non_adt = - the trait `Copy` cannot be implemented for this type - .label = type is not a structure or enumeration - -hir_typeck_trait_object_declared_with_no_traits = - at least one trait is required for an object type - .alias_span = this alias does not contain a trait - hir_typeck_functional_record_update_on_non_struct = functional record update syntax requires a struct diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0c0a7515d9c..3ffc583d43f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -309,6 +309,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.deferred_asm_checks.borrow_mut().push((asm, expr.hir_id)); self.check_expr_asm(asm) } + ExprKind::OffsetOf(container, ref fields) => { + self.check_offset_of(container, fields, expr) + } ExprKind::Break(destination, ref expr_opt) => { self.check_expr_break(destination, expr_opt.as_deref(), expr) } @@ -2450,15 +2453,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_did: DefId, return_ty: Option<Ty<'tcx>>, ) -> ErrorGuaranteed { - let struct_path = self.tcx().def_path_str(base_did); - let kind_name = self.tcx().def_descr(base_did); - let mut err = struct_span_err!( - self.tcx().sess, - field.span, - E0616, - "field `{field}` of {kind_name} `{struct_path}` is private", - ); - err.span_label(field.span, "private field"); + let mut err = self.private_field_err(field, base_did); + // Also check if an accessible method exists, which is often what is meant. if self.method_exists(field, expr_t, expr.hir_id, false, return_ty) && !self.expr_in_place(expr.hir_id) @@ -2698,6 +2694,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err } + fn private_field_err( + &self, + field: Ident, + base_did: DefId, + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let struct_path = self.tcx().def_path_str(base_did); + let kind_name = self.tcx().def_descr(base_did); + let mut err = struct_span_err!( + self.tcx().sess, + field.span, + E0616, + "field `{field}` of {kind_name} `{struct_path}` is private", + ); + err.span_label(field.span, "private field"); + + err + } + pub(crate) fn get_field_candidates_considering_privacy( &self, span: Span, @@ -3042,4 +3056,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.mk_unit() } } + + fn check_offset_of( + &self, + container: &'tcx hir::Ty<'tcx>, + fields: &[Ident], + expr: &'tcx hir::Expr<'tcx>, + ) -> Ty<'tcx> { + let container = self.to_ty(container).normalized; + + let mut field_indices = Vec::with_capacity(fields.len()); + let mut current_container = container; + + for &field in fields { + let container = self.structurally_resolved_type(expr.span, current_container); + + match container.kind() { + ty::Adt(container_def, substs) if !container_def.is_enum() => { + let block = self.tcx.hir().local_def_id_to_hir_id(self.body_id); + let (ident, def_scope) = + self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block); + + let fields = &container_def.non_enum_variant().fields; + if let Some((index, field)) = fields + .iter_enumerated() + .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident) + { + let field_ty = self.field_ty(expr.span, field, substs); + + // FIXME: DSTs with static alignment should be allowed + self.require_type_is_sized(field_ty, expr.span, traits::MiscObligation); + + if field.vis.is_accessible_from(def_scope, self.tcx) { + self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None); + } else { + self.private_field_err(ident, container_def.did()).emit(); + } + + // Save the index of all fields regardless of their visibility in case + // of error recovery. + field_indices.push(index); + current_container = field_ty; + + continue; + } + } + ty::Tuple(tys) => { + let fstr = field.as_str(); + + if let Ok(index) = fstr.parse::<usize>() { + if fstr == index.to_string() { + if let Some(&field_ty) = tys.get(index) { + field_indices.push(index.into()); + current_container = field_ty; + + continue; + } + } + } + } + _ => (), + }; + + self.no_such_field_err(field, container, expr.hir_id).emit(); + + break; + } + + self.typeck_results + .borrow_mut() + .offset_of_data_mut() + .insert(expr.hir_id, (container, field_indices)); + + self.tcx.types.usize + } } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index ee1c6fbfd65..94b6a0f8f47 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -300,6 +300,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::Continue(..) | hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Err(_) => {} hir::ExprKind::Loop(blk, ..) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 13a869caa8f..2b5af4bc81b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -420,9 +420,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast_c: &hir::AnonConst, param_def_id: DefId, ) -> ty::Const<'tcx> { - let const_def = - ty::WithOptConstParam { did: ast_c.def_id, const_param_did: Some(param_def_id) }; - let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def); + let did = ast_c.def_id; + self.tcx.feed_anon_const_type(did, self.tcx.type_of(param_def_id)); + let c = ty::Const::from_anon_const(self.tcx, did); self.register_wf_obligation( c.into(), self.tcx.hir().span(ast_c.hir_id), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index c6fd0b61035..3ba679df3ed 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,6 @@ use rustc_infer::infer; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; use rustc_span::symbol::Ident; @@ -250,16 +249,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { - if let Some(param) = param { - if let GenericArgKind::Type(ty) = self.var_for_def(span, param).unpack() { - return ty; - } - unreachable!() - } else { - self.next_ty_var(TypeVariableOrigin { + match param { + Some(param) => self.var_for_def(span, param).as_type().unwrap(), + None => self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span, - }) + }), } } @@ -269,16 +264,12 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { param: Option<&ty::GenericParamDef>, span: Span, ) -> Const<'tcx> { - if let Some(param) = param { - if let GenericArgKind::Const(ct) = self.var_for_def(span, param).unpack() { - return ct; - } - unreachable!() - } else { - self.next_const_var( + match param { + Some(param) => self.var_for_def(span, param).as_const().unwrap(), + None => self.next_const_var( ty, ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span }, - ) + ), } } diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index 3e9a9ce1b31..28c44aa5703 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -215,6 +215,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { | ExprKind::Continue(..) | ExprKind::Ret(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) @@ -485,6 +486,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { | ExprKind::Field(..) | ExprKind::Index(..) | ExprKind::InlineAsm(..) + | ExprKind::OffsetOf(..) | ExprKind::Let(..) | ExprKind::Lit(..) | ExprKind::Path(..) diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 45890abad92..5ccac9a6925 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -59,6 +59,7 @@ use rustc_errors::{ struct_span_err, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan, SubdiagnosticMessage, }; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; @@ -66,7 +67,6 @@ use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::check_abi; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -152,25 +152,9 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet<LocalDef &*tcx.typeck(def_id).used_trait_imports } -fn typeck_item_bodies(tcx: TyCtxt<'_>, (): ()) { - tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id)); -} - -fn typeck_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, - (did, param_did): (LocalDefId, DefId), -) -> &ty::TypeckResults<'tcx> { - let fallback = move || tcx.type_of(param_did).subst_identity(); - typeck_with_fallback(tcx, did, fallback) -} - fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> { - if let Some(param_did) = tcx.opt_const_param_of(def_id) { - tcx.typeck_const_arg((def_id, param_did)) - } else { - let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); - typeck_with_fallback(tcx, def_id, fallback) - } + let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); + typeck_with_fallback(tcx, def_id, fallback) } /// Used only to get `TypeckResults` for type inference during error recovery. @@ -491,8 +475,6 @@ fn has_expected_num_generic_args( pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { - typeck_item_bodies, - typeck_const_arg, typeck, diagnostic_only_typeck, has_typeck_results, diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 6c861b5930a..f5fca14eca8 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -381,6 +381,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), } } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index e876fa27593..9432a5840b2 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -70,6 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.visit_user_provided_tys(); wbcx.visit_user_provided_sigs(); wbcx.visit_generator_interior_types(); + wbcx.visit_offset_of_container_types(); wbcx.typeck_results.rvalue_scopes = mem::take(&mut self.typeck_results.borrow_mut().rvalue_scopes); @@ -295,7 +296,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> { self.visit_field_id(field.hir_id); } } - hir::ExprKind::Field(..) => { + hir::ExprKind::Field(..) | hir::ExprKind::OffsetOf(..) => { self.visit_field_id(e.hir_id); } hir::ExprKind::ConstBlock(anon_const) => { @@ -682,6 +683,28 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } + fn visit_offset_of_container_types(&mut self) { + let fcx_typeck_results = self.fcx.typeck_results.borrow(); + assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); + let common_hir_owner = fcx_typeck_results.hir_owner; + + for (local_id, &(container, ref indices)) in + fcx_typeck_results.offset_of_data().items_in_stable_order() + { + let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + + if cfg!(debug_assertions) && container.needs_infer() { + span_bug!( + hir_id.to_span(self.fcx.tcx), + "writeback: `{:?}` has inference variables", + container + ); + }; + + self.typeck_results.offset_of_data_mut().insert(hir_id, (container, indices.clone())); + } + } + fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T where T: TypeFoldable<TyCtxt<'tcx>>, diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index ad89393956e..59a0623c1e1 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fs_util = { path = "../rustc_fs_util" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index df958e4a61f..11710c368ce 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -33,6 +33,6 @@ pub use persist::LoadResult; pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 02ac83a5e8b..9dd5868adc7 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -12,6 +12,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index f298b95ca35..df15cab00b4 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -131,10 +131,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.dump_constraints(); } - let graph = self.construct_graph(); self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); - self.collect_var_errors(&var_data, &graph, errors); + self.collect_var_errors(&var_data, errors); var_data } @@ -622,7 +621,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn collect_var_errors( &self, var_data: &LexicalRegionResolutions<'tcx>, - graph: &RegionGraph<'tcx>, errors: &mut Vec<RegionResolutionError<'tcx>>, ) { debug!("collect_var_errors, var_data = {:#?}", var_data.values); @@ -640,6 +638,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // overlapping locations. let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars()); + // Only construct the graph when necessary, because it's moderately + // expensive. + let mut graph = None; + for (node_vid, value) in var_data.values.iter_enumerated() { match *value { VarValue::Empty(_) | VarValue::Value(_) => { /* Inference successful */ } @@ -672,7 +674,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // influence the constraints on this value for // richer diagnostics in `static_impl_trait`. - self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors); + let g = graph.get_or_insert_with(|| self.construct_graph()); + self.collect_error_for_expanding_node(g, &mut dup_vec, node_vid, errors); } } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f263a0773e4..1cd09cde0fc 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1228,11 +1228,11 @@ impl<'tcx> InferCtxt<'tcx> { /// hence that `resolve_regions_and_report_errors` can never be /// called. This is used only during NLL processing to "hand off" ownership /// of the set of region variables into the NLL region context. - pub fn take_region_var_origins(&self) -> VarInfos { + pub fn get_region_var_origins(&self) -> VarInfos { let mut inner = self.inner.borrow_mut(); let (var_infos, data) = inner .region_constraint_storage - .take() + .clone() .expect("regions already resolved") .with_log(&mut inner.undo_log) .into_infos_and_data(); @@ -1500,7 +1500,7 @@ impl<'tcx> InferCtxt<'tcx> { Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)), Ok(None) => { let tcx = self.tcx; - let def_id = unevaluated.def.did; + let def_id = unevaluated.def; span_bug!( tcx.def_span(def_id), "unable to construct a constant value for the unevaluated constant {:?}", @@ -1547,8 +1547,8 @@ impl<'tcx> InferCtxt<'tcx> { substs = replace_param_and_infer_substs_with_placeholder(tcx, substs); } } else { - substs = InternalSubsts::identity_for_item(tcx, unevaluated.def.did); - param_env = tcx.param_env(unevaluated.def.did); + substs = InternalSubsts::identity_for_item(tcx, unevaluated.def); + param_env = tcx.param_env(unevaluated.def); } } diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index ff23087fe8d..cb63d2f18b6 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -143,7 +143,7 @@ fn compute_components<'tcx>( // through and constrain Pi. let mut subcomponents = smallvec![]; let mut subvisited = SsoHashSet::new(); - compute_components_recursive(tcx, ty.into(), &mut subcomponents, &mut subvisited); + compute_alias_components_recursive(tcx, ty, &mut subcomponents, &mut subvisited); out.push(Component::EscapingAlias(subcomponents.into_iter().collect())); } } @@ -193,7 +193,43 @@ fn compute_components<'tcx>( /// /// This should not be used to get the components of `parent` itself. /// Use [push_outlives_components] instead. -pub(super) fn compute_components_recursive<'tcx>( +pub(super) fn compute_alias_components_recursive<'tcx>( + tcx: TyCtxt<'tcx>, + alias_ty: Ty<'tcx>, + out: &mut SmallVec<[Component<'tcx>; 4]>, + visited: &mut SsoHashSet<GenericArg<'tcx>>, +) { + let ty::Alias(kind, alias_ty) = alias_ty.kind() else { bug!() }; + let opt_variances = if *kind == ty::Opaque { tcx.variances_of(alias_ty.def_id) } else { &[] }; + for (index, child) in alias_ty.substs.iter().enumerate() { + if opt_variances.get(index) == Some(&ty::Bivariant) { + continue; + } + if !visited.insert(child) { + continue; + } + match child.unpack() { + GenericArgKind::Type(ty) => { + compute_components(tcx, ty, out, visited); + } + GenericArgKind::Lifetime(lt) => { + // Ignore late-bound regions. + if !lt.is_late_bound() { + out.push(Component::Region(lt)); + } + } + GenericArgKind::Const(_) => { + compute_components_recursive(tcx, child, out, visited); + } + } + } +} + +/// Collect [Component]s for *all* the substs of `parent`. +/// +/// This should not be used to get the components of `parent` itself. +/// Use [push_outlives_components] instead. +fn compute_components_recursive<'tcx>( tcx: TyCtxt<'tcx>, parent: GenericArg<'tcx>, out: &mut SmallVec<[Component<'tcx>; 4]>, diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index ccf11c61b57..2f5e2e417a6 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -344,12 +344,14 @@ where // the problem is to add `T: 'r`, which isn't true. So, if there are no // inference variables, we use a verify constraint instead of adding // edges, which winds up enforcing the same condition. + let is_opaque = alias_ty.kind(self.tcx) == ty::Opaque; if approx_env_bounds.is_empty() && trait_bounds.is_empty() - && (alias_ty.needs_infer() || alias_ty.kind(self.tcx) == ty::Opaque) + && (alias_ty.needs_infer() || is_opaque) { debug!("no declared bounds"); - self.substs_must_outlive(alias_ty.substs, origin, region); + let opt_variances = is_opaque.then(|| self.tcx.variances_of(alias_ty.def_id)); + self.substs_must_outlive(alias_ty.substs, origin, region, opt_variances); return; } @@ -395,22 +397,31 @@ where self.delegate.push_verify(origin, GenericKind::Alias(alias_ty), region, verify_bound); } + #[instrument(level = "debug", skip(self))] fn substs_must_outlive( &mut self, substs: SubstsRef<'tcx>, origin: infer::SubregionOrigin<'tcx>, region: ty::Region<'tcx>, + opt_variances: Option<&[ty::Variance]>, ) { let constraint = origin.to_constraint_category(); - for k in substs { + for (index, k) in substs.iter().enumerate() { match k.unpack() { GenericArgKind::Lifetime(lt) => { - self.delegate.push_sub_region_constraint( - origin.clone(), - region, - lt, - constraint, - ); + let variance = if let Some(variances) = opt_variances { + variances[index] + } else { + ty::Invariant + }; + if variance == ty::Invariant { + self.delegate.push_sub_region_constraint( + origin.clone(), + region, + lt, + constraint, + ); + } } GenericArgKind::Type(ty) => { self.type_must_outlive(origin.clone(), ty, region, constraint); diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index bae246418b0..e1cb53bc71d 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,4 +1,4 @@ -use crate::infer::outlives::components::{compute_components_recursive, Component}; +use crate::infer::outlives::components::{compute_alias_components_recursive, Component}; use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::region_constraints::VerifyIfEq; use crate::infer::VerifyBound; @@ -130,7 +130,12 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> { // see the extensive comment in projection_must_outlive let recursive_bound = { let mut components = smallvec![]; - compute_components_recursive(self.tcx, alias_ty_as_ty.into(), &mut components, visited); + compute_alias_components_recursive( + self.tcx, + alias_ty_as_ty.into(), + &mut components, + visited, + ); self.bound_from_components(&components, visited) }; diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 738a1237651..e92ba05aa67 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -35,7 +35,7 @@ extern crate tracing; extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod errors; pub mod infer; diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 98d3ab87f9c..4569c35e182 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -16,6 +16,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_borrowck = { path = "../rustc_borrowck" } rustc_builtin_macros = { path = "../rustc_builtin_macros" } rustc_expand = { path = "../rustc_expand" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_macros = { path = "../rustc_macros" } rustc_parse = { path = "../rustc_parse" } diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 9664ba8bd8a..51bd8381e93 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -13,7 +13,7 @@ extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod callbacks; mod errors; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 0e4e20c7cd1..61923db9623 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -761,27 +761,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // passes are timed inside typeck rustc_hir_analysis::check_crate(tcx)?; - sess.time("misc_checking_2", || { - parallel!( - { - sess.time("match_checking", || { - tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id)) - }); - }, - { - sess.time("liveness_checking", || { - tcx.hir().par_body_owners(|def_id| { - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? - tcx.ensure().check_liveness(def_id.to_def_id()); - }); - }); - } - ); - }); - sess.time("MIR_borrow_checking", || { tcx.hir().par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); }); @@ -794,9 +773,14 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { } tcx.ensure().has_ffi_unwind_calls(def_id); - if tcx.hir().body_const_context(def_id).is_some() { - tcx.ensure() - .mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(def_id)); + // If we need to codegen, ensure that we emit all errors from + // `mir_drops_elaborated_and_const_checked` now, to avoid discovering + // them later during codegen. + if tcx.sess.opts.output_types.should_codegen() + || tcx.hir().body_const_context(def_id).is_some() + { + tcx.ensure().mir_drops_elaborated_and_const_checked(def_id); + tcx.ensure().unused_generic_params(ty::InstanceDef::Item(def_id.to_def_id())); } } }); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 10dfd32d418..ce0f90bc1cc 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -747,7 +747,7 @@ fn test_unstable_options_tracking_hash() { tracked!(emit_thin_lto, false); tracked!(export_executable_symbols, true); tracked!(fewer_names, Some(true)); - tracked!(flatten_format_args, true); + tracked!(flatten_format_args, false); tracked!(force_unstable_if_unmarked, true); tracked!(fuel, Some(("abc".to_string(), 99))); tracked!(function_sections, Some(false)); @@ -768,6 +768,7 @@ fn test_unstable_options_tracking_hash() { tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); + tracked!(mir_keep_place_mention, true); tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); @@ -776,7 +777,7 @@ fn test_unstable_options_tracking_hash() { tracked!(no_link, true); tracked!(no_profiler_runtime, true); tracked!(no_unique_section_names, true); - tracked!(oom, OomStrategy::Panic); + tracked!(oom, OomStrategy::Unwind); tracked!(osx_rpath_install_name, true); tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index abe61406c21..539eea3d816 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -11,6 +11,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 55bef6d3b3d..aeb791901bd 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -166,10 +166,8 @@ declare_lint_pass!(BoxPointers => [BOX_POINTERS]); impl BoxPointers { fn check_heap_type(&self, cx: &LateContext<'_>, span: Span, ty: Ty<'_>) { for leaf in ty.walk() { - if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { - if leaf_ty.is_box() { - cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); - } + if let GenericArgKind::Type(leaf_ty) = leaf.unpack() && leaf_ty.is_box() { + cx.emit_spanned_lint(BOX_POINTERS, span, BuiltinBoxPointers { ty }); } } } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index b3578540516..76f07257907 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -82,9 +82,9 @@ pub use array_into_iter::ARRAY_INTO_ITER; use rustc_ast as ast; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_macros::fluent_messages; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 648a7c6eed6..79253cbc8b4 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -33,6 +33,11 @@ pub fn method_context(cx: &LateContext<'_>, id: LocalDefId) -> MethodLateContext } } +fn assoc_item_in_trait_impl(cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) -> bool { + let item = cx.tcx.associated_item(ii.owner_id); + item.trait_item_def_id.is_some() +} + declare_lint! { /// The `non_camel_case_types` lint detects types, variants, traits and /// type parameters that don't have camel case names. @@ -177,6 +182,7 @@ impl EarlyLintPass for NonCamelCaseTypes { // trait impls where we should have warned for the trait definition already. ast::ItemKind::Impl(box ast::Impl { of_trait: None, items, .. }) => { for it in items { + // FIXME: this doesn't respect `#[allow(..)]` on the item itself. if let ast::AssocItemKind::Type(..) = it.kind { self.check_case(cx, "associated type", &it.ident); } @@ -494,15 +500,6 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { hir::ItemKind::Const(..) => { NonUpperCaseGlobals::check_upper_case(cx, "constant", &it.ident); } - // we only want to check inherent associated consts, trait consts - // are linted at def-site. - hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) => { - for it in *items { - if let hir::AssocItemKind::Const = it.kind { - NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &it.ident); - } - } - } _ => {} } } @@ -513,6 +510,12 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals { } } + fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) { + if let hir::ImplItemKind::Const(..) = ii.kind && !assoc_item_in_trait_impl(cx, ii) { + NonUpperCaseGlobals::check_upper_case(cx, "associated constant", &ii.ident); + } + } + fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) { // Lint for constants that look like binding identifiers (#7526) if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.kind { diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp index 448a1f62f69..35d6b9ed7a4 100644 --- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp @@ -39,6 +39,7 @@ enum class LLVMRustArchiveKind { BSD, DARWIN, COFF, + AIX_BIG, }; static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { @@ -51,6 +52,8 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { return Archive::K_DARWIN; case LLVMRustArchiveKind::COFF: return Archive::K_COFF; + case LLVMRustArchiveKind::AIX_BIG: + return Archive::K_AIXBIG; default: report_fatal_error("Bad ArchiveKind."); } diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c9acbab253e..90cce9a8650 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -310,12 +310,14 @@ static size_t getLongestEntryLength(ArrayRef<KV> Table) { extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) { const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch(); + const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable(); unsigned MaxCPULen = getLongestEntryLength(CPUTable); printf("Available CPUs for this target:\n"); + // Don't print the "native" entry when the user specifies --target with a + // different arch since that could be wrong or misleading. if (HostArch == TargetArch) { const StringRef HostCPU = sys::getHostCPUName(); printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", @@ -523,14 +525,14 @@ extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmS extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) { - if (any_isa<const Module *>(WrappedIr)) - return any_cast<const Module *>(WrappedIr)->getName().str(); - if (any_isa<const Function *>(WrappedIr)) - return any_cast<const Function *>(WrappedIr)->getName().str(); - if (any_isa<const Loop *>(WrappedIr)) - return any_cast<const Loop *>(WrappedIr)->getName().str(); - if (any_isa<const LazyCallGraph::SCC *>(WrappedIr)) - return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName(); + if (const auto *Cast = any_cast<const Module *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Function *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const Loop *>(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast<const LazyCallGraph::SCC *>(&WrappedIr)) + return (*Cast)->getName(); return "<UNKNOWN>"; } diff --git a/compiler/rustc_macros/Cargo.toml b/compiler/rustc_macros/Cargo.toml index 745983e7e86..1f1201b0035 100644 --- a/compiler/rustc_macros/Cargo.toml +++ b/compiler/rustc_macros/Cargo.toml @@ -7,11 +7,7 @@ edition = "2021" proc-macro = true [dependencies] -annotate-snippets = "0.9" -fluent-bundle = "0.15.2" -fluent-syntax = "0.11" synstructure = "0.13.0" syn = { version = "2", features = ["full"] } proc-macro2 = "1" quote = "1" -unic-langid = { version = "0.9.0", features = ["macros"] } diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 78df0cd1d34..bd84681cbb4 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -1,12 +1,10 @@ mod diagnostic; mod diagnostic_builder; mod error; -mod fluent; mod subdiagnostic; mod utils; use diagnostic::{DiagnosticDerive, LintDiagnosticDerive}; -pub(crate) use fluent::fluent_messages; use proc_macro2::TokenStream; use quote::format_ident; use subdiagnostic::SubdiagnosticDeriveBuilder; diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 737500cc257..904f8eb5731 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -54,60 +54,6 @@ pub fn newtype_index(input: TokenStream) -> TokenStream { newtype::newtype(input) } -/// Implements the `fluent_messages` macro, which performs compile-time validation of the -/// compiler's Fluent resources (i.e. that the resources parse and don't multiply define the same -/// messages) and generates constants that make using those messages in diagnostics more ergonomic. -/// -/// For example, given the following invocation of the macro.. -/// -/// ```ignore (rust) -/// fluent_messages! { "./typeck.ftl" } -/// ``` -/// ..where `typeck.ftl` has the following contents.. -/// -/// ```fluent -/// typeck_field_multiply_specified_in_initializer = -/// field `{$ident}` specified more than once -/// .label = used more than once -/// .label_previous_use = first use of `{$ident}` -/// ``` -/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and -/// will generate the following code: -/// -/// ```ignore (rust) -/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); -/// -/// mod fluent_generated { -/// mod typeck { -/// pub const field_multiply_specified_in_initializer: DiagnosticMessage = -/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer"); -/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage = -/// DiagnosticMessage::fluent_attr( -/// "typeck_field_multiply_specified_in_initializer", -/// "previous_use_label" -/// ); -/// } -/// } -/// ``` -/// When emitting a diagnostic, the generated constants can be used as follows: -/// -/// ```ignore (rust) -/// let mut err = sess.struct_span_err( -/// span, -/// fluent::typeck::field_multiply_specified_in_initializer -/// ); -/// err.span_default_label(span); -/// err.span_label( -/// previous_use_span, -/// fluent::typeck::field_multiply_specified_in_initializer_label_previous_use -/// ); -/// err.emit(); -/// ``` -#[proc_macro] -pub fn fluent_messages(input: TokenStream) -> TokenStream { - diagnostics::fluent_messages(input) -} - decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive); decl_derive!( [HashStable_Generic, attributes(stable_hasher)] => diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index 4d7c133e09b..0e54d6aa946 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -18,6 +18,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 79b8b417257..f0158aeae85 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -155,19 +155,9 @@ metadata_no_multiple_global_alloc = metadata_prev_global_alloc = previous global allocator defined here -metadata_no_multiple_alloc_error_handler = - cannot define multiple allocation error handlers - .label = cannot define a new allocation error handler - -metadata_prev_alloc_error_handler = - previous allocation error handler defined here - metadata_conflicting_global_alloc = the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name} -metadata_conflicting_alloc_error_handler = - the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name} - metadata_global_alloc_required = no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 23aceca0622..89751b0b721 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -38,13 +38,8 @@ pub struct CStore { /// This crate needs an allocator and either provides it itself, or finds it in a dependency. /// If the above is true, then this field denotes the kind of the found allocator. allocator_kind: Option<AllocatorKind>, - /// This crate needs an allocation error handler and either provides it itself, or finds it in a dependency. - /// If the above is true, then this field denotes the kind of the found allocator. - alloc_error_handler_kind: Option<AllocatorKind>, /// This crate has a `#[global_allocator]` item. has_global_allocator: bool, - /// This crate has a `#[alloc_error_handler]` item. - has_alloc_error_handler: bool, /// The interned [StableCrateId]s. pub(crate) stable_crate_ids: StableCrateIdMap, @@ -221,18 +216,10 @@ impl CStore { self.allocator_kind } - pub(crate) fn alloc_error_handler_kind(&self) -> Option<AllocatorKind> { - self.alloc_error_handler_kind - } - pub(crate) fn has_global_allocator(&self) -> bool { self.has_global_allocator } - pub(crate) fn has_alloc_error_handler(&self) -> bool { - self.has_alloc_error_handler - } - pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { let json_unused_externs = tcx.sess.opts.json_unused_externs; @@ -268,9 +255,7 @@ impl CStore { metas: IndexVec::from_iter(iter::once(None)), injected_panic_runtime: None, allocator_kind: None, - alloc_error_handler_kind: None, has_global_allocator: false, - has_alloc_error_handler: false, stable_crate_ids, unused_externs: Vec::new(), } @@ -776,14 +761,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } spans => !spans.is_empty(), }; - self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) { - [span1, span2, ..] => { - self.sess - .emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 }); - true - } - spans => !spans.is_empty(), - }; // Check to see if we actually need an allocator. This desire comes // about through the `#![needs_allocator]` attribute and is typically @@ -824,21 +801,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } } } - let mut alloc_error_handler = - self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate")); - for (_, data) in self.cstore.iter_crate_data() { - if data.has_alloc_error_handler() { - match alloc_error_handler { - Some(other_crate) => { - self.sess.emit_err(errors::ConflictingAllocErrorHandler { - crate_name: data.name(), - other_crate_name: other_crate, - }); - } - None => alloc_error_handler = Some(data.name()), - } - } - } if global_allocator.is_some() { self.cstore.allocator_kind = Some(AllocatorKind::Global); @@ -854,14 +816,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } self.cstore.allocator_kind = Some(AllocatorKind::Default); } - - if alloc_error_handler.is_some() { - self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Global); - } else { - // The alloc crate provides a default allocation error handler if - // one isn't specified. - self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default); - } } fn inject_dependency_if( @@ -1037,28 +991,6 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> { f.spans } -fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> { - struct Finder { - name: Symbol, - spans: Vec<Span>, - } - impl<'ast> visit::Visitor<'ast> for Finder { - fn visit_item(&mut self, item: &'ast ast::Item) { - if item.ident.name == self.name - && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) - { - self.spans.push(item.span); - } - visit::walk_item(self, item) - } - } - - let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::oom)); - let mut f = Finder { name, spans: Vec::new() }; - visit::walk_crate(&mut f, krate); - f.spans -} - // On Windows the compiler would sometimes intermittently fail to open the // proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the // system still holds a lock on the file, so we retry a few times before calling it diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 51b41b5f6a2..7ecb551a3e5 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -353,16 +353,6 @@ pub struct NoMultipleGlobalAlloc { } #[derive(Diagnostic)] -#[diag(metadata_no_multiple_alloc_error_handler)] -pub struct NoMultipleAllocErrorHandler { - #[primary_span] - #[label] - pub span2: Span, - #[label(metadata_prev_alloc_error_handler)] - pub span1: Span, -} - -#[derive(Diagnostic)] #[diag(metadata_conflicting_global_alloc)] pub struct ConflictingGlobalAlloc { pub crate_name: Symbol, @@ -370,13 +360,6 @@ pub struct ConflictingGlobalAlloc { } #[derive(Diagnostic)] -#[diag(metadata_conflicting_alloc_error_handler)] -pub struct ConflictingAllocErrorHandler { - pub crate_name: Symbol, - pub other_crate_name: Symbol, -} - -#[derive(Diagnostic)] #[diag(metadata_global_alloc_required)] pub struct GlobalAllocRequired; diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 81e62eccb8a..9f664d0f0c8 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -28,7 +28,7 @@ extern crate tracing; pub use rmeta::{provide, provide_extern}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; mod dependency_format; mod foreign_modules; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 951fb303e3c..c9ab07f5f27 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -876,16 +876,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { variant_did, ctor, data.discr, - self.root - .tables - .children - .get(self, index) - .expect("fields are not encoded for a variant") - .decode(self) - .map(|index| ty::FieldDef { - did: self.local_def_id(index), - name: self.item_name(index), - vis: self.get_visibility(index), + self.get_associated_item_or_field_def_ids(index) + .map(|did| ty::FieldDef { + did, + name: self.item_name(did.index), + vis: self.get_visibility(did.index), }) .collect(), adt_kind, @@ -910,7 +905,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let variants = if let ty::AdtKind::Enum = adt_kind { self.root .tables - .children + .module_children_non_reexports .get(self, item_id) .expect("variants are not encoded for an enum") .decode(self) @@ -1022,11 +1017,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } else { // Iterate over all children. - for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) { - // FIXME: Do not encode RPITITs as a part of this list. - if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() { - yield self.get_mod_child(child_index, sess); - } + let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); + for child_index in non_reexports.unwrap().decode(self) { + yield self.get_mod_child(child_index, sess); } let reexports = self.root.tables.module_children_reexports.get(self, id); @@ -1058,17 +1051,16 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .map_or(false, |ident| ident.name == kw::SelfLower) } - fn get_associated_item_def_ids( + fn get_associated_item_or_field_def_ids( self, id: DefIndex, - sess: &'a Session, ) -> impl Iterator<Item = DefId> + 'a { self.root .tables - .children + .associated_item_or_field_def_ids .get(self, id) - .expect("associated items not encoded for an item") - .decode((self, sess)) + .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id)) + .decode(self) .map(move |child_index| self.local_def_id(child_index)) } @@ -1691,10 +1683,6 @@ impl CrateMetadata { self.root.has_global_allocator } - pub(crate) fn has_alloc_error_handler(&self) -> bool { - self.root.has_alloc_error_handler - } - pub(crate) fn has_default_lib_allocator(&self) -> bool { self.root.has_default_lib_allocator } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 31798afb852..4aa3768fc3b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -276,7 +276,7 @@ provide! { tcx, def_id, other, cdata, tcx.calculate_dtor(def_id, |_,_| Ok(())) } associated_item_def_ids => { - tcx.arena.alloc_from_iter(cdata.get_associated_item_def_ids(def_id.index, tcx.sess)) + tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) } associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } @@ -290,7 +290,6 @@ provide! { tcx, def_id, other, cdata, is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } - has_alloc_error_handler => { cdata.root.has_alloc_error_handler } has_panic_handler => { cdata.root.has_panic_handler } is_profiler_runtime => { cdata.root.profiler_runtime } required_panic_strategy => { cdata.root.required_panic_strategy } @@ -379,7 +378,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { // resolve! Does this work? Unsure! That's what the issue is about *providers = Providers { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), - alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) @@ -496,7 +494,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)), has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(), - has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(), postorder_cnums: |tcx, ()| { tcx.arena .alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE)) @@ -516,14 +513,6 @@ impl CStore { self.get_crate_data(def.krate).get_ctor(def.index) } - pub fn module_children_untracked<'a>( - &'a self, - def_id: DefId, - sess: &'a Session, - ) -> impl Iterator<Item = ModChild> + 'a { - self.get_crate_data(def_id.krate).get_module_children(def_id.index, sess) - } - pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { let _prof_timer = sess.prof.generic_activity("metadata_load_macro"); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index d6500cd93a7..fd8e49efea0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -676,7 +676,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(), has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), - has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE), has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), has_default_lib_allocator: attr::contains_name(&attrs, sym::default_lib_allocator), proc_macro_data, @@ -824,6 +823,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::AssocTy | DefKind::TyParam | DefKind::ConstParam + | DefKind::LifetimeParam | DefKind::Fn | DefKind::Const | DefKind::Static(_) @@ -840,10 +840,7 @@ fn should_encode_span(def_kind: DefKind) -> bool { | DefKind::Impl { .. } | DefKind::Closure | DefKind::Generator => true, - DefKind::ForeignMod - | DefKind::ImplTraitPlaceholder - | DefKind::LifetimeParam - | DefKind::GlobalAsm => false, + DefKind::ForeignMod | DefKind::ImplTraitPlaceholder | DefKind::GlobalAsm => false, } } @@ -1367,7 +1364,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if adt_def.is_enum() { let module_children = tcx.module_children_non_reexports(local_def_id); - record_array!(self.tables.children[def_id] <- + record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().map(|def_id| def_id.local_def_index)); } else { // For non-enum, there is only one variant, and its def_id is the adt's. @@ -1385,7 +1382,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.variant_data[variant.def_id] <- data); self.tables.constness.set_some(variant.def_id.index, hir::Constness::Const); - record_array!(self.tables.children[variant.def_id] <- variant.fields.iter().map(|f| { + record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index })); @@ -1415,7 +1412,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id)); } else { let non_reexports = tcx.module_children_non_reexports(local_def_id); - record_array!(self.tables.children[def_id] <- + record_array!(self.tables.module_children_non_reexports[def_id] <- non_reexports.iter().map(|def_id| def_id.local_def_index)); record_defaulted_array!(self.tables.module_children_reexports[def_id] <- @@ -1539,8 +1536,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); - let instance = - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id())); + let instance = ty::InstanceDef::Item(def_id.to_def_id()); let unused = tcx.unused_generic_params(instance); self.tables.unused_generic_params.set(def_id.local_def_index, unused); } @@ -1618,7 +1614,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_info_for_item({:?})", def_id); let record_associated_item_def_ids = |this: &mut Self, def_ids: &[DefId]| { - record_array!(this.tables.children[def_id] <- def_ids.iter().map(|&def_id| { + record_array!(this.tables.associated_item_or_field_def_ids[def_id] <- def_ids.iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index })) @@ -1679,6 +1675,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Trait(..) => { record!(self.tables.trait_def[def_id] <- self.tcx.trait_def(def_id)); + let module_children = tcx.module_children_non_reexports(item.owner_id.def_id); + record_array!(self.tables.module_children_non_reexports[def_id] <- + module_children.iter().map(|def_id| def_id.local_def_index)); + let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record_associated_item_def_ids(self, associated_item_def_ids); for &item_def_id in associated_item_def_ids { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index a6a34765324..ee1c495ed1e 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -225,7 +225,6 @@ pub(crate) struct CrateRoot { panic_in_drop_strategy: PanicStrategy, edition: Edition, has_global_allocator: bool, - has_alloc_error_handler: bool, has_panic_handler: bool, has_default_lib_allocator: bool, @@ -361,7 +360,8 @@ define_tables! { - optional: attributes: Table<DefIndex, LazyArray<ast::Attribute>>, - children: Table<DefIndex, LazyArray<DefIndex>>, + module_children_non_reexports: Table<DefIndex, LazyArray<DefIndex>>, + associated_item_or_field_def_ids: Table<DefIndex, LazyArray<DefIndex>>, opt_def_kind: Table<DefIndex, DefKind>, visibility: Table<DefIndex, LazyValue<ty::Visibility<DefIndex>>>, def_span: Table<DefIndex, LazyValue<Span>>, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 5b2ec9029b1..dfbe8ac0ba3 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -21,6 +21,7 @@ rustc_errors = { path = "../rustc_errors" } # Used for intra-doc links rustc_error_messages = { path = "../rustc_error_messages" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 82e396a9dd3..2dc5b896993 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -364,7 +364,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { #[inline(always)] fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { let HirId { owner, local_id } = *self; - format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32()) + format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32()) } #[inline(always)] diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 64aff27744f..5c01a661326 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1217,7 +1217,7 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { } fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id.to_def_id()); + let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 2fa769d3abb..76a8367b2c4 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -75,7 +75,7 @@ extern crate tracing; extern crate smallvec; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; #[cfg(test)] mod tests; diff --git a/compiler/rustc_middle/src/mir/graphviz.rs b/compiler/rustc_middle/src/mir/graphviz.rs index cf6d46e1e2c..2de73db3a3c 100644 --- a/compiler/rustc_middle/src/mir/graphviz.rs +++ b/compiler/rustc_middle/src/mir/graphviz.rs @@ -16,19 +16,16 @@ where { let def_ids = dump_mir_def_ids(tcx, single); - let mirs = - def_ids - .iter() - .flat_map(|def_id| { - if tcx.is_const_fn_raw(*def_id) { - vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)] - } else { - vec![tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - *def_id, - )))] - } - }) - .collect::<Vec<_>>(); + let mirs = def_ids + .iter() + .flat_map(|def_id| { + if tcx.is_const_fn_raw(*def_id) { + vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)] + } else { + vec![tcx.instance_mir(ty::InstanceDef::Item(*def_id))] + } + }) + .collect::<Vec<_>>(); let use_subgraphs = mirs.len() > 1; if use_subgraphs { diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 856d821a5cf..ed4ee93e97d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -42,7 +42,7 @@ impl<'tcx> TyCtxt<'tcx> { span: Option<Span>, ) -> EvalToConstValueResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference - // variables. We reject those here since `resolve_opt_const_arg` + // variables. We reject those here since `resolve` // would fail otherwise. // // When trying to evaluate constants containing inference variables, @@ -51,7 +51,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve_opt_const_arg( + match ty::Instance::resolve( self, param_env, // FIXME: maybe have a separate version for resolving mir::UnevaluatedConst? ct.def, ct.substs, @@ -73,7 +73,7 @@ impl<'tcx> TyCtxt<'tcx> { span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { // Cannot resolve `Unevaluated` constants that contain inference - // variables. We reject those here since `resolve_opt_const_arg` + // variables. We reject those here since `resolve` // would fail otherwise. // // When trying to evaluate constants containing inference variables, @@ -82,7 +82,7 @@ impl<'tcx> TyCtxt<'tcx> { bug!("did not expect inference variables here"); } - match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) { + match ty::Instance::resolve(self, param_env, ct.def, ct.substs) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| { @@ -94,14 +94,14 @@ impl<'tcx> TyCtxt<'tcx> { // used generic parameters is a bug of evaluation, so checking for it // here does feel somewhat sensible. if !self.features().generic_const_exprs && ct.substs.has_non_region_param() { - assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst)); - let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def); + assert!(matches!(self.def_kind(ct.def), DefKind::AnonConst)); + let mir_body = self.mir_for_ctfe(ct.def); if mir_body.is_polymorphic { - let Some(local_def_id) = ct.def.did.as_local() else { return }; + let Some(local_def_id) = ct.def.as_local() else { return }; self.struct_span_lint_hir( lint::builtin::CONST_EVALUATABLE_UNCHECKED, self.hir().local_def_id_to_hir_id(local_def_id), - self.def_span(ct.def.did), + self.def_span(ct.def), "cannot use constants which depend on generic parameters in types", |err| err, ) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index f985aae9a22..6b6a2e561f5 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -191,20 +191,13 @@ pub struct MirSource<'tcx> { impl<'tcx> MirSource<'tcx> { pub fn item(def_id: DefId) -> Self { - MirSource { - instance: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - promoted: None, - } + MirSource { instance: InstanceDef::Item(def_id), promoted: None } } pub fn from_instance(instance: InstanceDef<'tcx>) -> Self { MirSource { instance, promoted: None } } - pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> { - self.instance.with_opt_param() - } - #[inline] pub fn def_id(&self) -> DefId { self.instance.def_id() @@ -2048,7 +2041,11 @@ impl<'tcx> Debug for Rvalue<'tcx> { } UnaryOp(ref op, ref a) => write!(fmt, "{:?}({:?})", op, a), Discriminant(ref place) => write!(fmt, "discriminant({:?})", place), - NullaryOp(ref op, ref t) => write!(fmt, "{:?}({:?})", op, t), + NullaryOp(ref op, ref t) => match op { + NullOp::SizeOf => write!(fmt, "SizeOf({:?})", t), + NullOp::AlignOf => write!(fmt, "AlignOf({:?})", t), + NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({:?}, {:?})", t, fields), + }, ThreadLocalRef(did) => ty::tls::with(|tcx| { let muta = tcx.static_mutability(did).unwrap().prefix_str(); write!(fmt, "&/*tls*/ {}{}", muta, tcx.def_path_str(did)) @@ -2436,16 +2433,6 @@ impl<'tcx> ConstantKind<'tcx> { Self::Val(val, ty) } - /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly - /// converted to a constant, everything else becomes `Unevaluated`. - pub fn from_anon_const( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { - Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id), param_env) - } - #[instrument(skip(tcx), level = "debug", ret)] pub fn from_inline_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); @@ -2485,28 +2472,25 @@ impl<'tcx> ConstantKind<'tcx> { ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty }) .substs; - let uneval = UnevaluatedConst { - def: ty::WithOptConstParam::unknown(def_id).to_global(), - substs, - promoted: None, - }; + let uneval = UnevaluatedConst { def: def_id.to_def_id(), substs, promoted: None }; debug_assert!(!uneval.has_free_regions()); Self::Unevaluated(uneval, ty) } + /// Literals are converted to `ConstantKindVal`, const generic parameters are eagerly + /// converted to a constant, everything else becomes `Unevaluated`. #[instrument(skip(tcx), level = "debug", ret)] - fn from_opt_const_arg_anon_const( + pub fn from_anon_const( tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, param_env: ty::ParamEnv<'tcx>, ) -> Self { - let body_id = match tcx.hir().get_by_def_id(def.did) { + let body_id = match tcx.hir().get_by_def_id(def) { hir::Node::AnonConst(ac) => ac.body, - _ => span_bug!( - tcx.def_span(def.did.to_def_id()), - "from_anon_const can only process anonymous constants" - ), + _ => { + span_bug!(tcx.def_span(def), "from_anon_const can only process anonymous constants") + } }; let expr = &tcx.hir().body(body_id).value; @@ -2522,7 +2506,7 @@ impl<'tcx> ConstantKind<'tcx> { }; debug!("expr.kind: {:?}", expr.kind); - let ty = tcx.type_of(def.def_id_for_type_of()).subst_identity(); + let ty = tcx.type_of(def).subst_identity(); debug!(?ty); // FIXME(const_generics): We currently have to special case parameters because `min_const_generics` @@ -2549,7 +2533,7 @@ impl<'tcx> ConstantKind<'tcx> { _ => {} } - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); let parent_substs = if let Some(parent_hir_id) = tcx.hir().opt_parent_id(hir_id) && let Some(parent_did) = parent_hir_id.as_owner() { @@ -2559,15 +2543,14 @@ impl<'tcx> ConstantKind<'tcx> { }; debug!(?parent_substs); - let did = def.did.to_def_id(); + let did = def.to_def_id(); let child_substs = InternalSubsts::identity_for_item(tcx, did); let substs = tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter())); debug!(?substs); - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let span = tcx.hir().span(hir_id); - let uneval = UnevaluatedConst::new(def.to_global(), substs); + let span = tcx.def_span(def); + let uneval = UnevaluatedConst::new(did, substs); debug!(?span, ?param_env); match tcx.const_eval_resolve(param_env, uneval, Some(span)) { @@ -2581,8 +2564,8 @@ impl<'tcx> ConstantKind<'tcx> { // new unevaluated const and error hard later in codegen Self::Unevaluated( UnevaluatedConst { - def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did), + def: did, + substs: InternalSubsts::identity_for_item(tcx, did), promoted: None, }, ty, @@ -2607,7 +2590,7 @@ impl<'tcx> ConstantKind<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { - pub def: ty::WithOptConstParam<DefId>, + pub def: DefId, pub substs: SubstsRef<'tcx>, pub promoted: Option<Promoted>, } @@ -2623,10 +2606,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { impl<'tcx> UnevaluatedConst<'tcx> { #[inline] - pub fn new( - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> UnevaluatedConst<'tcx> { + pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> { UnevaluatedConst { def, substs, promoted: Default::default() } } } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index a9468a90b53..67235f0f524 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -373,7 +373,7 @@ impl<'tcx> CodegenUnit<'tcx> { // instances into account. The others don't matter for // the codegen tests and can even make item order // unstable. - InstanceDef::Item(def) => def.did.as_local().map(Idx::index), + InstanceDef::Item(def) => def.as_local().map(Idx::index), InstanceDef::VTableShim(..) | InstanceDef::ReifyShim(..) | InstanceDef::Intrinsic(..) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 7e51953599d..89510bbb3aa 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -298,8 +298,7 @@ pub fn write_mir_pretty<'tcx>( // are shared between mir_for_ctfe and optimized_mir write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?; } else { - let instance_mir = - tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id))); + let instance_mir = tcx.instance_mir(ty::InstanceDef::Item(def_id)); render_body(w, instance_mir)?; } } @@ -464,11 +463,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ConstantKind::Ty(ct) => match ct.kind() { ty::ConstKind::Param(p) => format!("Param({})", p), ty::ConstKind::Unevaluated(uv) => { - format!( - "Unevaluated({}, {:?})", - self.tcx.def_path_str(uv.def.did), - uv.substs, - ) + format!("Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.substs,) } ty::ConstKind::Value(val) => format!("Value({})", fmt_valtree(&val)), ty::ConstKind::Error(_) => "Error".to_string(), @@ -481,7 +476,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> { ConstantKind::Unevaluated(uv, _) => { format!( "Unevaluated({}, {:?}, {:?})", - self.tcx.def_path_str(uv.def.did), + self.tcx.def_path_str(uv.def), uv.substs, uv.promoted, ) diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index cfdf1dcf5c0..17eaf3e08d8 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -1,12 +1,12 @@ //! Values computed by queries that use MIR. -use crate::mir::{Body, ConstantKind, Promoted}; +use crate::mir::ConstantKind; use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordSet; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::BitMatrix; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::Span; @@ -454,42 +454,3 @@ pub struct CoverageInfo { /// The total number of coverage region counter expressions added to the MIR `Body`. pub num_expressions: u32, } - -/// Shims which make dealing with `WithOptConstParam` easier. -/// -/// For more information on why this is needed, consider looking -/// at the docs for `WithOptConstParam` itself. -impl<'tcx> TyCtxt<'tcx> { - #[inline] - pub fn mir_const_qualif_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> ConstQualifs { - if let Some(param_did) = def.const_param_did { - self.mir_const_qualif_const_arg((def.did, param_did)) - } else { - self.mir_const_qualif(def.did) - } - } - - #[inline] - pub fn promoted_mir_opt_const_arg( - self, - def: ty::WithOptConstParam<DefId>, - ) -> &'tcx IndexVec<Promoted, Body<'tcx>> { - if let Some((did, param_did)) = def.as_const_arg() { - self.promoted_mir_of_const_arg((did, param_did)) - } else { - self.promoted_mir(def.did) - } - } - - #[inline] - pub fn mir_for_ctfe_opt_const_arg(self, def: ty::WithOptConstParam<DefId>) -> &'tcx Body<'tcx> { - if let Some((did, param_did)) = def.as_const_arg() { - self.mir_for_ctfe_of_const_arg((did, param_did)) - } else { - self.mir_for_ctfe(def.did) - } - } -} diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c38a347809f..69ce6835ba6 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -331,9 +331,8 @@ pub enum StatementKind<'tcx> { /// This is especially useful for `let _ = PLACE;` bindings that desugar to a single /// `PlaceMention(PLACE)`. /// - /// When executed at runtime this is a nop. - /// - /// Disallowed after drop elaboration. + /// When executed at runtime, this computes the given place, but then discards + /// it without doing a load. It is UB if the place is not pointing to live memory. PlaceMention(Box<Place<'tcx>>), /// Encodes a user's type ascription. These need to be preserved @@ -1115,7 +1114,7 @@ pub enum Rvalue<'tcx> { CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>), /// Computes a value as described by the operation. - NullaryOp(NullOp, Ty<'tcx>), + NullaryOp(NullOp<'tcx>, Ty<'tcx>), /// Exactly like `BinaryOp`, but less operands. /// @@ -1211,12 +1210,14 @@ pub enum AggregateKind<'tcx> { Generator(DefId, SubstsRef<'tcx>, hir::Movability), } -#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] -pub enum NullOp { +#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] +pub enum NullOp<'tcx> { /// Returns the size of a value of that type SizeOf, /// Returns the minimum alignment of a type AlignOf, + /// Returns the offset of a field + OffsetOf(&'tcx List<FieldIdx>), } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 4f00abf7fab..5ca82413448 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -188,7 +188,9 @@ impl<'tcx> Rvalue<'tcx> { } Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx), Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize, + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => { + tcx.types.usize + } Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), AggregateKind::Tuple => { diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ace856b9f95..06874741bb0 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -16,7 +16,6 @@ TrivialTypeTraversalAndLiftImpls! { UserTypeAnnotationIndex, BorrowKind, CastKind, - NullOp, hir::Movability, BasicBlock, SwitchTargets, @@ -26,6 +25,7 @@ TrivialTypeTraversalAndLiftImpls! { TrivialTypeTraversalImpls! { ConstValue<'tcx>, + NullOp<'tcx>, } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] { diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index 23b28ac5ca9..fa62b7f32b1 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -174,14 +174,6 @@ impl AsLocalKey for DefId { } } -impl Key for ty::WithOptConstParam<LocalDefId> { - type CacheSelector = DefaultCacheSelector<Self>; - - fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - self.did.default_span(tcx) - } -} - impl Key for SimplifiedType { type CacheSelector = DefaultCacheSelector<Self>; @@ -313,7 +305,7 @@ impl<'tcx> Key for (ty::UnevaluatedConst<'tcx>, ty::UnevaluatedConst<'tcx>) { type CacheSelector = DefaultCacheSelector<Self>; fn default_span(&self, tcx: TyCtxt<'_>) -> Span { - (self.0).def.did.default_span(tcx) + (self.0).def.default_span(tcx) } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7e26e05025f..4b7bc60926e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -83,7 +83,7 @@ rustc_queries! { /// Avoid calling this query directly. query hir_module_items(key: LocalDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache - desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -92,14 +92,14 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner(key: hir::OwnerId) -> Option<crate::hir::Owner<'tcx>> { - desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// /// Definitions that were generated with no HIR, would be fed to return `None`. query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{ - desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } feedable } @@ -108,7 +108,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_parent(key: hir::OwnerId) -> hir::HirId { - desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR nodes and bodies inside the HIR owner `key`. @@ -116,7 +116,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_nodes(key: hir::OwnerId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> { - desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR attributes inside the HIR owner `key`. @@ -124,30 +124,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { - desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) } - } - - /// Computes the `DefId` of the corresponding const parameter in case the `key` is a - /// const argument and returns `None` otherwise. - /// - /// ```ignore (incomplete) - /// let a = foo::<7>(); - /// // ^ Calling `opt_const_param_of` for this argument, - /// - /// fn foo<const N: usize>() - /// // ^ returns this `DefId`. - /// - /// fn bar() { - /// // ^ While calling `opt_const_param_of` for other bodies returns `None`. - /// } - /// ``` - // It looks like caching this query on disk actually slightly - // worsened performance in #74376. - // - // Once const generics are more prevalently used, we might want to - // consider only caching calls returning `Some`. - query opt_const_param_of(key: LocalDefId) -> Option<DefId> { - desc { |tcx| "computing the optional const parameter of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } } /// Given the def_id of a const-generic parameter, computes the associated default const @@ -318,7 +295,7 @@ rustc_queries! { query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { eval_always // fetches `resolutions` arena_cache - desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } } query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { @@ -328,7 +305,7 @@ rustc_queries! { query parent_module_from_def_id(key: LocalDefId) -> LocalDefId { eval_always - desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key) } } query expn_that_defined(key: DefId) -> rustc_span::ExpnId { @@ -344,7 +321,7 @@ rustc_queries! { /// Checks whether a type is representable or infinitely sized query representability(_: LocalDefId) -> rustc_middle::ty::Representability { - desc { "checking if `{}` is representable", tcx.def_path_str(key.to_def_id()) } + desc { "checking if `{}` is representable", tcx.def_path_str(key) } // infinitely sized types will cause a cycle cycle_delay_bug // we don't want recursive representability calls to be forced with @@ -369,26 +346,24 @@ rustc_queries! { } /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. - query thir_body(key: ty::WithOptConstParam<LocalDefId>) - -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> - { + query thir_body(key: LocalDefId) -> Result<(&'tcx Steal<thir::Thir<'tcx>>, thir::ExprId), ErrorGuaranteed> { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash - desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } } /// Create a THIR tree for debugging. - query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String { + query thir_tree(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) } } /// Create a list-like THIR representation for debugging. - query thir_flat(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx String { + query thir_flat(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) } } /// Set of all the `DefId`s in this crate that have MIR associated with @@ -407,31 +382,19 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - query mir_const_qualif_const_arg( - key: (LocalDefId, DefId) - ) -> mir::ConstQualifs { - desc { - |tcx| "const checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. - query mir_built(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } + query mir_built(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } } /// Fetch the MIR for a given `DefId` up till the point where it is /// ready for const qualification. /// /// See the README for the `mir` module for details. - query mir_const(key: ty::WithOptConstParam<LocalDefId>) -> &'tcx Steal<mir::Body<'tcx>> { - desc { - |tcx| "preparing {}`{}` for borrow checking", - if key.const_param_did.is_some() { "the const argument " } else { "" }, - tcx.def_path_str(key.did.to_def_id()), - } + query mir_const(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { + desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) } no_hash } @@ -444,22 +407,10 @@ rustc_queries! { } separate_provide_extern } - /// Try to build an abstract representation of the given constant. - query thir_abstract_const_of_const_arg( - key: (LocalDefId, DefId) - ) -> Result<Option<ty::Const<'tcx>>, ErrorGuaranteed> { - desc { - |tcx| - "building an abstract representation for the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } - query mir_drops_elaborated_and_const_checked( - key: ty::WithOptConstParam<LocalDefId> - ) -> &'tcx Steal<mir::Body<'tcx>> { + query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal<mir::Body<'tcx>> { no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.did.to_def_id()) } + desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } } query mir_for_ctfe( @@ -470,30 +421,18 @@ rustc_queries! { separate_provide_extern } - query mir_for_ctfe_of_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::Body<'tcx> { - desc { - |tcx| "caching MIR for CTFE of the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } - - query mir_promoted(key: ty::WithOptConstParam<LocalDefId>) -> - ( - &'tcx Steal<mir::Body<'tcx>>, - &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> - ) { + query mir_promoted(key: LocalDefId) -> ( + &'tcx Steal<mir::Body<'tcx>>, + &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>> + ) { no_hash - desc { - |tcx| "processing MIR for {}`{}`", - if key.const_param_did.is_some() { "the const argument " } else { "" }, - tcx.def_path_str(key.did.to_def_id()), - } + desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } } query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { desc { |tcx| "finding symbols for captures of closure `{}`", - tcx.def_path_str(key.to_def_id()) + tcx.def_path_str(key) } } @@ -505,7 +444,7 @@ rustc_queries! { } query check_generator_obligations(key: LocalDefId) { - desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key) } } /// MIR after our optimization passes have run. This is MIR that is ready @@ -544,14 +483,6 @@ rustc_queries! { cache_on_disk_if { key.is_local() } separate_provide_extern } - query promoted_mir_of_const_arg( - key: (LocalDefId, DefId) - ) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { - desc { - |tcx| "optimizing promoted MIR for the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } /// Erases regions from `ty` to yield a new type. /// Normally you would just use `tcx.erase_regions(value)`, @@ -595,7 +526,7 @@ rustc_queries! { /// `explicit_predicates_of` and `explicit_item_bounds` will then take /// the appropriate subsets of the predicates here. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } /// Returns the predicates written explicitly by the user. @@ -739,9 +670,10 @@ rustc_queries! { desc { "computing the inferred outlives predicates for items in this crate" } } - /// Maps from an impl/trait `DefId` to a list of the `DefId`s of its items. + /// Maps from an impl/trait or struct/variant `DefId` + /// to a list of the `DefId`s of its associated items or fields. query associated_item_def_ids(key: DefId) -> &'tcx [DefId] { - desc { |tcx| "collecting associated items of `{}`", tcx.def_path_str(key) } + desc { |tcx| "collecting associated items or fields of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern } @@ -837,28 +769,16 @@ rustc_queries! { /// The result of unsafety-checking this `LocalDefId`. query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query unsafety_check_result_for_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::UnsafetyCheckResult { - desc { - |tcx| "unsafety-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be /// used with `-Zthir-unsafeck`. query thir_check_unsafety(key: LocalDefId) { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query thir_check_unsafety_for_const_arg(key: (LocalDefId, DefId)) { - desc { - |tcx| "unsafety-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Returns the types assumed to be well formed while "inside" of the given item. /// @@ -913,7 +833,7 @@ rustc_queries! { desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } } - query check_liveness(key: DefId) { + query check_liveness(key: LocalDefId) { desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) } } @@ -952,29 +872,17 @@ rustc_queries! { separate_provide_extern } - query typeck_item_bodies(_: ()) -> () { - desc { "type-checking all item bodies" } - } - query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } - query typeck_const_arg( - key: (LocalDefId, DefId) - ) -> &'tcx ty::TypeckResults<'tcx> { - desc { - |tcx| "type-checking the const argument `{}`", - tcx.def_path_str(key.0.to_def_id()), - } - } query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet<LocalDefId> { - desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -989,15 +897,9 @@ rustc_queries! { /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> { - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } } - query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> { - desc { - |tcx| "borrow-checking the const argument`{}`", - tcx.def_path_str(key.0.to_def_id()) - } - } /// Gets a complete map from all types to their inherent impls. /// Not meant to be used directly outside of coherence. @@ -1017,7 +919,7 @@ rustc_queries! { query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking whether impl `{}` follows the orphan rules", - tcx.def_path_str(key.to_def_id()), + tcx.def_path_str(key), } } @@ -1029,7 +931,7 @@ rustc_queries! { desc { |tcx| "computing if `{}` (transitively) calls `{}`", key.0, - tcx.def_path_str(key.1.to_def_id()), + tcx.def_path_str(key.1), } } @@ -1120,7 +1022,7 @@ rustc_queries! { } query check_match(key: LocalDefId) { - desc { |tcx| "match-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -1449,13 +1351,6 @@ rustc_queries! { desc { "checking if the crate has_global_allocator" } separate_provide_extern } - query has_alloc_error_handler(_: CrateNum) -> bool { - // This query depends on untracked global state in CStore - eval_always - fatal_cycle - desc { "checking if the crate has_alloc_error_handler" } - separate_provide_extern - } query has_panic_handler(_: CrateNum) -> bool { fatal_cycle desc { "checking if the crate has_panic_handler" } @@ -1467,7 +1362,7 @@ rustc_queries! { separate_provide_extern } query has_ffi_unwind_calls(key: LocalDefId) -> bool { - desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } cache_on_disk_if { true } } query required_panic_strategy(_: CrateNum) -> Option<PanicStrategy> { @@ -1513,7 +1408,7 @@ rustc_queries! { } query check_well_formed(key: hir::OwnerId) -> () { - desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } } // The `DefId`s of all non-generic functions and statics in the given crate @@ -1542,7 +1437,7 @@ rustc_queries! { query is_unreachable_local_definition(def_id: LocalDefId) -> bool { desc { |tcx| "checking whether `{}` is reachable from outside the crate", - tcx.def_path_str(def_id.to_def_id()), + tcx.def_path_str(def_id), } } @@ -1736,7 +1631,7 @@ rustc_queries! { separate_provide_extern } query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> { - desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) } } query lib_features(_: ()) -> &'tcx LibFeatures { @@ -1828,10 +1723,6 @@ rustc_queries! { eval_always desc { "getting the allocator kind for the current crate" } } - query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> { - eval_always - desc { "alloc error handler kind for the current crate" } - } query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> { desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } @@ -1840,7 +1731,7 @@ rustc_queries! { desc { "fetching potentially unused trait imports" } } query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet<Symbol> { - desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) } } query stability_index(_: ()) -> &'tcx stability::Index { @@ -2117,15 +2008,6 @@ rustc_queries! { desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) } } - query resolve_instance_of_const_arg( - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)> - ) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> { - desc { - "resolving instance of the const argument `{}`", - ty::Instance::new(key.value.0.to_def_id(), key.value.2), - } - } - query reveal_opaque_types_in_bounds(key: &'tcx ty::List<ty::Predicate<'tcx>>) -> &'tcx ty::List<ty::Predicate<'tcx>> { desc { "revealing opaque types in `{:?}`", key } } @@ -2172,7 +2054,7 @@ rustc_queries! { query compare_impl_const( key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.to_def_id()) } + desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0) } } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 7d79a13d3fd..8700a98b365 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -20,7 +20,7 @@ use rustc_middle::mir::interpret::AllocId; use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp}; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts}; +use rustc_middle::ty::{self, AdtDef, FnSig, List, Ty, UpvarSubsts}; use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; @@ -481,6 +481,11 @@ pub enum ExprKind<'tcx> { }, /// Inline assembly, i.e. `asm!()`. InlineAsm(Box<InlineAsmExpr<'tcx>>), + /// Field offset (`offset_of!`) + OffsetOf { + container: Ty<'tcx>, + fields: &'tcx List<FieldIdx>, + }, /// An expression taking a reference to a thread local. ThreadLocalRef(DefId), /// A `yield` expression. @@ -929,8 +934,8 @@ mod size_asserts { static_assert_size!(Block, 56); static_assert_size!(Expr<'_>, 64); static_assert_size!(ExprKind<'_>, 40); - static_assert_size!(Pat<'_>, 72); - static_assert_size!(PatKind<'_>, 56); + static_assert_size!(Pat<'_>, 64); + static_assert_size!(PatKind<'_>, 48); static_assert_size!(Stmt<'_>, 56); static_assert_size!(StmtKind<'_>, 48); // tidy-alphabetical-end diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs index 5614528c4cb..5c7ec31cf93 100644 --- a/compiler/rustc_middle/src/thir/visit.rs +++ b/compiler/rustc_middle/src/thir/visit.rs @@ -160,6 +160,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp } } } + OffsetOf { container: _, fields: _ } => {} ThreadLocalRef(_) => {} Yield { value } => visitor.visit_expr(&visitor.thir()[value]), } diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 223b763e34b..029cf793ad8 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -36,15 +36,8 @@ pub type BoundAbstractConst<'tcx> = Result<Option<EarlyBinder<ty::Const<'tcx>>>, impl<'tcx> TyCtxt<'tcx> { /// Returns a const without substs applied - pub fn bound_abstract_const( - self, - uv: ty::WithOptConstParam<DefId>, - ) -> BoundAbstractConst<'tcx> { - let ac = if let Some((did, param_did)) = uv.as_const_arg() { - self.thir_abstract_const_of_const_arg((did, param_did)) - } else { - self.thir_abstract_const(uv.did) - }; + pub fn bound_abstract_const(self, uv: DefId) -> BoundAbstractConst<'tcx> { + let ac = self.thir_abstract_const(uv); Ok(ac?.map(|ac| EarlyBinder(ac))) } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 8ef4a46a733..5454d406dd1 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -19,6 +19,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; use rustc_serialize::{Decodable, Encodable}; use rustc_span::Span; +use rustc_target::abi::FieldIdx; pub use rustc_type_ir::{TyDecoder, TyEncoder}; use std::hash::Hash; use std::intrinsics; @@ -401,6 +402,15 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty } } +impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<FieldIdx> { + fn decode(decoder: &mut D) -> &'tcx Self { + let len = decoder.read_usize(); + decoder + .interner() + .mk_fields_from_iter((0..len).map::<FieldIdx, _>(|_| Decodable::decode(decoder))) + } +} + impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List<Ty<'tcx>>, @@ -412,6 +422,7 @@ impl_decodable_via_ref! { &'tcx mir::coverage::CodeRegion, &'tcx ty::List<ty::BoundVariableKind>, &'tcx ty::List<ty::Predicate<'tcx>>, + &'tcx ty::List<FieldIdx>, } #[macro_export] diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index bcedae233d9..0a191ff7626 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -53,19 +53,12 @@ impl<'tcx> Const<'tcx> { /// Literals and const generic parameters are eagerly converted to a constant, everything else /// becomes `Unevaluated`. - pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { - Self::from_opt_const_arg_anon_const(tcx, ty::WithOptConstParam::unknown(def_id)) - } - #[instrument(skip(tcx), level = "debug")] - pub fn from_opt_const_arg_anon_const( - tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, - ) -> Self { - let body_id = match tcx.hir().get_by_def_id(def.did) { + pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self { + let body_id = match tcx.hir().get_by_def_id(def) { hir::Node::AnonConst(ac) => ac.body, _ => span_bug!( - tcx.def_span(def.did.to_def_id()), + tcx.def_span(def.to_def_id()), "from_anon_const can only process anonymous constants" ), }; @@ -73,17 +66,14 @@ impl<'tcx> Const<'tcx> { let expr = &tcx.hir().body(body_id).value; debug!(?expr); - let ty = tcx - .type_of(def.def_id_for_type_of()) - .no_bound_vars() - .expect("const parameter types cannot be generic"); + let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic"); match Self::try_eval_lit_or_param(tcx, ty, expr) { Some(v) => v, None => tcx.mk_const( ty::UnevaluatedConst { - def: def.to_global(), - substs: InternalSubsts::identity_for_item(tcx, def.did), + def: def.to_def_id(), + substs: InternalSubsts::identity_for_item(tcx, def.to_def_id()), }, ty, ), diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 560caa041a7..1ac2cd13982 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -17,7 +17,7 @@ use super::ScalarInt; #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] pub struct UnevaluatedConst<'tcx> { - pub def: ty::WithOptConstParam<DefId>, + pub def: DefId, pub substs: SubstsRef<'tcx>, } @@ -36,10 +36,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { impl<'tcx> UnevaluatedConst<'tcx> { #[inline] - pub fn new( - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> UnevaluatedConst<'tcx> { + pub fn new(def: DefId, substs: SubstsRef<'tcx>) -> UnevaluatedConst<'tcx> { UnevaluatedConst { def, substs } } } @@ -224,9 +221,9 @@ impl<'tcx> ConstKind<'tcx> { // FIXME(eddyb, skinny121) pass `InferCtxt` into here when it's available, so that // we can call `infcx.const_eval_resolve` which handles inference variables. let param_env_and = if (param_env, unevaluated).has_non_region_infer() { - tcx.param_env(unevaluated.def.did).and(ty::UnevaluatedConst { + tcx.param_env(unevaluated.def).and(ty::UnevaluatedConst { def: unevaluated.def, - substs: InternalSubsts::identity_for_item(tcx, unevaluated.def.did), + substs: InternalSubsts::identity_for_item(tcx, unevaluated.def), }) } else { tcx.erase_regions(param_env) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1871775ee4a..80d28b2e188 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -13,7 +13,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; -use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted}; +use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::query::LocalCrate; use crate::thir::Thir; use crate::traits; @@ -24,7 +24,7 @@ use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, Region, RegionKind, ReprOptions, - TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, TypeckResults, UintTy, Visibility, + TraitObjectVisitor, Ty, TyKind, TyVar, TyVid, TypeAndMut, UintTy, Visibility, }; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; use rustc_ast::{self as ast, attr}; @@ -80,6 +80,8 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; +use super::query::IntoQueryParam; + const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { @@ -141,6 +143,7 @@ pub struct CtxtInterners<'tcx> { type_: InternedSet<'tcx, WithCachedTypeInfo<TyKind<'tcx>>>, const_lists: InternedSet<'tcx, List<ty::Const<'tcx>>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, + type_lists: InternedSet<'tcx, List<Ty<'tcx>>>, canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>, region: InternedSet<'tcx, RegionKind<'tcx>>, poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>, @@ -154,6 +157,7 @@ pub struct CtxtInterners<'tcx> { layout: InternedSet<'tcx, LayoutS>, adt_def: InternedSet<'tcx, AdtDefData>, external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>, + fields: InternedSet<'tcx, List<FieldIdx>>, } impl<'tcx> CtxtInterners<'tcx> { @@ -163,6 +167,7 @@ impl<'tcx> CtxtInterners<'tcx> { type_: Default::default(), const_lists: Default::default(), substs: Default::default(), + type_lists: Default::default(), region: Default::default(), poly_existential_predicates: Default::default(), canonical_var_infos: Default::default(), @@ -176,6 +181,7 @@ impl<'tcx> CtxtInterners<'tcx> { layout: Default::default(), adt_def: Default::default(), external_constraints: Default::default(), + fields: Default::default(), } } @@ -447,6 +453,14 @@ impl<'tcx> TyCtxt<'tcx> { pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> { TyCtxtFeed { tcx: self, key: LOCAL_CRATE } } + + /// In order to break cycles involving `AnonConst`, we need to set the expected type by side + /// effect. However, we do not want this as a general capability, so this interface restricts + /// to the only allowed case. + pub fn feed_anon_const_type(self, key: LocalDefId, value: ty::EarlyBinder<Ty<'tcx>>) { + debug_assert_eq!(self.def_kind(key), DefKind::AnonConst); + TyCtxtFeed { tcx: self, key }.type_of(value) + } } impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> { @@ -581,28 +595,6 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn typeck_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> &'tcx TypeckResults<'tcx> { - if let Some(param_did) = def.const_param_did { - self.typeck_const_arg((def.did, param_did)) - } else { - self.typeck(def.did) - } - } - - pub fn mir_borrowck_opt_const_arg( - self, - def: ty::WithOptConstParam<LocalDefId>, - ) -> &'tcx BorrowCheckResult<'tcx> { - if let Some(param_did) = def.const_param_did { - self.mir_borrowck_const_arg((def.did, param_did)) - } else { - self.mir_borrowck(def.did) - } - } - pub fn alloc_steal_thir(self, thir: Thir<'tcx>) -> &'tcx Steal<Thir<'tcx>> { self.arena.alloc(Steal::new(thir)) } @@ -834,7 +826,8 @@ impl<'tcx> TyCtxt<'tcx> { self.features_query(()) } - pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { + pub fn def_key(self, id: impl IntoQueryParam<DefId>) -> rustc_hir::definitions::DefKey { + let id = id.into_query_param(); // Accessing the DefKey is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { self.definitions_untracked().def_key(id) @@ -1278,25 +1271,6 @@ macro_rules! nop_lift { }; } -// Can't use the macros as we have reuse the `substs` here. -// -// See `mk_type_list` for more info. -impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> { - type Lifted = &'tcx List<Ty<'tcx>>; - fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - if self.is_empty() { - return Some(List::empty()); - } - - tcx.interners - .substs - .contains_pointer_to(&InternedInSet(self.as_substs())) - // SAFETY: `self` is interned and therefore valid - // for the entire lifetime of the `TyCtxt`. - .then(|| unsafe { mem::transmute::<&'a List<Ty<'a>>, &'tcx List<Ty<'tcx>>>(self) }) - } -} - macro_rules! nop_list_lift { ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { @@ -1320,6 +1294,7 @@ nop_lift! {const_; Const<'a> => Const<'tcx>} nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>} nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>} +nop_list_lift! {type_lists; Ty<'a> => Ty<'tcx>} nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} @@ -1594,12 +1569,14 @@ macro_rules! slice_interners { slice_interners!( const_lists: pub mk_const_list(Const<'tcx>), substs: pub mk_substs(GenericArg<'tcx>), + type_lists: pub mk_type_list(Ty<'tcx>), canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>), poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>), predicates: intern_predicates(Predicate<'tcx>), projs: pub mk_projs(ProjectionKind), place_elems: pub mk_place_elems(PlaceElem<'tcx>), bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind), + fields: pub mk_fields(FieldIdx), ); impl<'tcx> TyCtxt<'tcx> { @@ -2193,18 +2170,6 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(iter, |xs| self.mk_const_list(xs)) } - pub fn mk_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> { - // Actually intern type lists as lists of `GenericArg`s. - // - // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound - // as explained in `ty_slice_as_generic_arg`. With this, - // we guarantee that even when transmuting between `List<Ty<'tcx>>` - // and `List<GenericArg<'tcx>>`, the uniqueness requirement for - // lists is upheld. - let substs = self.mk_substs(ty::subst::ty_slice_as_generic_args(ts)); - substs.try_as_type_list().unwrap() - } - // Unlike various other `mk_*_from_iter` functions, this one uses `I: // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice // variant, because of the need to combine `inputs` and `output`. This @@ -2280,6 +2245,14 @@ impl<'tcx> TyCtxt<'tcx> { T::collect_and_apply(iter, |xs| self.mk_place_elems(xs)) } + pub fn mk_fields_from_iter<I, T>(self, iter: I) -> T::Output + where + I: Iterator<Item = T>, + T: CollectAndApply<FieldIdx, &'tcx List<FieldIdx>>, + { + T::collect_and_apply(iter, |xs| self.mk_fields(xs)) + } + pub fn mk_substs_trait( self, self_ty: Ty<'tcx>, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 5a6ee123811..68002bfcfbd 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -178,7 +178,7 @@ impl FlagComputation { &ty::Alias(ty::Projection, data) => { self.add_flags(TypeFlags::HAS_TY_PROJECTION); - self.add_projection_ty(data); + self.add_alias_ty(data); } &ty::Alias(ty::Opaque, ty::AliasTy { substs, .. }) => { @@ -267,7 +267,7 @@ impl FlagComputation { projection_ty, term, })) => { - self.add_projection_ty(projection_ty); + self.add_alias_ty(projection_ty); self.add_term(term); } ty::PredicateKind::WellFormed(arg) => { @@ -372,8 +372,8 @@ impl FlagComputation { } } - fn add_projection_ty(&mut self, projection_ty: ty::AliasTy<'_>) { - self.add_substs(projection_ty.substs); + fn add_alias_ty(&mut self, alias_ty: ty::AliasTy<'_>) { + self.add_substs(alias_ty.substs); } fn add_substs(&mut self, substs: &[GenericArg<'_>]) { diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 4c7822acdf7..02baa395c3c 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -73,34 +73,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArg<'t } } -impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKind<'tcx> { - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - match self { - // WARNING: We dedup cache the `HashStable` results for `List` - // while ignoring types and freely transmute - // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. - // See `fn mk_type_list` for more details. - // - // We therefore hash types without adding a hash for their discriminant. - // - // In order to make it very unlikely for the sequence of bytes being hashed for - // a `GenericArgKind::Type` to be the same as the sequence of bytes being - // hashed for one of the other variants, we hash some very high number instead - // of their actual discriminant since `TyKind` should never start with anything - // that high. - ty::subst::GenericArgKind::Type(ty) => ty.hash_stable(hcx, hasher), - ty::subst::GenericArgKind::Const(ct) => { - 0xF3u8.hash_stable(hcx, hasher); - ct.hash_stable(hcx, hasher); - } - ty::subst::GenericArgKind::Lifetime(lt) => { - 0xF5u8.hash_stable(hcx, hasher); - lt.hash_stable(hcx, hasher); - } - } - } -} - // AllocIds get resolved to whatever they point to (to be stable) impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e73225f70cc..cc86cba6fda 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -34,7 +34,7 @@ pub enum InstanceDef<'tcx> { /// - `fn` items /// - closures /// - generators - Item(ty::WithOptConstParam<DefId>), + Item(DefId), /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI). /// @@ -143,7 +143,7 @@ impl<'tcx> Instance<'tcx> { match self.def { InstanceDef::Item(def) => tcx - .upstream_monomorphizations_for(def.did) + .upstream_monomorphizations_for(def) .and_then(|monos| monos.get(&self.substs).cloned()), InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs), _ => None, @@ -155,8 +155,8 @@ impl<'tcx> InstanceDef<'tcx> { #[inline] pub fn def_id(self) -> DefId { match self { - InstanceDef::Item(def) => def.did, - InstanceDef::VTableShim(def_id) + InstanceDef::Item(def_id) + | InstanceDef::VTableShim(def_id) | InstanceDef::ReifyShim(def_id) | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) @@ -172,7 +172,7 @@ impl<'tcx> InstanceDef<'tcx> { /// Returns the `DefId` of instances which might not require codegen locally. pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option<DefId> { match self { - ty::InstanceDef::Item(def) => Some(def.did), + ty::InstanceDef::Item(def) => Some(def), ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => { Some(def_id) } @@ -189,23 +189,6 @@ impl<'tcx> InstanceDef<'tcx> { } #[inline] - pub fn with_opt_param(self) -> ty::WithOptConstParam<DefId> { - match self { - InstanceDef::Item(def) => def, - InstanceDef::VTableShim(def_id) - | InstanceDef::ReifyShim(def_id) - | InstanceDef::FnPtrShim(def_id, _) - | InstanceDef::Virtual(def_id, _) - | InstanceDef::Intrinsic(def_id) - | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } - | InstanceDef::DropGlue(def_id, _) - | InstanceDef::CloneShim(def_id, _) - | InstanceDef::ThreadLocalShim(def_id) - | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), - } - } - - #[inline] pub fn get_attrs( &self, tcx: TyCtxt<'tcx>, @@ -222,7 +205,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_inline(&self, tcx: TyCtxt<'tcx>) -> bool { use rustc_hir::definitions::DefPathData; let def_id = match *self { - ty::InstanceDef::Item(def) => def.did, + ty::InstanceDef::Item(def) => def, ty::InstanceDef::DropGlue(_, Some(_)) => return false, ty::InstanceDef::ThreadLocalShim(_) => return false, _ => return true, @@ -273,8 +256,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn requires_caller_location(&self, tcx: TyCtxt<'_>) -> bool { match *self { - InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. }) - | InstanceDef::Virtual(def_id, _) => { + InstanceDef::Item(def_id) | InstanceDef::Virtual(def_id, _) => { tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER) } InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller, @@ -358,7 +340,7 @@ impl<'tcx> Instance<'tcx> { def_id, substs ); - Instance { def: InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs } + Instance { def: InstanceDef::Item(def_id), substs } } pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> { @@ -403,18 +385,21 @@ impl<'tcx> Instance<'tcx> { /// couldn't complete due to errors elsewhere - this is distinct /// from `Ok(None)` to avoid misleading diagnostics when an error /// has already been/will be emitted, for the original cause + #[instrument(level = "debug", skip(tcx))] pub fn resolve( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, def_id: DefId, substs: SubstsRef<'tcx>, ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - Instance::resolve_opt_const_arg( - tcx, - param_env, - ty::WithOptConstParam::unknown(def_id), - substs, - ) + // All regions in the result of this query are erased, so it's + // fine to erase all of the input regions. + + // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)` + // below is more likely to ignore the bounds in scope (e.g. if the only + // generic parameters mentioned by `substs` were lifetime ones). + let substs = tcx.erase_regions(substs); + tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs)))) } pub fn expect_resolve( @@ -432,31 +417,6 @@ impl<'tcx> Instance<'tcx> { } } - // This should be kept up to date with `resolve`. - pub fn resolve_opt_const_arg( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - def: ty::WithOptConstParam<DefId>, - substs: SubstsRef<'tcx>, - ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - // All regions in the result of this query are erased, so it's - // fine to erase all of the input regions. - - // HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)` - // below is more likely to ignore the bounds in scope (e.g. if the only - // generic parameters mentioned by `substs` were lifetime ones). - let substs = tcx.erase_regions(substs); - - // FIXME(eddyb) should this always use `param_env.with_reveal_all()`? - if let Some((did, param_did)) = def.as_const_arg() { - tcx.resolve_instance_of_const_arg( - tcx.erase_regions(param_env.and((did, param_did, substs))), - ) - } else { - tcx.resolve_instance(tcx.erase_regions(param_env.and((def.did, substs)))) - } - } - pub fn resolve_for_fn_ptr( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -470,7 +430,7 @@ impl<'tcx> Instance<'tcx> { match resolved.def { InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => { debug!(" => fn pointer created for function with #[track_caller]"); - resolved.def = InstanceDef::ReifyShim(def.did); + resolved.def = InstanceDef::ReifyShim(def); } InstanceDef::Virtual(def_id, _) => { debug!(" => fn pointer created for virtual call"); @@ -513,23 +473,23 @@ impl<'tcx> Instance<'tcx> { if resolved.def.requires_caller_location(tcx) // 2) The caller location parameter comes from having `#[track_caller]` // on the implementation, and *not* on the trait method. - && !tcx.should_inherit_track_caller(def.did) + && !tcx.should_inherit_track_caller(def) // If the method implementation comes from the trait definition itself // (e.g. `trait Foo { #[track_caller] my_fn() { /* impl */ } }`), // then we don't need to generate a shim. This check is needed because // `should_inherit_track_caller` returns `false` if our method // implementation comes from the trait block, and not an impl block && !matches!( - tcx.opt_associated_item(def.did), + tcx.opt_associated_item(def), Some(ty::AssocItem { container: ty::AssocItemContainer::TraitContainer, .. }) ) { - if tcx.is_closure(def.did) { + if tcx.is_closure(def) { debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}", - def.did, def_id, substs); + def, def_id, substs); // Create a shim for the `FnOnce/FnMut/Fn` method we are calling // - unlike functions, invoking a closure always goes through a @@ -537,9 +497,9 @@ impl<'tcx> Instance<'tcx> { resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs }; } else { debug!( - " => vtable fn pointer created for function with #[track_caller]: {:?}", def.did + " => vtable fn pointer created for function with #[track_caller]: {:?}", def ); - resolved.def = InstanceDef::ReifyShim(def.did); + resolved.def = InstanceDef::ReifyShim(def); } } } @@ -714,11 +674,8 @@ fn polymorphize<'tcx>( debug!("fold_ty: ty={:?}", ty); match *ty.kind() { ty::Closure(def_id, substs) => { - let polymorphized_substs = polymorphize( - self.tcx, - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - substs, - ); + let polymorphized_substs = + polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs); if substs == polymorphized_substs { ty } else { @@ -726,11 +683,8 @@ fn polymorphize<'tcx>( } } ty::Generator(def_id, substs, movability) => { - let polymorphized_substs = polymorphize( - self.tcx, - ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), - substs, - ); + let polymorphized_substs = + polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs); if substs == polymorphized_substs { ty } else { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1061c320793..42b98540ac7 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1007,7 +1007,7 @@ impl<'tcx> Term<'tcx> { _ => None, }, TermKind::Const(ct) => match ct.kind() { - ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def.did, uv.substs)), + ConstKind::Unevaluated(uv) => Some(tcx.mk_alias_ty(uv.def, uv.substs)), _ => None, }, } @@ -1471,135 +1471,6 @@ pub struct BoundConst<'tcx> { pub type PlaceholderConst<'tcx> = Placeholder<BoundVar>; -/// A `DefId` which, in case it is a const argument, is potentially bundled with -/// the `DefId` of the generic parameter it instantiates. -/// -/// This is used to avoid calls to `type_of` for const arguments during typeck -/// which cause cycle errors. -/// -/// ```rust -/// struct A; -/// impl A { -/// fn foo<const N: usize>(&self) -> [u8; N] { [0; N] } -/// // ^ const parameter -/// } -/// struct B; -/// impl B { -/// fn foo<const M: u8>(&self) -> usize { 42 } -/// // ^ const parameter -/// } -/// -/// fn main() { -/// let a = A; -/// let _b = a.foo::<{ 3 + 7 }>(); -/// // ^^^^^^^^^ const argument -/// } -/// ``` -/// -/// Let's look at the call `a.foo::<{ 3 + 7 }>()` here. We do not know -/// which `foo` is used until we know the type of `a`. -/// -/// We only know the type of `a` once we are inside of `typeck(main)`. -/// We also end up normalizing the type of `_b` during `typeck(main)` which -/// requires us to evaluate the const argument. -/// -/// To evaluate that const argument we need to know its type, -/// which we would get using `type_of(const_arg)`. This requires us to -/// resolve `foo` as it can be either `usize` or `u8` in this example. -/// However, resolving `foo` once again requires `typeck(main)` to get the type of `a`, -/// which results in a cycle. -/// -/// In short we must not call `type_of(const_arg)` during `typeck(main)`. -/// -/// When first creating the `ty::Const` of the const argument inside of `typeck` we have -/// already resolved `foo` so we know which const parameter this argument instantiates. -/// This means that we also know the expected result of `type_of(const_arg)` even if we -/// aren't allowed to call that query: it is equal to `type_of(const_param)` which is -/// trivial to compute. -/// -/// If we now want to use that constant in a place which potentially needs its type -/// we also pass the type of its `const_param`. This is the point of `WithOptConstParam`, -/// except that instead of a `Ty` we bundle the `DefId` of the const parameter. -/// Meaning that we need to use `type_of(const_param_did)` if `const_param_did` is `Some` -/// to get the type of `did`. -#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift, TyEncodable, TyDecodable)] -#[derive(PartialEq, Eq, PartialOrd, Ord)] -#[derive(Hash, HashStable)] -pub struct WithOptConstParam<T> { - pub did: T, - /// The `DefId` of the corresponding generic parameter in case `did` is - /// a const argument. - /// - /// Note that even if `did` is a const argument, this may still be `None`. - /// All queries taking `WithOptConstParam` start by calling `tcx.opt_const_param_of(def.did)` - /// to potentially update `param_did` in the case it is `None`. - pub const_param_did: Option<DefId>, -} - -impl<T> WithOptConstParam<T> { - /// Creates a new `WithOptConstParam` setting `const_param_did` to `None`. - #[inline(always)] - pub fn unknown(did: T) -> WithOptConstParam<T> { - WithOptConstParam { did, const_param_did: None } - } -} - -impl WithOptConstParam<LocalDefId> { - /// Returns `Some((did, param_did))` if `def_id` is a const argument, - /// `None` otherwise. - #[inline(always)] - pub fn try_lookup(did: LocalDefId, tcx: TyCtxt<'_>) -> Option<(LocalDefId, DefId)> { - tcx.opt_const_param_of(did).map(|param_did| (did, param_did)) - } - - /// In case `self` is unknown but `self.did` is a const argument, this returns - /// a `WithOptConstParam` with the correct `const_param_did`. - #[inline(always)] - pub fn try_upgrade(self, tcx: TyCtxt<'_>) -> Option<WithOptConstParam<LocalDefId>> { - if self.const_param_did.is_none() { - if let const_param_did @ Some(_) = tcx.opt_const_param_of(self.did) { - return Some(WithOptConstParam { did: self.did, const_param_did }); - } - } - - None - } - - pub fn to_global(self) -> WithOptConstParam<DefId> { - WithOptConstParam { did: self.did.to_def_id(), const_param_did: self.const_param_did } - } - - pub fn def_id_for_type_of(self) -> DefId { - if let Some(did) = self.const_param_did { did } else { self.did.to_def_id() } - } -} - -impl WithOptConstParam<DefId> { - pub fn as_local(self) -> Option<WithOptConstParam<LocalDefId>> { - self.did - .as_local() - .map(|did| WithOptConstParam { did, const_param_did: self.const_param_did }) - } - - pub fn as_const_arg(self) -> Option<(LocalDefId, DefId)> { - if let Some(param_did) = self.const_param_did { - if let Some(did) = self.did.as_local() { - return Some((did, param_did)); - } - } - - None - } - - pub fn is_local(self) -> bool { - self.did.is_local() - } - - pub fn def_id_for_type_of(self) -> DefId { - self.const_param_did.unwrap_or(self.did) - } -} - /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. @@ -2367,7 +2238,7 @@ impl<'tcx> TyCtxt<'tcx> { match instance { ty::InstanceDef::Item(def) => { debug!("calling def_kind on def: {:?}", def); - let def_kind = self.def_kind(def.did); + let def_kind = self.def_kind(def); debug!("returned from def_kind: {:?}", def_kind); match def_kind { DefKind::Const @@ -2375,13 +2246,10 @@ impl<'tcx> TyCtxt<'tcx> { | DefKind::AssocConst | DefKind::Ctor(..) | DefKind::AnonConst - | DefKind::InlineConst => self.mir_for_ctfe_opt_const_arg(def), + | DefKind::InlineConst => self.mir_for_ctfe(def), // If the caller wants `mir_for_ctfe` of a function they should not be using // `instance_mir`, so we'll assume const fn also wants the optimized version. - _ => { - assert_eq!(def.const_param_did, None); - self.optimized_mir(def.did) - } + _ => self.optimized_mir(def), } } ty::InstanceDef::VTableShim(..) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index d947d96041e..5ce32c7aaaa 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -327,6 +327,6 @@ pub fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { if def_id.is_top_level_module() { "top-level module".to_string() } else { - format!("module `{}`", tcx.def_path_str(def_id.to_def_id())) + format!("module `{}`", tcx.def_path_str(def_id)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index af76cf7cc4e..4c95d0f8415 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,4 +1,5 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -738,7 +739,9 @@ pub trait PrettyPrinter<'tcx>: } } ty::Placeholder(placeholder) => match placeholder.bound.kind { - ty::BoundTyKind::Anon => p!(write("Placeholder({:?})", placeholder)), + ty::BoundTyKind::Anon => { + self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { @@ -1172,6 +1175,18 @@ pub trait PrettyPrinter<'tcx>: } } + fn pretty_print_placeholder_var( + &mut self, + ui: ty::UniverseIndex, + var: ty::BoundVar, + ) -> Result<(), Self::Error> { + if ui == ty::UniverseIndex::ROOT { + write!(self, "!{}", var.index()) + } else { + write!(self, "!{}_{}", ui.index(), var.index()) + } + } + fn ty_infer_name(&self, _: ty::TyVid) -> Option<Symbol> { None } @@ -1328,13 +1343,13 @@ pub trait PrettyPrinter<'tcx>: match ct.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) => { - match self.tcx().def_kind(def.did) { + match self.tcx().def_kind(def) { DefKind::Const | DefKind::AssocConst => { - p!(print_value_path(def.did, substs)) + p!(print_value_path(def, substs)) } DefKind::AnonConst => { if def.is_local() - && let span = self.tcx().def_span(def.did) + && let span = self.tcx().def_span(def) && let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { p!(write("{}", snip)) @@ -1344,7 +1359,7 @@ pub trait PrettyPrinter<'tcx>: // cause printing to enter an infinite recursion if the anon const is in the self type i.e. // `impl<T: Default> Default for [T; 32 - 1 - 1 - 1] {` // where we would try to print `<[T; /* print `constant#0` again */] as Default>::{constant#0}` - p!(write("{}::{}", self.tcx().crate_name(def.did.krate), self.tcx().def_path(def.did).to_string_no_crate_verbose())) + p!(write("{}::{}", self.tcx().crate_name(def.krate), self.tcx().def_path(def).to_string_no_crate_verbose())) } } defkind => bug!("`{:?}` has unexpected defkind {:?}", ct, defkind), @@ -1787,17 +1802,27 @@ fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace { impl<'t> TyCtxt<'t> { /// Returns a string identifying this `DefId`. This string is /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { + pub fn def_path_str(self, def_id: impl IntoQueryParam<DefId>) -> String { self.def_path_str_with_substs(def_id, &[]) } - pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn def_path_str_with_substs( + self, + def_id: impl IntoQueryParam<DefId>, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer() } - pub fn value_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn value_path_str_with_substs( + self, + def_id: impl IntoQueryParam<DefId>, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer() diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 97592cbc567..bd8a22473fb 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -76,6 +76,9 @@ use std::ops::Deref; use std::path::PathBuf; use std::sync::Arc; +use rustc_data_structures::fingerprint::Fingerprint; +use rustc_query_system::ich::StableHashingContext; + #[derive(Default)] pub struct QuerySystem<'tcx> { pub arenas: QueryArenas<'tcx>, @@ -477,7 +480,7 @@ macro_rules! define_feedable { $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> { $(#[$attr])* #[inline(always)] - pub fn $name(self, value: query_provided::$name<'tcx>) -> $V { + pub fn $name(self, value: query_provided::$name<'tcx>) { let key = self.key().into_query_param(); let tcx = self.tcx; @@ -485,13 +488,25 @@ macro_rules! define_feedable { let value = restore::<$V>(erased); let cache = &tcx.query_system.caches.$name; + let hasher: Option<fn(&mut StableHashingContext<'_>, &_) -> _> = hash_result!([$($modifiers)*]); match try_get_cached(tcx, cache, &key) { Some(old) => { let old = restore::<$V>(old); - bug!( - "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", - stringify!($name), - ) + if let Some(hasher) = hasher { + let (value_hash, old_hash): (Fingerprint, Fingerprint) = tcx.with_stable_hashing_context(|mut hcx| + (hasher(&mut hcx, &value), hasher(&mut hcx, &old)) + ); + assert_eq!( + old_hash, value_hash, + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } else { + bug!( + "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}", + stringify!($name), + ) + } } None => { let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key); @@ -503,7 +518,6 @@ macro_rules! define_feedable { hash_result!([$($modifiers)*]), ); cache.complete(key, erased, dep_node_index); - value } } } @@ -573,7 +587,7 @@ mod sealed { } } -use sealed::IntoQueryParam; +pub use sealed::IntoQueryParam; impl<'tcx> TyCtxt<'tcx> { pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind { diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index f05b873432d..a439211ca33 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -21,7 +21,6 @@ use std::marker::PhantomData; use std::mem; use std::num::NonZeroUsize; use std::ops::{ControlFlow, Deref}; -use std::slice; /// An entity in the Rust type system, which can be one of /// several kinds (types, lifetimes, and consts). @@ -48,38 +47,13 @@ const TYPE_TAG: usize = 0b00; const REGION_TAG: usize = 0b01; const CONST_TAG: usize = 0b10; -#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, TyEncodable, TyDecodable, PartialEq, Eq, PartialOrd, Ord, HashStable)] pub enum GenericArgKind<'tcx> { Lifetime(ty::Region<'tcx>), Type(Ty<'tcx>), Const(ty::Const<'tcx>), } -/// This function goes from `&'a [Ty<'tcx>]` to `&'a [GenericArg<'tcx>]` -/// -/// This is sound as, for types, `GenericArg` is just -/// `NonZeroUsize::new_unchecked(ty as *const _ as usize)` as -/// long as we use `0` for the `TYPE_TAG`. -pub fn ty_slice_as_generic_args<'a, 'tcx>(ts: &'a [Ty<'tcx>]) -> &'a [GenericArg<'tcx>] { - assert_eq!(TYPE_TAG, 0); - // SAFETY: the whole slice is valid and immutable. - // `Ty` and `GenericArg` is explained above. - unsafe { slice::from_raw_parts(ts.as_ptr().cast(), ts.len()) } -} - -impl<'tcx> List<Ty<'tcx>> { - /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. - /// - /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have - /// be interned together, see `mk_type_list` for more details. - #[inline] - pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> { - assert_eq!(TYPE_TAG, 0); - // SAFETY: `List<T>` is `#[repr(C)]`. `Ty` and `GenericArg` is explained above. - unsafe { &*(self as *const List<Ty<'tcx>> as *const List<GenericArg<'tcx>>) } - } -} - impl<'tcx> GenericArgKind<'tcx> { #[inline] fn pack(self) -> GenericArg<'tcx> { @@ -180,30 +154,45 @@ impl<'tcx> GenericArg<'tcx> { } } - /// Unpack the `GenericArg` as a region when it is known certainly to be a region. - pub fn expect_region(self) -> ty::Region<'tcx> { + #[inline] + pub fn as_type(self) -> Option<Ty<'tcx>> { + match self.unpack() { + GenericArgKind::Type(ty) => Some(ty), + _ => None, + } + } + + #[inline] + pub fn as_region(self) -> Option<ty::Region<'tcx>> { + match self.unpack() { + GenericArgKind::Lifetime(re) => Some(re), + _ => None, + } + } + + #[inline] + pub fn as_const(self) -> Option<ty::Const<'tcx>> { match self.unpack() { - GenericArgKind::Lifetime(lt) => lt, - _ => bug!("expected a region, but found another kind"), + GenericArgKind::Const(ct) => Some(ct), + _ => None, } } + /// Unpack the `GenericArg` as a region when it is known certainly to be a region. + pub fn expect_region(self) -> ty::Region<'tcx> { + self.as_region().unwrap_or_else(|| bug!("expected a region, but found another kind")) + } + /// Unpack the `GenericArg` as a type when it is known certainly to be a type. /// This is true in cases where `Substs` is used in places where the kinds are known /// to be limited (e.g. in tuples, where the only parameters are type parameters). pub fn expect_ty(self) -> Ty<'tcx> { - match self.unpack() { - GenericArgKind::Type(ty) => ty, - _ => bug!("expected a type, but found another kind"), - } + self.as_type().unwrap_or_else(|| bug!("expected a type, but found another kind")) } /// Unpack the `GenericArg` as a const when it is known certainly to be a const. pub fn expect_const(self) -> ty::Const<'tcx> { - match self.unpack() { - GenericArgKind::Const(c) => c, - _ => bug!("expected a const, but found another kind"), - } + self.as_const().unwrap_or_else(|| bug!("expected a const, but found another kind")) } pub fn is_non_region_infer(self) -> bool { @@ -268,13 +257,16 @@ pub type InternalSubsts<'tcx> = List<GenericArg<'tcx>>; pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>; impl<'tcx> InternalSubsts<'tcx> { - /// Checks whether all elements of this list are types, if so, transmute. - pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> { - self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))).then(|| { - assert_eq!(TYPE_TAG, 0); - // SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`. - unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) } - }) + /// Converts substs to a type list. + /// + /// # Panics + /// + /// If any of the generic arguments are not types. + pub fn into_type_list(&self, tcx: TyCtxt<'tcx>) -> &'tcx List<Ty<'tcx>> { + tcx.mk_type_list_from_iter(self.iter().map(|arg| match arg.unpack() { + GenericArgKind::Type(ty) => ty, + _ => bug!("`into_type_list` called on substs with non-types"), + })) } /// Interpret these substitutions as the substitutions of a closure type. @@ -379,22 +371,17 @@ impl<'tcx> InternalSubsts<'tcx> { #[inline] pub fn types(&'tcx self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'tcx { - self.iter() - .filter_map(|k| if let GenericArgKind::Type(ty) = k.unpack() { Some(ty) } else { None }) + self.iter().filter_map(|k| k.as_type()) } #[inline] pub fn regions(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Region<'tcx>> + 'tcx { - self.iter().filter_map(|k| { - if let GenericArgKind::Lifetime(lt) = k.unpack() { Some(lt) } else { None } - }) + self.iter().filter_map(|k| k.as_region()) } #[inline] pub fn consts(&'tcx self) -> impl DoubleEndedIterator<Item = ty::Const<'tcx>> + 'tcx { - self.iter().filter_map(|k| { - if let GenericArgKind::Const(ct) = k.unpack() { Some(ct) } else { None } - }) + self.iter().filter_map(|k| k.as_const()) } #[inline] @@ -410,31 +397,21 @@ impl<'tcx> InternalSubsts<'tcx> { #[inline] #[track_caller] pub fn type_at(&self, i: usize) -> Ty<'tcx> { - if let GenericArgKind::Type(ty) = self[i].unpack() { - ty - } else { - bug!("expected type for param #{} in {:?}", i, self); - } + self[i].as_type().unwrap_or_else(|| bug!("expected type for param #{} in {:?}", i, self)) } #[inline] #[track_caller] pub fn region_at(&self, i: usize) -> ty::Region<'tcx> { - if let GenericArgKind::Lifetime(lt) = self[i].unpack() { - lt - } else { - bug!("expected region for param #{} in {:?}", i, self); - } + self[i] + .as_region() + .unwrap_or_else(|| bug!("expected region for param #{} in {:?}", i, self)) } #[inline] #[track_caller] pub fn const_at(&self, i: usize) -> ty::Const<'tcx> { - if let GenericArgKind::Const(ct) = self[i].unpack() { - ct - } else { - bug!("expected const for param #{} in {:?}", i, self); - } + self[i].as_const().unwrap_or_else(|| bug!("expected const for param #{} in {:?}", i, self)) } #[inline] diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 6747da7abd3..e61037e5ea8 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -139,40 +139,6 @@ impl<'tcx> TyCtxt<'tcx> { treat_projections: TreatProjections, mut f: impl FnMut(DefId), ) { - let _: Option<()> = - self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| { - f(did); - None - }); - } - - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn non_blanket_impls_for_ty( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - ) -> impl Iterator<Item = DefId> + 'tcx { - let impls = self.trait_impls_of(trait_def_id); - if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { - if let Some(impls) = impls.non_blanket_impls.get(&simp) { - return impls.iter().copied(); - } - } - - [].iter().copied() - } - - /// Applies function to every impl that could possibly match the self type `self_ty` and returns - /// the first non-none value. - /// - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn find_map_relevant_impl<T>( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - treat_projections: TreatProjections, - mut f: impl FnMut(DefId) -> Option<T>, - ) -> Option<T> { // FIXME: This depends on the set of all impls for the trait. That is // unfortunate wrt. incremental compilation. // @@ -181,9 +147,7 @@ impl<'tcx> TyCtxt<'tcx> { let impls = self.trait_impls_of(trait_def_id); for &impl_def_id in impls.blanket_impls.iter() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } // Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using @@ -199,20 +163,30 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) { if let Some(impls) = impls.non_blanket_impls.get(&simp) { for &impl_def_id in impls { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } } else { for &impl_def_id in impls.non_blanket_impls.values().flatten() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } + } - None + /// `trait_def_id` MUST BE the `DefId` of a trait. + pub fn non_blanket_impls_for_ty( + self, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + ) -> impl Iterator<Item = DefId> + 'tcx { + let impls = self.trait_impls_of(trait_def_id); + if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { + if let Some(impls) = impls.non_blanket_impls.get(&simp) { + return impls.iter().copied(); + } + } + + [].iter().copied() } /// Returns an iterator containing all impls for `trait_def_id`. diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 47943b94c3b..ef8955b1d3a 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -208,6 +208,9 @@ pub struct TypeckResults<'tcx> { /// Contains the data for evaluating the effect of feature `capture_disjoint_fields` /// on closure size. pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>, + + /// Container types and field indices of `offset_of!` expressions + offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>, } /// Whenever a value may be live across a generator yield, the type of that value winds up in the @@ -280,6 +283,7 @@ impl<'tcx> TypeckResults<'tcx> { generator_interior_predicates: Default::default(), treat_byte_string_as_slice: Default::default(), closure_size_eval: Default::default(), + offset_of_data: Default::default(), } } @@ -530,6 +534,14 @@ impl<'tcx> TypeckResults<'tcx> { pub fn coercion_casts(&self) -> &ItemLocalSet { &self.coercion_casts } + + pub fn offset_of_data(&self) -> LocalTableInContext<'_, (Ty<'tcx>, Vec<FieldIdx>)> { + LocalTableInContext { hir_owner: self.hir_owner, data: &self.offset_of_data } + } + + pub fn offset_of_data_mut(&mut self) -> LocalTableInContextMut<'_, (Ty<'tcx>, Vec<FieldIdx>)> { + LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.offset_of_data } + } } /// Validate that the given HirId (respectively its `local_id` part) can be diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index dbe2eebe336..9dbd9fbbb5b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,7 +2,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; -use crate::ty::fast_reject::TreatProjections; use crate::ty::layout::IntegerExt; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -359,21 +358,29 @@ impl<'tcx> TyCtxt<'tcx> { self.ensure().coherent_trait(drop_trait); let ty = self.type_of(adt_did).subst_identity(); - let (did, constness) = self.find_map_relevant_impl( - drop_trait, - ty, - // FIXME: This could also be some other mode, like "unexpected" - TreatProjections::ForLookup, - |impl_did| { - if let Some(item_id) = self.associated_item_def_ids(impl_did).first() { - if validate(self, impl_did).is_ok() { - return Some((*item_id, self.constness(impl_did))); - } - } - None - }, - )?; + let mut dtor_candidate = None; + self.for_each_relevant_impl(drop_trait, ty, |impl_did| { + let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + return; + }; + + if validate(self, impl_did).is_err() { + // Already `ErrorGuaranteed`, no need to delay a span bug here. + return; + } + + if let Some((old_item_id, _)) = dtor_candidate { + self.sess + .struct_span_err(self.def_span(item_id), "multiple drop impls found") + .span_note(self.def_span(old_item_id), "other impl here") + .delay_as_bug(); + } + + dtor_candidate = Some((*item_id, self.constness(impl_did))); + }); + let (did, constness) = dtor_candidate?; Some(ty::Destructor { did, constness }) } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 182945b9c3d..04a635a6803 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -194,7 +194,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::FnDef(_, substs) => { stack.extend(substs.iter().rev()); } - ty::Tuple(ts) => stack.extend(ts.as_substs().iter().rev()), + ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)), ty::GeneratorWitness(ts) => { stack.extend(ts.skip_binder().iter().rev().map(|ty| ty.into())); } diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 55aa4fcff2c..5c38c0acc7f 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -158,8 +158,8 @@ pub fn recursive_type_error( } let items_list = { let mut s = String::new(); - for (i, (item_id, _)) in item_and_field_ids.iter().enumerate() { - let path = tcx.def_path_str(item_id.to_def_id()); + for (i, &(item_id, _)) in item_and_field_ids.iter().enumerate() { + let path = tcx.def_path_str(item_id); write!(&mut s, "`{path}`").unwrap(); if i == (ITEM_LIMIT - 1) && cycle_len > ITEM_LIMIT { write!(&mut s, " and {} more", cycle_len - 5).unwrap(); diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index f24b165d7c2..58449ee9eb4 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -14,6 +14,7 @@ rustc_apfloat = { path = "../rustc_apfloat" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_index = { path = "../rustc_index" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 99291740ac8..fbcfd433724 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -78,7 +78,7 @@ pub fn as_constant_inner<'tcx>( ExprKind::NamedConst { def_id, substs, ref user_ty } => { let user_ty = user_ty.as_ref().and_then(push_cuta); - let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = mir::UnevaluatedConst::new(def_id, substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty, span, literal } @@ -90,7 +90,7 @@ pub fn as_constant_inner<'tcx>( Constant { user_ty: None, span, literal } } ExprKind::ConstBlock { did: def_id, substs } => { - let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = mir::UnevaluatedConst::new(def_id, substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty: None, span, literal } diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index fb775766c65..7ec57add66b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -557,6 +557,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::ConstBlock { .. } | ExprKind::StaticRef { .. } | ExprKind::InlineAsm { .. } + | ExprKind::OffsetOf { .. } | ExprKind::Yield { .. } | ExprKind::ThreadLocalRef(_) | ExprKind::Call { .. } => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 8631749a524..fbde0b28f54 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -481,6 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { })))) } + ExprKind::OffsetOf { container, fields } => { + block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container)) + } + ExprKind::Literal { .. } | ExprKind::NamedConst { .. } | ExprKind::NonHirLiteral { .. } diff --git a/compiler/rustc_mir_build/src/build/expr/category.rs b/compiler/rustc_mir_build/src/build/expr/category.rs index d33401f0764..d9aa461c19d 100644 --- a/compiler/rustc_mir_build/src/build/expr/category.rs +++ b/compiler/rustc_mir_build/src/build/expr/category.rs @@ -67,7 +67,8 @@ impl Category { | ExprKind::Repeat { .. } | ExprKind::Assign { .. } | ExprKind::AssignOp { .. } - | ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)), + | ExprKind::ThreadLocalRef(_) + | ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)), ExprKind::ConstBlock { .. } | ExprKind::Literal { .. } diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 9b38ac1cc4c..29ff916d2cc 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -561,7 +561,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { | ExprKind::ZstLiteral { .. } | ExprKind::ConstParam { .. } | ExprKind::ThreadLocalRef(_) - | ExprKind::StaticRef { .. } => { + | ExprKind::StaticRef { .. } + | ExprKind::OffsetOf { .. } => { debug_assert!(match Category::of(&expr.kind).unwrap() { // should be handled above Category::Rvalue(RvalueFunc::Into) => false, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index bc50bcbc3d0..82274318dcf 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -32,43 +32,32 @@ use super::lints; pub(crate) fn mir_built( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> &rustc_data_structures::steal::Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_built(def); - } - - let mut body = mir_build(tcx, def); - if def.const_param_did.is_some() { - assert!(matches!(body.source.instance, ty::InstanceDef::Item(_))); - body.source = MirSource::from_instance(ty::InstanceDef::Item(def.to_global())); - } - - tcx.alloc_steal_mir(body) + tcx.alloc_steal_mir(mir_build(tcx, def)) } /// Construct the MIR for a given `DefId`. -fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> { +fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // Ensure unsafeck and abstract const building is ran before we steal the THIR. - match def { - ty::WithOptConstParam { did, const_param_did: Some(const_param_did) } => { - tcx.ensure_with_value().thir_check_unsafety_for_const_arg((did, const_param_did)); - tcx.ensure_with_value().thir_abstract_const_of_const_arg((did, const_param_did)); - } - ty::WithOptConstParam { did, const_param_did: None } => { - tcx.ensure_with_value().thir_check_unsafety(did); - tcx.ensure_with_value().thir_abstract_const(did); - tcx.ensure_with_value().check_match(did); - } - } + tcx.ensure_with_value().thir_check_unsafety(def); + tcx.ensure_with_value().thir_abstract_const(def); + tcx.ensure_with_value().check_match(def); let body = match tcx.thir_body(def) { - Err(error_reported) => construct_error(tcx, def.did, error_reported), + Err(error_reported) => construct_error(tcx, def, error_reported), Ok((thir, expr)) => { // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); + tcx.ensure().check_match(def); + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + tcx.ensure().check_liveness(def); + match thir.body_type { thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, &thir, expr, fn_sig), thir::BodyTy::Const(ty) => construct_const(tcx, def, &thir, expr, ty), @@ -161,8 +150,7 @@ struct Builder<'a, 'tcx> { thir: &'a Thir<'tcx>, cfg: CFG<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, - def_id: DefId, + def_id: LocalDefId, hir_id: hir::HirId, parent_module: DefId, check_overflow: bool, @@ -428,26 +416,26 @@ macro_rules! unpack { fn construct_fn<'tcx>( tcx: TyCtxt<'tcx>, - fn_def: ty::WithOptConstParam<LocalDefId>, + fn_def: LocalDefId, thir: &Thir<'tcx>, expr: ExprId, fn_sig: ty::FnSig<'tcx>, ) -> Body<'tcx> { - let span = tcx.def_span(fn_def.did); - let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def.did); - let generator_kind = tcx.generator_kind(fn_def.did); + let span = tcx.def_span(fn_def); + let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def); + let generator_kind = tcx.generator_kind(fn_def); // The representation of thir for `-Zunpretty=thir-tree` relies on // the entry expression being the last element of `thir.exprs`. assert_eq!(expr.as_usize(), thir.exprs.len() - 1); // Figure out what primary body this item has. - let body_id = tcx.hir().body_owned_by(fn_def.did); + let body_id = tcx.hir().body_owned_by(fn_def); let span_with_body = tcx.hir().span_with_body(fn_id); let return_ty_span = tcx .hir() .fn_decl_by_hir_id(fn_id) - .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def.did)) + .unwrap_or_else(|| span_bug!(span, "can't build MIR for {:?}", fn_def)) .output .span(); @@ -457,7 +445,7 @@ fn construct_fn<'tcx>( }; let mut abi = fn_sig.abi; - if let DefKind::Closure = tcx.def_kind(fn_def.did) { + if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. abi = Abi::Rust; @@ -483,7 +471,7 @@ fn construct_fn<'tcx>( { return custom::build_custom_mir( tcx, - fn_def.did.to_def_id(), + fn_def.to_def_id(), fn_id, thir, expr, @@ -547,12 +535,12 @@ fn construct_fn<'tcx>( fn construct_const<'a, 'tcx>( tcx: TyCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, thir: &'a Thir<'tcx>, expr: ExprId, const_ty: Ty<'tcx>, ) -> Body<'tcx> { - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); // Figure out what primary body this item has. let (span, const_ty_span) = match tcx.hir().get(hir_id) { @@ -568,10 +556,10 @@ fn construct_const<'a, 'tcx>( .. }) => (*span, ty.span), Node::AnonConst(_) => { - let span = tcx.def_span(def.did); + let span = tcx.def_span(def); (span, span) } - _ => span_bug!(tcx.def_span(def.did), "can't build MIR for {:?}", def.did), + _ => span_bug!(tcx.def_span(def), "can't build MIR for {:?}", def), }; let infcx = tcx.infer_ctxt().build(); @@ -669,7 +657,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn new( thir: &'a Thir<'tcx>, infcx: InferCtxt<'tcx>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, hir_id: hir::HirId, span: Span, arg_count: usize, @@ -688,20 +676,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { check_overflow |= tcx.sess.overflow_checks(); // Constants always need overflow checks. check_overflow |= matches!( - tcx.hir().body_owner_kind(def.did), + tcx.hir().body_owner_kind(def), hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) ); let lint_level = LintLevel::Explicit(hir_id); - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); let mut builder = Builder { thir, tcx, infcx, - region_scope_tree: tcx.region_scope_tree(def.did), + region_scope_tree: tcx.region_scope_tree(def), param_env, - def, - def_id: def.did.to_def_id(), + def_id: def, hir_id, parent_module: tcx.parent_module(hir_id).to_def_id(), check_overflow, @@ -741,7 +728,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Body::new( - MirSource::item(self.def_id), + MirSource::item(self.def_id.to_def_id()), self.cfg.basic_blocks, self.source_scopes, self.local_decls, @@ -779,7 +766,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let tcx = self.tcx; self.upvars = tcx - .closure_captures(self.def.did) + .closure_captures(self.def_id) .iter() .zip(capture_tys) .enumerate() diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 03a7f2d70fa..0506f2bf238 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -117,10 +117,10 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { } /// Handle closures/generators/inline-consts, which is unsafecked with their parent body. - fn visit_inner_body(&mut self, def: ty::WithOptConstParam<LocalDefId>) { + fn visit_inner_body(&mut self, def: LocalDefId) { if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) { let inner_thir = &inner_thir.borrow(); - let hir_context = self.tcx.hir().local_def_id_to_hir_id(def.did); + let hir_context = self.tcx.hir().local_def_id_to_hir_id(def); let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self }; inner_visitor.visit_expr(&inner_thir[expr]); // Unsafe blocks can be used in the inner body, make sure to take it into account @@ -323,6 +323,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { | ExprKind::Box { .. } | ExprKind::If { .. } | ExprKind::InlineAsm { .. } + | ExprKind::OffsetOf { .. } | ExprKind::LogicalOp { .. } | ExprKind::Use { .. } => { // We don't need to save the old value and restore it @@ -396,18 +397,11 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { movability: _, fake_reads: _, }) => { - let closure_def = if let Some((did, const_param_id)) = - ty::WithOptConstParam::try_lookup(closure_id, self.tcx) - { - ty::WithOptConstParam { did, const_param_did: Some(const_param_id) } - } else { - ty::WithOptConstParam::unknown(closure_id) - }; - self.visit_inner_body(closure_def); + self.visit_inner_body(closure_id); } ExprKind::ConstBlock { did, substs: _ } => { let def_id = did.expect_local(); - self.visit_inner_body(ty::WithOptConstParam::unknown(def_id)); + self.visit_inner_body(def_id); } ExprKind::Field { lhs, .. } => { let lhs = &self.thir[lhs]; @@ -706,14 +700,14 @@ impl UnsafeOpKind { } } -pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { +pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { // THIR unsafeck is gated under `-Z thir-unsafeck` if !tcx.sess.opts.unstable_opts.thir_unsafeck { return; } // Closures and inline consts are handled by their owner, if it has a body - if tcx.is_typeck_child(def.did.to_def_id()) { + if tcx.is_typeck_child(def.to_def_id()) { return; } @@ -726,7 +720,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { return; } - let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); + let hir_id = tcx.hir().local_def_id_to_hir_id(def); let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| { if fn_sig.header.unsafety == hir::Unsafety::Unsafe { BodyUnsafety::Unsafe(fn_sig.span) @@ -734,7 +728,7 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { BodyUnsafety::Safe } }); - let body_target_features = &tcx.body_codegen_attrs(def.did.to_def_id()).target_features; + let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features; let safety_context = if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe }; let mut visitor = UnsafetyVisitor { @@ -746,23 +740,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { body_target_features, assignment_info: None, in_union_destructure: false, - param_env: tcx.param_env(def.did), + param_env: tcx.param_env(def), inside_adt: false, }; visitor.visit_expr(&thir[expr]); } - -pub(crate) fn thir_check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.thir_check_unsafety_for_const_arg(def) - } else { - check_unsafety(tcx, ty::WithOptConstParam::unknown(def_id)) - } -} - -pub(crate) fn thir_check_unsafety_for_const_arg( - tcx: TyCtxt<'_>, - (did, param_did): (LocalDefId, DefId), -) { - check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) -} diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 3f9236c9dd9..2765a107cf0 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -25,7 +25,7 @@ pub mod thir; use rustc_middle::ty::query::Providers; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; fluent_messages! { "../messages.ftl" } @@ -35,7 +35,6 @@ pub fn provide(providers: &mut Providers) { providers.lit_to_mir_constant = build::lit_to_mir_constant; providers.mir_built = build::mir_built; providers.thir_check_unsafety = check_unsafety::thir_check_unsafety; - providers.thir_check_unsafety_for_const_arg = check_unsafety::thir_check_unsafety_for_const_arg; providers.thir_body = thir::cx::thir_body; providers.thir_tree = thir::print::thir_tree; providers.thir_flat = thir::print::thir_flat; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 8e2e92e6f6a..ce13d522aae 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -664,6 +664,14 @@ impl<'tcx> Cx<'tcx> { line_spans: asm.line_spans, })), + hir::ExprKind::OffsetOf(_, _) => { + let data = self.typeck_results.offset_of_data(); + let &(container, ref indices) = data.get(expr.hir_id).unwrap(); + let fields = tcx.mk_fields_from_iter(indices.iter().copied()); + + ExprKind::OffsetOf { container, fields } + } + hir::ExprKind::ConstBlock(ref anon_const) => { let ty = self.typeck_results().node_type(anon_const.hir_id); let did = anon_const.def_id.to_def_id(); diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 070544446e3..463f639defe 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -20,25 +20,25 @@ use rustc_span::Span; pub(crate) fn thir_body( tcx: TyCtxt<'_>, - owner_def: ty::WithOptConstParam<LocalDefId>, + owner_def: LocalDefId, ) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); - let body = hir.body(hir.body_owned_by(owner_def.did)); + let body = hir.body(hir.body_owned_by(owner_def)); let mut cx = Cx::new(tcx, owner_def); if let Some(reported) = cx.typeck_results.tainted_by_errors { return Err(reported); } let expr = cx.mirror_expr(&body.value); - let owner_id = hir.local_def_id_to_hir_id(owner_def.did); + let owner_id = hir.local_def_id_to_hir_id(owner_def); if let Some(ref fn_decl) = hir.fn_decl_by_hir_id(owner_id) { - let closure_env_param = cx.closure_env_param(owner_def.did, owner_id); + let closure_env_param = cx.closure_env_param(owner_def, owner_id); let explicit_params = cx.explicit_params(owner_id, fn_decl, body); cx.thir.params = closure_env_param.into_iter().chain(explicit_params).collect(); // The resume argument may be missing, in that case we need to provide it here. // It will always be `()` in this case. - if tcx.def_kind(owner_def.did) == DefKind::Generator && body.params.is_empty() { + if tcx.def_kind(owner_def) == DefKind::Generator && body.params.is_empty() { cx.thir.params.push(Param { ty: tcx.mk_unit(), pat: None, @@ -78,13 +78,12 @@ struct Cx<'tcx> { } impl<'tcx> Cx<'tcx> { - fn new(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) -> Cx<'tcx> { - let typeck_results = tcx.typeck_opt_const_arg(def); - let did = def.did; + fn new(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Cx<'tcx> { + let typeck_results = tcx.typeck(def); let hir = tcx.hir(); - let hir_id = hir.local_def_id_to_hir_id(did); + let hir_id = hir.local_def_id_to_hir_id(def); - let body_type = if hir.body_owner_kind(did).is_fn_or_closure() { + let body_type = if hir.body_owner_kind(def).is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) BodyTy::Fn(typeck_results.liberated_fn_sigs()[hir_id]) @@ -106,11 +105,11 @@ impl<'tcx> Cx<'tcx> { Cx { tcx, thir: Thir::new(body_type), - param_env: tcx.param_env(def.did), - region_scope_tree: tcx.region_scope_tree(def.did), + param_env: tcx.param_env(def), + region_scope_tree: tcx.region_scope_tree(def), typeck_results, rvalue_scopes: &typeck_results.rvalue_scopes, - body_owner: did.to_def_id(), + body_owner: def.to_def_id(), adjustment_span: None, apply_adjustments: hir .attrs(hir_id) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 0ef48c42f87..2b52d70af2a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -27,7 +27,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::Span; pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) { - let Ok((thir, expr)) = tcx.thir_body(ty::WithOptConstParam::unknown(def_id)) else { return }; + let Ok((thir, expr)) = tcx.thir_body(def_id) else { return }; let thir = thir.borrow(); let pattern_arena = TypedArena::default(); let mut visitor = MatchVisitor { diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ed61d6ee78b..b2f2a64e29c 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_span::def_id::LocalDefId; use std::fmt::{self, Write}; -pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { +pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => { let thir = thir.steal(); @@ -15,7 +15,7 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalD } } -pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { +pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { match super::cx::thir_body(tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), @@ -519,6 +519,19 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> { self.print_inline_asm_expr(&**expr, depth_lvl + 2); print_indented!(self, "}", depth_lvl); } + OffsetOf { container, fields } => { + print_indented!(self, "OffsetOf {", depth_lvl); + print_indented!(self, format!("container: {:?}", container), depth_lvl + 1); + print_indented!(self, "fields: [", depth_lvl + 1); + + for field in fields.iter() { + print_indented!(self, format!("{:?}", field), depth_lvl + 2); + print_indented!(self, ",", depth_lvl + 1); + } + + print_indented!(self, "]", depth_lvl + 1); + print_indented!(self, "}", depth_lvl); + } ThreadLocalRef(def_id) => { print_indented!(self, "ThreadLocalRef {", depth_lvl); print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1); diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 68c61a18d72..4a296bb3367 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -13,6 +13,7 @@ tracing = "0.1" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 43caa2ea973..fc4efb943e6 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -16,8 +16,8 @@ extern crate rustc_middle; use rustc_ast::MetaItem; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def_id::DefId; -use rustc_macros::fluent_messages; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 64ed7a29f6f..736ca62cacc 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -360,7 +360,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { | Rvalue::AddressOf(..) | Rvalue::Discriminant(..) | Rvalue::Len(..) - | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {} + | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {} } } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index d908f6b3a9b..ce6d865a7dc 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -148,7 +148,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { if let Some(uv) = maybe_uneval { if uv.promoted.is_none() { - let def_id = uv.def.def_id_for_type_of(); + let def_id = uv.def; if self.tcx.def_kind(def_id) == DefKind::InlineConst { let local_def_id = def_id.expect_local(); let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = @@ -375,22 +375,7 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> { } pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { - unsafety_check_result: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.unsafety_check_result_for_const_arg(def) - } else { - unsafety_check_result(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - unsafety_check_result_for_const_arg: |tcx, (did, param_did)| { - unsafety_check_result( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - ) - }, - ..*providers - }; + *providers = Providers { unsafety_check_result, ..*providers }; } /// Context information for [`UnusedUnsafeVisitor`] traversal, @@ -492,10 +477,7 @@ fn check_unused_unsafe( unused_unsafes } -fn unsafety_check_result( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &UnsafetyCheckResult { +fn unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult { debug!("unsafety_violations({:?})", def); // N.B., this borrow is valid because all the consumers of @@ -510,13 +492,13 @@ fn unsafety_check_result( }); } - let param_env = tcx.param_env(def.did); + let param_env = tcx.param_env(def); - let mut checker = UnsafetyChecker::new(body, def.did, tcx, param_env); + let mut checker = UnsafetyChecker::new(body, def, tcx, param_env); checker.visit_body(&body); - let unused_unsafes = (!tcx.is_typeck_child(def.did.to_def_id())) - .then(|| check_unused_unsafe(tcx, def.did, &checker.used_unsafe_blocks)); + let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id())) + .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks)); tcx.arena.alloc(UnsafetyCheckResult { violations: checker.violations, diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 0923824db48..d435d3ee69b 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -24,7 +24,6 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) - | StatementKind::PlaceMention(..) | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) | StatementKind::FakeRead(..) => statement.make_nop(), _ => (), diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 692b3182f7d..b9bfbefcad9 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -16,7 +16,7 @@ pub struct ConstDebugInfo; impl<'tcx> MirPass<'tcx> for ConstDebugInfo { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.opts.unstable_opts.unsound_mir_opts && sess.mir_opt_level() > 0 + sess.mir_opt_level() > 0 } fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs index 3bd7f31b45d..bf01b45eb40 100644 --- a/compiler/rustc_mir_transform/src/coverage/query.rs +++ b/compiler/rustc_mir_transform/src/coverage/query.rs @@ -164,7 +164,6 @@ fn is_inlined(body: &Body<'_>, statement: &Statement<'_>) -> bool { /// whether that means const mir or runtime mir. For `const fn` this opts for runtime /// mir. fn mir_body(tcx: TyCtxt<'_>, def_id: DefId) -> &mir::Body<'_> { - let id = ty::WithOptConstParam::unknown(def_id); - let def = ty::InstanceDef::Item(id); + let def = ty::InstanceDef::Item(def_id); tcx.instance_mir(def) } diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a56c5cc5c12..c0861f99620 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -323,7 +323,7 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> { impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map) -> Self { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); Self { map, tcx, diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 18c407b42d3..7bc5183a00a 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -54,11 +54,10 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS | StatementKind::Coverage(_) | StatementKind::Intrinsic(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(_) | StatementKind::Nop => (), - StatementKind::FakeRead(_) - | StatementKind::PlaceMention(_) - | StatementKind::AscribeUserType(_, _) => { + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase!", &statement.kind) } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 5a842714e5d..78758e2db28 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -582,10 +582,9 @@ impl WriteInfo { | StatementKind::Nop | StatementKind::Coverage(_) | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) => (), - StatementKind::FakeRead(_) - | StatementKind::AscribeUserType(_, _) - | StatementKind::PlaceMention(_) => { + | StatementKind::StorageDead(_) + | StatementKind::PlaceMention(_) => (), + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase", statement) } } diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index c9b24adba0c..db68adc8bc9 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -48,7 +48,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { return false; } - let body = &*tcx.mir_built(ty::WithOptConstParam::unknown(local_def_id)).borrow(); + let body = &*tcx.mir_built(local_def_id).borrow(); let body_ty = tcx.type_of(def_id).skip_binder(); let body_abi = match body_ty.kind() { diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 8601c1b2d71..f26c6de9648 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -3,7 +3,7 @@ use rustc_errors::Applicability; use rustc_hir::def_id::DefId; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; -use rustc_middle::ty::{self, EarlyBinder, GenericArgKind, PredicateKind, SubstsRef, Ty, TyCtxt}; +use rustc_middle::ty::{self, EarlyBinder, PredicateKind, SubstsRef, Ty, TyCtxt}; use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES; use rustc_span::{symbol::sym, Span}; use rustc_target::spec::abi::Abi; @@ -45,14 +45,12 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> { // Handle calls to `transmute` if self.tcx.is_diagnostic_item(sym::transmute, def_id) { let arg_ty = args[0].ty(self.body, self.tcx); - for generic_inner_ty in arg_ty.walk() { - if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { - if let Some((fn_id, fn_substs)) = - FunctionItemRefChecker::is_fn_ref(inner_ty) - { - let span = self.nth_arg_span(&args, 0); - self.emit_lint(fn_id, fn_substs, source_info, span); - } + for inner_ty in arg_ty.walk().filter_map(|arg| arg.as_type()) { + if let Some((fn_id, fn_substs)) = + FunctionItemRefChecker::is_fn_ref(inner_ty) + { + let span = self.nth_arg_span(&args, 0); + self.emit_lint(fn_id, fn_substs, source_info, span); } } } else { @@ -82,24 +80,22 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let arg_defs = self.tcx.fn_sig(def_id).subst_identity().skip_binder().inputs(); for (arg_num, arg_def) in arg_defs.iter().enumerate() { // For all types reachable from the argument type in the fn sig - for generic_inner_ty in arg_def.walk() { - if let GenericArgKind::Type(inner_ty) = generic_inner_ty.unpack() { - // If the inner type matches the type bound by `Pointer` - if inner_ty == bound_ty { - // Do a substitution using the parameters from the callsite - let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); - if let Some((fn_id, fn_substs)) = - FunctionItemRefChecker::is_fn_ref(subst_ty) - { - let mut span = self.nth_arg_span(args, arg_num); - if span.from_expansion() { - // The operand's ctxt wouldn't display the lint since it's inside a macro so - // we have to use the callsite's ctxt. - let callsite_ctxt = span.source_callsite().ctxt(); - span = span.with_ctxt(callsite_ctxt); - } - self.emit_lint(fn_id, fn_substs, source_info, span); + for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) { + // If the inner type matches the type bound by `Pointer` + if inner_ty == bound_ty { + // Do a substitution using the parameters from the callsite + let subst_ty = EarlyBinder(inner_ty).subst(self.tcx, substs_ref); + if let Some((fn_id, fn_substs)) = + FunctionItemRefChecker::is_fn_ref(subst_ty) + { + let mut span = self.nth_arg_span(args, arg_num); + if span.from_expansion() { + // The operand's ctxt wouldn't display the lint since it's inside a macro so + // we have to use the callsite's ctxt. + let callsite_ctxt = span.source_callsite().ctxt(); + span = span.with_ctxt(callsite_ctxt); } + self.emit_lint(fn_id, fn_substs, source_info, span); } } } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 507e12d7238..5b3a66bc3d2 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1399,7 +1399,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( ) -> GeneratorLayout<'tcx> { assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir); - let (body, _) = tcx.mir_promoted(ty::WithOptConstParam::unknown(def_id)); + let (body, _) = tcx.mir_promoted(def_id); let body = body.borrow(); let body = &*body; diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 1525933aee3..552bf43329c 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -26,8 +26,6 @@ const CALL_PENALTY: usize = 25; const LANDINGPAD_PENALTY: usize = 50; const RESUME_PENALTY: usize = 45; -const UNKNOWN_SIZE_COST: usize = 10; - const TOP_DOWN_DEPTH_LIMIT: usize = 5; pub struct Inline; @@ -464,12 +462,6 @@ impl<'tcx> Inliner<'tcx> { } } - // Count up the cost of local variables and temps, if we know the size - // use that, otherwise we use a moderately-large dummy cost. - for v in callee_body.vars_and_temps_iter() { - checker.visit_local_decl(v, &callee_body.local_decls[v]); - } - // Abort if type validation found anything fishy. checker.validation?; @@ -764,14 +756,6 @@ impl<'tcx> Inliner<'tcx> { } } -fn type_size_of<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>, -) -> Option<u64> { - tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes()) -} - /// Verify that the callee body is compatible with the caller. /// /// This visitor mostly computes the inlining cost, @@ -845,24 +829,6 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { self.super_terminator(terminator, location); } - /// Count up the cost of local variables and temps, if we know the size - /// use that, otherwise we use a moderately-large dummy cost. - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - let tcx = self.tcx; - let ptr_size = tcx.data_layout.pointer_size.bytes(); - - let ty = self.instance.subst_mir(tcx, &local_decl.ty); - // Cost of the var is the size in machine-words, if we know - // it. - if let Some(size) = type_size_of(tcx, self.param_env, ty) { - self.cost += ((size + ptr_size - 1) / ptr_size) as usize; - } else { - self.cost += UNKNOWN_SIZE_COST; - } - - self.super_local_decl(local, local_decl) - } - /// This method duplicates code from MIR validation in an attempt to detect type mismatches due /// to normalization failure. fn visit_projection_elem( diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 8aa3c23d019..098ce0391fc 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -13,7 +13,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( tcx: TyCtxt<'tcx>, (root, target): (ty::Instance<'tcx>, LocalDefId), ) -> bool { - trace!(%root, target = %tcx.def_path_str(target.to_def_id())); + trace!(%root, target = %tcx.def_path_str(target)); let param_env = tcx.param_env_reveal_all_normalized(target); assert_ne!( root.def_id().expect_local(), @@ -148,8 +148,7 @@ pub(crate) fn mir_inliner_callees<'tcx>( let guard; let body = match (instance, instance.def_id().as_local()) { (InstanceDef::Item(_), Some(def_id)) => { - let def = ty::WithOptConstParam::unknown(def_id); - steal = tcx.mir_promoted(def).0; + steal = tcx.mir_promoted(def_id).0; guard = steal.borrow(); &*guard } diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 3d06a0a495f..432852a1fdd 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -1,11 +1,9 @@ //! Performs various peephole optimizations. +use crate::simplify::combine_duplicate_switch_targets; use crate::MirPass; use rustc_hir::Mutability; -use rustc_middle::mir::{ - BinOp, Body, CastKind, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, - Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, -}; +use rustc_middle::mir::*; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; @@ -46,7 +44,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine { &mut block.terminator.as_mut().unwrap(), &mut block.statements, ); - ctx.combine_duplicate_switch_targets(&mut block.terminator.as_mut().unwrap()); + combine_duplicate_switch_targets(block.terminator.as_mut().unwrap()); } } } @@ -264,19 +262,6 @@ impl<'tcx> InstCombineContext<'tcx, '_> { terminator.kind = TerminatorKind::Goto { target: destination_block }; } - fn combine_duplicate_switch_targets(&self, terminator: &mut Terminator<'tcx>) { - let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind - else { return }; - - let otherwise = targets.otherwise(); - if targets.iter().any(|t| t.1 == otherwise) { - *targets = SwitchTargets::new( - targets.iter().filter(|t| t.1 != otherwise), - targets.otherwise(), - ); - } - } - fn combine_intrinsic_assert( &self, terminator: &mut Terminator<'tcx>, diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 9447a2ff040..430a6f6cef5 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -120,7 +120,7 @@ impl EnumSizeOpt { fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); - let param_env = tcx.param_env(body_did); + let param_env = tcx.param_env_reveal_all_normalized(body_did); let blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 4ab07ab4256..6d8b4dc91f4 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -23,7 +23,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::steal::Steal; use rustc_hir as hir; use rustc_hir::def::DefKind; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_index::vec::IndexVec; use rustc_middle::mir::visit::Visitor as _; @@ -48,6 +48,7 @@ mod add_retag; mod check_const_item_mutation; mod check_packed_ref; pub mod check_unsafety; +mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup pub mod cleanup_post_borrowck; mod const_debuginfo; @@ -111,36 +112,17 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { mir_keys, mir_const, - mir_const_qualif: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.mir_const_qualif_const_arg(def) - } else { - mir_const_qualif(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - mir_const_qualif_const_arg: |tcx, (did, param_did)| { - mir_const_qualif(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, + mir_const_qualif, mir_promoted, mir_drops_elaborated_and_const_checked, mir_for_ctfe, - mir_for_ctfe_of_const_arg, mir_generator_witnesses: generator::mir_generator_witnesses, optimized_mir, is_mir_available, is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did), mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable, mir_inliner_callees: inline::cycle::mir_inliner_callees, - promoted_mir: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.promoted_mir_of_const_arg(def) - } else { - promoted_mir(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - promoted_mir_of_const_arg: |tcx, (did, param_did)| { - promoted_mir(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) - }, + promoted_mir, deduced_param_attrs: deduce_param_attrs::deduced_param_attrs, ..*providers }; @@ -234,8 +216,8 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> { set } -fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> ConstQualifs { - let const_kind = tcx.hir().body_const_context(def.did); +fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs { + let const_kind = tcx.hir().body_const_context(def); // No need to const-check a non-const `fn`. if const_kind.is_none() { @@ -253,7 +235,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> return Default::default(); } - let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def.did) }; + let ccx = check_consts::ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def) }; let mut validator = check_consts::check::Checker::new(&ccx); validator.check_body(); @@ -266,22 +248,14 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> /// Make MIR ready for const evaluation. This is run on all MIR, not just on consts! /// FIXME(oli-obk): it's unclear whether we still need this phase (and its corresponding query). /// We used to have this for pre-miri MIR based const eval. -fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_const(def); - } - +fn mir_const(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { // Unsafety check uses the raw mir, so make sure it is run. if !tcx.sess.opts.unstable_opts.thir_unsafeck { - if let Some(param_did) = def.const_param_did { - tcx.ensure_with_value().unsafety_check_result_for_const_arg((def.did, param_did)); - } else { - tcx.ensure_with_value().unsafety_check_result(def.did); - } + tcx.ensure_with_value().unsafety_check_result(def); } // has_ffi_unwind_calls query uses the raw mir, so make sure it is run. - tcx.ensure_with_value().has_ffi_unwind_calls(def.did); + tcx.ensure_with_value().has_ffi_unwind_calls(def); let mut body = tcx.mir_built(def).steal(); @@ -307,16 +281,12 @@ fn mir_const(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Steal< /// Compute the main MIR body and the list of MIR bodies of the promoteds. fn mir_promoted( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> (&Steal<Body<'_>>, &Steal<IndexVec<Promoted, Body<'_>>>) { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_promoted(def); - } - // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. // Also this means promotion can rely on all const checks having been done. - let const_qualifs = tcx.mir_const_qualif_opt_const_arg(def); + let const_qualifs = tcx.mir_const_qualif(def); let mut body = tcx.mir_const(def).steal(); if let Some(error_reported) = const_qualifs.tainted_by_errors { body.tainted_by_errors = Some(error_reported); @@ -344,38 +314,22 @@ fn mir_promoted( /// Compute the MIR that is used during CTFE (and thus has no optimizations run on it) fn mir_for_ctfe(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &Body<'_> { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.mir_for_ctfe_of_const_arg(def) - } else { - tcx.arena.alloc(inner_mir_for_ctfe(tcx, ty::WithOptConstParam::unknown(def_id))) - } -} - -/// Same as `mir_for_ctfe`, but used to get the MIR of a const generic parameter. -/// The docs on `WithOptConstParam` explain this a bit more, but the TLDR is that -/// we'd get cycle errors with `mir_for_ctfe`, because typeck would need to typeck -/// the const parameter while type checking the main body, which in turn would try -/// to type check the main body again. -fn mir_for_ctfe_of_const_arg(tcx: TyCtxt<'_>, (did, param_did): (LocalDefId, DefId)) -> &Body<'_> { - tcx.arena.alloc(inner_mir_for_ctfe( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - )) + tcx.arena.alloc(inner_mir_for_ctfe(tcx, def_id)) } -fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> Body<'_> { +fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // FIXME: don't duplicate this between the optimized_mir/mir_for_ctfe queries - if tcx.is_constructor(def.did.to_def_id()) { + if tcx.is_constructor(def.to_def_id()) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const // qualification and borrow checking the trouble of special casing // constructors. - return shim::build_adt_ctor(tcx, def.did.to_def_id()); + return shim::build_adt_ctor(tcx, def.to_def_id()); } let context = tcx .hir() - .body_const_context(def.did) + .body_const_context(def) .expect("mir_for_ctfe should not be used for runtime functions"); let body = tcx.mir_drops_elaborated_and_const_checked(def).borrow().clone(); @@ -413,29 +367,19 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) - /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't /// end up missing the source MIR due to stealing happening. -fn mir_drops_elaborated_and_const_checked( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &Steal<Body<'_>> { - if let Some(def) = def.try_upgrade(tcx) { - return tcx.mir_drops_elaborated_and_const_checked(def); - } - +fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { if tcx.sess.opts.unstable_opts.drop_tracking_mir - && let DefKind::Generator = tcx.def_kind(def.did) + && let DefKind::Generator = tcx.def_kind(def) { - tcx.ensure_with_value().mir_generator_witnesses(def.did); + tcx.ensure_with_value().mir_generator_witnesses(def); } - let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def); + let mir_borrowck = tcx.mir_borrowck(def); - let is_fn_like = tcx.def_kind(def.did).is_fn_like(); + let is_fn_like = tcx.def_kind(def).is_fn_like(); if is_fn_like { - let did = def.did.to_def_id(); - let def = ty::WithOptConstParam::unknown(did); - // Do not compute the mir call graph without said call graph actually being used. if inline::Inline.is_enabled(&tcx.sess) { - tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def)); + tcx.ensure_with_value().mir_inliner_callees(ty::InstanceDef::Item(def.to_def_id())); } } @@ -517,8 +461,11 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Returns the sequence of passes that do the initial cleanup of runtime MIR. fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let passes: &[&dyn MirPass<'tcx>] = - &[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::ElaborateDrops]; + let passes: &[&dyn MirPass<'tcx>] = &[ + &lower_intrinsics::LowerIntrinsics, + &remove_place_mention::RemovePlaceMention, + &simplify::SimplifyCfg::ElaborateDrops, + ]; pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup))); @@ -564,12 +511,12 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0. &const_debuginfo::ConstDebugInfo, - &o1(simplify_branches::SimplifyConstConditionPassName::AfterConstProp), + &o1(simplify_branches::SimplifyConstCondition::AfterConstProp), &early_otherwise_branch::EarlyOtherwiseBranch, &simplify_comparison_integral::SimplifyComparisonIntegral, &dead_store_elimination::DeadStoreElimination, &dest_prop::DestinationPropagation, - &o1(simplify_branches::SimplifyConstConditionPassName::Final), + &o1(simplify_branches::SimplifyConstCondition::Final), &o1(remove_noop_landing_pads::RemoveNoopLandingPads), &o1(simplify::SimplifyCfg::Final), &nrvo::RenameReturnPlace, @@ -588,7 +535,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Optimize the MIR and prepare it for codegen. fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> { - assert_eq!(ty::WithOptConstParam::try_lookup(did, tcx), None); tcx.arena.alloc(inner_optimized_mir(tcx, did)) } @@ -610,8 +556,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { Some(other) => panic!("do not use `optimized_mir` for constants: {:?}", other), } debug!("about to call mir_drops_elaborated..."); - let body = - tcx.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did)).steal(); + let body = tcx.mir_drops_elaborated_and_const_checked(did).steal(); let mut body = remap_mir_for_const_eval_select(tcx, body, hir::Constness::NotConst); debug!("body: {:#?}", body); run_optimization_passes(tcx, &mut body); @@ -621,15 +566,12 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> { /// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for /// constant evaluation once all substitutions become known. -fn promoted_mir( - tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, -) -> &IndexVec<Promoted, Body<'_>> { - if tcx.is_constructor(def.did.to_def_id()) { +fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> { + if tcx.is_constructor(def.to_def_id()) { return tcx.arena.alloc(IndexVec::new()); } - let tainted_by_errors = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors; + let tainted_by_errors = tcx.mir_borrowck(def).tainted_by_errors; let mut promoted = tcx.mir_promoted(def).1.steal(); for body in &mut promoted { diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index c136642dff2..c7d3f6c9f04 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -221,7 +221,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } - sym::transmute => { + sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { span_bug!( diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index ce05db5b762..59942dc76f9 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -46,7 +46,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let def_id = body.source.def_id(); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let bbs = body.basic_blocks.as_mut(); let mut should_cleanup = false; diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs new file mode 100644 index 00000000000..8be1c37572d --- /dev/null +++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs @@ -0,0 +1,23 @@ +//! This pass removes `PlaceMention` statement, which has no effect at codegen. + +use crate::MirPass; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +pub struct RemovePlaceMention; + +impl<'tcx> MirPass<'tcx> for RemovePlaceMention { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + !sess.opts.unstable_opts.mir_keep_place_mention + } + + fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + trace!("Running RemovePlaceMention on {:?}", body.source); + for data in body.basic_blocks.as_mut_preserves_cfg() { + data.statements.retain(|statement| match statement.kind { + StatementKind::PlaceMention(..) | StatementKind::Nop => false, + _ => true, + }) + } + } +} diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index abe6cb285f5..23442f8b97b 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -35,10 +35,22 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { } #[inline] + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _: Location) { + // We have to use `try_normalize_erasing_regions` here, since it's + // possible that we visit impossible-to-satisfy where clauses here, + // see #91745 + if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.literal) { + constant.literal = c; + } + } + + #[inline] fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - *ty = self.tcx.try_normalize_erasing_regions(self.param_env, *ty).unwrap_or(*ty); + if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) { + *ty = t; + } } } diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index ef367faf6a7..2479856b727 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -303,8 +303,7 @@ fn find_determining_place<'tcx>( | Rvalue::NullaryOp(_, _) | Rvalue::ShallowInitBox(_, _) | Rvalue::UnaryOp(_, Operand::Constant(_)) - | Rvalue::Cast(_, Operand::Constant(_), _) - => return None, + | Rvalue::Cast(_, Operand::Constant(_), _) => return None, } } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4396a83e8b8..d4debae5c58 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -355,7 +355,7 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env); @@ -836,7 +836,7 @@ fn build_call_shim<'tcx>( pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let param_env = tcx.param_env(ctor_id); + let param_env = tcx.param_env_reveal_all_normalized(ctor_id); // Normalize the sig. let sig = tcx diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 88574addaa0..e1ca7c107b9 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -278,6 +278,18 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } +pub fn combine_duplicate_switch_targets(terminator: &mut Terminator<'_>) { + if let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind { + let otherwise = targets.otherwise(); + if targets.iter().any(|t| t.1 == otherwise) { + *targets = SwitchTargets::new( + targets.iter().filter(|t| t.1 != otherwise), + targets.otherwise(), + ); + } + } +} + pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { struct OptApplier<'tcx> { tcx: TyCtxt<'tcx>, @@ -298,6 +310,8 @@ pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut B } } + combine_duplicate_switch_targets(terminator); + self.super_terminator(terminator, location); } } diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index ddaf86a9e73..1ff48816986 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -2,23 +2,21 @@ use crate::MirPass; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; -pub enum SimplifyConstConditionPassName { +pub enum SimplifyConstCondition { AfterConstProp, Final, } /// A pass that replaces a branch with a goto when its condition is known. -impl<'tcx> MirPass<'tcx> for SimplifyConstConditionPassName { +impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { fn name(&self) -> &'static str { match self { - SimplifyConstConditionPassName::AfterConstProp => { - "SimplifyConstCondition-after-const-prop" - } - SimplifyConstConditionPassName::Final => "SimplifyConstCondition-final", + SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop", + SimplifyConstCondition::Final => "SimplifyConstCondition-final", } } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for block in body.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index dcad1518eb6..113ca2fc5ad 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -37,7 +37,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let opts = helper.find_optimizations(); let mut storage_deads_to_insert = vec![]; let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![]; - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for opt in opts { trace!("SUCCESS: Applying {:?}", opt); // replace terminator with a switchInt that switches on the integer directly diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index be0aa0fc4c1..5389b9f52eb 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -109,7 +109,9 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { continue; }; - let layout = tcx.layout_of(tcx.param_env(body.source.def_id()).and(discriminant_ty)); + let layout = tcx.layout_of( + tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty), + ); let allowed_variants = if let Ok(layout) = layout { variant_discriminants(&layout, discriminant_ty, tcx) diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index c8af10576b4..5ecd68c79bb 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -13,6 +13,7 @@ tracing = "0.1" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2ed628871d2..5ac9c8e2073 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1230,7 +1230,7 @@ impl<'v> RootCollector<'_, 'v> { DefKind::GlobalAsm => { debug!( "RootCollector: ItemKind::GlobalAsm({})", - self.tcx.def_path_str(id.owner_id.to_def_id()) + self.tcx.def_path_str(id.owner_id) ); self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 5000fb71937..aea9f719027 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -10,8 +10,8 @@ extern crate tracing; extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::lang_items::LangItem; -use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; use rustc_middle::ty::query::{Providers, TyCtxtAt}; diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 49126045d0c..bd24deb590a 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -16,17 +16,20 @@ use super::PartitioningCx; use crate::collector::InliningMap; use crate::partitioning::merging; use crate::partitioning::{ - MonoItemPlacement, Partitioner, PostInliningPartitioning, PreInliningPartitioning, + MonoItemPlacement, Partition, PostInliningPartitioning, PreInliningPartitioning, }; pub struct DefaultPartitioning; -impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { - fn place_root_mono_items( +impl<'tcx> Partition<'tcx> for DefaultPartitioning { + fn place_root_mono_items<I>( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, - ) -> PreInliningPartitioning<'tcx> { + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>, + { let mut roots = FxHashSet::default(); let mut codegen_units = FxHashMap::default(); let is_incremental_build = cx.tcx.sess.opts.incremental.is_some(); @@ -267,7 +270,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( match mono_item { MonoItem::Fn(instance) => { let def_id = match instance.def { - ty::InstanceDef::Item(def) => def.did, + ty::InstanceDef::Item(def) => def, ty::InstanceDef::VTableShim(..) | ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::FnPtrShim(..) @@ -421,8 +424,7 @@ fn mono_item_visibility<'tcx>( }; let def_id = match instance.def { - InstanceDef::Item(def) => def.did, - InstanceDef::DropGlue(def_id, Some(_)) => def_id, + InstanceDef::Item(def_id) | InstanceDef::DropGlue(def_id, Some(_)) => def_id, // We match the visibility of statics here InstanceDef::ThreadLocalShim(def_id) => { diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 18aa0742c09..993e35c7fd2 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -118,18 +118,81 @@ use crate::errors::{ CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode, UnknownPartitionStrategy, }; +enum Partitioner { + Default(default::DefaultPartitioning), + // Other partitioning strategies can go here. + Unknown, +} + +impl<'tcx> Partition<'tcx> for Partitioner { + fn place_root_mono_items<I>( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>, + { + match self { + Partitioner::Default(partitioner) => partitioner.place_root_mono_items(cx, mono_items), + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn merge_codegen_units( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: &mut PreInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.merge_codegen_units(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn place_inlined_mono_items( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: PreInliningPartitioning<'tcx>, + ) -> PostInliningPartitioning<'tcx> { + match self { + Partitioner::Default(partitioner) => { + partitioner.place_inlined_mono_items(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn internalize_symbols( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + post_inlining_partitioning: &mut PostInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.internalize_symbols(cx, post_inlining_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } +} + pub struct PartitioningCx<'a, 'tcx> { tcx: TyCtxt<'tcx>, target_cgu_count: usize, inlining_map: &'a InliningMap<'tcx>, } -trait Partitioner<'tcx> { - fn place_root_mono_items( +trait Partition<'tcx> { + fn place_root_mono_items<I>( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, - ) -> PreInliningPartitioning<'tcx>; + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator<Item = MonoItem<'tcx>>; fn merge_codegen_units( &mut self, @@ -150,26 +213,27 @@ trait Partitioner<'tcx> { ); } -fn get_partitioner<'tcx>(tcx: TyCtxt<'tcx>) -> Box<dyn Partitioner<'tcx>> { +fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner { let strategy = match &tcx.sess.opts.unstable_opts.cgu_partitioning_strategy { None => "default", Some(s) => &s[..], }; match strategy { - "default" => Box::new(default::DefaultPartitioning), - _ => { - tcx.sess.emit_fatal(UnknownPartitionStrategy); - } + "default" => Partitioner::Default(default::DefaultPartitioning), + _ => Partitioner::Unknown, } } -pub fn partition<'tcx>( +pub fn partition<'tcx, I>( tcx: TyCtxt<'tcx>, - mono_items: &mut dyn Iterator<Item = MonoItem<'tcx>>, + mono_items: &mut I, max_cgu_count: usize, inlining_map: &InliningMap<'tcx>, -) -> Vec<CodegenUnit<'tcx>> { +) -> Vec<CodegenUnit<'tcx>> +where + I: Iterator<Item = MonoItem<'tcx>>, +{ let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); let mut partitioner = get_partitioner(tcx); @@ -182,7 +246,9 @@ pub fn partition<'tcx>( partitioner.place_root_mono_items(cx, mono_items) }; - initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut initial_partitioning.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter()); @@ -202,7 +268,9 @@ pub fn partition<'tcx>( partitioner.place_inlined_mono_items(cx, initial_partitioning) }; - post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut post_inlining.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter()); @@ -380,7 +448,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co || { let mut codegen_units = partition( tcx, - &mut items.iter().cloned(), + &mut items.iter().copied(), tcx.sess.codegen_units(), &inlining_map, ); diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 63263a642ac..ddc62d9c390 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -232,7 +232,7 @@ impl<'a, 'tcx> MarkUsedGenericParams<'a, 'tcx> { /// a closure, generator or constant). #[instrument(level = "debug", skip(self, def_id, substs))] fn visit_child_body(&mut self, def_id: DefId, substs: SubstsRef<'tcx>) { - let instance = ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)); + let instance = ty::InstanceDef::Item(def_id); let unused = self.tcx.unused_generic_params(instance); debug!(?self.unused_parameters, ?unused); for (i, arg) in substs.iter().enumerate() { @@ -272,10 +272,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { // Avoid considering `T` unused when constants are of the form: // `<Self as Foo<T>>::foo::promoted[p]` if let Some(p) = promoted { - if self.def_id == def.did && !self.tcx.generics_of(def.did).has_self { + if self.def_id == def && !self.tcx.generics_of(def).has_self { // If there is a promoted, don't look at the substs - since it will always contain // the generic parameters, instead, traverse the promoted MIR. - let promoted = self.tcx.promoted_mir(def.did); + let promoted = self.tcx.promoted_mir(def); self.visit_body(&promoted[p]); } } @@ -305,9 +305,9 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for MarkUsedGenericParams<'a, 'tcx> { ControlFlow::Continue(()) } ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs }) - if matches!(self.tcx.def_kind(def.did), DefKind::AnonConst) => + if matches!(self.tcx.def_kind(def), DefKind::AnonConst) => { - self.visit_child_body(def.did, substs); + self.visit_child_body(def, substs); ControlFlow::Continue(()) } _ => c.super_visit_with(self), diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index 3eb158c817c..1bd9f66290d 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 17466cd0e6d..507f6e4182e 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -20,7 +20,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult}; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_session::parse::ParseSess; use rustc_span::{FileName, SourceFile, Span}; diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index 44f991f8c15..0413b5b4fb9 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -12,6 +12,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_session = { path = "../rustc_session" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 5cfe691df17..3ae5b45d330 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -237,6 +237,37 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } + fn handle_offset_of(&mut self, expr: &'tcx hir::Expr<'tcx>) { + let data = self.typeck_results().offset_of_data(); + let &(container, ref indices) = + data.get(expr.hir_id).expect("no offset_of_data for offset_of"); + + let body_did = self.typeck_results().hir_owner.to_def_id(); + let param_env = self.tcx.param_env(body_did); + + let mut current_ty = container; + + for &index in indices { + match current_ty.kind() { + ty::Adt(def, subst) => { + let field = &def.non_enum_variant().fields[index]; + + self.insert_def_id(field.did); + let field_ty = field.ty(self.tcx, subst); + + current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty); + } + // we don't need to mark tuple fields as live, + // but we may need to mark subfields + ty::Tuple(tys) => { + current_ty = + self.tcx.normalize_erasing_regions(param_env, tys[index.as_usize()]); + } + _ => span_bug!(expr.span, "named field access on non-ADT"), + } + } + } + fn mark_live_symbols(&mut self) { let mut scanned = LocalDefIdSet::default(); while let Some(id) = self.worklist.pop() { @@ -405,6 +436,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { hir::ExprKind::Closure(cls) => { self.insert_def_id(cls.def_id.to_def_id()); } + hir::ExprKind::OffsetOf(..) => { + self.handle_offset_of(expr); + } _ => (), } diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 47e032758f2..dc5e454074d 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -302,7 +302,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { [ ConstBlock, Array, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, DropTemps, Let, If, Loop, Match, Closure, Block, Assign, AssignOp, Field, Index, - Path, AddrOf, Break, Continue, Ret, InlineAsm, Struct, Repeat, Yield, Err + Path, AddrOf, Break, Continue, Ret, InlineAsm, OffsetOf, Struct, Repeat, Yield, + Err ] ); hir_visit::walk_expr(self, e) @@ -568,7 +569,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { Array, ConstBlock, Call, MethodCall, Tup, Binary, Unary, Lit, Cast, Type, Let, If, While, ForLoop, Loop, Match, Closure, Block, Async, Await, TryBlock, Assign, AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, - InlineAsm, FormatArgs, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err + InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, IncludedBytes, Err ] ); ast_visit::walk_expr(self, e) diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index b7e07aff42b..eca3bae9a1c 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -19,7 +19,7 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty::query::Providers; mod check_attr; diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index a8471ce3b6f..a4f99a628ab 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -90,7 +90,7 @@ use rustc_errors::Applicability; use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet}; use rustc_index::vec::IndexVec; @@ -98,6 +98,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::DUMMY_SP; use rustc_span::{BytePos, Span}; use std::collections::VecDeque; @@ -137,14 +138,9 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String { } } -fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { - let local_def_id = match def_id.as_local() { - None => return, - Some(def_id) => def_id, - }; - +fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Don't run unused pass for #[derive()] - let parent = tcx.local_parent(local_def_id); + let parent = tcx.local_parent(def_id); if let DefKind::Impl { .. } = tcx.def_kind(parent) && tcx.has_attr(parent, sym::automatically_derived) { @@ -152,12 +148,12 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { } // Don't run unused pass for #[naked] - if tcx.has_attr(def_id, sym::naked) { + if tcx.has_attr(def_id.to_def_id(), sym::naked) { return; } let mut maps = IrMaps::new(tcx); - let body_id = tcx.hir().body_owned_by(local_def_id); + let body_id = tcx.hir().body_owned_by(def_id); let hir_id = tcx.hir().body_owner(body_id); let body = tcx.hir().body(body_id); @@ -173,7 +169,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { maps.visit_body(body); // compute liveness - let mut lsets = Liveness::new(&mut maps, local_def_id); + let mut lsets = Liveness::new(&mut maps, def_id); let entry_ln = lsets.compute(&body, hir_id); lsets.log_liveness(entry_ln, body_id.hir_id); @@ -331,7 +327,7 @@ impl<'tcx> IrMaps<'tcx> { pats.extend(inner_pat.iter()); } Struct(_, fields, _) => { - let (short, not_short): (Vec<_>, _) = + let (short, not_short): (Vec<hir::PatField<'_>>, _) = fields.iter().partition(|f| f.is_shorthand); shorthand_field_ids.extend(short.iter().map(|f| f.pat.hir_id)); pats.extend(not_short.iter().map(|f| f.pat)); @@ -473,6 +469,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Type(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) @@ -591,8 +588,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> bool { - let successor = self.successors[ln].unwrap(); - self.assigned_on_entry(successor, var) + match self.successors[ln] { + Some(successor) => self.assigned_on_entry(successor, var), + None => { + self.ir.tcx.sess.delay_span_bug(DUMMY_SP, "no successor"); + true + } + } } fn write_vars<F>(&self, wr: &mut dyn Write, mut test: F) -> io::Result<()> @@ -1129,7 +1131,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) - | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ, + | hir::ExprKind::Path(hir::QPath::LangItem(..)) + | hir::ExprKind::OffsetOf(..) => succ, // Note that labels have been resolved, so we don't need to look // at the label ident @@ -1418,6 +1421,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Block(..) | hir::ExprKind::AddrOf(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Repeat(..) | hir::ExprKind::Closure { .. } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index c398467f03e..cf8d9300a11 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -203,6 +203,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { | ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) + | ExprKind::OffsetOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) => { diff --git a/compiler/rustc_plugin_impl/Cargo.toml b/compiler/rustc_plugin_impl/Cargo.toml index fa27bfc61d1..c930b3365fd 100644 --- a/compiler/rustc_plugin_impl/Cargo.toml +++ b/compiler/rustc_plugin_impl/Cargo.toml @@ -12,6 +12,7 @@ rustc_errors = { path = "../rustc_errors" } rustc_lint = { path = "../rustc_lint" } rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_ast = { path = "../rustc_ast" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs index 672189e22cf..faa7495ef9f 100644 --- a/compiler/rustc_plugin_impl/src/lib.rs +++ b/compiler/rustc_plugin_impl/src/lib.rs @@ -12,8 +12,8 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_lint::LintStore; -use rustc_macros::fluent_messages; mod errors; pub mod load; diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index 744cb77dd00..08c4067705c 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -9,6 +9,7 @@ rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index dcebfca08fa..9567329192d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -17,12 +17,12 @@ use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; -use rustc_macros::fluent_messages; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 40869fdc467..c05323c2d6c 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -300,7 +300,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { interpret_alloc_index.reserve(new_n - n); for idx in n..new_n { let id = encoder.interpret_allocs[idx]; - let pos = encoder.position() as u32; + let pos: u32 = encoder.position().try_into().unwrap(); interpret_alloc_index.push(pos); interpret::specialized_encode_alloc_id(&mut encoder, tcx, id); } diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 579a789244b..08b588a8c94 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::SelfProfiler; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; -use rustc_middle::ty::{TyCtxt, WithOptConstParam}; +use rustc_middle::ty::TyCtxt; use rustc_query_system::query::QueryCache; use std::fmt::Debug; use std::io::Write; @@ -151,37 +151,6 @@ impl SpecIntoSelfProfilingString for LocalDefId { } } -impl<T: SpecIntoSelfProfilingString> SpecIntoSelfProfilingString for WithOptConstParam<T> { - fn spec_to_self_profile_string(&self, builder: &mut QueryKeyStringBuilder<'_, '_>) -> StringId { - // We print `WithOptConstParam` values as tuples to make them shorter - // and more readable, without losing information: - // - // "WithOptConstParam { did: foo::bar, const_param_did: Some(foo::baz) }" - // becomes "(foo::bar, foo::baz)" and - // "WithOptConstParam { did: foo::bar, const_param_did: None }" - // becomes "(foo::bar, _)". - - let did = StringComponent::Ref(self.did.to_self_profile_string(builder)); - - let const_param_did = if let Some(const_param_did) = self.const_param_did { - let const_param_did = builder.def_id_to_string_id(const_param_did); - StringComponent::Ref(const_param_did) - } else { - StringComponent::Value("_") - }; - - let components = [ - StringComponent::Value("("), - did, - StringComponent::Value(", "), - const_param_did, - StringComponent::Value(")"), - ]; - - builder.profiler.alloc_string(&components[..]) - } -} - impl<T0, T1> SpecIntoSelfProfilingString for (T0, T1) where T0: SpecIntoSelfProfilingString, diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 12b4a114313..34e57637976 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -12,6 +12,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index bb812b006e9..8c9e9cfad60 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -16,7 +16,7 @@ extern crate rustc_data_structures; extern crate rustc_macros; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod cache; pub mod dep_graph; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 4a6d07a03cc..bce01debc53 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -410,9 +410,28 @@ where // as its feeding query had. So if the fed query is red, so is its feeder, which will // get evaluated first, and re-feed the query. if let Some((cached_result, _)) = cache.lookup(&key) { - panic!( - "fed query later has its value computed. The already cached value: {}", - (query.format_value())(&cached_result) + let Some(hasher) = query.hash_result() else { + panic!( + "no_hash fed query later has its value computed.\n\ + Remove `no_hash` modifier to allow recomputation.\n\ + The already cached value: {}", + (query.format_value())(&cached_result) + ); + }; + + let (old_hash, new_hash) = qcx.dep_context().with_stable_hashing_context(|mut hcx| { + (hasher(&mut hcx, &cached_result), hasher(&mut hcx, &result)) + }); + let formatter = query.format_value(); + debug_assert_eq!( + old_hash, + new_hash, + "Computed query value for {:?}({:?}) is inconsistent with fed value,\n\ + computed={:#?}\nfed={:#?}", + query.dep_kind(), + key, + formatter(&result), + formatter(&cached_result), ); } } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index 5c4ec44d2b8..1c16d85f1b9 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -16,6 +16,7 @@ rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 01f002c9408..192badcbc37 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -223,3 +223,6 @@ resolve_remove_surrounding_derive = resolve_add_as_non_derive = add as non-Derive macro `#[{$macro_path}]` + +resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it + .help = you can define integration tests in a directory named `tests` diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index f905cec1011..967c9e22fb2 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -197,10 +197,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) { - // Query `module_children` is not used because hashing spans in its result is expensive. - let children = - Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess)); - for child in children { + for child in self.tcx.module_children(module.def_id()) { let parent_scope = ParentScope::module(module, self); BuildReducedGraphVisitor { r: self, parent_scope } .build_reduced_graph_for_external_crate_res(child); @@ -929,9 +926,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res(&mut self, child: ModChild) { + fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) { let parent = self.parent_scope.module; - let ModChild { ident, res, vis, reexport_chain } = child; + let ModChild { ident, res, vis, ref reexport_chain } = *child; let span = self.r.def_span( reexport_chain .first() diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index af0ec236df0..6197af105a9 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -508,3 +508,12 @@ pub(crate) struct RemoveSurroundingDerive { pub(crate) struct AddAsNonDerive<'a> { pub(crate) macro_path: &'a str, } + +#[derive(Diagnostic)] +#[diag(resolve_proc_macro_same_crate)] +pub(crate) struct ProcMacroSameCrate { + #[primary_span] + pub(crate) span: Span, + #[help] + pub(crate) is_test: bool, +} diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b820d56b8af..282f12bd3c0 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -33,6 +33,7 @@ use rustc_errors::{ Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage, }; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet}; @@ -40,7 +41,6 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_hir::TraitCandidate; use rustc_index::vec::IndexVec; -use rustc_macros::fluent_messages; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 22b014c0651..2211fb56ccd 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,7 +1,7 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. -use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; +use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; use crate::Namespace::*; use crate::{BuiltinMacroState, Determinacy}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; @@ -513,10 +513,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(def_id) = def_id.as_local() { self.unused_macros.remove(&def_id); if self.proc_macro_stubs.contains(&def_id) { - self.tcx.sess.span_err( - path.span, - "can't use a procedural macro from the same crate that defines it", - ); + self.tcx.sess.emit_err(errors::ProcMacroSameCrate { + span: path.span, + is_test: self.tcx.sess.is_test_crate(), + }); } } } diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 9eae99be2e9..d433391f272 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -367,6 +367,7 @@ fn preprocess_link(link: &str) -> Box<str> { let link = link.strip_suffix("{}").unwrap_or(link); let link = link.strip_suffix("[]").unwrap_or(link); let link = if link != "!" { link.strip_suffix('!').unwrap_or(link) } else { link }; + let link = link.trim(); strip_generics_from_path(link).unwrap_or_else(|_| link.into()) } diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 9e337dde995..15dbfbfd387 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -10,6 +10,7 @@ tracing = "0.1" rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_serialize = { path = "../rustc_serialize" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 79eb31bb105..419b6afe7c6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3048,9 +3048,9 @@ pub(crate) mod dep_tracking { #[derive(Clone, Copy, PartialEq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] pub enum OomStrategy { /// Generate a panic that can be caught by `catch_unwind`. - Panic, + Unwind, - /// Abort the process immediately. + /// Calls the panic hook as normal but aborts instead of unwinding. Abort, } @@ -3059,7 +3059,7 @@ impl OomStrategy { pub fn should_panic(self) -> u8 { match self { - OomStrategy::Panic => 1, + OomStrategy::Unwind => 1, OomStrategy::Abort => 0, } } diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 40879db49de..7fdbd48d563 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -227,28 +227,29 @@ pub fn get_or_default_sysroot() -> Result<PathBuf, String> { ))?; // if `dir` points target's dir, move up to the sysroot - if dir.ends_with(crate::config::host_triple()) { + let mut sysroot_dir = if dir.ends_with(crate::config::host_triple()) { dir.parent() // chop off `$target` .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| { - // chop off `lib` (this could be also $arch dir if the host sysroot uses a - // multi-arch layout like Debian or Ubuntu) - match p.parent() { - Some(p) => match p.file_name() { - Some(f) if f == "lib" => p.parent(), // first chop went for $arch, so chop again for `lib` - _ => Some(p), - }, - None => None, - } - }) + .and_then(|p| p.parent()) // chop off `lib` .map(|s| s.to_owned()) - .ok_or(format!( - "Could not move 3 levels upper using `parent()` on {}", - dir.display() - )) + .ok_or_else(|| { + format!("Could not move 3 levels upper using `parent()` on {}", dir.display()) + })? } else { - Ok(dir.to_owned()) + dir.to_owned() + }; + + // On multiarch linux systems, there will be multiarch directory named + // with the architecture(e.g `x86_64-linux-gnu`) under the `lib` directory. + // Which cause us to mistakenly end up in the lib directory instead of the sysroot directory. + if sysroot_dir.ends_with("lib") { + sysroot_dir = + sysroot_dir.parent().map(|real_sysroot| real_sysroot.to_owned()).ok_or_else( + || format!("Could not move to parent path of {}", sysroot_dir.display()), + )? } + + Ok(sysroot_dir) } // Use env::args().next() to get the path of the executable without diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 968728905e7..590a68c6600 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -19,7 +19,7 @@ pub mod errors; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod cgu_reuse_tracker; pub mod utils; diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 631dd0a2146..98bcacbe7ff 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -662,7 +662,7 @@ mod parse { pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { match v { - Some("panic") => *slot = OomStrategy::Panic, + Some("unwind") => *slot = OomStrategy::Unwind, Some("abort") => *slot = OomStrategy::Abort, _ => return false, } @@ -1452,9 +1452,9 @@ options! { fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED], "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \ (default: no)"), - flatten_format_args: bool = (false, parse_bool, [TRACKED], + flatten_format_args: bool = (true, parse_bool, [TRACKED], "flatten nested format_args!() and literals into a simplified format_args!() call \ - (default: no)"), + (default: yes)"), force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED], "force all crates to be `rustc_private` unstable (default: no)"), fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED], @@ -1558,6 +1558,9 @@ options! { "use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \ enabled, overriding all other checks. Passes that are not specified are enabled or \ disabled by other flags as usual."), + mir_keep_place_mention: bool = (false, parse_bool, [TRACKED], + "keep place mention MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ + (default: no)"), #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 4dad3c6bce7..09cb6fd22d5 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -128,6 +128,18 @@ fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir stable_mir::mir::Place { local: place.local.as_usize() } } +fn rustc_unwind_to_unwind( + unwind: &rustc_middle::mir::UnwindAction, +) -> stable_mir::mir::UnwindAction { + use rustc_middle::mir::UnwindAction; + match unwind { + UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, + UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, + UnwindAction::Terminate => stable_mir::mir::UnwindAction::Terminate, + UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), + } +} + fn rustc_terminator_to_terminator( terminator: &rustc_middle::mir::Terminator<'_>, ) -> stable_mir::mir::Terminator { @@ -151,7 +163,15 @@ fn rustc_terminator_to_terminator( Return => Terminator::Return, Unreachable => Terminator::Unreachable, Drop { .. } => todo!(), - Call { .. } => todo!(), + Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { + Terminator::Call { + func: rustc_op_to_op(func), + args: args.iter().map(|arg| rustc_op_to_op(arg)).collect(), + destination: rustc_place_to_place(destination), + target: target.map(|t| t.as_usize()), + unwind: rustc_unwind_to_unwind(unwind), + } + } Assert { .. } => todo!(), Yield { .. } => todo!(), GeneratorDrop => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index c504065c993..bd5e6b68a12 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -33,7 +33,7 @@ pub enum Terminator { args: Vec<Operand>, destination: Place, target: Option<usize>, - cleanup: Option<usize>, + unwind: UnwindAction, }, Assert { cond: Operand, @@ -45,6 +45,14 @@ pub enum Terminator { } #[derive(Clone, Debug)] +pub enum UnwindAction { + Continue, + Unreachable, + Terminate, + Cleanup(usize), +} + +#[derive(Clone, Debug)] pub enum Statement { Assign(Place, Operand), Nop, diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 83f4907d517..8a900ca427e 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1044,17 +1044,26 @@ impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Use the global `SourceMap` to print the span. If that's not // available, fall back to printing the raw values. - with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { - write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) - } else { - f.debug_struct("Span") - .field("lo", &self.lo()) - .field("hi", &self.hi()) - .field("ctxt", &self.ctxt()) - .finish() - } - }) + + fn fallback(span: Span, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Span") + .field("lo", &span.lo()) + .field("hi", &span.hi()) + .field("ctxt", &span.ctxt()) + .finish() + } + + if SESSION_GLOBALS.is_set() { + with_session_globals(|session_globals| { + if let Some(source_map) = &*session_globals.source_map.borrow() { + write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) + } else { + fallback(*self, f) + } + }) + } else { + fallback(*self, f) + } } } diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index c600298c51a..1eea0f63ca0 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -181,19 +181,23 @@ impl Span { #[inline] pub fn ctxt(self) -> SyntaxContext { let ctxt_or_tag = self.ctxt_or_tag as u32; - if ctxt_or_tag <= MAX_CTXT { - if self.len_or_tag == LEN_TAG || self.len_or_tag & PARENT_MASK == 0 { - // Inline format or interned format with inline ctxt. - SyntaxContext::from_u32(ctxt_or_tag) + // Check for interned format. + if self.len_or_tag == LEN_TAG { + if ctxt_or_tag == CTXT_TAG { + // Fully interned format. + let index = self.base_or_index; + with_span_interner(|interner| interner.spans[index as usize].ctxt) } else { - // Inline format or interned format with inline parent. - // We know that the SyntaxContext is root. - SyntaxContext::root() + // Interned format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } + } else if self.len_or_tag & PARENT_MASK == 0 { + // Inline format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } else { - // Interned format. - let index = self.base_or_index; - with_span_interner(|interner| interner.spans[index as usize].ctxt) + // Inline format with inline parent. + // We know that the SyntaxContext is root. + SyntaxContext::root() } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d6ee7ac34aa..70b9088de50 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1037,6 +1037,7 @@ symbols! { object_safe_for_dispatch, of, offset, + offset_of, omit_gdb_pretty_printer_section, on, on_unimplemented, @@ -1504,6 +1505,7 @@ symbols! { transmute_generic_consts, transmute_opts, transmute_trait, + transmute_unchecked, transparent, transparent_enums, transparent_unions, diff --git a/compiler/rustc_symbol_mangling/Cargo.toml b/compiler/rustc_symbol_mangling/Cargo.toml index 4e447eab02e..052ef8bb94c 100644 --- a/compiler/rustc_symbol_mangling/Cargo.toml +++ b/compiler/rustc_symbol_mangling/Cargo.toml @@ -15,6 +15,7 @@ twox-hash = "1.6.3" rustc_span = { path = "../rustc_span" } rustc_middle = { path = "../rustc_middle" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_target = { path = "../rustc_target" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index c2fd3304f2b..c97406868b6 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -101,9 +101,9 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_fluent_macro::fluent_messages; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; -use rustc_macros::fluent_messages; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index b4d5b7f3621..985b2210745 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -83,7 +83,7 @@ impl SymbolNamesTest<'_> { tcx.sess.emit_err(TestOutput { span: attr.span, kind: Kind::DefPath, - content: with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id())), + content: with_no_trimmed_paths!(tcx.def_path_str(def_id)), }); } } diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 262e8546a5d..a9152b8113f 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -814,16 +814,10 @@ fn transform_substs<'tcx>( substs: SubstsRef<'tcx>, options: TransformTyOptions, ) -> SubstsRef<'tcx> { - let substs = substs.iter().map(|subst| { - if let GenericArgKind::Type(ty) = subst.unpack() { - if is_c_void_ty(tcx, ty) { - tcx.mk_unit().into() - } else { - transform_ty(tcx, ty, options).into() - } - } else { - subst - } + let substs = substs.iter().map(|subst| match subst.unpack() { + GenericArgKind::Type(ty) if is_c_void_ty(tcx, ty) => tcx.mk_unit().into(), + GenericArgKind::Type(ty) => transform_ty(tcx, ty, options).into(), + _ => subst, }); tcx.mk_substs_from_iter(substs) } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 8d2e92cc76c..589cd3cf96b 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -124,6 +124,21 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { { Ty::is_unit(self) } + + pub fn offset_of_subfield<C>(self, cx: &C, indices: impl Iterator<Item = usize>) -> Size + where + Ty: TyAbiInterface<'a, C>, + { + let mut layout = self; + let mut offset = Size::ZERO; + + for index in indices { + offset += layout.fields.offset(index); + layout = layout.field(cx, index); + } + + offset + } } impl<'a, Ty> TyAndLayout<'a, Ty> { diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 5c6dcc0aba9..4c7f64b2078 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -19,6 +19,7 @@ pub enum Arch { I386, I686, X86_64, + X86_64h, X86_64_sim, X86_64_macabi, Arm64_macabi, @@ -36,6 +37,7 @@ impl Arch { I386 => "i386", I686 => "i686", X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64h => "x86_64h", } } @@ -44,13 +46,13 @@ impl Arch { Armv7 | Armv7k | Armv7s => "arm", Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", I386 | I686 => "x86", - X86_64 | X86_64_sim | X86_64_macabi => "x86_64", + X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", }) } fn target_abi(self) -> &'static str { match self { - Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 => "", + Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... @@ -67,6 +69,10 @@ impl Arch { Arm64_32 => "apple-s4", I386 | I686 => "yonah", X86_64 | X86_64_sim => "core2", + // Note: `core-avx2` is slightly more advanced than `x86_64h`, see + // comments (and disabled features) in `x86_64h_apple_darwin` for + // details. + X86_64h => "core-avx2", X86_64_macabi => "core2", Arm64_macabi => "apple-a12", Arm64_sim => "apple-a12", @@ -182,8 +188,13 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> { } fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { - // Note: Arm64_sim is not included since macOS has no simulator. - if matches!(arch, Arm64 | Arm64_macabi) { (11, 0) } else { (10, 7) } + match arch { + // Note: Arm64_sim is not included since macOS has no simulator. + Arm64 | Arm64_macabi => (11, 0), + // x86_64h-apple-darwin only supports macOS 10.8 and later + X86_64h => (10, 8), + _ => (10, 7), + } } fn macos_deployment_target(arch: Arch) -> (u32, u32) { @@ -227,7 +238,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> // of the linking environment that's wrong and reversed. match arch { Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim - | Arm64_sim => { + | X86_64h | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], diff --git a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs index ebd74012dcd..9bcd56bed00 100644 --- a/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/m68k_unknown_linux_gnu.rs @@ -3,6 +3,7 @@ use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); + base.cpu = "M68020".into(); base.max_atomic_width = Some(32); Target { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 3ee3a8ea227..10d38c34919 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1112,6 +1112,7 @@ supported_targets! { ("aarch64-apple-darwin", aarch64_apple_darwin), ("x86_64-apple-darwin", x86_64_apple_darwin), + ("x86_64h-apple-darwin", x86_64h_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), // FIXME(#106649): Remove aarch64-fuchsia in favor of aarch64-unknown-fuchsia diff --git a/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs new file mode 100644 index 00000000000..54f7490b2c0 --- /dev/null +++ b/compiler/rustc_target/src/spec/x86_64h_apple_darwin.rs @@ -0,0 +1,44 @@ +use super::apple_base::{macos_llvm_target, opts, Arch}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{StackProbeType, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::X86_64h; + let mut base = opts("macos", arch); + base.max_atomic_width = Some(128); + base.frame_pointer = FramePointer::Always; + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); + base.stack_probes = StackProbeType::X86; + base.supported_sanitizers = + SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; + + // x86_64h is core2-avx without a few of the features which would otherwise + // be guaranteed, so we need to disable those. This imitates clang's logic: + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L77-L78 + // - https://github.com/llvm/llvm-project/blob/bd1f7c417/clang/lib/Driver/ToolChains/Arch/X86.cpp#L133-L141 + // + // FIXME: Sadly, turning these off here disables them in such a way that they + // aren't re-enabled by `-Ctarget-cpu=native` (on a machine that has them). + // It would be nice if this were not the case, but fixing it seems tricky + // (and given that the main use-case for this target is for use in universal + // binaries, probably not that important). + base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into(); + // Double-check that the `cpu` is what we expect (if it's not the list above + // may need updating). + assert_eq!( + base.cpu, "core-avx2", + "you need to adjust the feature list in x86_64h-apple-darwin if you change this", + ); + + Target { + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + .into(), + arch: arch.target_arch(), + options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, + } +} diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index d3eba43b47e..a81459317be 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -14,6 +14,7 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index f866cb016e2..ed3994be987 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -37,7 +37,7 @@ extern crate rustc_middle; extern crate smallvec; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; pub mod errors; pub mod infer; diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index bb574954587..bd52957d162 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> { pub(super) search_graph: &'a mut SearchGraph<'tcx>, pub(super) nested_goals: NestedGoals<'tcx>, + + // Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`? + // + // If so, then it can no longer be used to make a canonical query response, + // since subsequent calls to `try_evaluate_added_goals` have possibly dropped + // ambiguous goals. Instead, a probe needs to be introduced somewhere in the + // evaluation code. + tainted: Result<(), NoSolution>, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { max_input_universe: ty::UniverseIndex::ROOT, var_values: CanonicalVarValues::dummy(), nested_goals: NestedGoals::new(), + tainted: Ok(()), }; let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal); @@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { max_input_universe: canonical_goal.max_universe, search_graph, nested_goals: NestedGoals::new(), + tainted: Ok(()), }; ecx.compute_goal(goal) }) @@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { }, ); + if response.is_err() { + self.tainted = Err(NoSolution); + } + self.nested_goals = goals; response } @@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { max_input_universe: self.max_input_universe, search_graph: self.search_graph, nested_goals: self.nested_goals.clone(), + tainted: self.tainted, }; self.infcx.probe(|_| f(&mut ecx)) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 23cf0f0c724..2dea36811d8 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -51,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { certainty: Certainty, ) -> QueryResult<'tcx> { let goals_certainty = self.try_evaluate_added_goals()?; + assert_eq!( + self.tainted, + Ok(()), + "EvalCtxt is tainted -- nested goals may have been dropped in a \ + previous call to `try_evaluate_added_goals!`" + ); + let certainty = certainty.unify_with(goals_certainty); let external_constraints = self.compute_external_query_constraints()?; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 14cb43b89c3..f0840e0443c 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -73,7 +73,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal.predicate.projection_ty, assumption_projection_pred.projection_ty, )?; - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.add_goals(requirements); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) @@ -114,7 +115,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { .into_iter() .map(|pred| goal.with(tcx, pred)), ); - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } else { @@ -198,7 +200,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const { let identity_substs = ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id); - let did = ty::WithOptConstParam::unknown(assoc_def.item.def_id); + let did = assoc_def.item.def_id; let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs)); ty.map_bound(|ty| tcx.mk_const(kind, ty).into()) @@ -206,7 +208,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty.map_bound(|ty| ty.into()) }; - ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))?; + ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs)) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -375,7 +378,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ), }; - ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -513,7 +517,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; ecx.probe(|ecx| { - ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 1abcc80d01a..8e7097ce4a7 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -645,12 +645,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Handling opaques here is kinda sus. Especially because we // simplify them to PlaceholderSimplifiedType. | ty::Alias(ty::Opaque, _) => { - if let Some(def_id) = self.tcx().find_map_relevant_impl( + let mut disqualifying_impl = None; + self.tcx().for_each_relevant_impl_treating_projections( goal.predicate.def_id(), goal.predicate.self_ty(), TreatProjections::NextSolverLookup, - Some, - ) { + |impl_def_id| { + disqualifying_impl = Some(impl_def_id); + }, + ); + if let Some(def_id) = disqualifying_impl { debug!(?def_id, ?goal, "disqualified auto-trait implementation"); // No need to actually consider the candidate here, // since we do that in `consider_impl_candidate`. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 182d995c4eb..222af4c2ace 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -796,10 +796,9 @@ impl<'tcx> AutoTraitFinder<'tcx> { Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())), Ok(None) => { let tcx = self.tcx; - let def_id = unevaluated.def.did; let reported = tcx.sess.emit_err(UnableToConstructConstantValue { - span: tcx.def_span(def_id), + span: tcx.def_span(unevaluated.def), unevaluated: unevaluated, }); Err(ErrorHandled::Reported(reported)) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 345e84990ed..9d99d30d45c 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -44,7 +44,7 @@ pub fn is_const_evaluatable<'tcx>( let ct = tcx.expand_abstract_consts(unexpanded_ct); let is_anon_ct = if let ty::ConstKind::Unevaluated(uv) = ct.kind() { - tcx.def_kind(uv.def.did) == DefKind::AnonConst + tcx.def_kind(uv.def) == DefKind::AnonConst } else { false }; @@ -119,7 +119,7 @@ pub fn is_const_evaluatable<'tcx>( tcx.sess .struct_span_fatal( // Slightly better span than just using `span` alone - if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def.did) } else { span }, + if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, "failed to evaluate generic const expression", ) .note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 726b08dc7d7..61e382bbe49 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -32,7 +32,6 @@ use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fast_reject::TreatProjections; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ @@ -1476,7 +1475,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }; let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant"); - let const_span = self.tcx.def_span(uv.def.did); + let const_span = self.tcx.def_span(uv.def); match self.tcx.sess.source_map().span_to_snippet(const_span) { Ok(snippet) => err.help(&format!( "try adding a `where` bound using this expression: `where [(); {}]:`", @@ -1771,7 +1770,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .tcx .mk_const( ty::UnevaluatedConst { - def: ty::WithOptConstParam::unknown(data.projection_ty.def_id), + def: data.projection_ty.def_id, substs: data.projection_ty.substs, }, ct.ty(), @@ -1836,57 +1835,61 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }); let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}"); - let secondary_span = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self - .tcx - .opt_associated_item(proj.projection_ty.def_id) - .and_then(|trait_assoc_item| { - self.tcx - .trait_of_item(proj.projection_ty.def_id) - .map(|id| (trait_assoc_item, id)) - }) - .and_then(|(trait_assoc_item, id)| { - let trait_assoc_ident = trait_assoc_item.ident(self.tcx); - self.tcx.find_map_relevant_impl( - id, - proj.projection_ty.self_ty(), - TreatProjections::ForLookup, - |did| { - self.tcx - .associated_items(did) - .in_definition_order() - .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident) - }, - ) - }) - .and_then(|item| match self.tcx.hir().get_if_local(item.def_id) { - Some( - hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Type(_, Some(ty)), - .. - }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Type(ty), - .. - }), - ) => Some(( - ty.span, - with_forced_trimmed_paths!(format!( - "type mismatch resolving `{}`", - self.resolve_vars_if_possible(predicate) - .print(FmtPrinter::new_with_limit( - self.tcx, - Namespace::TypeNS, - rustc_session::Limit(5), - )) - .unwrap() - .into_buffer() - )), + let secondary_span = (|| { + let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = + predicate.kind().skip_binder() + else { + return None; + }; + + let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?; + let trait_assoc_ident = trait_assoc_item.ident(self.tcx); + + let mut associated_items = vec![]; + self.tcx.for_each_relevant_impl( + self.tcx.trait_of_item(proj.projection_ty.def_id)?, + proj.projection_ty.self_ty(), + |impl_def_id| { + associated_items.extend( + self.tcx + .associated_items(impl_def_id) + .in_definition_order() + .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident), + ); + }, + ); + + let [associated_item]: &[ty::AssocItem] = &associated_items[..] else { + return None; + }; + match self.tcx.hir().get_if_local(associated_item.def_id) { + Some( + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Type(ty), + .. + }), + ) => Some(( + ty.span, + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.resolve_vars_if_possible(predicate) + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(5), + )) + .unwrap() + .into_buffer() )), - _ => None, - }), - _ => None, - }; + )), + _ => None, + } + })(); + self.note_type_err( &mut diag, &obligation.cause, @@ -2228,14 +2231,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>, ) -> bool { - let get_trait_impl = |trait_def_id| { - self.tcx.find_map_relevant_impl( + let get_trait_impls = |trait_def_id| { + let mut trait_impls = vec![]; + self.tcx.for_each_relevant_impl( trait_def_id, trait_ref.skip_binder().self_ty(), - TreatProjections::ForLookup, - Some, - ) + |impl_def_id| { + trait_impls.push(impl_def_id); + }, + ); + trait_impls }; + let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); let traits_with_same_path: std::collections::BTreeSet<_> = self .tcx @@ -2245,17 +2252,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .collect(); let mut suggested = false; for trait_with_same_path in traits_with_same_path { - if let Some(impl_def_id) = get_trait_impl(trait_with_same_path) { - let impl_span = self.tcx.def_span(impl_def_id); - err.span_help(impl_span, "trait impl with same name found"); - let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); - let crate_msg = format!( - "perhaps two different versions of crate `{}` are being used?", - trait_crate - ); - err.note(&crate_msg); - suggested = true; + let trait_impls = get_trait_impls(trait_with_same_path); + if trait_impls.is_empty() { + continue; } + let impl_spans: Vec<_> = + trait_impls.iter().map(|impl_def_id| self.tcx.def_span(*impl_def_id)).collect(); + err.span_help( + impl_spans, + format!("trait impl{} with same name found", pluralize!(trait_impls.len())), + ); + let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); + let crate_msg = format!( + "perhaps two different versions of crate `{}` are being used?", + trait_crate + ); + err.note(&crate_msg); + suggested = true; } suggested } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 26cadab3e9f..43196d1e629 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -540,8 +540,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { use ty::ConstKind::Unevaluated; match (c1.kind(), c2.kind()) { (Unevaluated(a), Unevaluated(b)) - if a.def.did == b.def.did - && tcx.def_kind(a.def.did) == DefKind::AssocConst => + if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst => { if let Ok(new_obligations) = infcx .at(&obligation.cause, obligation.param_env) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 5e042ffc603..ea45412e47f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1272,14 +1272,29 @@ fn project<'cx, 'tcx>( ProjectionCandidateSet::Single(candidate) => { Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate))) } - ProjectionCandidateSet::None => Ok(Projected::NoProgress( - // FIXME(associated_const_generics): this may need to change in the future? - // need to investigate whether or not this is fine. - selcx - .tcx() - .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) - .into(), - )), + ProjectionCandidateSet::None => { + let tcx = selcx.tcx(); + let term = match tcx.def_kind(obligation.predicate.def_id) { + DefKind::AssocTy | DefKind::ImplTraitPlaceholder => tcx + .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) + .into(), + DefKind::AssocConst => tcx + .mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new( + obligation.predicate.def_id, + obligation.predicate.substs, + )), + tcx.type_of(obligation.predicate.def_id) + .subst(tcx, obligation.predicate.substs), + ) + .into(), + kind => { + bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id)) + } + }; + + Ok(Projected::NoProgress(term)) + } // Error occurred while trying to processing impls. ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)), // Inherent ambiguity that prevents us from even enumerating the @@ -2131,9 +2146,8 @@ fn confirm_impl_candidate<'cx, 'tcx>( let ty = tcx.type_of(assoc_ty.item.def_id); let is_const = matches!(tcx.def_kind(assoc_ty.item.def_id), DefKind::AssocConst); let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const { - let identity_substs = - crate::traits::InternalSubsts::identity_for_item(tcx, assoc_ty.item.def_id); - let did = ty::WithOptConstParam::unknown(assoc_ty.item.def_id); + let did = assoc_ty.item.def_id; + let identity_substs = crate::traits::InternalSubsts::identity_for_item(tcx, did); let kind = ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs)); ty.map_bound(|ty| tcx.mk_const(kind, ty).into()) } else { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index a019d00461b..1db9b8ce92e 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -11,7 +11,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections}; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::traits; @@ -875,12 +875,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Adt(..) => { - // Find a custom `impl Drop` impl, if it exists - let relevant_impl = self.tcx().find_map_relevant_impl( + let mut relevant_impl = None; + self.tcx().for_each_relevant_impl( self.tcx().require_lang_item(LangItem::Drop, None), obligation.predicate.skip_binder().trait_ref.self_ty(), - TreatProjections::ForLookup, - Some, + |impl_def_id| { + if let Some(old_impl_def_id) = relevant_impl { + self.tcx() + .sess + .struct_span_err( + self.tcx().def_span(impl_def_id), + "multiple drop impls found", + ) + .span_note(self.tcx().def_span(old_impl_def_id), "other impl here") + .delay_as_bug(); + } + + relevant_impl = Some(impl_def_id); + }, ); if let Some(impl_def_id) = relevant_impl { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 0fdba524e25..081e4d7cfa4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -896,8 +896,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { use ty::ConstKind::Unevaluated; match (c1.kind(), c2.kind()) { (Unevaluated(a), Unevaluated(b)) - if a.def.did == b.def.did - && tcx.def_kind(a.def.did) == DefKind::AssocConst => + if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst => { if let Ok(InferOk { obligations, value: () }) = self .infcx diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 3d026506a5a..40e19abc0d0 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -170,29 +170,20 @@ pub fn predicate_obligations<'tcx>( ty::PredicateKind::WellFormed(arg) => { wf.compute(arg); } - ty::PredicateKind::ObjectSafe(_) => {} - ty::PredicateKind::ClosureKind(..) => {} - ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => { - wf.compute(a.into()); - wf.compute(b.into()); - } - ty::PredicateKind::Coerce(ty::CoercePredicate { a, b }) => { - wf.compute(a.into()); - wf.compute(b.into()); - } + ty::PredicateKind::ConstEvaluatable(ct) => { wf.compute(ct.into()); } - ty::PredicateKind::ConstEquate(c1, c2) => { - wf.compute(c1.into()); - wf.compute(c2.into()); - } - ty::PredicateKind::Ambiguous => {} - ty::PredicateKind::TypeWellFormedFromEnv(..) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } - ty::PredicateKind::AliasRelate(..) => { - bug!("We should only wf check where clauses and `AliasRelate` is not a `Clause`") + + ty::PredicateKind::ObjectSafe(_) + | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous + | ty::PredicateKind::AliasRelate(..) + | ty::PredicateKind::TypeWellFormedFromEnv(..) => { + bug!("We should only wf check where clauses, unexpected predicate: {predicate:?}") } } @@ -487,7 +478,7 @@ impl<'tcx> WfPredicates<'tcx> { match ct.kind() { ty::ConstKind::Unevaluated(uv) => { if !ct.has_escaping_bound_vars() { - let obligations = self.nominal_obligations(uv.def.did, uv.substs); + let obligations = self.nominal_obligations(uv.def, uv.substs); self.out.extend(obligations); let predicate = diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 31eea22d72b..4d225e36b22 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -60,6 +60,20 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst } } +impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> + for &'tcx ty::List<Ty<'tcx>> +{ + fn lower_into( + self, + interner: RustInterner<'tcx>, + ) -> chalk_ir::Substitution<RustInterner<'tcx>> { + chalk_ir::Substitution::from_iter( + interner, + self.iter().map(|ty| GenericArg::from(ty).lower_into(interner)), + ) + } +} + impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> { fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> { interner @@ -351,9 +365,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> { ty::GeneratorWitness(_) => unimplemented!(), ty::GeneratorWitnessMIR(..) => unimplemented!(), ty::Never => chalk_ir::TyKind::Never, - ty::Tuple(types) => { - chalk_ir::TyKind::Tuple(types.len(), types.as_substs().lower_into(interner)) - } + ty::Tuple(types) => chalk_ir::TyKind::Tuple(types.len(), types.lower_into(interner)), ty::Alias(ty::Projection, ty::AliasTy { def_id, substs, .. }) => { chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { associated_ty_id: chalk_ir::AssocTypeId(def_id), @@ -435,7 +447,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { TyKind::GeneratorWitness(..) => unimplemented!(), TyKind::Never => ty::Never, TyKind::Tuple(_len, substitution) => { - ty::Tuple(substitution.lower_into(interner).try_as_type_list().unwrap()) + ty::Tuple(substitution.lower_into(interner).into_type_list(interner.tcx)) } TyKind::Slice(ty) => ty::Slice(ty.lower_into(interner)), TyKind::Raw(mutbl, ty) => ty::RawPtr(ty::TypeAndMut { diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 52fbd3ae047..51885c9b47e 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -9,6 +9,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_hir = { path = "../rustc_hir" } +rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index b67607a4db6..b08a92570ed 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -132,7 +132,7 @@ fn recurse_build<'tcx>( tcx.mk_const(val, node.ty) } &ExprKind::NamedConst { def_id, substs, user_ty: _ } => { - let uneval = ty::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = ty::UnevaluatedConst::new(def_id, substs); tcx.mk_const(uneval, node.ty) } ExprKind::ConstParam { param, .. } => tcx.mk_const(*param, node.ty), @@ -256,6 +256,7 @@ fn recurse_build<'tcx>( ExprKind::VarRef { .. } | ExprKind::UpvarRef { .. } | ExprKind::StaticRef { .. } + | ExprKind::OffsetOf { .. } | ExprKind::ThreadLocalRef(_) => { error(GenericConstantTooComplexSub::OperationNotSupported(node.span))? } @@ -347,6 +348,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { | thir::ExprKind::ZstLiteral { .. } | thir::ExprKind::StaticRef { .. } | thir::ExprKind::InlineAsm(_) + | thir::ExprKind::OffsetOf { .. } | thir::ExprKind::ThreadLocalRef(_) | thir::ExprKind::Yield { .. } => false, } @@ -391,52 +393,36 @@ impl<'a, 'tcx> visit::Visitor<'a, 'tcx> for IsThirPolymorphic<'a, 'tcx> { /// Builds an abstract const, do not use this directly, but use `AbstractConst::new` instead. pub fn thir_abstract_const( tcx: TyCtxt<'_>, - def: ty::WithOptConstParam<LocalDefId>, + def: LocalDefId, ) -> Result<Option<ty::Const<'_>>, ErrorGuaranteed> { - if tcx.features().generic_const_exprs { - match tcx.def_kind(def.did) { - // FIXME(generic_const_exprs): We currently only do this for anonymous constants, - // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether - // we want to look into them or treat them as opaque projections. - // - // Right now we do neither of that and simply always fail to unify them. - DefKind::AnonConst | DefKind::InlineConst => (), - _ => return Ok(None), - } - - let body = tcx.thir_body(def)?; - let (body, body_id) = (&*body.0.borrow(), body.1); + if !tcx.features().generic_const_exprs { + return Ok(None); + } - let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; - visit::walk_expr(&mut is_poly_vis, &body[body_id]); - if !is_poly_vis.is_poly { - return Ok(None); - } + match tcx.def_kind(def) { + // FIXME(generic_const_exprs): We currently only do this for anonymous constants, + // meaning that we do not look into associated constants. I(@lcnr) am not yet sure whether + // we want to look into them or treat them as opaque projections. + // + // Right now we do neither of that and simply always fail to unify them. + DefKind::AnonConst | DefKind::InlineConst => (), + _ => return Ok(None), + } - let root_span = body.exprs[body_id].span; + let body = tcx.thir_body(def)?; + let (body, body_id) = (&*body.0.borrow(), body.1); - Some(recurse_build(tcx, body, body_id, root_span)).transpose() - } else { - Ok(None) + let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body }; + visit::walk_expr(&mut is_poly_vis, &body[body_id]); + if !is_poly_vis.is_poly { + return Ok(None); } + + let root_span = body.exprs[body_id].span; + + Some(recurse_build(tcx, body, body_id, root_span)).transpose() } pub fn provide(providers: &mut ty::query::Providers) { - *providers = ty::query::Providers { - destructure_const, - thir_abstract_const: |tcx, def_id| { - if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { - tcx.thir_abstract_const_of_const_arg(def) - } else { - thir_abstract_const(tcx, ty::WithOptConstParam::unknown(def_id)) - } - }, - thir_abstract_const_of_const_arg: |tcx, (did, param_did)| { - thir_abstract_const( - tcx, - ty::WithOptConstParam { did, const_param_did: Some(param_did) }, - ) - }, - ..*providers - }; + *providers = ty::query::Providers { destructure_const, thir_abstract_const, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 47cd7af221d..21cc3c9517e 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -1,5 +1,5 @@ use rustc_errors::ErrorGuaranteed; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; @@ -14,54 +14,26 @@ fn resolve_instance<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, (DefId, SubstsRef<'tcx>)>, ) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, substs)) = key.into_parts(); - if let Some(did) = did.as_local() { - if let Some(param_did) = tcx.opt_const_param_of(did) { - return tcx.resolve_instance_of_const_arg(param_env.and((did, param_did, substs))); - } - } - - inner_resolve_instance(tcx, param_env.and((ty::WithOptConstParam::unknown(did), substs))) -} - -fn resolve_instance_of_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (LocalDefId, DefId, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { - let (param_env, (did, const_param_did, substs)) = key.into_parts(); - inner_resolve_instance( - tcx, - param_env.and(( - ty::WithOptConstParam { did: did.to_def_id(), const_param_did: Some(const_param_did) }, - substs, - )), - ) -} - -fn inner_resolve_instance<'tcx>( - tcx: TyCtxt<'tcx>, - key: ty::ParamEnvAnd<'tcx, (ty::WithOptConstParam<DefId>, SubstsRef<'tcx>)>, -) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> { let (param_env, (def, substs)) = key.into_parts(); - let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) { + let result = if let Some(trait_def_id) = tcx.trait_of_item(def) { debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env); resolve_associated_item( tcx, - def.did, + def, param_env, trait_def_id, tcx.normalize_erasing_regions(param_env, substs), ) } else { - let ty = tcx.type_of(def.def_id_for_type_of()); + let ty = tcx.type_of(def); let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty.skip_binder()); let def = match *item_type.kind() { ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => { debug!(" => intrinsic"); - ty::InstanceDef::Intrinsic(def.did) + ty::InstanceDef::Intrinsic(def) } ty::FnDef(def_id, substs) if Some(def_id) == tcx.lang_items().drop_in_place_fn() => { let ty = substs.type_at(0); @@ -206,15 +178,11 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, substs)) } traits::ImplSource::Generator(generator_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - generator_data.generator_def_id, - )), + def: ty::InstanceDef::Item(generator_data.generator_def_id), substs: generator_data.substs, }), traits::ImplSource::Future(future_data) => Some(Instance { - def: ty::InstanceDef::Item(ty::WithOptConstParam::unknown( - future_data.generator_def_id, - )), + def: ty::InstanceDef::Item(future_data.generator_def_id), substs: future_data.substs, }), traits::ImplSource::Closure(closure_data) => { @@ -298,6 +266,5 @@ fn resolve_associated_item<'tcx>( } pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { resolve_instance, resolve_instance_of_const_arg, ..*providers }; + *providers = ty::query::Providers { resolve_instance, ..*providers }; } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 2613445f39b..9d5a72a73cd 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -19,7 +19,7 @@ extern crate rustc_middle; extern crate tracing; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::fluent_messages; +use rustc_fluent_macro::fluent_messages; use rustc_middle::ty::query::Providers; mod abi; diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 62e699eefd7..4c1f2dd0e53 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -203,6 +203,10 @@ pub enum TyKind<I: Interner> { /// `for<'a, T> &'a (): Trait<T>` and then convert the introduced bound variables /// back to inference variables in a new inference context when inside of the query. /// + /// It is conventional to render anonymous bound types like `^N` or `^D_N`, + /// where `N` is the bound variable's anonymous index into the binder, and + /// `D` is the debruijn index, or totally omitted if the debruijn index is zero. + /// /// See the `rustc-dev-guide` for more details about /// [higher-ranked trait bounds][1] and [canonical queries][2]. /// @@ -212,6 +216,12 @@ pub enum TyKind<I: Interner> { /// A placeholder type, used during higher ranked subtyping to instantiate /// bound variables. + /// + /// It is conventional to render anonymous placeholer types like `!N` or `!U_N`, + /// where `N` is the placeholder variable's anonymous index (which corresponds + /// to the bound variable's index from the binder from which it was instantiated), + /// and `U` is the universe index in which it is instantiated, or totally omitted + /// if the universe index is zero. Placeholder(I::PlaceholderType), /// A type variable used during type checking. diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 95c07abf731..8975ba3f06b 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -35,3 +35,6 @@ compiler-builtins-mem = ['compiler_builtins/mem'] compiler-builtins-c = ["compiler_builtins/c"] compiler-builtins-no-asm = ["compiler_builtins/no-asm"] compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"] + +# Make panics and failed asserts immediately abort without formatting any message +panic_immediate_abort = ["core/panic_immediate_abort"] diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 6f2ba957bcd..0db23e55a86 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,6 +14,11 @@ use core::ptr::{self, NonNull}; #[doc(inline)] pub use core::alloc::*; +#[cfg(not(no_global_oom_handling))] +use core::any::Any; +#[cfg(not(no_global_oom_handling))] +use core::panic::BoxMeUp; + #[cfg(test)] mod tests; @@ -343,14 +348,77 @@ pub(crate) unsafe fn box_free<T: ?Sized, A: Allocator>(ptr: Unique<T>, alloc: A) } } -// # Allocation error handler +/// Payload passed to the panic handler when `handle_alloc_error` is called. +#[unstable(feature = "panic_oom_payload", issue = "none")] +#[derive(Debug)] +pub struct AllocErrorPanicPayload { + layout: Layout, +} + +impl AllocErrorPanicPayload { + /// Internal function for the standard library to clone a payload. + #[unstable(feature = "std_internals", issue = "none")] + #[doc(hidden)] + pub fn internal_clone(&self) -> Self { + AllocErrorPanicPayload { layout: self.layout } + } + /// Returns the [`Layout`] of the allocation attempt that caused the error. + #[unstable(feature = "panic_oom_payload", issue = "none")] + pub fn layout(&self) -> Layout { + self.layout + } +} + +#[unstable(feature = "std_internals", issue = "none")] #[cfg(not(no_global_oom_handling))] -extern "Rust" { - // This is the magic symbol to call the global alloc error handler. rustc generates - // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the - // default implementations below (`__rdl_oom`) otherwise. - fn __rust_alloc_error_handler(size: usize, align: usize) -> !; +unsafe impl BoxMeUp for AllocErrorPanicPayload { + fn take_box(&mut self) -> *mut (dyn Any + Send) { + use crate::boxed::Box; + Box::into_raw(Box::new(self.internal_clone())) + } + + fn get(&mut self) -> &(dyn Any + Send) { + self + } +} + +// # Allocation error handler + +#[cfg(all(not(no_global_oom_handling), not(test)))] +fn rust_oom(layout: Layout) -> ! { + if cfg!(feature = "panic_immediate_abort") { + core::intrinsics::abort() + } + + extern "Rust" { + // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call + // that gets resolved to the `#[panic_handler]` function. + #[lang = "panic_impl"] + fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !; + + // This symbol is emitted by rustc . + // Its value depends on the -Zoom={unwind,abort} compiler option. + static __rust_alloc_error_handler_should_panic: u8; + } + + // Hack to work around issues with the lifetime of Arguments. + match format_args!("memory allocation of {} bytes failed", layout.size()) { + fmt => { + // Create a PanicInfo with a custom payload for the panic handler. + let can_unwind = unsafe { __rust_alloc_error_handler_should_panic != 0 }; + let mut pi = core::panic::PanicInfo::internal_constructor( + Some(&fmt), + core::panic::Location::caller(), + can_unwind, + ); + let payload = AllocErrorPanicPayload { layout }; + pi.set_payload(&payload); + + // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. + unsafe { panic_impl(&pi) } + } + } } /// Abort on memory allocation error or failure. @@ -358,13 +426,6 @@ extern "Rust" { /// Callers of memory allocation APIs wishing to abort computation /// in response to an allocation error are encouraged to call this function, /// rather than directly invoking `panic!` or similar. -/// -/// The default behavior of this function is to print a message to standard error -/// and abort the process. -/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. -/// -/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html -/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[cfg(all(not(no_global_oom_handling), not(test)))] @@ -375,9 +436,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { } fn rt_error(layout: Layout) -> ! { - unsafe { - __rust_alloc_error_handler(layout.size(), layout.align()); - } + rust_oom(layout); } unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } @@ -387,6 +446,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { #[cfg(all(not(no_global_oom_handling), test))] pub use std::alloc::handle_alloc_error; +#[cfg(bootstrap)] #[cfg(all(not(no_global_oom_handling), not(test)))] #[doc(hidden)] #[allow(unused_attributes)] @@ -398,7 +458,7 @@ pub mod __alloc_error_handler { pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. + // Its value depends on the -Zoom={unwind,abort} compiler option. static __rust_alloc_error_handler_should_panic: u8; } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7f88327bf19..ad86c193098 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -576,8 +576,7 @@ impl<T, A: Allocator> Box<T, A> { /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> { + pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -809,9 +808,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn assume_init(self) -> Box<T, A> { + pub unsafe fn assume_init(self) -> Box<T, A> { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } @@ -844,9 +842,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// } /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn write(mut boxed: Self, value: T) -> Box<T, A> { + pub fn write(mut boxed: Self, value: T) -> Box<T, A> { unsafe { (*boxed).write(value); boxed.assume_init() @@ -1090,9 +1087,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let (leaked, alloc) = Box::into_unique(b); (leaked.as_ptr(), alloc) } @@ -1102,10 +1098,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] #[doc(hidden)] - pub const fn into_unique(b: Self) -> (Unique<T>, A) { + pub fn into_unique(b: Self) -> (Unique<T>, A) { // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a // raw pointer for the type system. Turning it directly into a raw pointer would not be // recognized as "releasing" the unique pointer to permit aliased raw accesses, @@ -1163,9 +1158,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// assert_eq!(*static_ref, [4, 2, 3]); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn leak<'a>(b: Self) -> &'a mut T + pub fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { @@ -1234,8 +1228,7 @@ impl<T: Default> Default for Box<T> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Box<[T]> { +impl<T> Default for Box<[T]> { #[inline] fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); @@ -1245,8 +1238,7 @@ impl<T> const Default for Box<[T]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Box<str> { +impl Default for Box<str> { #[inline] fn default() -> Self { // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`. @@ -1443,8 +1435,7 @@ impl<T> From<T> for Box<T> { } #[stable(feature = "pin", since = "1.33.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>> +impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>> where A: 'static, { @@ -1880,8 +1871,7 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { +impl<T: ?Sized, A: Allocator> Deref for Box<T, A> { type Target = T; fn deref(&self) -> &T { @@ -1890,8 +1880,7 @@ impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> { +impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> { fn deref_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index ad48315fd70..f83c8f83cc9 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; use core::ptr::{self, NonNull}; @@ -202,9 +202,7 @@ impl<H> WithHeader<H> { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::<T>() == 0 && mem::size_of::<H>() == 0 - ); + debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -249,9 +247,7 @@ impl<H> WithHeader<H> { alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); } else { debug_assert!( - value_offset == 0 - && mem::size_of::<H>() == 0 - && self.value_layout.size() == 0 + value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0 ); } } diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 1da86e1a46a..e03b501ae4d 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -551,8 +551,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[unstable(feature = "fmt_internals", issue = "none")] -pub use core::fmt::rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::Alignment; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index aa240c37e84..2c6a266e2a1 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,7 +106,6 @@ #![feature(coerce_unsized)] #![feature(const_align_of_val)] #![feature(const_box)] -#![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_eval_select)] #![feature(const_maybe_uninit_as_mut_ptr)] @@ -136,6 +135,7 @@ #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array_transpose)] +#![feature(panic_internals)] #![feature(pattern)] #![feature(pointer_byte_offsets)] #![feature(provide_any)] @@ -174,7 +174,6 @@ #![feature(associated_type_bounds)] #![feature(c_unwind)] #![feature(cfg_sanitize)] -#![feature(const_deref)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_ptr_write)] diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index be41919b9dc..cf16a3424a0 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -2247,8 +2247,7 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for String { +impl Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 2b1a787cc54..3091efabd68 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { let unyielded_ptr = this.iter.as_slice().as_ptr(); // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move { + if !T::IS_ZST { let start_ptr = source_vec.as_mut_ptr().add(start); // memmove back unyielded elements @@ -197,7 +195,7 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { } } - let iter = mem::replace(&mut self.iter, (&mut []).iter()); + let iter = mem::take(&mut self.iter); let drop_len = iter.len(); let mut vec = self.vec; diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index 8c03f1692d9..650f9213890 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -1,5 +1,5 @@ use crate::alloc::{Allocator, Global}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ptr; use core::slice; @@ -96,9 +96,7 @@ where unsafe { // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move && this.idx < this.old_len && this.del > 0 { + if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { let ptr = this.vec.as_mut_ptr(); let src = ptr.add(this.idx); let dst = src.sub(this.del); diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 3736a6e0b0e..765c095e37b 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3022,8 +3022,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Vec<T> { +impl<T> Default for Vec<T> { /// Creates an empty `Vec<T>`. /// /// The vector will not allocate until elements are pushed onto it. diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index 68ebd8e35ee..4cacee0414d 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -61,7 +61,7 @@ fn box_deref_lval() { pub struct ConstAllocator; -unsafe impl const Allocator for ConstAllocator { +unsafe impl Allocator for ConstAllocator { fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { match layout.size() { 0 => Ok(NonNull::slice_from_raw_parts(layout.dangling(), 0)), diff --git a/library/alloc/tests/const_fns.rs b/library/alloc/tests/const_fns.rs index 49b837becbc..4e7d7fc833e 100644 --- a/library/alloc/tests/const_fns.rs +++ b/library/alloc/tests/const_fns.rs @@ -1,13 +1,16 @@ // Test const functions in the library pub const MY_VEC: Vec<usize> = Vec::new(); -pub const MY_VEC2: Vec<usize> = Default::default(); + +// FIXME(#110395) +// pub const MY_VEC2: Vec<usize> = Default::default(); pub const MY_STRING: String = String::new(); -pub const MY_STRING2: String = Default::default(); -pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); -pub const MY_BOXED_STR: Box<str> = Default::default(); +// pub const MY_STRING2: String = Default::default(); + +// pub const MY_BOXED_SLICE: Box<[usize]> = Default::default(); +// pub const MY_BOXED_STR: Box<str> = Default::default(); use std::collections::{BTreeMap, BTreeSet}; @@ -23,11 +26,11 @@ pub const SET_IS_EMPTY: bool = SET.is_empty(); #[test] fn test_const() { - assert_eq!(MY_VEC, MY_VEC2); - assert_eq!(MY_STRING, MY_STRING2); + assert_eq!(MY_VEC, /* MY_VEC */ vec![]); + assert_eq!(MY_STRING, /* MY_STRING2 */ String::default()); - assert_eq!(MY_VEC, *MY_BOXED_SLICE); - assert_eq!(MY_STRING, *MY_BOXED_STR); + // assert_eq!(MY_VEC, *MY_BOXED_SLICE); + // assert_eq!(MY_STRING, *MY_BOXED_STR); assert_eq!(MAP_LEN, 0); assert_eq!(SET_LEN, 0); diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 0667cd7bc07..0eca4c9bb07 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -3,7 +3,6 @@ #![feature(assert_matches)] #![feature(btree_drain_filter)] #![feature(cow_is_borrowed)] -#![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_heap)] #![feature(const_mut_refs)] @@ -33,7 +32,6 @@ #![feature(slice_partition_dedup)] #![feature(string_remove_matches)] #![feature(const_btree_len)] -#![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(const_str_from_utf8)] #![feature(panic_update_hook)] diff --git a/library/backtrace b/library/backtrace -Subproject 07872f28cd8a65c3c7428811548dc85f1f2fb05 +Subproject 8ad84ca5ad88ade697637387e7cb4d7c3cf4bde diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index ac3d84718d5..59730303734 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -231,9 +231,8 @@ impl Layout { /// Returns an error if the combination of `self.size()` and the given /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> { + pub fn align_to(&self, align: usize) -> Result<Self, LayoutError> { Layout::from_size_align(self.size(), cmp::max(self.align(), align)) } @@ -315,9 +314,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { + pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { // This cannot overflow. Quoting from the invariant of Layout: // > `size`, when rounded up to the nearest multiple of `align`, // > must not overflow isize (i.e., the rounded value must be @@ -376,9 +374,8 @@ impl Layout { /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { + pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = cmp::max(self.align, next.align); let pad = self.padding_needed_for(next.align()); @@ -403,9 +400,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> { + pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> { let size = self.size().checked_mul(n).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(size, self.align) @@ -418,9 +414,8 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] - pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> { + pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> { let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?; // The safe constructor is called here to enforce the isize size limit. Layout::from_size_alignment(new_size, self.align) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index ff390322d55..d6ae2b8213f 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -105,7 +105,6 @@ impl fmt::Display for AllocError { /// /// [*currently allocated*]: #currently-allocated-memory #[unstable(feature = "allocator_api", issue = "32838")] -#[const_trait] pub unsafe trait Allocator { /// Attempts to allocate a block of memory. /// diff --git a/library/core/src/any.rs b/library/core/src/any.rs index c27646b8f33..bb93ea509d8 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -662,8 +662,7 @@ impl dyn Any + Send + Sync { /// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth /// noting that the hashes and ordering will vary between Rust releases. Beware /// of relying on them inside of your code! -#[derive(Clone, Copy, Debug, Hash, Eq)] -#[derive_const(PartialEq, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[stable(feature = "rust1", since = "1.0.0")] pub struct TypeId { t: u64, diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 73e2c2cfbbe..587877dff55 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -3,8 +3,9 @@ use crate::num::NonZeroUsize; use crate::{ fmt, + intrinsics::transmute_unchecked, iter::{self, ExactSizeIterator, FusedIterator, TrustedLen}, - mem::{self, MaybeUninit}, + mem::MaybeUninit, ops::{IndexRange, Range}, ptr, }; @@ -63,18 +64,11 @@ impl<T, const N: usize> IntoIterator for [T; N] { // an array of `T`. // // With that, this initialization satisfies the invariants. - - // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it - // works with const generics: - // `mem::transmute::<[T; N], [MaybeUninit<T>; N]>(array)` // - // Until then, we can use `mem::transmute_copy` to create a bitwise copy - // as a different type, then forget `array` so that it is not dropped. - unsafe { - let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) }; - mem::forget(self); - iter - } + // FIXME: If normal `transmute` ever gets smart enough to allow this + // directly, use it instead of `transmute_unchecked`. + let data: [MaybeUninit<T>; N] = unsafe { transmute_unchecked(self) }; + IntoIter { data, alive: IndexRange::zero_to(N) } } } diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 1643842d607..98c87b2c393 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -148,8 +148,7 @@ impl Error for TryFromSliceError { } #[stable(feature = "try_from_slice_error", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<Infallible> for TryFromSliceError { +impl From<Infallible> for TryFromSliceError { fn from(x: Infallible) -> TryFromSliceError { match x {} } @@ -172,16 +171,14 @@ impl<T, const N: usize> AsMut<[T]> for [T; N] { } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T, const N: usize> const Borrow<[T]> for [T; N] { +impl<T, const N: usize> Borrow<[T]> for [T; N] { fn borrow(&self) -> &[T] { self } } #[stable(feature = "array_borrow", since = "1.4.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T, const N: usize> const BorrowMut<[T]> for [T; N] { +impl<T, const N: usize> BorrowMut<[T]> for [T; N] { fn borrow_mut(&mut self) -> &mut [T] { self } @@ -336,10 +333,9 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] { } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I, const N: usize> const Index<I> for [T; N] +impl<T, I, const N: usize> Index<I> for [T; N] where - [T]: ~const Index<I>, + [T]: Index<I>, { type Output = <[T] as Index<I>>::Output; @@ -350,10 +346,9 @@ where } #[stable(feature = "index_trait_on_arrays", since = "1.50.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I, const N: usize> const IndexMut<I> for [T; N] +impl<T, I, const N: usize> IndexMut<I> for [T; N] where - [T]: ~const IndexMut<I>, + [T]: IndexMut<I>, { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { @@ -435,8 +430,7 @@ impl<T: Copy> SpecArrayClone for T { macro_rules! array_impl_default { {$n:expr, $t:ident $($ts:ident)*} => { #[stable(since = "1.4.0", feature = "array_default")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<T> const Default for [T; $n] where T: ~const Default { + impl<T> Default for [T; $n] where T: Default { fn default() -> [T; $n] { [$t::default(), $($ts::default()),*] } @@ -445,8 +439,7 @@ macro_rules! array_impl_default { }; {$n:expr,} => { #[stable(since = "1.4.0", feature = "array_default")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<T> const Default for [T; $n] { + impl<T> Default for [T; $n] { fn default() -> [T; $n] { [] } } }; diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index db1c505ba38..03cdff9b13b 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,7 +1,5 @@ //! impl bool {} -use crate::marker::Destruct; - impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), /// or `None` otherwise. @@ -31,12 +29,8 @@ impl bool { /// assert_eq!(a, 2); /// ``` #[stable(feature = "bool_to_option", since = "1.62.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then_some<T>(self, t: T) -> Option<T> - where - T: ~const Destruct, - { + pub fn then_some<T>(self, t: T) -> Option<T> { if self { Some(t) } else { None } } @@ -61,13 +55,8 @@ impl bool { /// assert_eq!(a, 1); /// ``` #[stable(feature = "lazy_bool_to_option", since = "1.50.0")] - #[rustc_const_unstable(feature = "const_bool_to_option", issue = "91917")] #[inline] - pub const fn then<T, F>(self, f: F) -> Option<T> - where - F: ~const FnOnce() -> T, - F: ~const Destruct, - { + pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> { if self { Some(f()) } else { None } } } diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs index 4a8302ee404..efc9ada3891 100644 --- a/library/core/src/borrow.rs +++ b/library/core/src/borrow.rs @@ -154,7 +154,6 @@ /// [`String`]: ../../std/string/struct.String.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Borrow"] -#[const_trait] pub trait Borrow<Borrowed: ?Sized> { /// Immutably borrows from an owned value. /// @@ -185,7 +184,6 @@ pub trait Borrow<Borrowed: ?Sized> { /// an underlying type by providing a mutable reference. See [`Borrow<T>`] /// for more information on borrowing as another type. #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> { /// Mutably borrows from an owned value. /// @@ -207,8 +205,7 @@ pub trait BorrowMut<Borrowed: ?Sized>: Borrow<Borrowed> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for T { +impl<T: ?Sized> Borrow<T> for T { #[rustc_diagnostic_item = "noop_method_borrow"] fn borrow(&self) -> &T { self @@ -216,32 +213,28 @@ impl<T: ?Sized> const Borrow<T> for T { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const BorrowMut<T> for T { +impl<T: ?Sized> BorrowMut<T> for T { fn borrow_mut(&mut self) -> &mut T { self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for &T { +impl<T: ?Sized> Borrow<T> for &T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const Borrow<T> for &mut T { +impl<T: ?Sized> Borrow<T> for &mut T { fn borrow(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_borrow", issue = "91522")] -impl<T: ?Sized> const BorrowMut<T> for &mut T { +impl<T: ?Sized> BorrowMut<T> for &mut T { fn borrow_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index d728dc03817..bcca8d924cd 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -370,8 +370,7 @@ impl<T: Ord + Copy> Ord for Cell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Cell<T> { +impl<T> From<T> for Cell<T> { /// Creates a new `Cell<T>` containing the given value. fn from(t: T) -> Cell<T> { Cell::new(t) @@ -1318,8 +1317,7 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for RefCell<T> { +impl<T> From<T> for RefCell<T> { /// Creates a new `RefCell<T>` containing the given value. fn from(t: T) -> RefCell<T> { RefCell::new(t) @@ -2126,8 +2124,7 @@ impl<T: Default> Default for UnsafeCell<T> { } #[stable(feature = "cell_from", since = "1.12.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for UnsafeCell<T> { +impl<T> From<T> for UnsafeCell<T> { /// Creates a new `UnsafeCell<T>` containing the given value. fn from(t: T) -> UnsafeCell<T> { UnsafeCell::new(t) @@ -2226,8 +2223,7 @@ impl<T: Default> Default for SyncUnsafeCell<T> { } #[unstable(feature = "sync_unsafe_cell", issue = "95439")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for SyncUnsafeCell<T> { +impl<T> From<T> for SyncUnsafeCell<T> { /// Creates a new `SyncUnsafeCell<T>` containing the given value. fn from(t: T) -> SyncUnsafeCell<T> { SyncUnsafeCell::new(t) diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index 5dc2d523198..a7cd59e50fc 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -284,8 +284,7 @@ impl<T: PartialEq> PartialEq for OnceCell<T> { impl<T: Eq> Eq for OnceCell<T> {} #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for OnceCell<T> { +impl<T> From<T> for OnceCell<T> { /// Creates a new `OnceCell<T>` which already contains the given `value`. #[inline] fn from(value: T) -> Self { diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 136bbcb8b21..b84e4b35b1c 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -27,8 +27,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { } #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u32 { +impl From<char> for u32 { /// Converts a [`char`] into a [`u32`]. /// /// # Examples @@ -47,8 +46,7 @@ impl const From<char> for u32 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u64 { +impl From<char> for u64 { /// Converts a [`char`] into a [`u64`]. /// /// # Examples @@ -69,8 +67,7 @@ impl const From<char> for u64 { } #[stable(feature = "more_char_conversions", since = "1.51.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<char> for u128 { +impl From<char> for u128 { /// Converts a [`char`] into a [`u128`]. /// /// # Examples @@ -123,8 +120,7 @@ impl TryFrom<char> for u8 { /// for a superset of Windows-1252 that fills the remaining blanks with corresponding /// C0 and C1 control codes. #[stable(feature = "char_convert", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<u8> for char { +impl From<u8> for char { /// Converts a [`u8`] into a [`char`]. /// /// # Examples diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 398437d9a02..a6d6230d3a6 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -36,8 +36,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::marker::Destruct; - /// A common trait for the ability to explicitly duplicate an object. /// /// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while @@ -106,7 +104,6 @@ use crate::marker::Destruct; #[lang = "clone"] #[rustc_diagnostic_item = "Clone"] #[rustc_trivial_field_reads] -#[const_trait] pub trait Clone: Sized { /// Returns a copy of the value. /// @@ -129,10 +126,7 @@ pub trait Clone: Sized { /// allocations. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn clone_from(&mut self, source: &Self) - where - Self: ~const Destruct, - { + fn clone_from(&mut self, source: &Self) { *self = source.clone() } } @@ -182,8 +176,7 @@ mod impls { ($($t:ty)*) => { $( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for $t { + impl Clone for $t { #[inline(always)] fn clone(&self) -> Self { *self @@ -201,8 +194,7 @@ mod impls { } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl const Clone for ! { + impl Clone for ! { #[inline] fn clone(&self) -> Self { *self @@ -210,8 +202,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for *const T { + impl<T: ?Sized> Clone for *const T { #[inline(always)] fn clone(&self) -> Self { *self @@ -219,8 +210,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for *mut T { + impl<T: ?Sized> Clone for *mut T { #[inline(always)] fn clone(&self) -> Self { *self @@ -229,8 +219,7 @@ mod impls { /// Shared references can be cloned, but mutable references *cannot*! #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_clone", issue = "91805")] - impl<T: ?Sized> const Clone for &T { + impl<T: ?Sized> Clone for &T { #[inline(always)] #[rustc_diagnostic_item = "noop_method_clone"] fn clone(&self) -> Self { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 55331475aff..87ec35c040f 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -25,8 +25,6 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; -use crate::marker::Destruct; - use self::Ordering::*; /// Trait for equality comparisons. @@ -212,7 +210,6 @@ use self::Ordering::*; label = "no implementation for `{Self} == {Rhs}`", append_const_msg )] -#[const_trait] #[rustc_diagnostic_item = "PartialEq"] pub trait PartialEq<Rhs: ?Sized = Self> { /// This method tests for `self` and `other` values to be equal, and is used @@ -324,17 +321,13 @@ pub struct AssertParamIsEq<T: Eq + ?Sized> { /// ``` /// use std::cmp::Ordering; /// -/// let result = 1.cmp(&2); -/// assert_eq!(Ordering::Less, result); +/// assert_eq!(1.cmp(&2), Ordering::Less); /// -/// let result = 1.cmp(&1); -/// assert_eq!(Ordering::Equal, result); +/// assert_eq!(1.cmp(&1), Ordering::Equal); /// -/// let result = 2.cmp(&1); -/// assert_eq!(Ordering::Greater, result); +/// assert_eq!(2.cmp(&1), Ordering::Greater); /// ``` -#[derive(Clone, Copy, Eq, Debug, Hash)] -#[derive_const(PartialOrd, Ord, PartialEq)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] #[stable(feature = "rust1", since = "1.0.0")] #[repr(i8)] pub enum Ordering { @@ -604,8 +597,7 @@ impl Ordering { pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T); #[stable(feature = "reverse_cmp_key", since = "1.19.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -impl<T: ~const PartialOrd> const PartialOrd for Reverse<T> { +impl<T: PartialOrd> PartialOrd for Reverse<T> { #[inline] fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> { other.0.partial_cmp(&self.0) @@ -763,7 +755,6 @@ impl<T: Clone> Clone for Reverse<T> { #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Ord"] -#[const_trait] pub trait Ord: Eq + PartialOrd<Self> { /// This method returns an [`Ordering`] between `self` and `other`. /// @@ -790,8 +781,8 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert_eq!(2, 1.max(2)); - /// assert_eq!(2, 2.max(2)); + /// assert_eq!(1.max(2), 2); + /// assert_eq!(2.max(2), 2); /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] @@ -799,7 +790,6 @@ pub trait Ord: Eq + PartialOrd<Self> { fn max(self, other: Self) -> Self where Self: Sized, - Self: ~const Destruct, { max_by(self, other, Ord::cmp) } @@ -811,8 +801,8 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert_eq!(1, 1.min(2)); - /// assert_eq!(2, 2.min(2)); + /// assert_eq!(1.min(2), 1); + /// assert_eq!(2.min(2), 2); /// ``` #[stable(feature = "ord_max_min", since = "1.21.0")] #[inline] @@ -820,7 +810,6 @@ pub trait Ord: Eq + PartialOrd<Self> { fn min(self, other: Self) -> Self where Self: Sized, - Self: ~const Destruct, { min_by(self, other, Ord::cmp) } @@ -837,17 +826,16 @@ pub trait Ord: Eq + PartialOrd<Self> { /// # Examples /// /// ``` - /// assert!((-3).clamp(-2, 1) == -2); - /// assert!(0.clamp(-2, 1) == 0); - /// assert!(2.clamp(-2, 1) == 1); + /// assert_eq!((-3).clamp(-2, 1), -2); + /// assert_eq!(0.clamp(-2, 1), 0); + /// assert_eq!(2.clamp(-2, 1), 1); /// ``` #[must_use] #[stable(feature = "clamp", since = "1.50.0")] fn clamp(self, min: Self, max: Self) -> Self where Self: Sized, - Self: ~const Destruct, - Self: ~const PartialOrd, + Self: PartialOrd, { assert!(min <= max); if self < min { @@ -1035,7 +1023,6 @@ pub macro Ord($item:item) { label = "no implementation for `{Self} < {Rhs}` and `{Self} > {Rhs}`", append_const_msg )] -#[const_trait] #[rustc_diagnostic_item = "PartialOrd"] pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// This method returns an ordering between `self` and `other` values if one exists. @@ -1070,11 +1057,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 < 2.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 < 1.0; - /// assert_eq!(result, false); + /// assert_eq!(1.0 < 1.0, false); + /// assert_eq!(1.0 < 2.0, true); + /// assert_eq!(2.0 < 1.0, false); /// ``` #[inline] #[must_use] @@ -1089,11 +1074,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 <= 2.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 <= 2.0; - /// assert_eq!(result, true); + /// assert_eq!(1.0 <= 1.0, true); + /// assert_eq!(1.0 <= 2.0, true); + /// assert_eq!(2.0 <= 1.0, false); /// ``` #[inline] #[must_use] @@ -1107,11 +1090,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 1.0 > 2.0; - /// assert_eq!(result, false); - /// - /// let result = 2.0 > 2.0; - /// assert_eq!(result, false); + /// assert_eq!(1.0 > 1.0, false); + /// assert_eq!(1.0 > 2.0, false); + /// assert_eq!(2.0 > 1.0, true); /// ``` #[inline] #[must_use] @@ -1126,11 +1107,9 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { /// # Examples /// /// ``` - /// let result = 2.0 >= 1.0; - /// assert_eq!(result, true); - /// - /// let result = 2.0 >= 2.0; - /// assert_eq!(result, true); + /// assert_eq!(1.0 >= 1.0, true); + /// assert_eq!(1.0 >= 2.0, false); + /// assert_eq!(2.0 >= 1.0, true); /// ``` #[inline] #[must_use] @@ -1160,15 +1139,14 @@ pub macro PartialOrd($item:item) { /// ``` /// use std::cmp; /// -/// assert_eq!(1, cmp::min(1, 2)); -/// assert_eq!(2, cmp::min(2, 2)); +/// assert_eq!(cmp::min(1, 2), 1); +/// assert_eq!(cmp::min(2, 2), 2); /// ``` #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_min")] -pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { +pub fn min<T: Ord>(v1: T, v2: T) -> T { v1.min(v2) } @@ -1181,18 +1159,16 @@ pub const fn min<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1); -/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); +/// let result = cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, 1); +/// +/// let result = cmp::min_by(-2, 3, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, -2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn min_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, -{ +pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v1, Ordering::Greater => v2, @@ -1208,20 +1184,17 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1); -/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2); +/// let result = cmp::min_by_key(-2, 1, |x: &i32| x.abs()); +/// assert_eq!(result, 1); +/// +/// let result = cmp::min_by_key(-2, 2, |x: &i32| x.abs()); +/// assert_eq!(result, -2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn min_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, - K: ~const Destruct, -{ - min_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2))) +pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) } /// Compares and returns the maximum of two values. @@ -1235,15 +1208,14 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(2, cmp::max(1, 2)); -/// assert_eq!(2, cmp::max(2, 2)); +/// assert_eq!(cmp::max(1, 2), 2); +/// assert_eq!(cmp::max(2, 2), 2); /// ``` #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] #[cfg_attr(not(test), rustc_diagnostic_item = "cmp_max")] -pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { +pub fn max<T: Ord>(v1: T, v2: T) -> T { v1.max(v2) } @@ -1256,18 +1228,16 @@ pub const fn max<T: ~const Ord + ~const Destruct>(v1: T, v2: T) -> T { /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2); -/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2); +/// let result = cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())); +/// assert_eq!(result, -2); +/// +/// let result = cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())) ; +/// assert_eq!(result, 2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn max_by<T, F: ~const FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, -{ +pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T { match compare(&v1, &v2) { Ordering::Less | Ordering::Equal => v2, Ordering::Greater => v1, @@ -1283,20 +1253,17 @@ where /// ``` /// use std::cmp; /// -/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2); -/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2); +/// let result = cmp::max_by_key(-2, 1, |x: &i32| x.abs()); +/// assert_eq!(result, -2); +/// +/// let result = cmp::max_by_key(-2, 2, |x: &i32| x.abs()); +/// assert_eq!(result, 2); /// ``` #[inline] #[must_use] #[stable(feature = "cmp_min_max_by", since = "1.53.0")] -#[rustc_const_unstable(feature = "const_cmp", issue = "92391")] -pub const fn max_by_key<T, F: ~const FnMut(&T) -> K, K: ~const Ord>(v1: T, v2: T, mut f: F) -> T -where - T: ~const Destruct, - F: ~const Destruct, - K: ~const Destruct, -{ - max_by(v1, v2, const |v1, v2| f(v1).cmp(&f(v2))) +pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T { + max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2))) } // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types @@ -1307,8 +1274,7 @@ mod impls { macro_rules! partial_eq_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for $t { + impl PartialEq for $t { #[inline] fn eq(&self, other: &$t) -> bool { (*self) == (*other) } #[inline] @@ -1318,8 +1284,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for () { + impl PartialEq for () { #[inline] fn eq(&self, _other: &()) -> bool { true @@ -1346,8 +1311,7 @@ mod impls { macro_rules! partial_ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for $t { + impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { match (*self <= *other, *self >= *other) { @@ -1370,8 +1334,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for () { + impl PartialOrd for () { #[inline] fn partial_cmp(&self, _: &()) -> Option<Ordering> { Some(Equal) @@ -1379,8 +1342,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for bool { + impl PartialOrd for bool { #[inline] fn partial_cmp(&self, other: &bool) -> Option<Ordering> { Some(self.cmp(other)) @@ -1392,8 +1354,7 @@ mod impls { macro_rules! ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for $t { + impl PartialOrd for $t { #[inline] fn partial_cmp(&self, other: &$t) -> Option<Ordering> { Some(self.cmp(other)) @@ -1409,8 +1370,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for $t { + impl Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { // The order here is important to generate more optimal assembly. @@ -1424,8 +1384,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for () { + impl Ord for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal @@ -1433,8 +1392,7 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for bool { + impl Ord for bool { #[inline] fn cmp(&self, other: &bool) -> Ordering { // Casting to i8's and converting the difference to an Ordering generates @@ -1453,8 +1411,7 @@ mod impls { ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialEq for ! { + impl PartialEq for ! { fn eq(&self, _: &!) -> bool { *self } @@ -1464,16 +1421,14 @@ mod impls { impl Eq for ! {} #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const PartialOrd for ! { + impl PartialOrd for ! { fn partial_cmp(&self, _: &!) -> Option<Ordering> { *self } } #[unstable(feature = "never_type", issue = "35121")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl const Ord for ! { + impl Ord for ! { fn cmp(&self, _: &!) -> Ordering { *self } @@ -1482,10 +1437,9 @@ mod impls { // & pointers #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<A: ?Sized, B: ?Sized> const PartialEq<&B> for &A + impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A where - A: ~const PartialEq<B>, + A: PartialEq<B>, { #[inline] fn eq(&self, other: &&B) -> bool { @@ -1497,10 +1451,9 @@ mod impls { } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<A: ?Sized, B: ?Sized> const PartialOrd<&B> for &A + impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A where - A: ~const PartialOrd<B>, + A: PartialOrd<B>, { #[inline] fn partial_cmp(&self, other: &&B) -> Option<Ordering> { diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 5888e2960bb..3ae787cac71 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -214,7 +214,6 @@ pub const fn identity<T>(x: T) -> T { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsRef")] -#[const_trait] pub trait AsRef<T: ?Sized> { /// Converts this type into a shared reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -366,7 +365,6 @@ pub trait AsRef<T: ?Sized> { /// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] -#[const_trait] pub trait AsMut<T: ?Sized> { /// Converts this type into a mutable reference of the (usually inferred) input type. #[stable(feature = "rust1", since = "1.0.0")] @@ -443,7 +441,6 @@ pub trait AsMut<T: ?Sized> { /// [`Vec`]: ../../std/vec/struct.Vec.html #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Into<T>: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -539,7 +536,6 @@ pub trait Into<T>: Sized { all(_Self = "&str", T = "std::string::String"), note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] -#[const_trait] pub trait From<T>: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] @@ -564,7 +560,6 @@ pub trait From<T>: Sized { /// [`Into`], see there for details. #[rustc_diagnostic_item = "TryInto"] #[stable(feature = "try_from", since = "1.34.0")] -#[const_trait] pub trait TryInto<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -641,7 +636,6 @@ pub trait TryInto<T>: Sized { /// [`try_from`]: TryFrom::try_from #[rustc_diagnostic_item = "TryFrom"] #[stable(feature = "try_from", since = "1.34.0")] -#[const_trait] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -658,10 +652,9 @@ pub trait TryFrom<T>: Sized { // As lifts over & #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsRef<U> for &T +impl<T: ?Sized, U: ?Sized> AsRef<U> for &T where - T: ~const AsRef<U>, + T: AsRef<U>, { #[inline] fn as_ref(&self) -> &U { @@ -671,10 +664,9 @@ where // As lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsRef<U> for &mut T +impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T where - T: ~const AsRef<U>, + T: AsRef<U>, { #[inline] fn as_ref(&self) -> &U { @@ -692,10 +684,9 @@ where // AsMut lifts over &mut #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized, U: ?Sized> const AsMut<U> for &mut T +impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T where - T: ~const AsMut<U>, + T: AsMut<U>, { #[inline] fn as_mut(&mut self) -> &mut U { @@ -713,10 +704,9 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const Into<U> for T +impl<T, U> Into<U> for T where - U: ~const From<T>, + U: From<T>, { /// Calls `U::from(self)`. /// @@ -730,8 +720,7 @@ where // From (and thus Into) is reflexive #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for T { +impl<T> From<T> for T { /// Returns the argument unchanged. #[inline(always)] fn from(t: T) -> T { @@ -748,8 +737,7 @@ impl<T> const From<T> for T { #[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead. #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<!> for T { +impl<T> From<!> for T { fn from(t: !) -> T { t } @@ -757,10 +745,9 @@ impl<T> const From<!> for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const TryInto<U> for T +impl<T, U> TryInto<U> for T where - U: ~const TryFrom<T>, + U: TryFrom<T>, { type Error = U::Error; @@ -773,10 +760,9 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, U> const TryFrom<U> for T +impl<T, U> TryFrom<U> for T where - U: ~const Into<T>, + U: Into<T>, { type Error = Infallible; @@ -876,8 +862,7 @@ impl AsMut<str> for str { pub enum Infallible {} #[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl const Clone for Infallible { +impl Clone for Infallible { fn clone(&self) -> Infallible { match *self {} } @@ -929,8 +914,7 @@ impl Ord for Infallible { } #[stable(feature = "convert_infallible", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<!> for Infallible { +impl From<!> for Infallible { fn from(x: !) -> Self { x } diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index a74a56bc5b2..56ab63be27d 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -44,8 +44,7 @@ impl_float_to_int!(f64 => u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize); macro_rules! impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] @@ -170,8 +169,7 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0" // bool -> Float #[stable(feature = "float_from_bool", since = "1.68.0")] -#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] -impl const From<bool> for f32 { +impl From<bool> for f32 { /// Converts `bool` to `f32` losslessly. The resulting value is positive /// `0.0` for `false` and `1.0` for `true` values. /// @@ -190,8 +188,7 @@ impl const From<bool> for f32 { } } #[stable(feature = "float_from_bool", since = "1.68.0")] -#[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] -impl const From<bool> for f64 { +impl From<bool> for f64 { /// Converts `bool` to `f64` losslessly. The resulting value is positive /// `0.0` for `false` and `1.0` for `true` values. /// @@ -214,8 +211,7 @@ impl const From<bool> for f64 { macro_rules! try_from_unbounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -233,8 +229,7 @@ macro_rules! try_from_unbounded { macro_rules! try_from_lower_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -256,8 +251,7 @@ macro_rules! try_from_lower_bounded { macro_rules! try_from_upper_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -279,8 +273,7 @@ macro_rules! try_from_upper_bounded { macro_rules! try_from_both_bounded { ($source:ty, $($target:ty),*) => {$( #[stable(feature = "try_from", since = "1.34.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const TryFrom<$source> for $target { + impl TryFrom<$source> for $target { type Error = TryFromIntError; /// Try to create the target number type from a source @@ -431,8 +424,7 @@ use crate::num::NonZeroUsize; macro_rules! nzint_impl_from { ($Small: ty, $Large: ty, #[$attr:meta], $doc: expr) => { #[$attr] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Small> for $Large { + impl From<$Small> for $Large { // Rustdocs on the impl block show a "[+] show undocumented items" toggle. // Rustdocs on functions do not. #[doc = $doc] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index d96b53de0a3..09dbc95810f 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -99,7 +99,6 @@ /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "Default")] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Default: Sized { /// Returns the "default value" for a type. /// @@ -190,8 +189,7 @@ pub macro Default($item:item) { macro_rules! default_impl { ($t:ty, $v:expr, $doc:tt) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $t { + impl Default for $t { #[inline] #[doc = $doc] fn default() -> $t { diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 4a5306ccaa7..bd2b2c36c43 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -324,14 +324,15 @@ impl CStr { /// assert_eq!(c_str.to_str().unwrap(), "AAAAAAAA"); /// ``` /// - #[rustc_allow_const_fn_unstable(const_slice_index)] #[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] #[rustc_const_stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> { let nul_pos = memchr::memchr(0, bytes); match nul_pos { Some(nul_pos) => { - let subslice = &bytes[..nul_pos + 1]; + // FIXME(const-hack) replace with range index + // SAFETY: nul_pos + 1 <= bytes.len() + let subslice = unsafe { crate::slice::from_raw_parts(bytes.as_ptr(), nul_pos + 1) }; // SAFETY: We know there is a nul byte at nul_pos, so this slice // (ending at the nul byte) is a well-formed C string. Ok(unsafe { CStr::from_bytes_with_nul_unchecked(subslice) }) @@ -536,7 +537,8 @@ impl CStr { pub const fn is_empty(&self) -> bool { // SAFETY: We know there is at least one byte; for empty strings it // is the NUL terminator. - (unsafe { self.inner.get_unchecked(0) }) == &0 + // FIXME(const-hack): use get_unchecked + unsafe { *self.inner.as_ptr() == 0 } } /// Converts this C string to a byte slice. @@ -560,8 +562,7 @@ impl CStr { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] - pub const fn to_bytes(&self) -> &[u8] { + pub fn to_bytes(&self) -> &[u8] { let bytes = self.to_bytes_with_nul(); // SAFETY: to_bytes_with_nul returns slice with length at least 1 unsafe { bytes.get_unchecked(..bytes.len() - 1) } @@ -612,8 +613,7 @@ impl CStr { /// assert_eq!(cstr.to_str(), Ok("foo")); /// ``` #[stable(feature = "cstr_to_str", since = "1.4.0")] - #[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")] - pub const fn to_str(&self) -> Result<&str, str::Utf8Error> { + pub fn to_str(&self) -> Result<&str, str::Utf8Error> { // N.B., when `CStr` is changed to perform the length check in `.to_bytes()` // instead of in `from_ptr()`, it may be worth considering if this should // be rewritten to do the UTF-8 check inline with the length calculation diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index fcda097f01f..a901ae72669 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -18,6 +18,7 @@ mod float; #[cfg(no_fp_fmt_parse)] mod nofloat; mod num; +mod rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "Alignment")] @@ -38,12 +39,6 @@ pub enum Alignment { #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; -#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] -#[doc(hidden)] -pub mod rt { - pub mod v1; -} - /// The type returned by formatter methods. /// /// # Examples @@ -227,7 +222,7 @@ impl<W: Write + ?Sized> Write for &mut W { pub struct Formatter<'a> { flags: u32, fill: char, - align: rt::v1::Alignment, + align: rt::Alignment, width: Option<usize>, precision: Option<usize>, @@ -248,7 +243,7 @@ impl<'a> Formatter<'a> { Formatter { flags: 0, fill: ' ', - align: rt::v1::Alignment::Unknown, + align: rt::Alignment::Unknown, width: None, precision: None, buf, @@ -433,17 +428,15 @@ impl<'a> Arguments<'a> { /// An `UnsafeArg` is required because the following invariants must be held /// in order for this function to be safe: /// 1. The `pieces` slice must be at least as long as `fmt`. - /// 2. Every [`rt::v1::Argument::position`] value within `fmt` must be a - /// valid index of `args`. - /// 3. Every [`rt::v1::Count::Param`] within `fmt` must contain a valid index of - /// `args`. + /// 2. Every `rt::Placeholder::position` value within `fmt` must be a valid index of `args`. + /// 3. Every `rt::Count::Param` within `fmt` must contain a valid index of `args`. #[doc(hidden)] #[inline] #[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] pub fn new_v1_formatted( pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>], - fmt: &'a [rt::v1::Argument], + fmt: &'a [rt::Placeholder], _unsafe_arg: UnsafeArg, ) -> Arguments<'a> { Arguments { pieces, fmt: Some(fmt), args } @@ -505,7 +498,7 @@ pub struct Arguments<'a> { pieces: &'a [&'static str], // Placeholder specs, or `None` if all specs are default (as in "{}{}"). - fmt: Option<&'a [rt::v1::Argument]>, + fmt: Option<&'a [rt::Placeholder]>, // Dynamic arguments for interpolation, to be interleaved with string // pieces. (Every argument is preceded by a string piece.) @@ -1281,15 +1274,15 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { Ok(()) } -unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV1<'_>]) -> Result { - fmt.fill = arg.format.fill; - fmt.align = arg.format.align; - fmt.flags = arg.format.flags; +unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[ArgumentV1<'_>]) -> Result { + fmt.fill = arg.fill; + fmt.align = arg.align; + fmt.flags = arg.flags; // SAFETY: arg and args come from the same Arguments, // which guarantees the indexes are always within bounds. unsafe { - fmt.width = getcount(args, &arg.format.width); - fmt.precision = getcount(args, &arg.format.precision); + fmt.width = getcount(args, &arg.width); + fmt.precision = getcount(args, &arg.precision); } // Extract the correct argument @@ -1302,11 +1295,11 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::v1::Argument, args: &[ArgumentV (value.formatter)(value.value, fmt) } -unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::v1::Count) -> Option<usize> { +unsafe fn getcount(args: &[ArgumentV1<'_>], cnt: &rt::Count) -> Option<usize> { match *cnt { - rt::v1::Count::Is(n) => Some(n), - rt::v1::Count::Implied => None, - rt::v1::Count::Param(i) => { + rt::Count::Is(n) => Some(n), + rt::Count::Implied => None, + rt::Count::Param(i) => { debug_assert!(i < args.len()); // SAFETY: cnt and args come from the same Arguments, // which guarantees this index is always within bounds. @@ -1449,9 +1442,9 @@ impl<'a> Formatter<'a> { // is zero Some(min) if self.sign_aware_zero_pad() => { let old_fill = crate::mem::replace(&mut self.fill, '0'); - let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right); + let old_align = crate::mem::replace(&mut self.align, rt::Alignment::Right); write_prefix(self, sign, prefix)?; - let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; + let post_padding = self.padding(min - width, Alignment::Right)?; self.buf.write_str(buf)?; post_padding.write(self)?; self.fill = old_fill; @@ -1460,7 +1453,7 @@ impl<'a> Formatter<'a> { } // Otherwise, the sign and prefix goes after the padding Some(min) => { - let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; + let post_padding = self.padding(min - width, Alignment::Right)?; write_prefix(self, sign, prefix)?; self.buf.write_str(buf)?; post_padding.write(self) @@ -1535,7 +1528,7 @@ impl<'a> Formatter<'a> { // If we're under both the maximum and the minimum width, then fill // up the minimum width with the specified string + some alignment. else { - let align = rt::v1::Alignment::Left; + let align = Alignment::Left; let post_padding = self.padding(width - chars_count, align)?; self.buf.write_str(s)?; post_padding.write(self) @@ -1550,17 +1543,19 @@ impl<'a> Formatter<'a> { pub(crate) fn padding( &mut self, padding: usize, - default: rt::v1::Alignment, + default: Alignment, ) -> result::Result<PostPadding, Error> { let align = match self.align { - rt::v1::Alignment::Unknown => default, - _ => self.align, + rt::Alignment::Unknown => default, + rt::Alignment::Left => Alignment::Left, + rt::Alignment::Right => Alignment::Right, + rt::Alignment::Center => Alignment::Center, }; let (pre_pad, post_pad) = match align { - rt::v1::Alignment::Left => (0, padding), - rt::v1::Alignment::Right | rt::v1::Alignment::Unknown => (padding, 0), - rt::v1::Alignment::Center => (padding / 2, (padding + 1) / 2), + Alignment::Left => (0, padding), + Alignment::Right => (padding, 0), + Alignment::Center => (padding / 2, (padding + 1) / 2), }; for _ in 0..pre_pad { @@ -1580,7 +1575,6 @@ impl<'a> Formatter<'a> { let mut formatted = formatted.clone(); let old_fill = self.fill; let old_align = self.align; - let mut align = old_align; if self.sign_aware_zero_pad() { // a sign always goes first let sign = formatted.sign; @@ -1589,9 +1583,8 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = ""; width = width.saturating_sub(sign.len()); - align = rt::v1::Alignment::Right; self.fill = '0'; - self.align = rt::v1::Alignment::Right; + self.align = rt::Alignment::Right; } // remaining parts go through the ordinary padding process. @@ -1600,7 +1593,7 @@ impl<'a> Formatter<'a> { // no padding self.write_formatted_parts(&formatted) } else { - let post_padding = self.padding(width - len, align)?; + let post_padding = self.padding(width - len, Alignment::Right)?; self.write_formatted_parts(&formatted)?; post_padding.write(self) }; @@ -1788,10 +1781,10 @@ impl<'a> Formatter<'a> { #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub fn align(&self) -> Option<Alignment> { match self.align { - rt::v1::Alignment::Left => Some(Alignment::Left), - rt::v1::Alignment::Right => Some(Alignment::Right), - rt::v1::Alignment::Center => Some(Alignment::Center), - rt::v1::Alignment::Unknown => None, + rt::Alignment::Left => Some(Alignment::Left), + rt::Alignment::Right => Some(Alignment::Right), + rt::Alignment::Center => Some(Alignment::Center), + rt::Alignment::Unknown => None, } } diff --git a/library/core/src/fmt/rt/v1.rs b/library/core/src/fmt/rt.rs index 6d70796f707..2c1a767691b 100644 --- a/library/core/src/fmt/rt/v1.rs +++ b/library/core/src/fmt/rt.rs @@ -1,20 +1,12 @@ -//! This is an internal module used by the ifmt! runtime. These structures are -//! emitted to static arrays to precompile format strings ahead of time. -//! -//! These definitions are similar to their `ct` equivalents, but differ in that -//! these can be statically allocated and are slightly optimized for the runtime #![allow(missing_debug_implementations)] +#![unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")] + +//! These are the lang items used by format_args!(). #[lang = "format_placeholder"] #[derive(Copy, Clone)] -// FIXME: Rename this to Placeholder -pub struct Argument { +pub struct Placeholder { pub position: usize, - pub format: FormatSpec, -} - -#[derive(Copy, Clone)] -pub struct FormatSpec { pub fill: char, pub align: Alignment, pub flags: u32, @@ -22,7 +14,7 @@ pub struct FormatSpec { pub width: Count, } -impl Argument { +impl Placeholder { #[inline(always)] pub const fn new( position: usize, @@ -32,7 +24,7 @@ impl Argument { precision: Count, width: Count, ) -> Self { - Self { position, format: FormatSpec { fill, align, flags, precision, width } } + Self { position, fill, align, flags, precision, width } } } diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs index 4e7bae7bcb0..a73b5b610a4 100644 --- a/library/core/src/hash/mod.rs +++ b/library/core/src/hash/mod.rs @@ -86,8 +86,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; -use crate::intrinsics::const_eval_select; -use crate::marker::{self, Destruct}; +use crate::marker; #[stable(feature = "rust1", since = "1.0.0")] #[allow(deprecated)] @@ -184,7 +183,6 @@ mod sip; /// [impl]: ../../std/primitive.str.html#impl-Hash-for-str #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Hash"] -#[const_trait] pub trait Hash { /// Feeds this value into the given [`Hasher`]. /// @@ -199,7 +197,7 @@ pub trait Hash { /// println!("Hash is {:x}!", hasher.finish()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - fn hash<H: ~const Hasher>(&self, state: &mut H); + fn hash<H: Hasher>(&self, state: &mut H); /// Feeds a slice of this type into the given [`Hasher`]. /// @@ -236,25 +234,13 @@ pub trait Hash { /// [`hash`]: Hash::hash /// [`hash_slice`]: Hash::hash_slice #[stable(feature = "hash_slice", since = "1.3.0")] - fn hash_slice<H: ~const Hasher>(data: &[Self], state: &mut H) + fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) where Self: Sized, { - //FIXME(const_trait_impl): revert to only a for loop - fn rt<T: Hash, H: Hasher>(data: &[T], state: &mut H) { - for piece in data { - piece.hash(state) - } - } - const fn ct<T: ~const Hash, H: ~const Hasher>(data: &[T], state: &mut H) { - let mut i = 0; - while i < data.len() { - data[i].hash(state); - i += 1; - } + for piece in data { + piece.hash(state) } - // SAFETY: same behavior, CT just uses while instead of for - unsafe { const_eval_select((data, state), ct, rt) }; } } @@ -327,7 +313,6 @@ pub use macros::Hash; /// [`write_u8`]: Hasher::write_u8 /// [`write_u32`]: Hasher::write_u32 #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait Hasher { /// Returns the hash value for the values written so far. /// @@ -573,8 +558,7 @@ pub trait Hasher { } #[stable(feature = "indirect_hasher_impl", since = "1.22.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl<H: ~const Hasher + ?Sized> const Hasher for &mut H { +impl<H: Hasher + ?Sized> Hasher for &mut H { fn finish(&self) -> u64 { (**self).finish() } @@ -654,7 +638,6 @@ impl<H: ~const Hasher + ?Sized> const Hasher for &mut H { /// [`build_hasher`]: BuildHasher::build_hasher /// [`HashMap`]: ../../std/collections/struct.HashMap.html #[stable(since = "1.7.0", feature = "build_hasher")] -#[const_trait] pub trait BuildHasher { /// Type of the hasher that will be created. #[stable(since = "1.7.0", feature = "build_hasher")] @@ -715,10 +698,10 @@ pub trait BuildHasher { /// ); /// ``` #[unstable(feature = "build_hasher_simple_hash_one", issue = "86161")] - fn hash_one<T: ~const Hash + ~const Destruct>(&self, x: T) -> u64 + fn hash_one<T: Hash>(&self, x: T) -> u64 where Self: Sized, - Self::Hasher: ~const Hasher + ~const Destruct, + Self::Hasher: Hasher, { let mut hasher = self.build_hasher(); x.hash(&mut hasher); @@ -782,8 +765,7 @@ impl<H> fmt::Debug for BuildHasherDefault<H> { } #[stable(since = "1.7.0", feature = "build_hasher")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl<H: ~const Default + Hasher> const BuildHasher for BuildHasherDefault<H> { +impl<H: Default + Hasher> BuildHasher for BuildHasherDefault<H> { type Hasher = H; fn build_hasher(&self) -> H { @@ -799,8 +781,7 @@ impl<H> Clone for BuildHasherDefault<H> { } #[stable(since = "1.7.0", feature = "build_hasher")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<H> const Default for BuildHasherDefault<H> { +impl<H> Default for BuildHasherDefault<H> { fn default() -> BuildHasherDefault<H> { BuildHasherDefault(marker::PhantomData) } @@ -825,15 +806,14 @@ mod impls { macro_rules! impl_write { ($(($ty:ident, $meth:ident),)*) => {$( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for $ty { + impl Hash for $ty { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.$meth(*self) } #[inline] - fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) { + fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) { let newlen = mem::size_of_val(data); let ptr = data.as_ptr() as *const u8; // SAFETY: `ptr` is valid and aligned, as this macro is only used @@ -862,37 +842,33 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for bool { + impl Hash for bool { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u8(*self as u8) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for char { + impl Hash for char { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u32(*self as u32) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for str { + impl Hash for str { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_str(self); } } #[stable(feature = "never_hash", since = "1.29.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for ! { + impl Hash for ! { #[inline] - fn hash<H: ~const Hasher>(&self, _: &mut H) { + fn hash<H: Hasher>(&self, _: &mut H) { *self } } @@ -900,10 +876,9 @@ mod impls { macro_rules! impl_hash_tuple { () => ( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl const Hash for () { + impl Hash for () { #[inline] - fn hash<H: ~const Hasher>(&self, _state: &mut H) {} + fn hash<H: Hasher>(&self, _state: &mut H) {} } ); @@ -911,11 +886,10 @@ mod impls { maybe_tuple_doc! { $($name)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<$($name: ~const Hash),+> const Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { + impl<$($name: Hash),+> Hash for ($($name,)+) where last_type!($($name,)+): ?Sized { #[allow(non_snake_case)] #[inline] - fn hash<S: ~const Hasher>(&self, state: &mut S) { + fn hash<S: Hasher>(&self, state: &mut S) { let ($(ref $name,)+) = *self; $($name.hash(state);)+ } @@ -958,29 +932,26 @@ mod impls { impl_hash_tuple! { T B C D E F G H I J K L } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ~const Hash> const Hash for [T] { + impl<T: Hash> Hash for [T] { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_length_prefix(self.len()); Hash::hash_slice(self, state) } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ?Sized + ~const Hash> const Hash for &T { + impl<T: ?Sized + Hash> Hash for &T { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); } } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_hash", issue = "104061")] - impl<T: ?Sized + ~const Hash> const Hash for &mut T { + impl<T: ?Sized + Hash> Hash for &mut T { #[inline] - fn hash<H: ~const Hasher>(&self, state: &mut H) { + fn hash<H: Hasher>(&self, state: &mut H) { (**self).hash(state); } } diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index 7f8287bf56f..6b9f2e84257 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -118,7 +118,7 @@ macro_rules! load_int_le { /// Safety: this performs unchecked indexing of `buf` at `start..start+len`, so /// that must be in-bounds. #[inline] -const unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { +unsafe fn u8to64_le(buf: &[u8], start: usize, len: usize) -> u64 { debug_assert!(len < 8); let mut i = 0; // current byte index (from LSB) in the output u64 let mut out = 0; @@ -225,8 +225,7 @@ impl<S: Sip> Hasher<S> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const super::Hasher for SipHasher { +impl super::Hasher for SipHasher { #[inline] fn write(&mut self, msg: &[u8]) { self.0.hasher.write(msg) @@ -244,8 +243,7 @@ impl const super::Hasher for SipHasher { } #[unstable(feature = "hashmap_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const super::Hasher for SipHasher13 { +impl super::Hasher for SipHasher13 { #[inline] fn write(&mut self, msg: &[u8]) { self.hasher.write(msg) @@ -262,7 +260,7 @@ impl const super::Hasher for SipHasher13 { } } -impl<S: ~const Sip> const super::Hasher for Hasher<S> { +impl<S: Sip> super::Hasher for Hasher<S> { // Note: no integer hashing methods (`write_u*`, `write_i*`) are defined // for this type. We could add them, copy the `short_write` implementation // in librustc_data_structures/sip128.rs, and add `write_u*`/`write_i*` @@ -342,7 +340,7 @@ impl<S: ~const Sip> const super::Hasher for Hasher<S> { } } -impl<S: Sip> const Clone for Hasher<S> { +impl<S: Sip> Clone for Hasher<S> { #[inline] fn clone(&self) -> Hasher<S> { Hasher { @@ -366,7 +364,6 @@ impl<S: Sip> Default for Hasher<S> { } #[doc(hidden)] -#[const_trait] trait Sip { fn c_rounds(_: &mut State); fn d_rounds(_: &mut State); @@ -375,7 +372,7 @@ trait Sip { #[derive(Debug, Clone, Default)] struct Sip13Rounds; -impl const Sip for Sip13Rounds { +impl Sip for Sip13Rounds { #[inline] fn c_rounds(state: &mut State) { compress!(state); @@ -392,7 +389,7 @@ impl const Sip for Sip13Rounds { #[derive(Debug, Clone, Default)] struct Sip24Rounds; -impl const Sip for Sip24Rounds { +impl Sip for Sip24Rounds { #[inline] fn c_rounds(state: &mut State) { compress!(state); diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index a205565773a..f6698589ccd 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -73,8 +73,8 @@ use crate::intrinsics; /// ``` /// /// While using `unreachable_unchecked()` is perfectly sound in the following -/// example, the compiler is able to prove that a division by zero is not -/// possible. Benchmarking reveals that `unreachable_unchecked()` provides +/// example, as the compiler is able to prove that a division by zero is not +/// possible, benchmarking reveals that `unreachable_unchecked()` provides /// no benefit over using [`unreachable!`], while the latter does not introduce /// the possibility of Undefined Behavior. /// diff --git a/library/core/src/internal_macros.rs b/library/core/src/internal_macros.rs index 5d4c9ba7395..5774107f520 100644 --- a/library/core/src/internal_macros.rs +++ b/library/core/src/internal_macros.rs @@ -1,23 +1,10 @@ // implements the unary operator "op &T" // based on "op T" where T is expected to be `Copy`able macro_rules! forward_ref_unop { - (impl const $imp:ident, $method:ident for $t:ty) => { - forward_ref_unop!(impl const $imp, $method for $t, + (impl $imp:ident, $method:ident for $t:ty) => { + forward_ref_unop!(impl $imp, $method for $t, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp for &$t { - type Output = <$t as $imp>::Output; - - #[inline] - fn $method(self) -> <$t as $imp>::Output { - $imp::$method(*self) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, #[$attr:meta]) => { #[$attr] impl $imp for &$t { @@ -34,45 +21,10 @@ macro_rules! forward_ref_unop { // implements binary operators "&T op U", "T op &U", "&T op &U" // based on "T op U" where T and U are expected to be `Copy`able macro_rules! forward_ref_binop { - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_binop!(impl const $imp, $method for $t, $u, + (impl $imp:ident, $method:ident for $t:ty, $u:ty) => { + forward_ref_binop!(impl $imp, $method for $t, $u, #[stable(feature = "rust1", since = "1.0.0")]); }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl<'a> const $imp<$u> for &'a $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: $u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(self, *other) - } - } - - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for &$t { - type Output = <$t as $imp<$u>>::Output; - - #[inline] - fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output { - $imp::$method(*self, *other) - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl<'a> $imp<$u> for &'a $t { @@ -113,21 +65,6 @@ macro_rules! forward_ref_op_assign { forward_ref_op_assign!(impl $imp, $method for $t, $u, #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; - (impl const $imp:ident, $method:ident for $t:ty, $u:ty) => { - forward_ref_op_assign!(impl const $imp, $method for $t, $u, - #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); - }; - // Equivalent to the non-const version, with the addition of `rustc_const_unstable` - (impl const $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { - #[$attr] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const $imp<&$u> for $t { - #[inline] - fn $method(&mut self, other: &$u) { - $imp::$method(self, *other); - } - } - }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] impl $imp<&$u> for $t { diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index ba03da411e3..39edfd8265b 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1376,6 +1376,20 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn transmute<Src, Dst>(src: Src) -> Dst; + /// Like [`transmute`], but even less checked at compile-time: rather than + /// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's + /// **Undefined Behaviour** at runtime. + /// + /// Prefer normal `transmute` where possible, for the extra checking, since + /// both do exactly the same thing at runtime, if they both compile. + /// + /// This is not expected to ever be exposed directly to users, rather it + /// may eventually be exposed through some more-constrained API. + #[cfg(not(bootstrap))] + #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] + #[rustc_nounwind] + pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst; + /// Returns `true` if the actual type given as `T` requires drop /// glue; returns `false` if the actual type provided for `T` /// implements `Copy`. @@ -2798,3 +2812,11 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) { write_bytes(dst, val, count) } } + +/// Polyfill for bootstrap +#[cfg(bootstrap)] +pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst { + use crate::mem::*; + // SAFETY: It's a transmute -- the caller promised it's fine. + unsafe { transmute_copy(&ManuallyDrop::new(src)) } +} diff --git a/library/core/src/iter/sources/empty.rs b/library/core/src/iter/sources/empty.rs index 617dfd12383..243df015f9a 100644 --- a/library/core/src/iter/sources/empty.rs +++ b/library/core/src/iter/sources/empty.rs @@ -81,8 +81,7 @@ impl<T> Clone for Empty<T> { // not #[derive] because that adds a Default bound on T, // which isn't necessary. #[stable(feature = "iter_empty", since = "1.2.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Empty<T> { +impl<T> Default for Empty<T> { fn default() -> Empty<T> { Empty(marker::PhantomData) } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e099700e3e7..76b3a32880d 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -228,7 +228,6 @@ pub trait FromIterator<A>: Sized { #[rustc_diagnostic_item = "IntoIterator"] #[rustc_skip_array_during_method_dispatch] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait IntoIterator { /// The type of the elements being iterated over. #[stable(feature = "rust1", since = "1.0.0")] @@ -264,7 +263,7 @@ pub trait IntoIterator { #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl<I: Iterator> const IntoIterator for I { +impl<I: Iterator> IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 02877604248..dabfce14474 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -70,7 +70,6 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[doc(notable_trait)] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] -#[const_trait] pub trait Iterator { /// The type of the elements being iterated over. #[rustc_diagnostic_item = "IteratorItem"] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 04243544b83..24a9d81d037 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -112,11 +112,7 @@ #![feature(const_caller_location)] #![feature(const_cell_into_inner)] #![feature(const_char_from_u32_unchecked)] -#![feature(const_clone)] -#![feature(const_cmp)] -#![feature(const_convert)] #![feature(const_cstr_methods)] -#![feature(const_default_impls)] #![feature(const_discriminant)] #![feature(const_eval_select)] #![feature(const_exact_div)] @@ -131,14 +127,11 @@ #![feature(const_intrinsic_forget)] #![feature(const_ipv4)] #![feature(const_ipv6)] -#![feature(const_is_char_boundary)] #![feature(const_likely)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init)] #![feature(const_maybe_uninit_uninit_array)] #![feature(const_nonnull_new)] -#![feature(const_num_from_num)] -#![feature(const_ops)] #![feature(const_option)] #![feature(const_option_ext)] #![feature(const_pin)] @@ -151,7 +144,6 @@ #![feature(const_ptr_write)] #![feature(const_raw_ptr_comparison)] #![feature(const_replace)] -#![feature(const_result_drop)] #![feature(const_size_of_val)] #![feature(const_size_of_val_raw)] #![feature(const_slice_from_raw_parts_mut)] @@ -161,7 +153,6 @@ #![feature(const_slice_split_at_mut)] #![feature(const_str_from_utf8_unchecked_mut)] #![feature(const_swap)] -#![feature(const_trait_impl)] #![feature(const_transmute_copy)] #![feature(const_try)] #![feature(const_type_id)] @@ -207,9 +198,9 @@ #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_refs_to_cell)] +#![feature(const_trait_impl)] #![feature(decl_macro)] #![feature(deprecated_suggestion)] -#![feature(derive_const)] #![feature(doc_cfg)] #![feature(doc_cfg_hide)] #![feature(doc_notable_trait)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7c93c93b4a0..cc3179ee780 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1531,16 +1531,6 @@ pub(crate) mod builtin { /* compiler built-in */ } - /// Attribute macro applied to a function to register it as a handler for allocation failure. - /// - /// See also [`std::alloc::handle_alloc_error`](../../../std/alloc/fn.handle_alloc_error.html). - #[unstable(feature = "alloc_error_handler", issue = "51540")] - #[allow_internal_unstable(rustc_attrs)] - #[rustc_builtin_macro] - pub macro alloc_error_handler($item:item) { - /* compiler built-in */ - } - /// Keeps the item it's applied to if the passed path is accessible, and removes it otherwise. #[unstable( feature = "cfg_accessible", diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 3cd4f5104ce..e85c0c0a688 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -732,8 +732,7 @@ impl<T: ?Sized> Clone for PhantomData<T> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T: ?Sized> const Default for PhantomData<T> { +impl<T: ?Sized> Default for PhantomData<T> { fn default() -> Self { Self } @@ -858,8 +857,8 @@ impl<T: ?Sized> Unpin for *mut T {} #[unstable(feature = "const_trait_impl", issue = "67792")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] -#[const_trait] #[rustc_deny_explicit_impl] +#[const_trait] pub trait Destruct {} /// A marker for tuple types. diff --git a/library/core/src/mem/manually_drop.rs b/library/core/src/mem/manually_drop.rs index 3d719afe49e..5f3d66e3773 100644 --- a/library/core/src/mem/manually_drop.rs +++ b/library/core/src/mem/manually_drop.rs @@ -146,8 +146,7 @@ impl<T: ?Sized> ManuallyDrop<T> { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for ManuallyDrop<T> { +impl<T: ?Sized> Deref for ManuallyDrop<T> { type Target = T; #[inline(always)] fn deref(&self) -> &T { @@ -156,8 +155,7 @@ impl<T: ?Sized> const Deref for ManuallyDrop<T> { } #[stable(feature = "manually_drop", since = "1.20.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const DerefMut for ManuallyDrop<T> { +impl<T: ?Sized> DerefMut for ManuallyDrop<T> { #[inline(always)] fn deref_mut(&mut self) -> &mut T { &mut self.value diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 9c6d48675a6..2588b7d2bef 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -945,14 +945,10 @@ impl<T> MaybeUninit<T> { // * `MaybeUninit<T>` and T are guaranteed to have the same layout // * `MaybeUninit` does not drop, so there are no double-frees // And thus the conversion is safe - let ret = unsafe { + unsafe { intrinsics::assert_inhabited::<[T; N]>(); - (&array as *const _ as *const [T; N]).read() - }; - - // FIXME: required to avoid `~const Destruct` bound - super::forget(array); - ret + intrinsics::transmute_unchecked(array) + } } /// Assuming all the elements are initialized, get a slice to them. diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 30ec73cabf8..7d2f2971523 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1279,3 +1279,45 @@ pub trait SizedTypeProperties: Sized { #[doc(hidden)] #[unstable(feature = "sized_type_properties", issue = "none")] impl<T> SizedTypeProperties for T {} + +/// Expands to the offset in bytes of a field from the beginning of the given type. +/// +/// Only structs, unions and tuples are supported. +/// +/// Nested field accesses may be used, but not array indexes like in `C`'s `offsetof`. +/// +/// Note that the output of this macro is not stable, except for `#[repr(C)]` types. +/// +/// # Examples +/// +/// ``` +/// #![feature(offset_of)] +/// +/// use std::mem; +/// #[repr(C)] +/// struct FieldStruct { +/// first: u8, +/// second: u16, +/// third: u8 +/// } +/// +/// assert_eq!(mem::offset_of!(FieldStruct, first), 0); +/// assert_eq!(mem::offset_of!(FieldStruct, second), 2); +/// assert_eq!(mem::offset_of!(FieldStruct, third), 4); +/// +/// #[repr(C)] +/// struct NestedA { +/// b: NestedB +/// } +/// +/// #[repr(C)] +/// struct NestedB(u8); +/// +/// assert_eq!(mem::offset_of!(NestedA, b.0), 0); +/// ``` +#[unstable(feature = "offset_of", issue = "106655")] +#[rustc_builtin_macro] +#[cfg(not(bootstrap))] +pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) { + /* compiler built-in */ +} diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index b53a330fa56..87ae30619c6 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -81,8 +81,7 @@ impl Assume { // FIXME(jswrenn): This const op is not actually usable. Why? // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 #[unstable(feature = "transmutability", issue = "99571")] -#[rustc_const_unstable(feature = "transmutability", issue = "99571")] -impl const core::ops::Add for Assume { +impl core::ops::Add for Assume { type Output = Assume; fn add(self, other_assumptions: Assume) -> Assume { @@ -93,8 +92,7 @@ impl const core::ops::Add for Assume { // FIXME(jswrenn): This const op is not actually usable. Why? // https://github.com/rust-lang/rust/pull/100726#issuecomment-1219928926 #[unstable(feature = "transmutability", issue = "99571")] -#[rustc_const_unstable(feature = "transmutability", issue = "99571")] -impl const core::ops::Sub for Assume { +impl core::ops::Sub for Assume { type Output = Assume; fn sub(self, other_assumptions: Assume) -> Assume { diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index 1bae4efe7d9..2ad0f1dc506 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -26,15 +26,14 @@ impl Error for TryFromIntError { } #[stable(feature = "try_from", since = "1.34.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<Infallible> for TryFromIntError { +impl From<Infallible> for TryFromIntError { fn from(x: Infallible) -> TryFromIntError { match x {} } } #[unstable(feature = "never_type", issue = "35121")] -impl const From<!> for TryFromIntError { +impl From<!> for TryFromIntError { fn from(never: !) -> TryFromIntError { // Match rather than coerce to make sure that code like // `From<Infallible> for TryFromIntError` above will keep working diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index aec15212d7f..17715c9291f 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -785,7 +785,7 @@ macro_rules! int_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shl(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is @@ -833,7 +833,7 @@ macro_rules! int_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shr(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked absolute value. Computes `self.abs()`, returning `None` if @@ -2603,13 +2603,16 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(const_cmp)] pub const fn signum(self) -> Self { // Picking the right way to phrase this is complicated // (<https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>) // so delegate it to `Ord` which is already producing -1/0/+1 // exactly like we need and can be the place to deal with the complexity. - self.cmp(&0) as _ + + // FIXME(const-hack): replace with cmp + if self < 0 { -1 } + else if self == 0 { 0 } + else { 1 } } /// Returns `true` if `self` is positive and `false` if the number is zero or diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 9b812bbfc23..fdd7be625ed 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -225,6 +225,23 @@ macro_rules! widening_impl { }; } +macro_rules! conv_rhs_for_unchecked_shift { + ($SelfT:ty, $x:expr) => {{ + #[inline] + fn conv(x: u32) -> $SelfT { + // FIXME(const-hack) replace with `.try_into().ok().unwrap_unchecked()`. + // SAFETY: Any legal shift amount must be losslessly representable in the self type. + unsafe { x.try_into().ok().unwrap_unchecked() } + } + #[inline] + const fn const_conv(x: u32) -> $SelfT { + x as _ + } + + intrinsics::const_eval_select(($x,), const_conv, conv) + }}; +} + impl i8 { int_impl! { Self = i8, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index ecfb735fad1..fc9b07d29e2 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,7 +1,7 @@ //! Definitions of integer that is known not to equal zero. use crate::fmt; -use crate::ops::{BitOr, BitOrAssign, Div, Rem}; +use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem}; use crate::str::FromStr; use super::from_str_radix; @@ -96,8 +96,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "from_nonzero", since = "1.31.0")] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$Ty> for $Int { + impl From<$Ty> for $Int { #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")] #[inline] fn from(nonzero: $Ty) -> Self { @@ -106,8 +105,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $Ty { + impl BitOr for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { @@ -118,8 +116,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Int> for $Ty { + impl BitOr<$Int> for $Ty { type Output = Self; #[inline] fn bitor(self, rhs: $Int) -> Self::Output { @@ -131,8 +128,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr<$Ty> for $Int { + impl BitOr<$Ty> for $Int { type Output = $Ty; #[inline] fn bitor(self, rhs: $Ty) -> Self::Output { @@ -144,8 +140,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $Ty { + impl BitOrAssign for $Ty { #[inline] fn bitor_assign(&mut self, rhs: Self) { *self = *self | rhs; @@ -153,8 +148,7 @@ macro_rules! nonzero_integers { } #[stable(feature = "nonzero_bitor", since = "1.45.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$Int> for $Ty { + impl BitOrAssign<$Int> for $Ty { #[inline] fn bitor_assign(&mut self, rhs: $Int) { *self = *self | rhs; @@ -276,8 +270,7 @@ macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div<$Ty> for $Int { + impl Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, /// truncating any fractional part of the exact result, and cannot panic. @@ -290,8 +283,7 @@ macro_rules! nonzero_integers_div { } #[stable(feature = "nonzero_div", since = "1.51.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem<$Ty> for $Int { + impl Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. #[inline] @@ -672,8 +664,7 @@ macro_rules! nonzero_signed_operations { /// assert_eq!(pos, pos.wrapping_abs()); /// assert_eq!(pos, neg.wrapping_abs()); /// assert_eq!(min, min.wrapping_abs()); - /// # // FIXME: add once Neg is implemented? - /// # // assert_eq!(max, (-max).wrapping_abs()); + /// assert_eq!(max, (-max).wrapping_abs()); /// # Some(()) /// # } /// ``` @@ -876,6 +867,20 @@ macro_rules! nonzero_signed_operations { unsafe { $Ty::new_unchecked(result) } } } + + #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] + impl Neg for $Ty { + type Output = $Ty; + + #[inline] + fn neg(self) -> $Ty { + // SAFETY: negation of nonzero cannot yield zero values. + unsafe { $Ty::new_unchecked(self.get().neg()) } + } + } + + forward_ref_unop! { impl Neg, neg for $Ty, + #[stable(feature = "signed_nonzero_neg", since = "CURRENT_RUSTC_VERSION")] } )+ } } diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 114deeea387..6f6b6dbb80b 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -939,7 +939,7 @@ macro_rules! uint_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shl`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shl(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shl(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked shift right. Computes `self >> rhs`, returning `None` @@ -987,7 +987,7 @@ macro_rules! uint_impl { // SAFETY: the caller must uphold the safety contract for // `unchecked_shr`. // Any legal shift amount is losslessly representable in the self type. - unsafe { intrinsics::unchecked_shr(self, rhs.try_into().ok().unwrap_unchecked()) } + unsafe { intrinsics::unchecked_shr(self, conv_rhs_for_unchecked_shift!($SelfT, rhs)) } } /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 5353d900e76..ed354a2e50b 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -87,8 +87,7 @@ impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> { macro_rules! sh_impl_signed { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -100,22 +99,20 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -127,26 +124,24 @@ macro_rules! sh_impl_signed { } } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } macro_rules! sh_impl_unsigned { ($t:ident, $f:ident) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for Wrapping<$t> { + impl Shl<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -154,22 +149,20 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shl, shl for Wrapping<$t>, $f, + forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for Wrapping<$t> { + impl ShlAssign<$f> for Wrapping<$t> { #[inline] fn shl_assign(&mut self, other: $f) { *self = *self << other; } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for Wrapping<$t> { + impl Shr<$f> for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -177,18 +170,17 @@ macro_rules! sh_impl_unsigned { Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32)) } } - forward_ref_binop! { impl const Shr, shr for Wrapping<$t>, $f, + forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f, #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for Wrapping<$t> { + impl ShrAssign<$f> for Wrapping<$t> { #[inline] fn shr_assign(&mut self, other: $f) { *self = *self >> other; } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for Wrapping<$t>, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f } }; } @@ -217,8 +209,7 @@ sh_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } macro_rules! wrapping_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for Wrapping<$t> { + impl Add for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -226,32 +217,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_add(other.0)) } } - forward_ref_binop! { impl const Add, add for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Add, add for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for Wrapping<$t> { + impl AddAssign for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: Wrapping<$t>) { *self = *self + other; } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign<$t> for Wrapping<$t> { + impl AddAssign<$t> for Wrapping<$t> { #[inline] fn add_assign(&mut self, other: $t) { *self = *self + Wrapping(other); } } - forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for Wrapping<$t> { + impl Sub for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -259,32 +247,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_sub(other.0)) } } - forward_ref_binop! { impl const Sub, sub for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Sub, sub for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for Wrapping<$t> { + impl SubAssign for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: Wrapping<$t>) { *self = *self - other; } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign<$t> for Wrapping<$t> { + impl SubAssign<$t> for Wrapping<$t> { #[inline] fn sub_assign(&mut self, other: $t) { *self = *self - Wrapping(other); } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for Wrapping<$t> { + impl Mul for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -296,28 +281,25 @@ macro_rules! wrapping_impl { #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for Wrapping<$t> { + impl MulAssign for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: Wrapping<$t>) { *self = *self * other; } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign<$t> for Wrapping<$t> { + impl MulAssign<$t> for Wrapping<$t> { #[inline] fn mul_assign(&mut self, other: $t) { *self = *self * Wrapping(other); } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_div", since = "1.3.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for Wrapping<$t> { + impl Div for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -325,32 +307,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_div(other.0)) } } - forward_ref_binop! { impl const Div, div for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Div, div for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for Wrapping<$t> { + impl DivAssign for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: Wrapping<$t>) { *self = *self / other; } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign<$t> for Wrapping<$t> { + impl DivAssign<$t> for Wrapping<$t> { #[inline] fn div_assign(&mut self, other: $t) { *self = *self / Wrapping(other); } } - forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_impls", since = "1.7.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for Wrapping<$t> { + impl Rem for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -358,32 +337,29 @@ macro_rules! wrapping_impl { Wrapping(self.0.wrapping_rem(other.0)) } } - forward_ref_binop! { impl const Rem, rem for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl Rem, rem for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for Wrapping<$t> { + impl RemAssign for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: Wrapping<$t>) { *self = *self % other; } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign<$t> for Wrapping<$t> { + impl RemAssign<$t> for Wrapping<$t> { #[inline] fn rem_assign(&mut self, other: $t) { *self = *self % Wrapping(other); } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for Wrapping<$t> { + impl Not for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -391,12 +367,11 @@ macro_rules! wrapping_impl { Wrapping(!self.0) } } - forward_ref_unop! { impl const Not, not for Wrapping<$t>, + forward_ref_unop! { impl Not, not for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for Wrapping<$t> { + impl BitXor for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -404,32 +379,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 ^ other.0) } } - forward_ref_binop! { impl const BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitXor, bitxor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for Wrapping<$t> { + impl BitXorAssign for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: Wrapping<$t>) { *self = *self ^ other; } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign<$t> for Wrapping<$t> { + impl BitXorAssign<$t> for Wrapping<$t> { #[inline] fn bitxor_assign(&mut self, other: $t) { *self = *self ^ Wrapping(other); } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for Wrapping<$t> { + impl BitOr for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -437,32 +409,29 @@ macro_rules! wrapping_impl { Wrapping(self.0 | other.0) } } - forward_ref_binop! { impl const BitOr, bitor for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitOr, bitor for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for Wrapping<$t> { + impl BitOrAssign for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: Wrapping<$t>) { *self = *self | other; } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign<$t> for Wrapping<$t> { + impl BitOrAssign<$t> for Wrapping<$t> { #[inline] fn bitor_assign(&mut self, other: $t) { *self = *self | Wrapping(other); } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, $t } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for Wrapping<$t> { + impl BitAnd for Wrapping<$t> { type Output = Wrapping<$t>; #[inline] @@ -470,39 +439,36 @@ macro_rules! wrapping_impl { Wrapping(self.0 & other.0) } } - forward_ref_binop! { impl const BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, + forward_ref_binop! { impl BitAnd, bitand for Wrapping<$t>, Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for Wrapping<$t> { + impl BitAndAssign for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: Wrapping<$t>) { *self = *self & other; } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } #[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign<$t> for Wrapping<$t> { + impl BitAndAssign<$t> for Wrapping<$t> { #[inline] fn bitand_assign(&mut self, other: $t) { *self = *self & Wrapping(other); } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, $t } #[stable(feature = "wrapping_neg", since = "1.10.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for Wrapping<$t> { + impl Neg for Wrapping<$t> { type Output = Self; #[inline] fn neg(self) -> Self { Wrapping(0) - self } } - forward_ref_unop! { impl const Neg, neg for Wrapping<$t>, + forward_ref_unop! { impl Neg, neg for Wrapping<$t>, #[stable(feature = "wrapping_ref", since = "1.14.0")] } )*) diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs index 0c7ee9630c6..1501dc4e38b 100644 --- a/library/core/src/ops/arith.rs +++ b/library/core/src/ops/arith.rs @@ -73,7 +73,6 @@ append_const_msg )] #[doc(alias = "+")] -#[const_trait] pub trait Add<Rhs = Self> { /// The resulting type after applying the `+` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -95,8 +94,7 @@ pub trait Add<Rhs = Self> { macro_rules! add_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Add for $t { + impl Add for $t { type Output = $t; #[inline] @@ -104,7 +102,7 @@ macro_rules! add_impl { fn add(self, other: $t) -> $t { self + other } } - forward_ref_binop! { impl const Add, add for $t, $t } + forward_ref_binop! { impl Add, add for $t, $t } )*) } @@ -183,7 +181,6 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } append_const_msg )] #[doc(alias = "-")] -#[const_trait] pub trait Sub<Rhs = Self> { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -205,8 +202,7 @@ pub trait Sub<Rhs = Self> { macro_rules! sub_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Sub for $t { + impl Sub for $t { type Output = $t; #[inline] @@ -214,7 +210,7 @@ macro_rules! sub_impl { fn sub(self, other: $t) -> $t { self - other } } - forward_ref_binop! { impl const Sub, sub for $t, $t } + forward_ref_binop! { impl Sub, sub for $t, $t } )*) } @@ -314,7 +310,6 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } label = "no implementation for `{Self} * {Rhs}`" )] #[doc(alias = "*")] -#[const_trait] pub trait Mul<Rhs = Self> { /// The resulting type after applying the `*` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -336,8 +331,7 @@ pub trait Mul<Rhs = Self> { macro_rules! mul_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Mul for $t { + impl Mul for $t { type Output = $t; #[inline] @@ -345,7 +339,7 @@ macro_rules! mul_impl { fn mul(self, other: $t) -> $t { self * other } } - forward_ref_binop! { impl const Mul, mul for $t, $t } + forward_ref_binop! { impl Mul, mul for $t, $t } )*) } @@ -449,7 +443,6 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } label = "no implementation for `{Self} / {Rhs}`" )] #[doc(alias = "/")] -#[const_trait] pub trait Div<Rhs = Self> { /// The resulting type after applying the `/` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -477,15 +470,14 @@ macro_rules! div_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*)*) } @@ -497,15 +489,14 @@ div_impl_integer! { macro_rules! div_impl_float { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Div for $t { + impl Div for $t { type Output = $t; #[inline] fn div(self, other: $t) -> $t { self / other } } - forward_ref_binop! { impl const Div, div for $t, $t } + forward_ref_binop! { impl Div, div for $t, $t } )*) } @@ -553,7 +544,6 @@ div_impl_float! { f32 f64 } label = "no implementation for `{Self} % {Rhs}`" )] #[doc(alias = "%")] -#[const_trait] pub trait Rem<Rhs = Self> { /// The resulting type after applying the `%` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -581,15 +571,14 @@ macro_rules! rem_impl_integer { /// #[doc = $panic] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*)*) } @@ -616,15 +605,14 @@ macro_rules! rem_impl_float { /// assert_eq!(x % y, remainder); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Rem for $t { + impl Rem for $t { type Output = $t; #[inline] fn rem(self, other: $t) -> $t { self % other } } - forward_ref_binop! { impl const Rem, rem for $t, $t } + forward_ref_binop! { impl Rem, rem for $t, $t } )*) } @@ -669,7 +657,6 @@ rem_impl_float! { f32 f64 } #[lang = "neg"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "-")] -#[const_trait] pub trait Neg { /// The resulting type after applying the `-` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -692,8 +679,7 @@ pub trait Neg { macro_rules! neg_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Neg for $t { + impl Neg for $t { type Output = $t; #[inline] @@ -701,7 +687,7 @@ macro_rules! neg_impl { fn neg(self) -> $t { -self } } - forward_ref_unop! { impl const Neg, neg for $t } + forward_ref_unop! { impl Neg, neg for $t } )*) } @@ -744,7 +730,6 @@ neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "+")] #[doc(alias = "+=")] -#[const_trait] pub trait AddAssign<Rhs = Self> { /// Performs the `+=` operation. /// @@ -762,14 +747,13 @@ pub trait AddAssign<Rhs = Self> { macro_rules! add_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const AddAssign for $t { + impl AddAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn add_assign(&mut self, other: $t) { *self += other } } - forward_ref_op_assign! { impl const AddAssign, add_assign for $t, $t } + forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t } )+) } @@ -812,7 +796,6 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "-")] #[doc(alias = "-=")] -#[const_trait] pub trait SubAssign<Rhs = Self> { /// Performs the `-=` operation. /// @@ -830,14 +813,13 @@ pub trait SubAssign<Rhs = Self> { macro_rules! sub_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const SubAssign for $t { + impl SubAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn sub_assign(&mut self, other: $t) { *self -= other } } - forward_ref_op_assign! { impl const SubAssign, sub_assign for $t, $t } + forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t } )+) } @@ -871,7 +853,6 @@ sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "*")] #[doc(alias = "*=")] -#[const_trait] pub trait MulAssign<Rhs = Self> { /// Performs the `*=` operation. /// @@ -889,14 +870,13 @@ pub trait MulAssign<Rhs = Self> { macro_rules! mul_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const MulAssign for $t { + impl MulAssign for $t { #[inline] #[rustc_inherit_overflow_checks] fn mul_assign(&mut self, other: $t) { *self *= other } } - forward_ref_op_assign! { impl const MulAssign, mul_assign for $t, $t } + forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t } )+) } @@ -930,7 +910,6 @@ mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "/")] #[doc(alias = "/=")] -#[const_trait] pub trait DivAssign<Rhs = Self> { /// Performs the `/=` operation. /// @@ -948,13 +927,12 @@ pub trait DivAssign<Rhs = Self> { macro_rules! div_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const DivAssign for $t { + impl DivAssign for $t { #[inline] fn div_assign(&mut self, other: $t) { *self /= other } } - forward_ref_op_assign! { impl const DivAssign, div_assign for $t, $t } + forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t } )+) } @@ -992,7 +970,6 @@ div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } )] #[doc(alias = "%")] #[doc(alias = "%=")] -#[const_trait] pub trait RemAssign<Rhs = Self> { /// Performs the `%=` operation. /// @@ -1010,13 +987,12 @@ pub trait RemAssign<Rhs = Self> { macro_rules! rem_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const RemAssign for $t { + impl RemAssign for $t { #[inline] fn rem_assign(&mut self, other: $t) { *self %= other } } - forward_ref_op_assign! { impl const RemAssign, rem_assign for $t, $t } + forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t } )+) } diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs index 327009801d1..c70f4a3da2e 100644 --- a/library/core/src/ops/bit.rs +++ b/library/core/src/ops/bit.rs @@ -31,7 +31,6 @@ #[lang = "not"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "!")] -#[const_trait] pub trait Not { /// The resulting type after applying the `!` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -55,23 +54,21 @@ pub trait Not { macro_rules! not_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Not for $t { + impl Not for $t { type Output = $t; #[inline] fn not(self) -> $t { !self } } - forward_ref_unop! { impl const Not, not for $t } + forward_ref_unop! { impl Not, not for $t } )*) } not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } #[stable(feature = "not_never", since = "1.60.0")] -#[rustc_const_unstable(feature = "const_ops", issue = "90080")] -impl const Not for ! { +impl Not for ! { type Output = !; #[inline] @@ -144,7 +141,6 @@ impl const Not for ! { message = "no implementation for `{Self} & {Rhs}`", label = "no implementation for `{Self} & {Rhs}`" )] -#[const_trait] pub trait BitAnd<Rhs = Self> { /// The resulting type after applying the `&` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -168,15 +164,14 @@ pub trait BitAnd<Rhs = Self> { macro_rules! bitand_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAnd for $t { + impl BitAnd for $t { type Output = $t; #[inline] fn bitand(self, rhs: $t) -> $t { self & rhs } } - forward_ref_binop! { impl const BitAnd, bitand for $t, $t } + forward_ref_binop! { impl BitAnd, bitand for $t, $t } )*) } @@ -246,7 +241,6 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} | {Rhs}`", label = "no implementation for `{Self} | {Rhs}`" )] -#[const_trait] pub trait BitOr<Rhs = Self> { /// The resulting type after applying the `|` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -270,15 +264,14 @@ pub trait BitOr<Rhs = Self> { macro_rules! bitor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOr for $t { + impl BitOr for $t { type Output = $t; #[inline] fn bitor(self, rhs: $t) -> $t { self | rhs } } - forward_ref_binop! { impl const BitOr, bitor for $t, $t } + forward_ref_binop! { impl BitOr, bitor for $t, $t } )*) } @@ -348,7 +341,6 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} ^ {Rhs}`", label = "no implementation for `{Self} ^ {Rhs}`" )] -#[const_trait] pub trait BitXor<Rhs = Self> { /// The resulting type after applying the `^` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -372,15 +364,14 @@ pub trait BitXor<Rhs = Self> { macro_rules! bitxor_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXor for $t { + impl BitXor for $t { type Output = $t; #[inline] fn bitxor(self, other: $t) -> $t { self ^ other } } - forward_ref_binop! { impl const BitXor, bitxor for $t, $t } + forward_ref_binop! { impl BitXor, bitxor for $t, $t } )*) } @@ -449,7 +440,6 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} << {Rhs}`", label = "no implementation for `{Self} << {Rhs}`" )] -#[const_trait] pub trait Shl<Rhs = Self> { /// The resulting type after applying the `<<` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -471,8 +461,7 @@ pub trait Shl<Rhs = Self> { macro_rules! shl_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shl<$f> for $t { + impl Shl<$f> for $t { type Output = $t; #[inline] @@ -482,7 +471,7 @@ macro_rules! shl_impl { } } - forward_ref_binop! { impl const Shl, shl for $t, $f } + forward_ref_binop! { impl Shl, shl for $t, $f } }; } @@ -569,7 +558,6 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } message = "no implementation for `{Self} >> {Rhs}`", label = "no implementation for `{Self} >> {Rhs}`" )] -#[const_trait] pub trait Shr<Rhs = Self> { /// The resulting type after applying the `>>` operator. #[stable(feature = "rust1", since = "1.0.0")] @@ -591,8 +579,7 @@ pub trait Shr<Rhs = Self> { macro_rules! shr_impl { ($t:ty, $f:ty) => { #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const Shr<$f> for $t { + impl Shr<$f> for $t { type Output = $t; #[inline] @@ -602,7 +589,7 @@ macro_rules! shr_impl { } } - forward_ref_binop! { impl const Shr, shr for $t, $f } + forward_ref_binop! { impl Shr, shr for $t, $f } }; } @@ -698,7 +685,6 @@ shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } message = "no implementation for `{Self} &= {Rhs}`", label = "no implementation for `{Self} &= {Rhs}`" )] -#[const_trait] pub trait BitAndAssign<Rhs = Self> { /// Performs the `&=` operation. /// @@ -728,13 +714,12 @@ pub trait BitAndAssign<Rhs = Self> { macro_rules! bitand_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitAndAssign for $t { + impl BitAndAssign for $t { #[inline] fn bitand_assign(&mut self, other: $t) { *self &= other } } - forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for $t, $t } + forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t } )+) } @@ -771,7 +756,6 @@ bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} |= {Rhs}`", label = "no implementation for `{Self} |= {Rhs}`" )] -#[const_trait] pub trait BitOrAssign<Rhs = Self> { /// Performs the `|=` operation. /// @@ -801,13 +785,12 @@ pub trait BitOrAssign<Rhs = Self> { macro_rules! bitor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitOrAssign for $t { + impl BitOrAssign for $t { #[inline] fn bitor_assign(&mut self, other: $t) { *self |= other } } - forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for $t, $t } + forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t } )+) } @@ -844,7 +827,6 @@ bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} ^= {Rhs}`", label = "no implementation for `{Self} ^= {Rhs}`" )] -#[const_trait] pub trait BitXorAssign<Rhs = Self> { /// Performs the `^=` operation. /// @@ -874,13 +856,12 @@ pub trait BitXorAssign<Rhs = Self> { macro_rules! bitxor_assign_impl { ($($t:ty)+) => ($( #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const BitXorAssign for $t { + impl BitXorAssign for $t { #[inline] fn bitxor_assign(&mut self, other: $t) { *self ^= other } } - forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for $t, $t } + forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t } )+) } @@ -915,7 +896,6 @@ bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } message = "no implementation for `{Self} <<= {Rhs}`", label = "no implementation for `{Self} <<= {Rhs}`" )] -#[const_trait] pub trait ShlAssign<Rhs = Self> { /// Performs the `<<=` operation. /// @@ -937,8 +917,7 @@ pub trait ShlAssign<Rhs = Self> { macro_rules! shl_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShlAssign<$f> for $t { + impl ShlAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shl_assign(&mut self, other: $f) { @@ -946,7 +925,7 @@ macro_rules! shl_assign_impl { } } - forward_ref_op_assign! { impl const ShlAssign, shl_assign for $t, $f } + forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f } }; } @@ -999,7 +978,6 @@ shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } message = "no implementation for `{Self} >>= {Rhs}`", label = "no implementation for `{Self} >>= {Rhs}`" )] -#[const_trait] pub trait ShrAssign<Rhs = Self> { /// Performs the `>>=` operation. /// @@ -1021,8 +999,7 @@ pub trait ShrAssign<Rhs = Self> { macro_rules! shr_assign_impl { ($t:ty, $f:ty) => { #[stable(feature = "op_assign_traits", since = "1.8.0")] - #[rustc_const_unstable(feature = "const_ops", issue = "90080")] - impl const ShrAssign<$f> for $t { + impl ShrAssign<$f> for $t { #[inline] #[rustc_inherit_overflow_checks] fn shr_assign(&mut self, other: $f) { @@ -1030,7 +1007,7 @@ macro_rules! shr_assign_impl { } } - forward_ref_op_assign! { impl const ShrAssign, shr_assign for $t, $f } + forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f } }; } diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 117706fb4b2..e10c438ef43 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -97,8 +97,7 @@ pub enum ControlFlow<B, C = ()> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<B, C> const ops::Try for ControlFlow<B, C> { +impl<B, C> ops::Try for ControlFlow<B, C> { type Output = C; type Residual = ControlFlow<B, convert::Infallible>; @@ -117,8 +116,7 @@ impl<B, C> const ops::Try for ControlFlow<B, C> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<B, C> const ops::FromResidual for ControlFlow<B, C> { +impl<B, C> ops::FromResidual for ControlFlow<B, C> { #[inline] fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self { match residual { @@ -128,8 +126,7 @@ impl<B, C> const ops::FromResidual for ControlFlow<B, C> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<B, C> const ops::Residual<C> for ControlFlow<B, convert::Infallible> { +impl<B, C> ops::Residual<C> for ControlFlow<B, convert::Infallible> { type TryType = ControlFlow<B, C>; } diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs index c67867f4436..08c35b6dac3 100644 --- a/library/core/src/ops/deref.rs +++ b/library/core/src/ops/deref.rs @@ -61,7 +61,6 @@ #[doc(alias = "&*")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "Deref"] -#[const_trait] pub trait Deref { /// The resulting type after dereferencing. #[stable(feature = "rust1", since = "1.0.0")] @@ -77,8 +76,7 @@ pub trait Deref { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for &T { +impl<T: ?Sized> Deref for &T { type Target = T; #[rustc_diagnostic_item = "noop_method_deref"] @@ -91,8 +89,7 @@ impl<T: ?Sized> const Deref for &T { impl<T: ?Sized> !DerefMut for &T {} #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl<T: ?Sized> const Deref for &mut T { +impl<T: ?Sized> Deref for &mut T { type Target = T; fn deref(&self) -> &T { @@ -170,7 +167,6 @@ impl<T: ?Sized> const Deref for &mut T { #[lang = "deref_mut"] #[doc(alias = "*")] #[stable(feature = "rust1", since = "1.0.0")] -#[const_trait] pub trait DerefMut: Deref { /// Mutably dereferences the value. #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs index b7e1aee9d84..67c8245f0bf 100644 --- a/library/core/src/ops/function.rs +++ b/library/core/src/ops/function.rs @@ -254,10 +254,9 @@ mod impls { use crate::marker::Tuple; #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const Fn<A> for &F + impl<A: Tuple, F: ?Sized> Fn<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { extern "rust-call" fn call(&self, args: A) -> F::Output { (**self).call(args) @@ -265,10 +264,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnMut<A> for &F + impl<A: Tuple, F: ?Sized> FnMut<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (**self).call(args) @@ -276,10 +274,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnOnce<A> for &F + impl<A: Tuple, F: ?Sized> FnOnce<A> for &F where - F: ~const Fn<A>, + F: Fn<A>, { type Output = F::Output; @@ -289,10 +286,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnMut<A> for &mut F + impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F where - F: ~const FnMut<A>, + F: FnMut<A>, { extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output { (*self).call_mut(args) @@ -300,10 +296,9 @@ mod impls { } #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_fn_trait_ref_impls", issue = "101803")] - impl<A: Tuple, F: ?Sized> const FnOnce<A> for &mut F + impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F where - F: ~const FnMut<A>, + F: FnMut<A>, { type Output = F::Output; extern "rust-call" fn call_once(self, args: A) -> F::Output { diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs index f3754484f6a..1f1784ec9b2 100644 --- a/library/core/src/ops/index.rs +++ b/library/core/src/ops/index.rs @@ -55,7 +55,6 @@ #[doc(alias = "]")] #[doc(alias = "[")] #[doc(alias = "[]")] -#[const_trait] pub trait Index<Idx: ?Sized> { /// The returned type after indexing. #[stable(feature = "rust1", since = "1.0.0")] @@ -165,8 +164,7 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] -#[const_trait] -pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> { +pub trait IndexMut<Idx: ?Sized>: Index<Idx> { /// Performs the mutable indexing (`container[index]`) operation. /// /// # Panics diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index b8ab2656473..ba5e6ddc752 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -96,7 +96,7 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { +impl<Idx: PartialOrd<Idx>> Range<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -116,11 +116,10 @@ impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -143,8 +142,7 @@ impl<Idx: ~const PartialOrd<Idx>> Range<Idx> { /// assert!( (f32::NAN..5.0).is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { !(self.start < self.end) } } @@ -201,7 +199,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeFrom<Idx> { +impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -216,11 +214,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeFrom<Idx> { /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -283,7 +280,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeTo<Idx> { +impl<Idx: PartialOrd<Idx>> RangeTo<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -298,11 +295,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeTo<Idx> { /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -474,7 +470,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { +impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -505,11 +501,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { /// assert!(!r.contains(&3) && !r.contains(&5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -541,9 +536,8 @@ impl<Idx: ~const PartialOrd<Idx>> RangeInclusive<Idx> { /// assert!(r.is_empty()); /// ``` #[stable(feature = "range_is_empty", since = "1.47.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] #[inline] - pub const fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { self.exhausted || !(self.start <= self.end) } } @@ -605,7 +599,7 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> { } } -impl<Idx: ~const PartialOrd<Idx>> RangeToInclusive<Idx> { +impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> { /// Returns `true` if `item` is contained in the range. /// /// # Examples @@ -620,11 +614,10 @@ impl<Idx: ~const PartialOrd<Idx>> RangeToInclusive<Idx> { /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` #[stable(feature = "range_contains", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] - pub const fn contains<U>(&self, item: &U) -> bool + pub fn contains<U>(&self, item: &U) -> bool where - Idx: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<Idx>, + Idx: PartialOrd<U>, + U: ?Sized + PartialOrd<Idx>, { <Self as RangeBounds<Idx>>::contains(self, item) } @@ -765,7 +758,6 @@ impl<T: Clone> Bound<&T> { /// `RangeBounds` is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`. #[stable(feature = "collections_range", since = "1.28.0")] -#[const_trait] pub trait RangeBounds<T: ?Sized> { /// Start index bound. /// @@ -818,8 +810,8 @@ pub trait RangeBounds<T: ?Sized> { #[stable(feature = "range_contains", since = "1.35.0")] fn contains<U>(&self, item: &U) -> bool where - T: ~const PartialOrd<U>, - U: ?Sized + ~const PartialOrd<T>, + T: PartialOrd<U>, + U: ?Sized + PartialOrd<T>, { (match self.start_bound() { Included(start) => start <= item, @@ -836,8 +828,7 @@ pub trait RangeBounds<T: ?Sized> { use self::Bound::{Excluded, Included, Unbounded}; #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T: ?Sized> const RangeBounds<T> for RangeFull { +impl<T: ?Sized> RangeBounds<T> for RangeFull { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -847,8 +838,7 @@ impl<T: ?Sized> const RangeBounds<T> for RangeFull { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeFrom<T> { +impl<T> RangeBounds<T> for RangeFrom<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -858,8 +848,7 @@ impl<T> const RangeBounds<T> for RangeFrom<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeTo<T> { +impl<T> RangeBounds<T> for RangeTo<T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -869,8 +858,7 @@ impl<T> const RangeBounds<T> for RangeTo<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for Range<T> { +impl<T> RangeBounds<T> for Range<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -880,8 +868,7 @@ impl<T> const RangeBounds<T> for Range<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeInclusive<T> { +impl<T> RangeBounds<T> for RangeInclusive<T> { fn start_bound(&self) -> Bound<&T> { Included(&self.start) } @@ -897,8 +884,7 @@ impl<T> const RangeBounds<T> for RangeInclusive<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeToInclusive<T> { +impl<T> RangeBounds<T> for RangeToInclusive<T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -908,8 +894,7 @@ impl<T> const RangeBounds<T> for RangeToInclusive<T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for (Bound<T>, Bound<T>) { +impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) { fn start_bound(&self) -> Bound<&T> { match *self { (Included(ref start), _) => Included(start), @@ -928,8 +913,7 @@ impl<T> const RangeBounds<T> for (Bound<T>, Bound<T>) { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<'a, T: ?Sized + 'a> const RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { +impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { fn start_bound(&self) -> Bound<&T> { self.0 } @@ -940,8 +924,7 @@ impl<'a, T: ?Sized + 'a> const RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeFrom<&T> { +impl<T> RangeBounds<T> for RangeFrom<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -951,8 +934,7 @@ impl<T> const RangeBounds<T> for RangeFrom<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeTo<&T> { +impl<T> RangeBounds<T> for RangeTo<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } @@ -962,8 +944,7 @@ impl<T> const RangeBounds<T> for RangeTo<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for Range<&T> { +impl<T> RangeBounds<T> for Range<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -973,8 +954,7 @@ impl<T> const RangeBounds<T> for Range<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeInclusive<&T> { +impl<T> RangeBounds<T> for RangeInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Included(self.start) } @@ -984,8 +964,7 @@ impl<T> const RangeBounds<T> for RangeInclusive<&T> { } #[stable(feature = "collections_range", since = "1.28.0")] -#[rustc_const_unstable(feature = "const_range_bounds", issue = "108082")] -impl<T> const RangeBounds<T> for RangeToInclusive<&T> { +impl<T> RangeBounds<T> for RangeToInclusive<&T> { fn start_bound(&self) -> Bound<&T> { Unbounded } diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index c254803fbf6..b4f69d0b213 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -128,8 +128,7 @@ use crate::ops::ControlFlow; )] #[doc(alias = "?")] #[lang = "Try"] -#[const_trait] -pub trait Try: ~const FromResidual { +pub trait Try: FromResidual { /// The type of the value produced by `?` when *not* short-circuiting. #[unstable(feature = "try_trait_v2", issue = "84277")] type Output; @@ -305,7 +304,6 @@ pub trait Try: ~const FromResidual { )] #[rustc_diagnostic_item = "FromResidual"] #[unstable(feature = "try_trait_v2", issue = "84277")] -#[const_trait] pub trait FromResidual<R = <Self as Try>::Residual> { /// Constructs the type from a compatible `Residual` type. /// @@ -358,11 +356,10 @@ where /// and in the other direction, /// `<Result<Infallible, E> as Residual<T>>::TryType = Result<T, E>`. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[const_trait] pub trait Residual<O> { /// The "return" type of this meta-function. #[unstable(feature = "try_trait_v2_residual", issue = "91285")] - type TryType: ~const Try<Output = O, Residual = Self>; + type TryType: Try<Output = O, Residual = Self>; } #[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")] @@ -389,16 +386,14 @@ impl<T> NeverShortCircuit<T> { } #[inline] - pub fn wrap_mut_2<A, B>( - mut f: impl ~const FnMut(A, B) -> T, - ) -> impl ~const FnMut(A, B) -> Self { - const move |a, b| NeverShortCircuit(f(a, b)) + pub fn wrap_mut_2<A, B>(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self { + move |a, b| NeverShortCircuit(f(a, b)) } } pub(crate) enum NeverShortCircuitResidual {} -impl<T> const Try for NeverShortCircuit<T> { +impl<T> Try for NeverShortCircuit<T> { type Output = T; type Residual = NeverShortCircuitResidual; @@ -413,14 +408,14 @@ impl<T> const Try for NeverShortCircuit<T> { } } -impl<T> const FromResidual for NeverShortCircuit<T> { +impl<T> FromResidual for NeverShortCircuit<T> { #[inline] fn from_residual(never: NeverShortCircuitResidual) -> Self { match never {} } } -impl<T> const Residual<T> for NeverShortCircuitResidual { +impl<T> Residual<T> for NeverShortCircuitResidual { type TryType = NeverShortCircuit<T>; } diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 057053297cd..82e7e69215e 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -547,7 +547,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; -use crate::marker::Destruct; use crate::panicking::{panic, panic_str}; use crate::pin::Pin; use crate::{ @@ -967,11 +966,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Some(x) => x, None => default, @@ -989,11 +984,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_else<F>(self, f: F) -> T + pub fn unwrap_or_else<F>(self, f: F) -> T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { match self { Some(x) => x, @@ -1022,10 +1015,9 @@ impl<T> Option<T> { /// [`FromStr`]: crate::str::FromStr #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn unwrap_or_default(self) -> T + pub fn unwrap_or_default(self) -> T where - T: ~const Default, + T: Default, { match self { Some(x) => x, @@ -1089,11 +1081,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map<U, F>(self, f: F) -> Option<U> + pub fn map<U, F>(self, f: F) -> Option<U> where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(x) => Some(f(x)), @@ -1118,11 +1108,9 @@ impl<T> Option<T> { /// ``` #[inline] #[unstable(feature = "result_option_inspect", issue = "91345")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn inspect<F>(self, f: F) -> Self + pub fn inspect<F>(self, f: F) -> Self where - F: ~const FnOnce(&T), - F: ~const Destruct, + F: FnOnce(&T), { if let Some(ref x) = self { f(x); @@ -1151,12 +1139,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or<U, F>(self, default: U, f: F) -> U + pub fn map_or<U, F>(self, default: U, f: F) -> U where - F: ~const FnOnce(T) -> U, - F: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1180,13 +1165,10 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn map_or_else<U, D, F>(self, default: D, f: F) -> U + pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U where - D: ~const FnOnce() -> U, - D: ~const Destruct, - F: ~const FnOnce(T) -> U, - F: ~const Destruct, + D: FnOnce() -> U, + F: FnOnce(T) -> U, { match self { Some(t) => f(t), @@ -1217,11 +1199,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or<E>(self, err: E) -> Result<T, E> - where - E: ~const Destruct, - { + pub fn ok_or<E>(self, err: E) -> Result<T, E> { match self { Some(v) => Ok(v), None => Err(err), @@ -1246,11 +1224,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn ok_or_else<E, F>(self, err: F) -> Result<T, E> + pub fn ok_or_else<E, F>(self, err: F) -> Result<T, E> where - F: ~const FnOnce() -> E, - F: ~const Destruct, + F: FnOnce() -> E, { match self { Some(v) => Ok(v), @@ -1274,10 +1250,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref(&self) -> Option<&T::Target> + pub fn as_deref(&self) -> Option<&T::Target> where - T: ~const Deref, + T: Deref, { match self.as_ref() { Some(t) => Some(t.deref()), @@ -1301,10 +1276,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_deref", since = "1.40.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> + pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> where - T: ~const DerefMut, + T: DerefMut, { match self.as_mut() { Some(t) => Some(t.deref_mut()), @@ -1388,12 +1362,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and<U>(self, optb: Option<U>) -> Option<U> - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn and<U>(self, optb: Option<U>) -> Option<U> { match self { Some(_) => optb, None => None, @@ -1430,11 +1399,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn and_then<U, F>(self, f: F) -> Option<U> + pub fn and_then<U, F>(self, f: F) -> Option<U> where - F: ~const FnOnce(T) -> Option<U>, - F: ~const Destruct, + F: FnOnce(T) -> Option<U>, { match self { Some(x) => f(x), @@ -1468,12 +1435,9 @@ impl<T> Option<T> { /// [`Some(t)`]: Some #[inline] #[stable(feature = "option_filter", since = "1.27.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn filter<P>(self, predicate: P) -> Self + pub fn filter<P>(self, predicate: P) -> Self where - T: ~const Destruct, - P: ~const FnOnce(&T) -> bool, - P: ~const Destruct, + P: FnOnce(&T) -> bool, { if let Some(x) = self { if predicate(&x) { @@ -1512,11 +1476,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or(self, optb: Option<T>) -> Option<T> - where - T: ~const Destruct, - { + pub fn or(self, optb: Option<T>) -> Option<T> { match self { Some(x) => Some(x), None => optb, @@ -1538,11 +1498,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn or_else<F>(self, f: F) -> Option<T> + pub fn or_else<F>(self, f: F) -> Option<T> where - F: ~const FnOnce() -> Option<T>, - F: ~const Destruct, + F: FnOnce() -> Option<T>, { match self { Some(x) => Some(x), @@ -1573,11 +1531,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_xor", since = "1.37.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn xor(self, optb: Option<T>) -> Option<T> - where - T: ~const Destruct, - { + pub fn xor(self, optb: Option<T>) -> Option<T> { match (self, optb) { (Some(a), None) => Some(a), (None, Some(b)) => Some(b), @@ -1611,11 +1565,7 @@ impl<T> Option<T> { #[must_use = "if you intended to set a value, consider assignment instead"] #[inline] #[stable(feature = "option_insert", since = "1.53.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn insert(&mut self, value: T) -> &mut T { *self = Some(value); // SAFETY: the code above just filled the option @@ -1644,11 +1594,7 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert(&mut self, value: T) -> &mut T - where - T: ~const Destruct, - { + pub fn get_or_insert(&mut self, value: T) -> &mut T { if let None = *self { *self = Some(value); } @@ -1679,12 +1625,11 @@ impl<T> Option<T> { /// ``` #[inline] #[unstable(feature = "option_get_or_insert_default", issue = "82901")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_default(&mut self) -> &mut T + pub fn get_or_insert_default(&mut self) -> &mut T where - T: ~const Default, + T: Default, { - const fn default<T: ~const Default>() -> T { + fn default<T: Default>() -> T { T::default() } @@ -1710,11 +1655,9 @@ impl<T> Option<T> { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn get_or_insert_with<F>(&mut self, f: F) -> &mut T + pub fn get_or_insert_with<F>(&mut self, f: F) -> &mut T where - F: ~const FnOnce() -> T, - F: ~const Destruct, + F: FnOnce() -> T, { if let None = *self { // the compiler isn't smart enough to know that we are not dropping a `T` @@ -1794,12 +1737,7 @@ impl<T> Option<T> { /// assert_eq!(x.zip(z), None); /// ``` #[stable(feature = "option_zip_option", since = "1.46.0")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip<U>(self, other: Option<U>) -> Option<(T, U)> - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn zip<U>(self, other: Option<U>) -> Option<(T, U)> { match (self, other) { (Some(a), Some(b)) => Some((a, b)), _ => None, @@ -1835,13 +1773,9 @@ impl<T> Option<T> { /// assert_eq!(x.zip_with(None, Point::new), None); /// ``` #[unstable(feature = "option_zip", issue = "70086")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R> + pub fn zip_with<U, F, R>(self, other: Option<U>, f: F) -> Option<R> where - F: ~const FnOnce(T, U) -> R, - F: ~const Destruct, - T: ~const Destruct, - U: ~const Destruct, + F: FnOnce(T, U) -> R, { match (self, other) { (Some(a), Some(b)) => Some(f(a, b)), @@ -1867,12 +1801,7 @@ impl<T, U> Option<(T, U)> { /// ``` #[inline] #[stable(feature = "unzip_option", since = "1.66.0")] - #[rustc_const_unstable(feature = "const_option", issue = "67441")] - pub const fn unzip(self) -> (Option<T>, Option<U>) - where - T: ~const Destruct, - U: ~const Destruct, - { + pub fn unzip(self) -> (Option<T>, Option<U>) { match self { Some((a, b)) => (Some(a), Some(b)), None => (None, None), @@ -1922,10 +1851,9 @@ impl<T> Option<&T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option<T> + pub fn cloned(self) -> Option<T> where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -1974,10 +1902,9 @@ impl<T> Option<&mut T> { /// ``` #[must_use = "`self` will be dropped if the result is not used"] #[stable(since = "1.26.0", feature = "option_ref_mut_cloned")] - #[rustc_const_unstable(feature = "const_option_cloned", issue = "91582")] - pub const fn cloned(self) -> Option<T> + pub fn cloned(self) -> Option<T> where - T: ~const Clone, + T: Clone, { match self { Some(t) => Some(t.clone()), @@ -2030,10 +1957,9 @@ const fn expect_failed(msg: &str) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T> const Clone for Option<T> +impl<T> Clone for Option<T> where - T: ~const Clone + ~const Destruct, + T: Clone, { #[inline] fn clone(&self) -> Self { @@ -2053,8 +1979,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Option<T> { +impl<T> Default for Option<T> { /// Returns [`None`][Option::None]. /// /// # Examples @@ -2114,8 +2039,7 @@ impl<'a, T> IntoIterator for &'a mut Option<T> { } #[stable(since = "1.12.0", feature = "option_from")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Option<T> { +impl<T> From<T> for Option<T> { /// Moves `val` into a new [`Some`]. /// /// # Examples @@ -2131,8 +2055,7 @@ impl<T> const From<T> for Option<T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a Option<T>> for Option<&'a T> { +impl<'a, T> From<&'a Option<T>> for Option<&'a T> { /// Converts from `&Option<T>` to `Option<&T>`. /// /// # Examples @@ -2159,8 +2082,7 @@ impl<'a, T> const From<&'a Option<T>> for Option<&'a T> { } #[stable(feature = "option_ref_from_ref_option", since = "1.30.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<'a, T> const From<&'a mut Option<T>> for Option<&'a mut T> { +impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> { /// Converts from `&mut Option<T>` to `Option<&mut T>` /// /// # Examples @@ -2507,8 +2429,7 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const ops::Try for Option<T> { +impl<T> ops::Try for Option<T> { type Output = T; type Residual = Option<convert::Infallible>; @@ -2527,8 +2448,7 @@ impl<T> const ops::Try for Option<T> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const ops::FromResidual for Option<T> { +impl<T> ops::FromResidual for Option<T> { #[inline] fn from_residual(residual: Option<convert::Infallible>) -> Self { match residual { @@ -2546,8 +2466,7 @@ impl<T> ops::FromResidual<ops::Yeet<()>> for Option<T> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<T> const ops::Residual<T> for Option<convert::Infallible> { +impl<T> ops::Residual<T> for Option<convert::Infallible> { type TryType = Option<T>; } diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 10525a16f3a..9c4c0f6ab7a 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -76,9 +76,7 @@ pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -pub use crate::macros::builtin::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, -}; +pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case}; #[unstable(feature = "derive_const", issue = "none")] pub use crate::macros::builtin::derive_const; diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index efe6d4183e3..bbf7199fffa 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -9,8 +9,7 @@ use crate::{cmp, fmt, hash, mem, num}; /// Note that particularly large alignments, while representable in this type, /// are likely not to be supported by actual allocators and linkers. #[unstable(feature = "ptr_alignment_type", issue = "102070")] -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(transparent)] pub struct Alignment(AlignmentEnum); @@ -170,7 +169,7 @@ impl From<Alignment> for usize { #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl const cmp::Ord for Alignment { +impl cmp::Ord for Alignment { #[inline] fn cmp(&self, other: &Self) -> cmp::Ordering { self.as_nonzero().get().cmp(&other.as_nonzero().get()) @@ -179,7 +178,7 @@ impl const cmp::Ord for Alignment { #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[unstable(feature = "ptr_alignment_type", issue = "102070")] -impl const cmp::PartialOrd for Alignment { +impl cmp::PartialOrd for Alignment { #[inline] fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) @@ -201,8 +200,7 @@ type AlignmentEnum = AlignmentEnum32; #[cfg(target_pointer_width = "64")] type AlignmentEnum = AlignmentEnum64; -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u16)] enum AlignmentEnum16 { _Align1Shl0 = 1 << 0, @@ -223,8 +221,7 @@ enum AlignmentEnum16 { _Align1Shl15 = 1 << 15, } -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u32)] enum AlignmentEnum32 { _Align1Shl0 = 1 << 0, @@ -261,8 +258,7 @@ enum AlignmentEnum32 { _Align1Shl31 = 1 << 31, } -#[derive(Copy, Clone, Eq)] -#[derive_const(PartialEq)] +#[derive(Copy, Clone, PartialEq, Eq)] #[repr(u64)] enum AlignmentEnum64 { _Align1Shl0 = 1 << 0, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 3838c39cc6a..603bd887333 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1650,11 +1650,10 @@ impl<T> *const [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output + pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked(self) } diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 818f1a919d0..555d58fad84 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1764,7 +1764,12 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz // miracles, given the situations this case has to deal with. // SAFETY: a is power-of-two hence non-zero. stride == 0 case is handled above. - let gcdpow = unsafe { cttz_nonzero(stride).min(cttz_nonzero(a)) }; + // FIXME(const-hack) replace with min + let gcdpow = unsafe { + let x = cttz_nonzero(stride); + let y = cttz_nonzero(a); + if x < y { x } else { y } + }; // SAFETY: gcdpow has an upper-bound that’s at most the number of bits in a usize. let gcd = unsafe { unchecked_shl(1usize, gcdpow) }; // SAFETY: gcd is always greater or equal to 1. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index e522b6dc15c..24b66c549a6 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -2036,11 +2036,10 @@ impl<T> *mut [T] { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline(always)] - pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output + pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. unsafe { index.get_unchecked_mut(self) } diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index a46804c186c..506d891d989 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -676,11 +676,10 @@ impl<T> NonNull<[T]> { /// } /// ``` #[unstable(feature = "slice_ptr_get", issue = "74265")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output> + pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output> where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { // SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds. // As a consequence, the resulting pointer cannot be null. @@ -689,8 +688,7 @@ impl<T> NonNull<[T]> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T: ?Sized> const Clone for NonNull<T> { +impl<T: ?Sized> Clone for NonNull<T> { #[inline(always)] fn clone(&self) -> Self { *self @@ -756,8 +754,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<Unique<T>> for NonNull<T> { +impl<T: ?Sized> From<Unique<T>> for NonNull<T> { #[inline] fn from(unique: Unique<T>) -> Self { // SAFETY: A Unique pointer cannot be null, so the conditions for @@ -767,8 +764,7 @@ impl<T: ?Sized> const From<Unique<T>> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<&mut T> for NonNull<T> { +impl<T: ?Sized> From<&mut T> for NonNull<T> { /// Converts a `&mut T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. @@ -780,8 +776,7 @@ impl<T: ?Sized> const From<&mut T> for NonNull<T> { } #[stable(feature = "nonnull", since = "1.25.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T: ?Sized> const From<&T> for NonNull<T> { +impl<T: ?Sized> From<&T> for NonNull<T> { /// Converts a `&T` to a `NonNull<T>`. /// /// This conversion is safe and infallible since references cannot be null. diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs index 64616142b41..a853f15edb7 100644 --- a/library/core/src/ptr/unique.rs +++ b/library/core/src/ptr/unique.rs @@ -70,7 +70,8 @@ impl<T: Sized> Unique<T> { #[must_use] #[inline] pub const fn dangling() -> Self { - Self::from(NonNull::dangling()) + // FIXME(const-hack) replace with `From` + Unique { pointer: NonNull::dangling(), _marker: PhantomData } } } @@ -134,13 +135,14 @@ impl<T: ?Sized> Unique<T> { #[must_use = "`self` will be dropped if the result is not used"] #[inline] pub const fn cast<U>(self) -> Unique<U> { - Unique::from(self.pointer.cast()) + // FIXME(const-hack): replace with `From` + // SAFETY: is `NonNull` + unsafe { Unique::new_unchecked(self.pointer.cast().as_ptr()) } } } #[unstable(feature = "ptr_internals", issue = "none")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T: ?Sized> const Clone for Unique<T> { +impl<T: ?Sized> Clone for Unique<T> { #[inline] fn clone(&self) -> Self { *self @@ -171,7 +173,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> const From<&mut T> for Unique<T> { +impl<T: ?Sized> From<&mut T> for Unique<T> { /// Converts a `&mut T` to a `Unique<T>`. /// /// This conversion is infallible since references cannot be null. @@ -182,7 +184,7 @@ impl<T: ?Sized> const From<&mut T> for Unique<T> { } #[unstable(feature = "ptr_internals", issue = "none")] -impl<T: ?Sized> const From<NonNull<T>> for Unique<T> { +impl<T: ?Sized> From<NonNull<T>> for Unique<T> { /// Converts a `NonNull<T>` to a `Unique<T>`. /// /// This conversion is infallible since `NonNull` cannot be null. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 241602c0e18..28cb02989ec 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -489,7 +489,6 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; -use crate::marker::Destruct; use crate::ops::{self, ControlFlow, Deref, DerefMut}; use crate::{convert, fmt, hint}; @@ -629,16 +628,10 @@ impl<T, E> Result<T, E> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn ok(self) -> Option<T> - where - E: ~const Destruct, - { + pub fn ok(self) -> Option<T> { match self { Ok(x) => Some(x), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(x) => None, + Err(_) => None, } } @@ -658,15 +651,9 @@ impl<T, E> Result<T, E> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] - pub const fn err(self) -> Option<E> - where - T: ~const Destruct, - { + pub fn err(self) -> Option<E> { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => None, + Ok(_) => None, Err(x) => Some(x), } } @@ -1287,18 +1274,10 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.and(y), Ok("different result type")); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn and<U>(self, res: Result<U, E>) -> Result<U, E> - where - T: ~const Destruct, - U: ~const Destruct, - E: ~const Destruct, - { + pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> { match self { - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Ok(x) => res, + Ok(_) => res, Err(e) => Err(e), } } @@ -1370,19 +1349,11 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.or(y), Ok(2)); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn or<F>(self, res: Result<T, F>) -> Result<T, F> - where - T: ~const Destruct, - E: ~const Destruct, - F: ~const Destruct, - { + pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> { match self { Ok(v) => Ok(v), - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => res, + Err(_) => res, } } @@ -1430,18 +1401,11 @@ impl<T, E> Result<T, E> { /// assert_eq!(x.unwrap_or(default), default); /// ``` #[inline] - #[rustc_const_unstable(feature = "const_result_drop", issue = "92384")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn unwrap_or(self, default: T) -> T - where - T: ~const Destruct, - E: ~const Destruct, - { + pub fn unwrap_or(self, default: T) -> T { match self { Ok(t) => t, - // FIXME: ~const Drop doesn't quite work right yet - #[allow(unused_variables)] - Err(e) => default, + Err(_) => default, } } @@ -1704,11 +1668,10 @@ fn unwrap_failed<T>(_msg: &str, _error: &T) -> ! { ///////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_clone", issue = "91805")] -impl<T, E> const Clone for Result<T, E> +impl<T, E> Clone for Result<T, E> where - T: ~const Clone + ~const Destruct, - E: ~const Clone + ~const Destruct, + T: Clone, + E: Clone, { #[inline] fn clone(&self) -> Self { @@ -1971,8 +1934,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, E> const ops::Try for Result<T, E> { +impl<T, E> ops::Try for Result<T, E> { type Output = T; type Residual = Result<convert::Infallible, E>; @@ -1991,10 +1953,7 @@ impl<T, E> const ops::Try for Result<T, E> { } #[unstable(feature = "try_trait_v2", issue = "84277")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T, E, F: ~const From<E>> const ops::FromResidual<Result<convert::Infallible, E>> - for Result<T, F> -{ +impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Result<T, F> { #[inline] #[track_caller] fn from_residual(residual: Result<convert::Infallible, E>) -> Self { @@ -2013,7 +1972,6 @@ impl<T, E, F: From<E>> ops::FromResidual<ops::Yeet<E>> for Result<T, F> { } #[unstable(feature = "try_trait_v2_residual", issue = "91285")] -#[rustc_const_unstable(feature = "const_try", issue = "74935")] -impl<T, E> const ops::Residual<T> for Result<convert::Infallible, E> { +impl<T, E> ops::Residual<T> for Result<convert::Infallible, E> { type TryType = Result<T, E>; } diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 3539353240a..6ef9f9c95e8 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -7,10 +7,9 @@ use crate::ops; use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I> const ops::Index<I> for [T] +impl<T, I> ops::Index<I> for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { type Output = I::Output; @@ -21,10 +20,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<T, I> const ops::IndexMut<I> for [T] +impl<T, I> ops::IndexMut<I> for [T] where - I: ~const SliceIndex<[T]>, + I: SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -162,7 +160,6 @@ mod private_slice_index { message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" )] -#[const_trait] pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")] @@ -211,7 +208,7 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for usize { +unsafe impl<T> SliceIndex<[T]> for usize { type Output = T; #[inline] @@ -271,7 +268,7 @@ unsafe impl<T> const SliceIndex<[T]> for usize { /// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here /// than there are for a general `Range<usize>` (which might be `100..3`). #[rustc_const_unstable(feature = "const_index_range_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange { +unsafe impl<T> SliceIndex<[T]> for ops::IndexRange { type Output = [T]; #[inline] @@ -347,7 +344,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { type Output = [T]; #[inline] @@ -428,7 +425,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { type Output = [T]; #[inline] @@ -466,7 +463,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> { type Output = [T]; #[inline] @@ -512,7 +509,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> { #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull { +unsafe impl<T> SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -548,7 +545,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull { #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { type Output = [T]; #[inline] @@ -592,7 +589,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> { #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> { +unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> { type Output = [T]; #[inline] diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 88b84bd1352..b2dd92a2379 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -685,7 +685,7 @@ where None } else { self.finished = true; - Some(mem::replace(&mut self.v, &mut [])) + Some(mem::take(&mut self.v)) } } } @@ -749,7 +749,7 @@ where match idx_opt { None => self.finish(), Some(idx) => { - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = head; Some(&mut tail[1..]) @@ -830,7 +830,7 @@ where if idx == self.v.len() { self.finished = true; } - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = tail; Some(head) @@ -876,7 +876,7 @@ where if idx == 0 { self.finished = true; } - let tmp = mem::replace(&mut self.v, &mut []); + let tmp = mem::take(&mut self.v); let (head, tail) = tmp.split_at_mut(idx); self.v = head; Some(tail) diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index b73e35f1e91..b1ca872b845 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -73,7 +73,7 @@ macro_rules! iterator { // Unsafe because the offset must not exceed `self.len()`. #[inline(always)] unsafe fn post_inc_start(&mut self, offset: usize) -> * $raw_mut T { - if mem::size_of::<T>() == 0 { + if T::IS_ZST { zst_shrink!(self, offset); self.ptr.as_ptr() } else { diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 98c8349eb60..3a8b59d727b 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -1,7 +1,6 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch -use crate::cmp; use crate::mem; const LO_USIZE: usize = usize::repeat_u8(0x01); @@ -83,8 +82,12 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> { let mut offset = ptr.align_offset(USIZE_BYTES); if offset > 0 { - offset = cmp::min(offset, len); - if let Some(index) = memchr_naive(x, &text[..offset]) { + // FIXME(const-hack, fee1-dead): replace with min + offset = if offset < len { offset } else { len }; + // FIXME(const-hack, fee1-dead): replace with range slicing + // SAFETY: offset is within bounds + let slice = unsafe { super::from_raw_parts(text.as_ptr(), offset) }; + if let Some(index) = memchr_naive(x, slice) { return Some(index); } } @@ -110,7 +113,10 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> { // Find the byte after the point the body loop stopped. // FIXME(const-hack): Use `?` instead. - if let Some(i) = memchr_naive(x, &text[offset..]) { Some(offset + i) } else { None } + // FIXME(const-hack, fee1-dead): use range slicing + // SAFETY: offset is within bounds + let slice = unsafe { super::from_raw_parts(text.as_ptr().add(offset), text.len() - offset) }; + if let Some(i) = memchr_naive(x, slice) { Some(offset + i) } else { None } } /// Returns the last index matching the byte `x` in `text`. diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f541808a618..d12809357a8 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -333,12 +333,11 @@ impl<T> [T] { /// assert_eq!(None, v.get(0..4)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get<I>(&self, index: I) -> Option<&I::Output> + pub fn get<I>(&self, index: I) -> Option<&I::Output> where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { index.get(self) } @@ -359,12 +358,11 @@ impl<T> [T] { /// assert_eq!(x, &[0, 42, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output> + pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output> where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { index.get_mut(self) } @@ -392,12 +390,11 @@ impl<T> [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output + pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { // SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. @@ -430,12 +427,11 @@ impl<T> [T] { /// assert_eq!(x, &[1, 13, 4]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] #[must_use] - pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output + pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output where - I: ~const SliceIndex<Self>, + I: SliceIndex<Self>, { // SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. @@ -678,9 +674,8 @@ impl<T> [T] { /// assert!(v == [3, 2, 1]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_reverse", issue = "100784")] #[inline] - pub const fn reverse(&mut self) { + pub fn reverse(&mut self) { let half_len = self.len() / 2; let Range { start, end } = self.as_mut_ptr_range(); @@ -703,7 +698,7 @@ impl<T> [T] { revswap(front_half, back_half, half_len); #[inline] - const fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) { + fn revswap<T>(a: &mut [T], b: &mut [T], n: usize) { debug_assert!(a.len() == n); debug_assert!(b.len() == n); @@ -4404,8 +4399,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for &[T] { +impl<T> Default for &[T] { /// Creates an empty slice. fn default() -> Self { &[] @@ -4413,8 +4407,7 @@ impl<T> const Default for &[T] { } #[stable(feature = "mut_slice_default", since = "1.5.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for &mut [T] { +impl<T> Default for &mut [T] { /// Creates a mutable empty slice. fn default() -> Self { &mut [] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 04169429949..a13107fd0de 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -206,9 +206,8 @@ impl str { /// ``` #[must_use] #[stable(feature = "is_char_boundary", since = "1.9.0")] - #[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")] #[inline] - pub const fn is_char_boundary(&self, index: usize) -> bool { + pub fn is_char_boundary(&self, index: usize) -> bool { // 0 is always ok. // Test for 0 explicitly so that it can optimize out the check // easily and skip reading string data for that case. @@ -436,9 +435,8 @@ impl str { /// assert!(v.get(..42).is_none()); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> { + pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> { i.get(self) } @@ -469,9 +467,8 @@ impl str { /// assert_eq!("HEllo", v); /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> { + pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> { i.get_mut(self) } @@ -502,9 +499,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked<I: ~const SliceIndex<str>>(&self, i: I) -> &I::Output { + pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -538,12 +534,8 @@ impl str { /// } /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] - #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] #[inline] - pub const unsafe fn get_unchecked_mut<I: ~const SliceIndex<str>>( - &mut self, - i: I, - ) -> &mut I::Output { + pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output { // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`; // the slice is dereferenceable because `self` is a safe reference. // The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is. @@ -2582,8 +2574,7 @@ impl AsRef<[u8]> for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for &str { +impl Default for &str { /// Creates an empty str #[inline] fn default() -> Self { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 41c097b55ee..1d52335f28e 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -50,10 +50,9 @@ impl PartialOrd for str { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<I> const ops::Index<I> for str +impl<I> ops::Index<I> for str where - I: ~const SliceIndex<str>, + I: SliceIndex<str>, { type Output = I::Output; @@ -64,10 +63,9 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -impl<I> const ops::IndexMut<I> for str +impl<I> ops::IndexMut<I> for str where - I: ~const SliceIndex<str>, + I: SliceIndex<str>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -96,7 +94,7 @@ const fn str_index_overflow_fail() -> ! { /// Equivalent to `&self[0 .. len]` or `&mut self[0 .. len]`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeFull { +unsafe impl SliceIndex<str> for ops::RangeFull { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -161,7 +159,7 @@ unsafe impl const SliceIndex<str> for ops::RangeFull { /// ``` #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::Range<usize> { +unsafe impl SliceIndex<str> for ops::Range<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -271,7 +269,7 @@ unsafe impl const SliceIndex<str> for ops::Range<usize> { /// character (as defined by `is_char_boundary`), or if `end > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeTo<usize> { +unsafe impl SliceIndex<str> for ops::RangeTo<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -340,7 +338,7 @@ unsafe impl const SliceIndex<str> for ops::RangeTo<usize> { /// a character (as defined by `is_char_boundary`), or if `begin > len`. #[stable(feature = "str_checked_slicing", since = "1.20.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> { +unsafe impl SliceIndex<str> for ops::RangeFrom<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -412,7 +410,7 @@ unsafe impl const SliceIndex<str> for ops::RangeFrom<usize> { /// byte offset or equal to `len`), if `begin > end`, or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> { +unsafe impl SliceIndex<str> for ops::RangeInclusive<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { @@ -464,7 +462,7 @@ unsafe impl const SliceIndex<str> for ops::RangeInclusive<usize> { /// `is_char_boundary`, or equal to `len`), or if `end >= len`. #[stable(feature = "inclusive_range", since = "1.26.0")] #[rustc_const_unstable(feature = "const_slice_index", issue = "none")] -unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> { +unsafe impl SliceIndex<str> for ops::RangeToInclusive<usize> { type Output = str; #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 2f6b1c74da0..b0ab634905f 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -147,8 +147,7 @@ pub struct AtomicBool { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for AtomicBool { +impl Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. #[inline] fn default() -> Self { @@ -179,8 +178,7 @@ pub struct AtomicPtr<T> { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for AtomicPtr<T> { +impl<T> Default for AtomicPtr<T> { /// Creates a null `AtomicPtr<T>`. fn default() -> AtomicPtr<T> { AtomicPtr::new(crate::ptr::null_mut()) @@ -1916,8 +1914,7 @@ impl<T> AtomicPtr<T> { #[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "atomic_bool_from", since = "1.24.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl const From<bool> for AtomicBool { +impl From<bool> for AtomicBool { /// Converts a `bool` into an `AtomicBool`. /// /// # Examples @@ -1935,8 +1932,7 @@ impl const From<bool> for AtomicBool { #[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "atomic_from", since = "1.23.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<*mut T> for AtomicPtr<T> { +impl<T> From<*mut T> for AtomicPtr<T> { /// Converts a `*mut T` into an `AtomicPtr<T>`. #[inline] fn from(p: *mut T) -> Self { @@ -2002,8 +1998,7 @@ macro_rules! atomic_int { pub const $atomic_init: $atomic_type = $atomic_type::new(0); #[$stable] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl const Default for $atomic_type { + impl Default for $atomic_type { #[inline] fn default() -> Self { Self::new(Default::default()) @@ -2011,8 +2006,7 @@ macro_rules! atomic_int { } #[$stable_from] - #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")] - impl const From<$int_type> for $atomic_type { + impl From<$int_type> for $atomic_type { #[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")] #[inline] fn from(v: $int_type) -> Self { Self::new(v) } diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs index af5bf441bb2..168516263f1 100644 --- a/library/core/src/task/poll.rs +++ b/library/core/src/task/poll.rs @@ -247,8 +247,7 @@ impl<T, E> Poll<Option<Result<T, E>>> { } #[stable(feature = "futures_api", since = "1.36.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "88674")] -impl<T> const From<T> for Poll<T> { +impl<T> From<T> for Poll<T> { /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`. /// /// # Example diff --git a/library/core/src/time.rs b/library/core/src/time.rs index ba1cb6efa04..b08d5782ab6 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -735,8 +735,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f64(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { match Duration::try_from_secs_f64(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -773,8 +772,7 @@ impl Duration { #[stable(feature = "duration_float", since = "1.38.0")] #[must_use] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn from_secs_f32(secs: f32) -> Duration { + pub fn from_secs_f32(secs: f32) -> Duration { match Duration::try_from_secs_f32(secs) { Ok(v) => v, Err(e) => panic!("{}", e.description()), @@ -798,8 +796,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f64(self, rhs: f64) -> Duration { + pub fn mul_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(rhs * self.as_secs_f64()) } @@ -820,8 +817,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn mul_f32(self, rhs: f32) -> Duration { + pub fn mul_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(rhs * self.as_secs_f32()) } @@ -842,8 +838,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f64(self, rhs: f64) -> Duration { + pub fn div_f64(self, rhs: f64) -> Duration { Duration::from_secs_f64(self.as_secs_f64() / rhs) } @@ -866,8 +861,7 @@ impl Duration { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] - pub const fn div_f32(self, rhs: f32) -> Duration { + pub fn div_f32(self, rhs: f32) -> Duration { Duration::from_secs_f32(self.as_secs_f32() / rhs) } @@ -1178,7 +1172,7 @@ impl fmt::Debug for Duration { emit_without_padding(f) } else { // We need to add padding. Use the `Formatter::padding` helper function. - let default_align = crate::fmt::rt::v1::Alignment::Left; + let default_align = fmt::Alignment::Left; let post_padding = f.padding(requested_w - actual_w, default_align)?; emit_without_padding(f)?; post_padding.write(f) @@ -1402,9 +1396,8 @@ impl Duration { /// assert_eq!(res, Ok(Duration::new(1, 2_929_688))); /// ``` #[stable(feature = "duration_checked_float", since = "1.66.0")] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] #[inline] - pub const fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> { + pub fn try_from_secs_f32(secs: f32) -> Result<Duration, TryFromFloatSecsError> { try_from_secs!( secs = secs, mantissa_bits = 23, @@ -1479,9 +1472,8 @@ impl Duration { /// assert_eq!(res, Ok(Duration::new(1, 2_929_688))); /// ``` #[stable(feature = "duration_checked_float", since = "1.66.0")] - #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] #[inline] - pub const fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> { + pub fn try_from_secs_f64(secs: f64) -> Result<Duration, TryFromFloatSecsError> { try_from_secs!( secs = secs, mantissa_bits = 52, diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 0620e7173bc..75d7a3f4005 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -22,8 +22,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const PartialEq),+> const PartialEq for ($($T,)+) + impl<$($T: PartialEq),+> PartialEq for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -50,8 +49,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const PartialOrd + ~const PartialEq),+> const PartialOrd for ($($T,)+) + impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -81,8 +79,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_cmp", issue = "92391")] - impl<$($T: ~const Ord),+> const Ord for ($($T,)+) + impl<$($T: Ord),+> Ord for ($($T,)+) where last_type!($($T,)+): ?Sized { @@ -96,8 +93,7 @@ macro_rules! tuple_impls { maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] - impl<$($T: ~const Default),+> const Default for ($($T,)+) { + impl<$($T: Default),+> Default for ($($T,)+) { #[inline] fn default() -> ($($T,)+) { ($({ let x: $T = Default::default(); x},)+) diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 94b0310603b..a67a842d340 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -306,9 +306,11 @@ fn atomic_compare_exchange() { ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok(); } +/* FIXME(#110395) #[test] fn atomic_const_from() { const _ATOMIC_U8: AtomicU8 = AtomicU8::from(1); const _ATOMIC_BOOL: AtomicBool = AtomicBool::from(true); const _ATOMIC_PTR: AtomicPtr<u32> = AtomicPtr::from(core::ptr::null_mut()); } +*/ diff --git a/library/core/tests/bool.rs b/library/core/tests/bool.rs index 4819ce911d6..47f6459915b 100644 --- a/library/core/tests/bool.rs +++ b/library/core/tests/bool.rs @@ -89,6 +89,7 @@ fn test_bool_to_option() { assert_eq!(false.then(|| 0), None); assert_eq!(true.then(|| 0), Some(0)); + /* FIXME(#110395) const fn zero() -> i32 { 0 } @@ -102,4 +103,5 @@ fn test_bool_to_option() { assert_eq!(B, Some(0)); assert_eq!(C, None); assert_eq!(D, Some(0)); + */ } diff --git a/library/core/tests/cell.rs b/library/core/tests/cell.rs index 7b77b2134cc..e084f867943 100644 --- a/library/core/tests/cell.rs +++ b/library/core/tests/cell.rs @@ -468,6 +468,7 @@ fn const_cells() { const CELL: Cell<i32> = Cell::new(3); const _: i32 = CELL.into_inner(); +/* FIXME(#110395) const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3); const _: i32 = UNSAFE_CELL.into_inner(); @@ -476,4 +477,5 @@ fn const_cells() { const CELL_FROM: Cell<i32> = Cell::from(3); const _: i32 = CELL.into_inner(); +*/ } diff --git a/library/core/tests/char.rs b/library/core/tests/char.rs index ac0b2ca168b..85ba51c9228 100644 --- a/library/core/tests/char.rs +++ b/library/core/tests/char.rs @@ -21,6 +21,7 @@ fn test_convert() { assert!(char::try_from(0xFFFF_FFFF_u32).is_err()); } +/* FIXME(#110395) #[test] const fn test_convert_const() { assert!(u32::from('a') == 0x61); @@ -30,6 +31,7 @@ const fn test_convert_const() { assert!(char::from(b'a') == 'a'); assert!(char::from(b'\xFF') == '\u{FF}'); } +*/ #[test] fn test_from_str() { diff --git a/library/core/tests/cmp.rs b/library/core/tests/cmp.rs index 8d0e59d5a49..72fdd490da1 100644 --- a/library/core/tests/cmp.rs +++ b/library/core/tests/cmp.rs @@ -217,18 +217,19 @@ fn cmp_default() { assert_eq!(Fool(false), Fool(true)); } +/* FIXME(#110395) mod const_cmp { use super::*; struct S(i32); - impl const PartialEq for S { + impl PartialEq for S { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } - impl const PartialOrd for S { + impl PartialOrd for S { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { let ret = match (self.0, other.0) { (a, b) if a > b => Ordering::Greater, @@ -248,3 +249,4 @@ mod const_cmp { const _: () = assert!(S(0) < S(1)); const _: () = assert!(S(1) > S(0)); } +*/ diff --git a/library/core/tests/convert.rs b/library/core/tests/convert.rs index f1048f4cf09..f76dd277884 100644 --- a/library/core/tests/convert.rs +++ b/library/core/tests/convert.rs @@ -1,3 +1,4 @@ +/* FIXME(#110395) #[test] fn convert() { const fn from(x: i32) -> i32 { @@ -14,3 +15,4 @@ fn convert() { const BAR: Vec<String> = into(Vec::new()); assert_eq!(BAR, Vec::<String>::new()); } +*/ diff --git a/library/core/tests/hash/mod.rs b/library/core/tests/hash/mod.rs index 267245f05dc..033bd1ed6ed 100644 --- a/library/core/tests/hash/mod.rs +++ b/library/core/tests/hash/mod.rs @@ -9,13 +9,13 @@ struct MyHasher { hash: u64, } -impl const Default for MyHasher { +impl Default for MyHasher { fn default() -> MyHasher { MyHasher { hash: 0 } } } -impl const Hasher for MyHasher { +impl Hasher for MyHasher { fn write(&mut self, buf: &[u8]) { // FIXME(const_trait_impl): change to for loop let mut i = 0; @@ -35,13 +35,14 @@ impl const Hasher for MyHasher { #[test] fn test_writer_hasher() { - const fn hash<T: ~const Hash>(t: &T) -> u64 { + // FIXME(#110395) + /* const */ fn hash<T: Hash>(t: &T) -> u64 { let mut s = MyHasher { hash: 0 }; t.hash(&mut s); s.finish() } - const { + /* const { // FIXME(fee1-dead): assert_eq assert!(hash(&()) == 0); assert!(hash(&5_u8) == 5); @@ -52,7 +53,7 @@ fn test_writer_hasher() { let s: &str = "a"; assert!(hash(&s) == 97 + 0xFF); - }; + }; */ assert_eq!(hash(&()), 0); @@ -113,7 +114,7 @@ struct CustomHasher { output: u64, } -impl const Hasher for CustomHasher { +impl Hasher for CustomHasher { fn finish(&self) -> u64 { self.output } @@ -125,21 +126,22 @@ impl const Hasher for CustomHasher { } } -impl const Default for CustomHasher { +impl Default for CustomHasher { fn default() -> CustomHasher { CustomHasher { output: 0 } } } -impl const Hash for Custom { - fn hash<H: ~const Hasher>(&self, state: &mut H) { +impl Hash for Custom { + fn hash<H: Hasher>(&self, state: &mut H) { state.write_u64(self.hash); } } #[test] fn test_custom_state() { - const fn hash<T: ~const Hash>(t: &T) -> u64 { + // FIXME(#110395) + /* const */ fn hash<T: Hash>(t: &T) -> u64 { let mut c = CustomHasher { output: 0 }; t.hash(&mut c); c.finish() @@ -147,7 +149,7 @@ fn test_custom_state() { assert_eq!(hash(&Custom { hash: 5 }), 5); - const { assert!(hash(&Custom { hash: 6 }) == 6) }; + // const { assert!(hash(&Custom { hash: 6 }) == 6) }; } // FIXME: Instantiated functions with i128 in the signature is not supported in Emscripten. diff --git a/library/core/tests/hash/sip.rs b/library/core/tests/hash/sip.rs index 3abf6efcfa9..0a67c485c98 100644 --- a/library/core/tests/hash/sip.rs +++ b/library/core/tests/hash/sip.rs @@ -23,12 +23,13 @@ fn hash<T: Hash>(x: &T) -> u64 { hash_with(SipHasher::new(), x) } +/* FIXME(#110395) #[test] const fn test_const_sip() { let val1 = 0x45; let val2 = 0xfeed; - const fn const_hash<T: ~const Hash>(x: &T) -> u64 { + const fn const_hash<T: Hash>(x: &T) -> u64 { let mut st = SipHasher::new(); x.hash(&mut st); st.finish() @@ -36,6 +37,7 @@ const fn test_const_sip() { assert!(const_hash(&(val1)) != const_hash(&(val2))); } +*/ #[test] #[allow(unused_must_use)] diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs index c7c3c479b71..e2f526d155e 100644 --- a/library/core/tests/lazy.rs +++ b/library/core/tests/lazy.rs @@ -46,11 +46,13 @@ fn unsync_once_cell_drop_empty() { drop(x); } +/* FIXME(#110395) #[test] const fn once_cell_const() { let _once_cell: OnceCell<u32> = OnceCell::new(); let _once_cell: OnceCell<u32> = OnceCell::from(32); } +*/ #[test] fn clone() { diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 6cdafa411d0..84859a54c26 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -8,16 +8,13 @@ #![feature(const_assume)] #![feature(const_align_of_val_raw)] #![feature(const_black_box)] -#![feature(const_bool_to_option)] #![feature(const_caller_location)] #![feature(const_cell_into_inner)] -#![feature(const_convert)] #![feature(const_hash)] #![feature(const_heap)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_assume_init_read)] #![feature(const_nonnull_new)] -#![feature(const_num_from_num)] #![feature(const_pointer_byte_offsets)] #![feature(const_pointer_is_aligned)] #![feature(const_ptr_as_ref)] @@ -112,6 +109,7 @@ #![feature(utf8_chunks)] #![feature(is_ascii_octdigit)] #![feature(get_many_mut)] +#![cfg_attr(not(bootstrap), feature(offset_of))] #![deny(unsafe_op_in_unsafe_fn)] #![deny(fuzzy_provenance_casts)] diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index f7740a114e7..7f033816901 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -364,3 +364,193 @@ fn const_maybe_uninit() { assert_eq!(FIELD_BY_FIELD, Foo { x: 1, y: 2 }); } + +#[test] +#[cfg(not(bootstrap))] +fn offset_of() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + struct Bar(u8, u8); + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 2); + assert_eq!(offset_of!(Foo, z.0), 4); + assert_eq!(offset_of!(Foo, z.1), 5); + + // Layout of tuples is unstable + assert!(offset_of!((u8, u16), 0) <= size_of::<(u8, u16)>() - 1); + assert!(offset_of!((u8, u16), 1) <= size_of::<(u8, u16)>() - 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_union() { + #[repr(C)] + union Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + #[derive(Copy, Clone)] + struct Bar(u8, u8); + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 0); + assert_eq!(offset_of!(Foo, z.0), 0); + assert_eq!(offset_of!(Foo, z.1), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_dst() { + #[repr(C)] + struct Alpha { + x: u8, + y: u16, + z: [u8], + } + + trait Trait {} + + #[repr(C)] + struct Beta { + x: u8, + y: u16, + z: dyn Trait, + } + + extern "C" { + type Extern; + } + + #[repr(C)] + struct Gamma { + x: u8, + y: u16, + z: Extern, + } + + assert_eq!(offset_of!(Alpha, x), 0); + assert_eq!(offset_of!(Alpha, y), 2); + + assert_eq!(offset_of!(Beta, x), 0); + assert_eq!(offset_of!(Beta, y), 2); + + assert_eq!(offset_of!(Gamma, x), 0); + assert_eq!(offset_of!(Gamma, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_packed() { + #[repr(C, packed)] + struct Foo { + x: u8, + y: u16, + } + + assert_eq!(offset_of!(Foo, x), 0); + assert_eq!(offset_of!(Foo, y), 1); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_projection() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + trait Projector { + type Type; + } + + impl Projector for () { + type Type = Foo; + } + + assert_eq!(offset_of!(<() as Projector>::Type, x), 0); + assert_eq!(offset_of!(<() as Projector>::Type, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_alias() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + type Bar = Foo; + + assert_eq!(offset_of!(Bar, x), 0); + assert_eq!(offset_of!(Bar, y), 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn const_offset_of() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + } + + const X_OFFSET: usize = offset_of!(Foo, x); + const Y_OFFSET: usize = offset_of!(Foo, y); + + assert_eq!(X_OFFSET, 0); + assert_eq!(Y_OFFSET, 2); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_without_const_promotion() { + #[repr(C)] + struct Foo<SuppressConstPromotion> { + x: u8, + y: u16, + _scp: SuppressConstPromotion, + } + + // Normally, offset_of is always const promoted. + // The generic parameter prevents this from happening. + // This is needed to test the codegen impl of offset_of + fn inner<SuppressConstPromotion>() { + assert_eq!(offset_of!(Foo<SuppressConstPromotion>, x), 0); + assert_eq!(offset_of!(Foo<SuppressConstPromotion>, y), 2); + } + + inner::<()>(); +} + +#[test] +#[cfg(not(bootstrap))] +fn offset_of_addr() { + #[repr(C)] + struct Foo { + x: u8, + y: u16, + z: Bar, + } + + #[repr(C)] + struct Bar(u8, u8); + + let base = Foo { x: 0, y: 0, z: Bar(0, 0) }; + + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, x), ptr::addr_of!(base.x).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, y), ptr::addr_of!(base.y).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.0), ptr::addr_of!(base.z.0).addr()); + assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.1), ptr::addr_of!(base.z.1).addr()); +} diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index a0ca919a851..007f8442533 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -215,11 +215,13 @@ fn nonzero_const() { const ONE: Option<NonZeroU8> = NonZeroU8::new(1); assert!(ONE.is_some()); + /* FIXME(#110395) const FROM_NONZERO_U8: u8 = u8::from(NONZERO_U8); assert_eq!(FROM_NONZERO_U8, 5); const NONZERO_CONVERT: NonZeroU32 = NonZeroU32::from(NONZERO_U8); assert_eq!(NONZERO_CONVERT.get(), 5); + */ } #[test] @@ -334,3 +336,21 @@ fn test_nonzero_uint_rem() { let x: u32 = 42u32 % nz; assert_eq!(x, 2u32); } + +#[test] +fn test_signed_nonzero_neg() { + assert_eq!((-NonZeroI8::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI8::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI16::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI16::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI32::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI32::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI64::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI64::new(-1).unwrap()).get(), 1); + + assert_eq!((-NonZeroI128::new(1).unwrap()).get(), -1); + assert_eq!((-NonZeroI128::new(-1).unwrap()).get(), 1); +} diff --git a/library/core/tests/num/const_from.rs b/library/core/tests/num/const_from.rs index aca18ef39de..fa58e771879 100644 --- a/library/core/tests/num/const_from.rs +++ b/library/core/tests/num/const_from.rs @@ -1,3 +1,4 @@ +/* FIXME(#110395) #[test] fn from() { use core::convert::TryFrom; @@ -23,3 +24,4 @@ fn from() { const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16); assert_eq!(I16_FROM_U16, Ok(1i16)); } +*/ diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index dca6321cf62..5defeb50d40 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -88,6 +88,7 @@ fn test_and() { assert_eq!(x.and(Some(2)), None); assert_eq!(x.and(None::<isize>), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.and(Some(2)); const B: Option<isize> = FOO.and(None); @@ -99,6 +100,7 @@ fn test_and() { const D: Option<isize> = BAR.and(None); assert_eq!(C, None); assert_eq!(D, None); + */ } #[test] @@ -119,6 +121,7 @@ fn test_and_then() { assert_eq!(x.and_then(plus_one), None); assert_eq!(x.and_then(none), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.and_then(plus_one); const B: Option<isize> = FOO.and_then(none); @@ -130,6 +133,7 @@ fn test_and_then() { const D: Option<isize> = BAR.and_then(none); assert_eq!(C, None); assert_eq!(D, None); + */ } #[test] @@ -142,6 +146,7 @@ fn test_or() { assert_eq!(x.or(Some(2)), Some(2)); assert_eq!(x.or(None), None); + /* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.or(Some(2)); const B: Option<isize> = FOO.or(None); @@ -153,6 +158,7 @@ fn test_or() { const D: Option<isize> = BAR.or(None); assert_eq!(C, Some(2)); assert_eq!(D, None); + */ } #[test] @@ -173,6 +179,7 @@ fn test_or_else() { assert_eq!(x.or_else(two), Some(2)); assert_eq!(x.or_else(none), None); +/* FIXME(#110395) const FOO: Option<isize> = Some(1); const A: Option<isize> = FOO.or_else(two); const B: Option<isize> = FOO.or_else(none); @@ -184,6 +191,7 @@ fn test_or_else() { const D: Option<isize> = BAR.or_else(none); assert_eq!(C, Some(2)); assert_eq!(D, None); +*/ } #[test] @@ -215,10 +223,12 @@ fn test_unwrap_or() { let x: Option<isize> = None; assert_eq!(x.unwrap_or(2), 2); + /* FIXME(#110395) const A: isize = Some(1).unwrap_or(2); const B: isize = None.unwrap_or(2); assert_eq!(A, 1); assert_eq!(B, 2); + */ } #[test] @@ -233,10 +243,12 @@ fn test_unwrap_or_else() { let x: Option<isize> = None; assert_eq!(x.unwrap_or_else(two), 2); + /* FIXME(#110395) const A: isize = Some(1).unwrap_or_else(two); const B: isize = None.unwrap_or_else(two); assert_eq!(A, 1); assert_eq!(B, 2); + */ } #[test] @@ -439,14 +451,15 @@ fn option_const() { const OPTION: Option<usize> = Some(32); assert_eq!(OPTION, Some(32)); - const OPTION_FROM: Option<usize> = Option::from(32); - assert_eq!(OPTION_FROM, Some(32)); + // FIXME(#110395) + // const OPTION_FROM: Option<usize> = Option::from(32); + // assert_eq!(OPTION_FROM, Some(32)); const REF: Option<&usize> = OPTION.as_ref(); assert_eq!(REF, Some(&32)); - const REF_FROM: Option<&usize> = Option::from(&OPTION); - assert_eq!(REF_FROM, Some(&32)); + // const REF_FROM: Option<&usize> = Option::from(&OPTION); + // assert_eq!(REF_FROM, Some(&32)); const IS_SOME: bool = OPTION.is_some(); assert!(IS_SOME); @@ -474,7 +487,7 @@ const fn option_const_mut() { None => unreachable!(), } } - +/* FIXME(const-hack) { let as_mut: Option<&mut usize> = Option::from(&mut option); match as_mut { @@ -482,6 +495,7 @@ const fn option_const_mut() { None => unreachable!(), } } +*/ } #[test] diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index 2975c81f8fe..872611937cc 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -425,14 +425,16 @@ fn duration_const() { const SECONDS_F32: f32 = Duration::SECOND.as_secs_f32(); assert_eq!(SECONDS_F32, 1.0); - const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0); - assert_eq!(FROM_SECONDS_F32, Duration::SECOND); + // FIXME(#110395) + // const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0); + // assert_eq!(FROM_SECONDS_F32, Duration::SECOND); const SECONDS_F64: f64 = Duration::SECOND.as_secs_f64(); assert_eq!(SECONDS_F64, 1.0); - const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0); - assert_eq!(FROM_SECONDS_F64, Duration::SECOND); + // FIXME(#110395) + // const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0); + // assert_eq!(FROM_SECONDS_F64, Duration::SECOND); const MILLIS: u128 = Duration::SECOND.as_millis(); assert_eq!(MILLIS, 1_000); @@ -463,6 +465,7 @@ fn duration_const() { const CHECKED_MUL: Option<Duration> = Duration::SECOND.checked_mul(1); assert_eq!(CHECKED_MUL, Some(Duration::SECOND)); +/* FIXME(#110395) const MUL_F32: Duration = Duration::SECOND.mul_f32(1.0); assert_eq!(MUL_F32, Duration::SECOND); @@ -477,6 +480,7 @@ fn duration_const() { const DIV_F64: Duration = Duration::SECOND.div_f64(1.0); assert_eq!(DIV_F64, Duration::SECOND); +*/ const DIV_DURATION_F32: f32 = Duration::SECOND.div_duration_f32(Duration::SECOND); assert_eq!(DIV_DURATION_F32, 1.0); diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index 4c1e196b5ad..54b11c543f1 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -14,6 +14,7 @@ use std::hash::Hash; use std::marker; use std::mem; use std::ops::Bound; +use std::ops::Range; use std::panic; use std::sync::atomic::AtomicUsize; use std::sync::Once; @@ -93,6 +94,7 @@ macro_rules! with_api { fn source_file($self: $S::Span) -> $S::SourceFile; fn parent($self: $S::Span) -> Option<$S::Span>; fn source($self: $S::Span) -> $S::Span; + fn byte_range($self: $S::Span) -> Range<usize>; fn start($self: $S::Span) -> LineColumn; fn end($self: $S::Span) -> LineColumn; fn before($self: $S::Span) -> $S::Span; @@ -519,3 +521,7 @@ pub struct ExpnGlobals<Span> { compound_traits!( struct ExpnGlobals<Span> { def_site, call_site, mixed_site } ); + +compound_traits!( + struct Range<T> { start, end } +); diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 9d081c8b842..c64665b6ae0 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -44,7 +44,7 @@ mod diagnostic; pub use diagnostic::{Diagnostic, Level, MultiSpan}; use std::cmp::Ordering; -use std::ops::RangeBounds; +use std::ops::{Range, RangeBounds}; use std::path::PathBuf; use std::str::FromStr; use std::{error, fmt}; @@ -488,6 +488,12 @@ impl Span { Span(self.0.source()) } + /// Returns the span's byte position range in the source file. + #[unstable(feature = "proc_macro_span", issue = "54725")] + pub fn byte_range(&self) -> Range<usize> { + self.0.byte_range() + } + /// Gets the starting line/column in the source file for this span. #[unstable(feature = "proc_macro_span", issue = "54725")] pub fn start(&self) -> LineColumn { diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 96c75f97f6e..109387b09d0 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -23,11 +23,11 @@ hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep std_detect = { path = "../stdarch/crates/std_detect", default-features = false, features = ['rustc-dep-of-std'] } # Dependencies of the `backtrace` crate -addr2line = { version = "0.17.0", optional = true, default-features = false } +addr2line = { version = "0.19.0", optional = true, default-features = false } rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] } -miniz_oxide = { version = "0.5.0", optional = true, default-features = false } +miniz_oxide = { version = "0.6.0", optional = true, default-features = false } [dependencies.object] -version = "0.29.0" +version = "0.30.0" optional = true default-features = false features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] @@ -67,7 +67,7 @@ llvm-libunwind = ["unwind/llvm-libunwind"] system-llvm-libunwind = ["unwind/system-llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message -panic_immediate_abort = ["core/panic_immediate_abort"] +panic_immediate_abort = ["alloc/panic_immediate_abort"] # Enable std_detect default features for stdarch/crates/std_detect: # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index c5a5991cc81..448a8edc291 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -57,9 +57,8 @@ #![stable(feature = "alloc_module", since = "1.28.0")] use core::intrinsics; +use core::ptr; use core::ptr::NonNull; -use core::sync::atomic::{AtomicPtr, Ordering}; -use core::{mem, ptr}; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] @@ -286,76 +285,6 @@ unsafe impl Allocator for System { } } -static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); - -/// Registers a custom allocation error hook, replacing any that was previously registered. -/// -/// The allocation error hook is invoked when an infallible memory allocation fails, before -/// the runtime aborts. The default hook prints a message to standard error, -/// but this behavior can be customized with the [`set_alloc_error_hook`] and -/// [`take_alloc_error_hook`] functions. -/// -/// The hook is provided with a `Layout` struct which contains information -/// about the allocation that failed. -/// -/// The allocation error hook is a global resource. -/// -/// # Examples -/// -/// ``` -/// #![feature(alloc_error_hook)] -/// -/// use std::alloc::{Layout, set_alloc_error_hook}; -/// -/// fn custom_alloc_error_hook(layout: Layout) { -/// panic!("memory allocation of {} bytes failed", layout.size()); -/// } -/// -/// set_alloc_error_hook(custom_alloc_error_hook); -/// ``` -#[unstable(feature = "alloc_error_hook", issue = "51245")] -pub fn set_alloc_error_hook(hook: fn(Layout)) { - HOOK.store(hook as *mut (), Ordering::SeqCst); -} - -/// Unregisters the current allocation error hook, returning it. -/// -/// *See also the function [`set_alloc_error_hook`].* -/// -/// If no custom hook is registered, the default hook will be returned. -#[unstable(feature = "alloc_error_hook", issue = "51245")] -pub fn take_alloc_error_hook() -> fn(Layout) { - let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); - if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } } -} - -fn default_alloc_error_hook(layout: Layout) { - extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. - static __rust_alloc_error_handler_should_panic: u8; - } - - #[allow(unused_unsafe)] - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { - panic!("memory allocation of {} bytes failed", layout.size()); - } else { - rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); - } -} - -#[cfg(not(test))] -#[doc(hidden)] -#[alloc_error_handler] -#[unstable(feature = "alloc_internals", issue = "none")] -pub fn rust_oom(layout: Layout) -> ! { - let hook = HOOK.load(Ordering::SeqCst); - let hook: fn(Layout) = - if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }; - hook(layout); - crate::process::abort() -} - #[cfg(not(test))] #[doc(hidden)] #[allow(unused_attributes)] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 3afc8287ecc..c722bad2e4f 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -3168,8 +3168,7 @@ impl DefaultHasher { } #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const Default for DefaultHasher { +impl Default for DefaultHasher { /// Creates a new `DefaultHasher` using [`new`]. /// See its documentation for more. /// @@ -3181,8 +3180,7 @@ impl const Default for DefaultHasher { } #[stable(feature = "hashmap_default_hasher", since = "1.13.0")] -#[rustc_const_unstable(feature = "const_hash", issue = "104061")] -impl const Hasher for DefaultHasher { +impl Hasher for DefaultHasher { // The underlying `SipHasher13` doesn't override the other // `write_*` methods, so it's ok not to forward them here. diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c550378e7d6..55580b23a62 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -249,9 +249,9 @@ pub struct DirBuilder { pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { fn inner(path: &Path) -> io::Result<Vec<u8>> { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut bytes = Vec::with_capacity(size as usize); - io::default_read_to_end(&mut file, &mut bytes)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut bytes = Vec::with_capacity(size.unwrap_or(0)); + io::default_read_to_end(&mut file, &mut bytes, size)?; Ok(bytes) } inner(path.as_ref()) @@ -289,9 +289,9 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> { pub fn read_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> { fn inner(path: &Path) -> io::Result<String> { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut string = String::with_capacity(size as usize); - io::default_read_to_string(&mut file, &mut string)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut string = String::with_capacity(size.unwrap_or(0)); + io::default_read_to_string(&mut file, &mut string, size)?; Ok(string) } inner(path.as_ref()) @@ -732,12 +732,12 @@ impl fmt::Debug for File { } /// Indicates how much extra capacity is needed to read the rest of the file. -fn buffer_capacity_required(mut file: &File) -> usize { - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let pos = file.stream_position().unwrap_or(0); +fn buffer_capacity_required(mut file: &File) -> Option<usize> { + let size = file.metadata().map(|m| m.len()).ok()?; + let pos = file.stream_position().ok()?; // Don't worry about `usize` overflow because reading will fail regardless // in that case. - size.saturating_sub(pos) as usize + Some(size.saturating_sub(pos) as usize) } #[stable(feature = "rust1", since = "1.0.0")] @@ -761,14 +761,16 @@ impl Read for File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -817,14 +819,16 @@ impl Read for &File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs index e5048dcc8ac..a7428776d8f 100644 --- a/library/std/src/io/impls.rs +++ b/library/std/src/io/impls.rs @@ -9,6 +9,7 @@ use crate::io::{ self, BorrowedCursor, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, Seek, SeekFrom, Write, }; use crate::mem; +use crate::str; // ============================================================================= // Forwarding implementations @@ -307,6 +308,17 @@ impl Read for &[u8] { *self = &self[len..]; Ok(len) } + + #[inline] + fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { + let content = str::from_utf8(self).map_err(|_| { + io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") + })?; + buf.push_str(content); + let len = self.len(); + *self = &self[len..]; + Ok(len) + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -336,7 +348,7 @@ impl Write for &mut [u8] { #[inline] fn write(&mut self, data: &[u8]) -> io::Result<usize> { let amt = cmp::min(data.len(), self.len()); - let (a, b) = mem::replace(self, &mut []).split_at_mut(amt); + let (a, b) = mem::take(self).split_at_mut(amt); a.copy_from_slice(&data[..amt]); *self = b; Ok(amt) @@ -434,6 +446,33 @@ impl<A: Allocator> Read for VecDeque<u8, A> { self.drain(..n); Ok(()) } + + #[inline] + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { + // The total len is known upfront so we can reserve it in a single call. + let len = self.len(); + buf.reserve(len); + + let (front, back) = self.as_slices(); + buf.extend_from_slice(front); + buf.extend_from_slice(back); + self.clear(); + Ok(len) + } + + #[inline] + fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { + // We have to use a single contiguous slice because the `VecDequeue` might be split in the + // middle of an UTF-8 character. + let len = self.len(); + let content = self.make_contiguous(); + let string = str::from_utf8(content).map_err(|_| { + io::const_io_error!(ErrorKind::InvalidData, "stream did not contain valid UTF-8") + })?; + buf.push_str(string); + self.clear(); + Ok(len) + } } /// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed. @@ -446,6 +485,21 @@ impl<A: Allocator> Write for VecDeque<u8, A> { } #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let len = bufs.iter().map(|b| b.len()).sum(); + self.reserve(len); + for buf in bufs { + self.extend(&**buf); + } + Ok(len) + } + + #[inline] + fn is_write_vectored(&self) -> bool { + true + } + + #[inline] fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { self.extend(buf); Ok(()) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 020c723925a..4cd7885bd4a 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -253,7 +253,7 @@ mod tests; use crate::cmp; use crate::fmt; -use crate::mem::replace; +use crate::mem::take; use crate::ops::{Deref, DerefMut}; use crate::slice; use crate::str; @@ -357,9 +357,17 @@ where // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every // time is 4,500 times (!) slower than a default reservation size of 32 if the // reader has a very small amount of data to return. -pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> { +pub(crate) fn default_read_to_end<R: Read + ?Sized>( + r: &mut R, + buf: &mut Vec<u8>, + size_hint: Option<usize>, +) -> Result<usize> { let start_len = buf.len(); let start_cap = buf.capacity(); + // Optionally limit the maximum bytes read on each iteration. + // This adds an arbitrary fiddle factor to allow for more data than we expect. + let max_read_size = + size_hint.and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE)); let mut initialized = 0; // Extra initialized bytes from previous loop iteration loop { @@ -367,7 +375,12 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8> buf.reserve(32); // buf is full, need more space } - let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into(); + let mut spare = buf.spare_capacity_mut(); + if let Some(size) = max_read_size { + let len = cmp::min(spare.len(), size); + spare = &mut spare[..len] + } + let mut read_buf: BorrowedBuf<'_> = spare.into(); // SAFETY: These bytes were initialized but not filled in the previous loop unsafe { @@ -419,6 +432,7 @@ pub(crate) fn default_read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8> pub(crate) fn default_read_to_string<R: Read + ?Sized>( r: &mut R, buf: &mut String, + size_hint: Option<usize>, ) -> Result<usize> { // Note that we do *not* call `r.read_to_end()` here. We are passing // `&mut Vec<u8>` (the raw contents of `buf`) into the `read_to_end` @@ -429,7 +443,7 @@ pub(crate) fn default_read_to_string<R: Read + ?Sized>( // To prevent extraneously checking the UTF-8-ness of the entire buffer // we pass it to our hardcoded `default_read_to_end` implementation which // we know is guaranteed to only read data into the end of the buffer. - unsafe { append_to_string(buf, |b| default_read_to_end(r, b)) } + unsafe { append_to_string(buf, |b| default_read_to_end(r, b, size_hint)) } } pub(crate) fn default_read_vectored<F>(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> @@ -709,7 +723,7 @@ pub trait Read { /// [`std::fs::read`]: crate::fs::read #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { - default_read_to_end(self, buf) + default_read_to_end(self, buf, None) } /// Read all bytes until EOF in this source, appending them to `buf`. @@ -752,7 +766,7 @@ pub trait Read { /// [`std::fs::read_to_string`]: crate::fs::read_to_string #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result<usize> { - default_read_to_string(self, buf) + default_read_to_string(self, buf, None) } /// Read the exact number of bytes required to fill `buf`. @@ -1186,7 +1200,7 @@ impl<'a> IoSliceMut<'a> { } } - *bufs = &mut replace(bufs, &mut [])[remove..]; + *bufs = &mut take(bufs)[remove..]; if bufs.is_empty() { assert!(n == accumulated_len, "advancing io slices beyond their length"); } else { @@ -1329,7 +1343,7 @@ impl<'a> IoSlice<'a> { } } - *bufs = &mut replace(bufs, &mut [])[remove..]; + *bufs = &mut take(bufs)[remove..]; if bufs.is_empty() { assert!(n == accumulated_len, "advancing io slices beyond their length"); } else { diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index f4a886d889a..6d30f5e6c6c 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -314,7 +314,7 @@ fn bench_read_to_end(b: &mut test::Bencher) { b.iter(|| { let mut lr = repeat(1).take(10000000); let mut vec = Vec::with_capacity(1024); - super::default_read_to_end(&mut lr, &mut vec) + super::default_read_to_end(&mut lr, &mut vec, None) }); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 98fcc76aa98..933f75d638b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -236,7 +236,6 @@ // // Language features: // tidy-alphabetical-start -#![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] @@ -289,6 +288,7 @@ #![feature(float_next_up_down)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(int_roundings)] #![feature(ip)] #![feature(ip_in_core)] #![feature(maybe_uninit_slice)] @@ -319,6 +319,7 @@ #![feature(get_mut_unchecked)] #![feature(map_try_insert)] #![feature(new_uninit)] +#![feature(panic_oom_payload)] #![feature(slice_concat_trait)] #![feature(thin_box)] #![feature(try_reserve_kind)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a46a29cbad6..ca4cf68ad54 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -245,19 +245,24 @@ fn default_hook(info: &PanicInfo<'_>) { // The current implementation always returns `Some`. let location = info.location().unwrap(); - - let msg = match info.payload().downcast_ref::<&'static str>() { - Some(s) => *s, - None => match info.payload().downcast_ref::<String>() { - Some(s) => &s[..], - None => "Box<dyn Any>", - }, - }; let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>"); let write = |err: &mut dyn crate::io::Write| { - let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + // Use the panic message directly if available, otherwise take it from + // the payload. + if let Some(msg) = info.message() { + let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + } else { + let msg = if let Some(s) = info.payload().downcast_ref::<&'static str>() { + *s + } else if let Some(s) = info.payload().downcast_ref::<String>() { + &s[..] + } else { + "Box<dyn Any>" + }; + let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + } static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -524,6 +529,8 @@ pub fn panicking() -> bool { #[cfg(not(test))] #[panic_handler] pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { + use alloc::alloc::AllocErrorPanicPayload; + struct PanicPayload<'a> { inner: &'a fmt::Arguments<'a>, string: Option<String>, @@ -550,8 +557,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn take_box(&mut self) -> *mut (dyn Any + Send) { // We do two allocations here, unfortunately. But (a) they're required with the current - // scheme, and (b) we don't handle panic + OOM properly anyway (see comment in - // begin_panic below). + // scheme, and (b) OOM uses its own separate payload type which doesn't allocate. let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } @@ -576,7 +582,14 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { let loc = info.location().unwrap(); // The current implementation always returns Some let msg = info.message().unwrap(); // The current implementation always returns Some crate::sys_common::backtrace::__rust_end_short_backtrace(move || { - if let Some(msg) = msg.as_str() { + if let Some(payload) = info.payload().downcast_ref::<AllocErrorPanicPayload>() { + rust_panic_with_hook( + &mut payload.internal_clone(), + info.message(), + loc, + info.can_unwind(), + ); + } else if let Some(msg) = msg.as_str() { rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind()); } else { rust_panic_with_hook( @@ -623,11 +636,7 @@ pub const fn begin_panic<M: Any + Send>(msg: M) -> ! { unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> { fn take_box(&mut self) -> *mut (dyn Any + Send) { - // Note that this should be the only allocation performed in this code path. Currently - // this means that panic!() on OOM will invoke this code path, but then again we're not - // really ready for panic on OOM anyway. If we do start doing this, then we should - // propagate this allocation to be performed in the parent of this thread instead of the - // thread that's panicking. + // Note that this should be the only allocation performed in this code path. let data = match self.inner.take() { Some(a) => Box::new(a) as Box<dyn Any + Send>, None => process::abort(), diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 2aefd7c513d..4f325a70b18 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -60,9 +60,7 @@ pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -pub use core::prelude::v1::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, -}; +pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case}; #[unstable(feature = "derive_const", issue = "none")] pub use core::prelude::v1::derive_const; diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index 8c34375ea07..36951c4f13e 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -344,8 +344,7 @@ impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceLock<T> {} impl<T: UnwindSafe> UnwindSafe for OnceLock<T> {} #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for OnceLock<T> { +impl<T> Default for OnceLock<T> { /// Creates a new empty cell. /// /// # Example diff --git a/library/std/src/sys/unsupported/io.rs b/library/std/src/sys/unsupported/io.rs index 82610ffab7e..6372fca74e0 100644 --- a/library/std/src/sys/unsupported/io.rs +++ b/library/std/src/sys/unsupported/io.rs @@ -30,7 +30,7 @@ impl<'a> IoSliceMut<'a> { #[inline] pub fn advance(&mut self, n: usize) { - let slice = mem::replace(&mut self.0, &mut []); + let slice = mem::take(&mut self.0); let (_, remaining) = slice.split_at_mut(n); self.0 = remaining; } diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index a158d1f718e..19d67e80a61 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -374,9 +374,9 @@ checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "3f508063cc7bb32987c71511216bd5a32be15bccb6a80b52df8b9d7f01fc3aa2" [[package]] name = "log" diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 0f3a9f96826..680a8da6adf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -575,7 +575,7 @@ class RustBuild(object): ] patchelf_args = ["--set-rpath", ":".join(rpath_entries)] if not fname.endswith(".so"): - # Finally, set the corret .interp for binaries + # Finally, set the correct .interp for binaries with open("{}/nix-support/dynamic-linker".format(nix_deps_dir)) as dynamic_linker: patchelf_args += ["--set-interpreter", dynamic_linker.read().rstrip()] @@ -722,11 +722,14 @@ class RustBuild(object): def build_bootstrap(self, color, verbose_count): """Build bootstrap""" - print("Building bootstrap") + env = os.environ.copy() + if "GITHUB_ACTIONS" in env: + print("::group::Building bootstrap") + else: + print("Building bootstrap") build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) - env = os.environ.copy() # `CARGO_BUILD_TARGET` breaks bootstrap build. # See also: <https://github.com/rust-lang/rust/issues/70208>. if "CARGO_BUILD_TARGET" in env: @@ -798,6 +801,9 @@ class RustBuild(object): # Run this from the source directory so cargo finds .cargo/config run(args, env=env, verbose=self.verbose, cwd=self.rust_root) + if "GITHUB_ACTIONS" in env: + print("::endgroup::") + def build_triple(self): """Build triple as in LLVM diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py index 20bd71f06e9..26bd80a008f 100644 --- a/src/bootstrap/bootstrap_test.py +++ b/src/bootstrap/bootstrap_test.py @@ -97,6 +97,7 @@ class GenerateAndParseConfig(unittest.TestCase): def test_no_args(self): build = self.serialize_and_parse([]) self.assertEqual(build.get_toml("changelog-seen"), '2') + self.assertEqual(build.get_toml("profile"), 'user') self.assertIsNone(build.get_toml("llvm.download-ci-llvm")) def test_set_section(self): @@ -107,10 +108,9 @@ class GenerateAndParseConfig(unittest.TestCase): build = self.serialize_and_parse(["--set", "target.x86_64-unknown-linux-gnu.cc=gcc"]) self.assertEqual(build.get_toml("cc", section="target.x86_64-unknown-linux-gnu"), 'gcc') - # Uncomment when #108928 is fixed. - # def test_set_top_level(self): - # build = self.serialize_and_parse(["--set", "profile=compiler"]) - # self.assertEqual(build.get_toml("profile"), 'compiler') + def test_set_top_level(self): + build = self.serialize_and_parse(["--set", "profile=compiler"]) + self.assertEqual(build.get_toml("profile"), 'compiler') if __name__ == '__main__': SUITE = unittest.TestSuite() diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 9666874d0fe..0d2d512b4b2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1399,7 +1399,7 @@ impl<'a> Builder<'a> { // Add extra cfg not defined in/by rustc // - // Note: Altrough it would seems that "-Zunstable-options" to `rustflags` is useless as + // Note: Although it would seems that "-Zunstable-options" to `rustflags` is useless as // cargo would implicitly add it, it was discover that sometimes bootstrap only use // `rustflags` without `cargo` making it required. rustflags.arg("-Zunstable-options"); @@ -1589,8 +1589,8 @@ impl<'a> Builder<'a> { // which adds to the runtime dynamic loader path when looking for // dynamic libraries. We use this by default on Unix platforms to ensure // that our nightlies behave the same on Windows, that is they work out - // of the box. This can be disabled, of course, but basically that's why - // we're gated on RUSTC_RPATH here. + // of the box. This can be disabled by setting `rpath = false` in `[rust]` + // table of `config.toml` // // Ok, so the astute might be wondering "why isn't `-C rpath` used // here?" and that is indeed a good question to ask. This codegen diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index c3e3fa009a6..87018574048 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -22,7 +22,7 @@ pub enum GitInfo { /// If the info should be used (`omit_git_hash` is false), this will be /// `Some`, otherwise it will be `None`. Present(Option<Info>), - /// This is not a git repostory, but the info can be fetched from the + /// This is not a git repository, but the info can be fetched from the /// `git-commit-info` file. RecordedForTarball(Info), } diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 44efc502e39..60de46ce64c 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -105,15 +105,7 @@ impl Step for Std { cargo.arg("--lib"); } - let msg = if compiler.host == target { - format!("Checking stage{} library artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} library artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library artifacts", target); run_cargo( builder, cargo, @@ -167,18 +159,7 @@ impl Step for Std { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!( - "Checking stage{} library test/bench/example targets ({target})", - builder.top_stage - ) - } else { - format!( - "Checking stage{} library test/bench/example targets ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library test/bench/example targets", target); run_cargo( builder, cargo, @@ -252,15 +233,7 @@ impl Step for Rustc { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!("Checking stage{} compiler artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} compiler artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("compiler artifacts", target); run_cargo( builder, cargo, @@ -317,15 +290,7 @@ impl Step for CodegenBackend { .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); rustc_cargo_env(builder, &mut cargo, target, compiler.stage); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend) - } else { - format!( - "Checking stage{} {} library ({} -> {})", - builder.top_stage, backend, &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&backend, target); run_cargo( builder, @@ -385,15 +350,7 @@ impl Step for RustAnalyzer { cargo.arg("--benches"); } - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", compiler.stage, "rust-analyzer") - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("rust-analyzer artifacts", target); run_cargo( builder, cargo, @@ -460,18 +417,7 @@ macro_rules! tool_check_step { // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 cargo.rustflag("-Zunstable-options"); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, stringify!($name).to_lowercase()) - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - builder.top_stage, - stringify!($name).to_lowercase(), - &compiler.host.triple, - target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target); run_cargo( builder, cargo, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8af5927e27f..7d2a6862500 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -143,23 +143,13 @@ impl Step for Std { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} stage{} library artifacts ({}) ", - crate_description(&self.crates), - compiler.stage, - compiler.host - ) - } else { - format!( - "Building{} stage{} library artifacts ({} -> {})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg( + Kind::Build, + compiler.stage, + format_args!("library artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -790,24 +780,13 @@ impl Step for Rustc { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} compiler artifacts (stage{} -> stage{})", - crate_description(&self.crates), - compiler.stage, - compiler.stage + 1 - ) - } else { - format!( - "Building{} compiler artifacts (stage{}:{} -> stage{}:{})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - compiler.stage + 1, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg_sysroot_tool( + Kind::Build, + compiler.stage, + format_args!("compiler artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -1114,15 +1093,7 @@ impl Step for CodegenBackend { let tmp_stamp = out_dir.join(".tmp.stamp"); - let msg = if compiler.host == target { - format!("Building stage{} codegen backend {}", compiler.stage, backend) - } else { - format!( - "Building stage{} codegen backend {} ({} -> {})", - compiler.stage, backend, compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target); let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false); if builder.config.dry_run() { return; @@ -1328,7 +1299,6 @@ impl Step for Sysroot { true } }); - return INTERNER.intern_path(sysroot); } // Symlink the source root into the same location inside the sysroot, diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index abd28b4005d..f95a97518c5 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -417,6 +417,8 @@ def parse_example_config(known_args, config): # Avoid using quotes unless it's necessary. targets[target][0] = targets[target][0].replace("x86_64-unknown-linux-gnu", "'{}'".format(target) if "." in target else target) + if 'profile' not in config: + set('profile', 'user', config) configure_file(sections, top_level_keys, targets, config) return section_order, sections, targets @@ -475,7 +477,7 @@ def configure_section(lines, config): def configure_top_level_key(lines, top_level_key, value): for i, line in enumerate(lines): if line.startswith('#' + top_level_key + ' = ') or line.startswith(top_level_key + ' = '): - lines[i] = "{} = {}".format(top_level_key, value) + lines[i] = "{} = {}".format(top_level_key, to_toml(value)) return raise RuntimeError("failed to find config line for {}".format(top_level_key)) @@ -521,8 +523,14 @@ def write_config_toml(writer, section_order, targets, sections): else: writer = write_uncommented(sections[section], writer) +def quit_if_file_exists(file): + if os.path.isfile(file): + err("Existing '" + file + "' detected.") if __name__ == "__main__": + # If 'config.toml' already exists, exit the script at this point + quit_if_file_exists('config.toml') + p("processing command line") # Parse all known arguments into a configuration structure that reflects the # TOML we're going to write out diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 372d0708c5b..3b35ca1d15d 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1965,20 +1965,6 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir } } - // FIXME: for reasons I don't understand, the LLVM so in the `rustc` component is different than the one in `rust-dev`. - // Only the one in `rustc` works with the downloaded compiler. - if builder.download_rustc() && target == builder.build.build { - let src_libdir = builder.ci_rustc_dir(target).join("lib"); - for entry in t!(std::fs::read_dir(&src_libdir)) { - let entry = t!(entry); - if entry.file_name().to_str().unwrap().starts_with("libLLVM-") { - install_llvm_file(builder, &entry.path(), dst_libdir); - return !builder.config.dry_run(); - } - } - panic!("libLLVM.so not found in src_libdir {}!", src_libdir.display()); - } - // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely // clear why this is the case, though. llvm-config will emit the versioned diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index b79969663ca..d8d3f300a35 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -145,10 +145,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let untracked_paths = untracked_paths_output .lines() .filter(|entry| entry.starts_with("??")) - .filter_map(|entry| { - let path = - entry.split(' ').nth(1).expect("every git status entry should list a path"); - path.ends_with(".rs").then_some(path) + .map(|entry| { + entry.split(' ').nth(1).expect("every git status entry should list a path") }); for untracked_path in untracked_paths { println!("skip untracked path {} during rustfmt invocations", untracked_path); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 42d895a3413..b62aa999246 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -12,7 +12,7 @@ use crate::util::t; use crate::dist; use crate::tarball::GeneratedTarball; -use crate::Compiler; +use crate::{Compiler, Kind}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::{Config, TargetSelection}; @@ -52,7 +52,7 @@ fn install_sh( host: Option<TargetSelection>, tarball: &GeneratedTarball, ) { - builder.info(&format!("Install {} stage{} ({:?})", package, stage, host)); + let _guard = builder.msg(Kind::Install, stage, package, host, host); let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bfdb029951f..238d167c4c2 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -19,13 +19,14 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; +use std::fmt::Display; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; -use build_helper::ci::CiEnv; +use build_helper::ci::{gha, CiEnv}; use channel::GitInfo; use config::{DryRun, Target}; use filetime::FileTime; @@ -993,6 +994,85 @@ impl Build { } } + fn msg_check( + &self, + what: impl Display, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + self.msg(Kind::Check, self.config.stage, what, self.config.build, target) + } + + fn msg_build( + &self, + compiler: Compiler, + what: impl Display, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + self.msg(Kind::Build, compiler.stage, what, compiler.host, target) + } + + /// Return a `Group` guard for a [`Step`] that is built for each `--stage`. + fn msg( + &self, + action: impl Into<Kind>, + stage: u32, + what: impl Display, + host: impl Into<Option<TargetSelection>>, + target: impl Into<Option<TargetSelection>>, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing stage{stage} {what}{fmt}"); + let msg = if let Some(target) = target.into() { + let host = host.into().unwrap(); + if host == target { + msg(format_args!(" ({target})")) + } else { + msg(format_args!(" ({host} -> {target})")) + } + } else { + msg(format_args!("")) + }; + self.group(&msg) + } + + /// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`. + fn msg_unstaged( + &self, + action: impl Into<Kind>, + what: impl Display, + target: TargetSelection, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = format!("{action:?}ing {what} for {target}"); + self.group(&msg) + } + + fn msg_sysroot_tool( + &self, + action: impl Into<Kind>, + stage: u32, + what: impl Display, + host: TargetSelection, + target: TargetSelection, + ) -> Option<gha::Group> { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing {what} {fmt}"); + let msg = if host == target { + msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1)) + } else { + msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1)) + }; + self.group(&msg) + } + + fn group(&self, msg: &str) -> Option<gha::Group> { + self.info(&msg); + match self.config.dry_run { + DryRun::SelfCheck => None, + DryRun::Disabled | DryRun::UserSelected => Some(gha::group(&msg)), + } + } + /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index a893c3a47c9..67cb8837391 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -21,7 +21,7 @@ use crate::channel; use crate::config::{Config, TargetSelection}; use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; -use crate::{CLang, GitRepo}; +use crate::{CLang, GitRepo, Kind}; use build_helper::ci::CiEnv; @@ -271,7 +271,7 @@ impl Step for Llvm { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } - builder.info(&format!("Building LLVM for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLVM", target); t!(stamp.remove()); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -813,7 +813,7 @@ impl Step for Lld { return out_dir; } - builder.info(&format!("Building LLD for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLD", target); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -911,7 +911,7 @@ impl Step for Sanitizers { return runtimes; } - builder.info(&format!("Building sanitizers for {}", self.target)); + let _guard = builder.msg_unstaged(Kind::Build, "sanitizers", self.target); t!(stamp.remove()); let _time = util::timeit(&builder); @@ -1103,7 +1103,7 @@ impl Step for CrtBeginEnd { return out_dir; } - builder.info("Building crtbegin.o and crtend.o"); + let _guard = builder.msg_unstaged(Kind::Build, "crtbegin.o and crtend.o", self.target); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); @@ -1153,7 +1153,7 @@ impl Step for Libunwind { run.builder.ensure(Libunwind { target: run.target }); } - /// Build linunwind.a + /// Build libunwind.a fn run(self, builder: &Builder<'_>) -> Self::Output { builder.update_submodule(&Path::new("src/llvm-project")); @@ -1168,7 +1168,7 @@ impl Step for Libunwind { return out_dir; } - builder.info(&format!("Building libunwind.a for {}", self.target.triple)); + let _guard = builder.msg_unstaged(Kind::Build, "libunwind.a", self.target); t!(fs::create_dir_all(&out_dir)); let mut cc_cfg = cc::Build::new(); diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index a56db9cccfe..bedf34d89e8 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -1,7 +1,7 @@ //! This module renders the JSON output of libtest into a human-readable form, trying to be as //! similar to libtest's native output as possible. //! -//! This is needed because we need to use libtest in JSON mode to extract granluar information +//! This is needed because we need to use libtest in JSON mode to extract granular information //! about the executed tests. Doing so suppresses the human-readable output, and (compared to Cargo //! and rustc) libtest doesn't include the rendered human-readable output as a JSON field. We had //! to reimplement all the rendering logic in this module because of that. diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 8a40b0f64f4..140259b0213 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -100,7 +100,7 @@ pub fn check(build: &mut Build) { Couldn't find required command: cmake You should install cmake, or set `download-ci-llvm = true` in the -`[llvm]` section section of `config.toml` to download LLVM rather +`[llvm]` section of `config.toml` to download LLVM rather than building it. " ); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ccf83974b8c..601351ea8e3 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -5,7 +5,6 @@ use std::env; use std::ffi::OsString; -use std::fmt; use std::fs; use std::iter; use std::path::{Path, PathBuf}; @@ -57,12 +56,12 @@ impl TestKind { } } -impl fmt::Display for TestKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match *self { - TestKind::Test => "Testing", - TestKind::Bench => "Benchmarking", - }) +impl Into<Kind> for TestKind { + fn into(self) -> Kind { + match self { + TestKind::Test => Kind::Test, + TestKind::Bench => Kind::Bench, + } } } @@ -1905,7 +1904,13 @@ impl BookTest { rustbook_cmd.env("RUSTC_BOOTSTRAP", "1"); rustbook_cmd.env("PATH", new_path).arg("test").arg(path); builder.add_rust_test_threads(&mut rustbook_cmd); - builder.info(&format!("Testing rustbook {}", self.path.display())); + let _guard = builder.msg( + Kind::Test, + compiler.stage, + format_args!("rustbook {}", self.path.display()), + compiler.host, + compiler.host, + ); let _time = util::timeit(&builder); let toolstate = if try_run(builder, &mut rustbook_cmd) { ToolState::TestPass @@ -2033,7 +2038,8 @@ impl Step for ErrorIndex { let mut tool = tool::ErrorIndex::command(builder); tool.arg("markdown").arg(&output); - builder.info(&format!("Testing error-index stage{}", compiler.stage)); + let _guard = + builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = util::timeit(&builder); builder.run_quiet(&mut tool); // The tests themselves need to link to std, so make sure it is @@ -2263,14 +2269,13 @@ impl Step for Crate { ); } - builder.info(&format!( - "{}{} stage{} ({} -> {})", + let _guard = builder.msg( test_kind, - crate_description(&self.crates), compiler.stage, - &compiler.host, - target - )); + crate_description(&self.crates), + compiler.host, + target, + ); let _time = util::timeit(&builder); crate::render_tests::try_run_tests(builder, &mut cargo.into()); } @@ -2386,10 +2391,8 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } - builder.info(&format!( - "{} rustdoc stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = builder.msg(test_kind, compiler.stage, "rustdoc", compiler.host, target); + let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2453,10 +2456,8 @@ impl Step for CrateRustdocJsonTypes { cargo.arg("'-Ctarget-feature=-crt-static'"); } - builder.info(&format!( - "{} rustdoc-json-types stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = + builder.msg(test_kind, compiler.stage, "rustdoc-json-types", compiler.host, target); let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2845,7 +2846,7 @@ impl Step for TestHelpers { return; } - builder.info("Building test helpers"); + let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target); t!(fs::create_dir_all(&dst)); let mut cfg = cc::Build::new(); // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 79eec6f848c..f3724b2c0e4 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -11,6 +11,7 @@ use crate::toolstate::ToolState; use crate::util::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; +use crate::{gha, Kind}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum SourceType { @@ -32,41 +33,27 @@ struct ToolBuild { allow_features: &'static str, } -fn tooling_output( - mode: Mode, - tool: &str, - build_stage: u32, - host: &TargetSelection, - target: &TargetSelection, -) -> String { - match mode { - // depends on compiler stage, different to host compiler - Mode::ToolRustc => { - if host == target { - format!("Building tool {} (stage{} -> stage{})", tool, build_stage, build_stage + 1) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, - build_stage, - host, - build_stage + 1, - target - ) - } +impl Builder<'_> { + fn msg_tool( + &self, + mode: Mode, + tool: &str, + build_stage: u32, + host: &TargetSelection, + target: &TargetSelection, + ) -> Option<gha::Group> { + match mode { + // depends on compiler stage, different to host compiler + Mode::ToolRustc => self.msg_sysroot_tool( + Kind::Build, + build_stage, + format_args!("tool {tool}"), + *host, + *target, + ), + // doesn't depend on compiler, same as host compiler + _ => self.msg(Kind::Build, build_stage, format_args!("tool {tool}"), *host, *target), } - // doesn't depend on compiler, same as host compiler - Mode::ToolStd => { - if host == target { - format!("Building tool {} (stage{})", tool, build_stage) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, build_stage, host, build_stage, target - ) - } - } - _ => format!("Building tool {} (stage{})", tool, build_stage), } } @@ -111,14 +98,13 @@ impl Step for ToolBuild { if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } - let msg = tooling_output( + let _guard = builder.msg_tool( self.mode, self.tool, self.compiler.stage, &self.compiler.host, &self.target, ); - builder.info(&msg); let mut cargo = Command::from(cargo); let is_expected = builder.try_run(&mut cargo); @@ -492,14 +478,13 @@ impl Step for Rustdoc { cargo.rustflag("--cfg=parallel_compiler"); } - let msg = tooling_output( + let _guard = builder.msg_tool( Mode::ToolRustc, "rustdoc", build_compiler.stage, &self.compiler.host, &target, ); - builder.info(&msg); builder.run(&mut cargo.into()); // Cargo adds a number of paths to the dylib search path on windows, which results in @@ -748,6 +733,7 @@ macro_rules! tool_extended { stable = $stable:expr $(,tool_std = $tool_std:literal)? $(,allow_features = $allow_features:expr)? + $(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)? ;)+) => { $( #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -790,7 +776,7 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> { - $builder.ensure(ToolBuild { + let tool = $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, tool: $tool_name, @@ -800,7 +786,27 @@ macro_rules! tool_extended { is_optional_tool: true, source_type: SourceType::InTree, allow_features: concat!($($allow_features)*), - }) + })?; + + if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 { + let bindir = $builder.sysroot($sel.compiler).join("bin"); + t!(fs::create_dir_all(&bindir)); + + #[allow(unused_variables)] + let tools_out = $builder + .cargo_out($sel.compiler, Mode::ToolRustc, $sel.target); + + $(for add_bin in $add_bins_to_sysroot { + let bin_source = tools_out.join(exe(add_bin, $sel.target)); + let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host)); + $builder.copy(&bin_source, &bin_destination); + })? + + let tool = bindir.join(exe($tool_name, $sel.compiler.host)); + Some(tool) + } else { + Some(tool) + } } } )+ @@ -814,15 +820,15 @@ macro_rules! tool_extended { tool_extended!((self, builder), Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true; CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true; - Clippy, "src/tools/clippy", "clippy-driver", stable=true; - Miri, "src/tools/miri", "miri", stable=false; - CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"]; + Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"]; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"]; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. Rls, "src/tools/rls", "rls", stable=true, tool_std=true; RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true; - Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"]; ); impl<'a> Builder<'a> { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index ea236bee563..9f7259f883a 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -211,7 +211,7 @@ For targets: `armv7-unknown-linux-gnueabihf` (\*) These options have been selected to match the configuration of the arm toolchains shipped with Ubuntu 15.10 (+) These options have been selected to match the gcc flags we use to compile C - libraries like jemalloc. See the mk/cfg/arm(v7)-uknown-linux-gnueabi{,hf}.mk + libraries like jemalloc. See the mk/cfg/arm(v7)-unknown-linux-gnueabi{,hf}.mk file in Rust's source code. ### `aarch64-linux-gnu.config` diff --git a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch index 08d0c5b2cac..4437a870b20 100644 --- a/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch +++ b/src/ci/docker/host-x86_64/disabled/riscv64gc-linux/0001-Remove-stime-function-calls.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Remove stime() function calls stime() has been deprecated in glibc 2.31 and replaced with clock_settime(). Let's replace the stime() function calls with -clock_settime() in preperation. +clock_settime() in preparation. function old new delta rdate_main 197 224 +27 diff --git a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config index 575584ef0cf..5bfbbae206b 100644 --- a/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips-linux/mips-linux-gnu.config @@ -528,7 +528,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config index 4b1efe24aed..c28d655427e 100644 --- a/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips64-linux/mips64-linux-gnu.config @@ -529,7 +529,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config index baff944cf97..50dfe7b2dd1 100644 --- a/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mips64el-linux/mips64el-linux-gnu.config @@ -529,7 +529,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config index adb2da7ddee..3566c7c8593 100644 --- a/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config +++ b/src/ci/docker/host-x86_64/dist-mipsel-linux/mipsel-linux-gnu.config @@ -528,7 +528,7 @@ CT_CC_GCC_DEC_FLOAT_AUTO=y CT_CC_GCC_HAS_ARCH_OPTIONS=y # -# archictecture-specific options +# architecture-specific options # CT_CC_GCC_mips_llsc=m CT_CC_GCC_mips_synci=m diff --git a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh index 0b06f5e3623..a5691da8cda 100755 --- a/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh +++ b/src/ci/docker/host-x86_64/mingw-check/validate-toolstate.sh @@ -1,5 +1,5 @@ #!/bin/bash -# A quick smoke test to make sure publish_tooolstate.py works. +# A quick smoke test to make sure publish_toolstate.py works. set -euo pipefail IFS=$'\n\t' diff --git a/src/ci/docker/scripts/qemu-bare-bones-rcS b/src/ci/docker/scripts/qemu-bare-bones-rcS index 3c29bedc13c..c5d807b2d7d 100644 --- a/src/ci/docker/scripts/qemu-bare-bones-rcS +++ b/src/ci/docker/scripts/qemu-bare-bones-rcS @@ -9,7 +9,7 @@ mount -t sysfs none /sys /addentropy < /addentropy cat /dev/urandom | head -n 2048 | /addentropy -# Set up IP that qemu expects. This confgures eth0 with the public IP that QEMU +# Set up IP that qemu expects. This configures eth0 with the public IP that QEMU # will communicate to as well as the loopback 127.0.0.1 address. ifconfig eth0 10.0.2.15 ifconfig lo up diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 8ded2ee59dd..48efa67191a 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -42,6 +42,7 @@ - [wasm64-unknown-unknown](platform-support/wasm64-unknown-unknown.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) + - [x86_64h-apple-darwin](platform-support/x86_64h-apple-darwin.md) - [Targets](targets/index.md) - [Built-in Targets](targets/built-in.md) - [Custom Targets](targets/custom.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c378532dbf6..75f97c1fc1e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -327,5 +327,6 @@ target | std | host | notes `x86_64-uwp-windows-gnu` | ✓ | | `x86_64-uwp-windows-msvc` | ✓ | | `x86_64-wrs-vxworks` | ? | | +`x86_64h-apple-darwin` | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/loongarch-linux.md b/src/doc/rustc/src/platform-support/loongarch-linux.md index d7d31d8724c..16ccaf46b2f 100644 --- a/src/doc/rustc/src/platform-support/loongarch-linux.md +++ b/src/doc/rustc/src/platform-support/loongarch-linux.md @@ -15,6 +15,8 @@ While the integer base ABI is implied by the machine field, the floating po | f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)| | sf | The base ABI uses no FPR for parameter passing. (lp64s) | +<br> + |`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` | |----------------------------------|-------------|----------|----------------------------------| | lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu | diff --git a/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md new file mode 100644 index 00000000000..1a6f7bb834c --- /dev/null +++ b/src/doc/rustc/src/platform-support/x86_64h-apple-darwin.md @@ -0,0 +1,57 @@ +# `x86_64h-apple-darwin` + +**Tier: 3** + +Target for macOS on late-generation `x86_64` Apple chips, usable as the +`x86_64h` entry in universal binaries, and equivalent to LLVM's +`x86_64h-apple-macosx*` targets. + +## Target maintainers + +- Thom Chiovoloni `thom@shift.click` <https://github.com/thomcc> + +## Requirements + +This target is an `x86_64` target that only supports Apple's late-gen +(Haswell-compatible) Intel chips. It enables a set of target features available +on these chips (AVX2 and similar), and MachO binaries built with this target may +be used as the `x86_64h` entry in universal binaries ("fat" MachO binaries), and +will fail to load on machines that do not support this. + +It should support the full standard library (`std` and `alloc` either with +default or user-defined allocators). This target is probably most useful when +targetted via cross-compilation (including from `x86_64-apple-darwin`), but if +built manually, the host tools work. + +It is similar to `x86_64-apple-darwin` in nearly all respects, although the +minimum supported OS version is slightly higher (it requires 10.8 rather than +`x86_64-apple-darwin`'s 10.7). + +## Building the target + +Users on Apple targets can build this by adding it to the `target` list in +`config.toml`, or with `-Zbuild-std`. + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Code built with this target can be run on the set of Intel macOS machines that +support running `x86_64h` binaries (relatively recent Intel macs). The Rust test +suite seems to work. + +## Cross-compilation toolchains and C code + +Cross-compilation to this target from Apple hosts should generally work without +much configuration, so long as XCode and the CommandLineTools are installed. +Targetting it from non-Apple hosts is difficult, but no moreso than targetting +`x86_64-apple-darwin`. + +When compiling C code for this target, either the "`x86_64h-apple-macosx*`" LLVM +targets should be used, or an argument like `-arch x86_64h` should be passed to +the C compiler. diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml index 1643fc8364b..395814e7488 100644 --- a/src/etc/installer/pkg/Distribution.xml +++ b/src/etc/installer/pkg/Distribution.xml @@ -23,7 +23,7 @@ </choices-outline> <!-- These 'selected' scripts ensure that install and uninstall can never be selected at - the same time. Exectly how they work is pretty mysterious, tied to the unspecified algorithm + the same time. Exactly how they work is pretty mysterious, tied to the unspecified algorithm the installer uses to traverse the options after one is toggled. --> <choice id="install" visible="true" diff --git a/src/etc/lldb_lookup.py b/src/etc/lldb_lookup.py index bca9c2ae192..36c7d82b34a 100644 --- a/src/etc/lldb_lookup.py +++ b/src/etc/lldb_lookup.py @@ -115,4 +115,4 @@ def synthetic_lookup(valobj, dict): if rust_type == RustType.STD_REF_CELL: return StdRefSyntheticProvider(valobj, dict, is_cell=True) - return DefaultSynthteticProvider(valobj, dict) + return DefaultSyntheticProvider(valobj, dict) diff --git a/src/etc/lldb_providers.py b/src/etc/lldb_providers.py index 697ad4293c3..4f73746f817 100644 --- a/src/etc/lldb_providers.py +++ b/src/etc/lldb_providers.py @@ -69,9 +69,9 @@ def unwrap_unique_or_non_null(unique_or_nonnull): return ptr if ptr.TypeIsPointerType() else ptr.GetChildAtIndex(0) -class DefaultSynthteticProvider: +class DefaultSyntheticProvider: def __init__(self, valobj, dict): - # type: (SBValue, dict) -> DefaultSynthteticProvider + # type: (SBValue, dict) -> DefaultSyntheticProvider # logger = Logger.Logger() # logger >> "Default synthetic provider for " + str(valobj.GetName()) self.valobj = valobj diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 3a3bf6a7ab9..e4c05b57378 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -20,7 +20,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { trace!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); for trait_def_id in cx.tcx.all_traits() { - if !cx.cache.effective_visibilities.is_directly_public(cx.tcx, trait_def_id) + if !cx.cache.effective_visibilities.is_reachable(cx.tcx, trait_def_id) || cx.generated_synthetics.get(&(ty.0, trait_def_id)).is_some() { continue; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index cca50df0db2..b802fd065fe 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -243,9 +243,9 @@ pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs: _ }) => { let s = if let Some(def) = def.as_local() { - print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def.did)) + print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def)) } else { - inline::print_inlined_const(cx.tcx, def.did) + inline::print_inlined_const(cx.tcx, def) }; s diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b392ba05836..46834a1d7f4 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -258,8 +258,6 @@ pub(crate) fn create_config( override_queries: Some(|_sess, providers, _external_providers| { // Most lints will require typechecking, so just don't run them. providers.lint_mod = |_, _| {}; - // Prevent `rustc_hir_analysis::check_crate` from calling `typeck` on all bodies. - providers.typeck_item_bodies = |_, _| {}; // hack so that `used_trait_imports` won't try to call typeck providers.used_trait_imports = |_, _| { static EMPTY_SET: LazyLock<UnordSet<LocalDefId>> = LazyLock::new(UnordSet::default); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 463184acaa1..a5f08fdac11 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -32,6 +32,7 @@ mod context; mod print_item; mod sidebar; mod span_map; +mod type_layout; mod write_shared; pub(crate) use self::context::*; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 9a968e48b27..3e71d41ec96 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -6,16 +6,14 @@ use rustc_hir as hir; use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_middle::middle::stability; -use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::{self, Adt, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_target::abi::{LayoutS, Primitive, TagEncoding, Variants}; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; +use super::type_layout::document_type_layout; use super::{ collect_paths_for_type, document, ensure_trailing_slash, get_filtered_impls_for_reference, item_ty_to_section, notable_traits_button, notable_traits_json, render_all_impls, @@ -1933,118 +1931,6 @@ fn document_non_exhaustive<'a>(item: &'a clean::Item) -> impl fmt::Display + 'a }) } -fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { - fn write_size_of_layout(mut w: impl fmt::Write, layout: &LayoutS, tag_size: u64) { - if layout.abi.is_unsized() { - write!(w, "(unsized)").unwrap(); - } else { - let size = layout.size.bytes() - tag_size; - write!(w, "{size} byte{pl}", pl = if size == 1 { "" } else { "s" }).unwrap(); - if layout.abi.is_uninhabited() { - write!( - w, - " (<a href=\"https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited\">uninhabited</a>)" - ).unwrap(); - } - } - } - - display_fn(move |mut f| { - if !cx.shared.show_type_layout { - return Ok(()); - } - - writeln!( - f, - "<h2 id=\"layout\" class=\"small-section-header\"> \ - Layout<a href=\"#layout\" class=\"anchor\">§</a></h2>" - )?; - writeln!(f, "<div class=\"docblock\">")?; - - let tcx = cx.tcx(); - let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); - match tcx.layout_of(param_env.and(ty)) { - Ok(ty_layout) => { - writeln!( - f, - "<div class=\"warning\"><p><strong>Note:</strong> Most layout information is \ - <strong>completely unstable</strong> and may even differ between compilations. \ - The only exception is types with certain <code>repr(...)</code> attributes. \ - Please see the Rust Reference’s \ - <a href=\"https://doc.rust-lang.org/reference/type-layout.html\">“Type Layout”</a> \ - chapter for details on type layout guarantees.</p></div>" - )?; - f.write_str("<p><strong>Size:</strong> ")?; - write_size_of_layout(&mut f, &ty_layout.layout.0, 0); - writeln!(f, "</p>")?; - if let Variants::Multiple { variants, tag, tag_encoding, .. } = - &ty_layout.layout.variants() - { - if !variants.is_empty() { - f.write_str( - "<p><strong>Size for each variant:</strong></p>\ - <ul>", - )?; - - let Adt(adt, _) = ty_layout.ty.kind() else { - span_bug!(tcx.def_span(ty_def_id), "not an adt") - }; - - let tag_size = if let TagEncoding::Niche { .. } = tag_encoding { - 0 - } else if let Primitive::Int(i, _) = tag.primitive() { - i.size().bytes() - } else { - span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int") - }; - - for (index, layout) in variants.iter_enumerated() { - let name = adt.variant(index).name; - write!(&mut f, "<li><code>{name}</code>: ")?; - write_size_of_layout(&mut f, layout, tag_size); - writeln!(&mut f, "</li>")?; - } - f.write_str("</ul>")?; - } - } - } - // This kind of layout error can occur with valid code, e.g. if you try to - // get the layout of a generic type such as `Vec<T>`. - Err(LayoutError::Unknown(_)) => { - writeln!( - f, - "<p><strong>Note:</strong> Unable to compute type layout, \ - possibly due to this type having generic parameters. \ - Layout can only be computed for concrete, fully-instantiated types.</p>" - )?; - } - // This kind of error probably can't happen with valid code, but we don't - // want to panic and prevent the docs from building, so we just let the - // user know that we couldn't compute the layout. - Err(LayoutError::SizeOverflow(_)) => { - writeln!( - f, - "<p><strong>Note:</strong> Encountered an error during type layout; \ - the type was too big.</p>" - )?; - } - Err(LayoutError::NormalizationFailure(_, _)) => { - writeln!( - f, - "<p><strong>Note:</strong> Encountered an error during type layout; \ - the type failed to be normalized.</p>" - )?; - } - } - - writeln!(f, "</div>") - }) -} - fn pluralize(count: usize) -> &'static str { if count > 1 { "s" } else { "" } } diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs new file mode 100644 index 00000000000..22aec623335 --- /dev/null +++ b/src/librustdoc/html/render/type_layout.rs @@ -0,0 +1,86 @@ +use askama::Template; + +use rustc_data_structures::captures::Captures; +use rustc_hir::def_id::DefId; +use rustc_middle::span_bug; +use rustc_middle::ty::layout::LayoutError; +use rustc_middle::ty::Adt; +use rustc_span::symbol::Symbol; +use rustc_target::abi::{Primitive, TagEncoding, Variants}; + +use std::fmt; + +use crate::html::format::display_fn; +use crate::html::render::Context; + +#[derive(Template)] +#[template(path = "type_layout.html")] +struct TypeLayout<'cx> { + variants: Vec<(Symbol, TypeLayoutSize)>, + type_layout_size: Result<TypeLayoutSize, LayoutError<'cx>>, +} + +#[derive(Template)] +#[template(path = "type_layout_size.html")] +struct TypeLayoutSize { + is_unsized: bool, + is_uninhabited: bool, + size: u64, +} + +pub(crate) fn document_type_layout<'a, 'cx: 'a>( + cx: &'a Context<'cx>, + ty_def_id: DefId, +) -> impl fmt::Display + 'a + Captures<'cx> { + display_fn(move |f| { + if !cx.shared.show_type_layout { + return Ok(()); + } + + let tcx = cx.tcx(); + let param_env = tcx.param_env(ty_def_id); + let ty = tcx.type_of(ty_def_id).subst_identity(); + let type_layout = tcx.layout_of(param_env.and(ty)); + + let variants = + if let Ok(type_layout) = type_layout && + let Variants::Multiple { variants, tag, tag_encoding, .. } = + type_layout.layout.variants() && + !variants.is_empty() + { + let tag_size = + if let TagEncoding::Niche { .. } = tag_encoding { + 0 + } else if let Primitive::Int(i, _) = tag.primitive() { + i.size().bytes() + } else { + span_bug!(cx.tcx().def_span(ty_def_id), "tag is neither niche nor int") + }; + variants + .iter_enumerated() + .map(|(variant_idx, variant_layout)| { + let Adt(adt, _) = type_layout.ty.kind() else { + span_bug!(cx.tcx().def_span(ty_def_id), "not an adt") + }; + let name = adt.variant(variant_idx).name; + let is_unsized = variant_layout.abi.is_unsized(); + let is_uninhabited = variant_layout.abi.is_uninhabited(); + let size = variant_layout.size.bytes() - tag_size; + let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; + (name, type_layout_size) + }) + .collect() + } else { + Vec::new() + }; + + let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| { + let is_unsized = layout.abi.is_unsized(); + let is_uninhabited = layout.abi.is_uninhabited(); + let size = layout.size.bytes(); + TypeLayoutSize { is_unsized, is_uninhabited, size } + }); + + Ok(TypeLayout { variants, type_layout_size }.render_into(f).unwrap()) + }) +} diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index d13c783d2e4..99cf8e443f0 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -7,7 +7,6 @@ margin-right: 0.3em; height: 1.2rem; width: 1.2rem; - color: inherit; border: 2px solid var(--settings-input-border-color); outline: none; -webkit-appearance: none; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 93d657fd605..bccf675c14b 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -375,10 +375,7 @@ function preLoadCss(cssUrl) { function handleEscape(ev) { searchState.clearInputTimeout(); - switchDisplayedElement(null); - if (browserSupportsHistoryApi()) { - history.replaceState(null, "", getNakedUrl() + window.location.hash); - } + searchState.hideResults(); ev.preventDefault(); searchState.defocus(); window.hideAllModals(true); // true = reset focus for tooltips @@ -533,9 +530,11 @@ function preLoadCss(cssUrl) { // ignored are included in the attribute `data-ignore-extern-crates`. const script = document .querySelector("script[data-ignore-extern-crates]"); - const ignoreExternCrates = script ? script.getAttribute("data-ignore-extern-crates") : ""; + const ignoreExternCrates = new Set( + (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",") + ); for (const lib of libs) { - if (lib === window.currentCrate || ignoreExternCrates.indexOf(lib) !== -1) { + if (lib === window.currentCrate || ignoreExternCrates.has(lib)) { continue; } const structs = imp[lib]; diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 929dae81c8d..3dc4f2149b8 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -2412,10 +2412,6 @@ function initSearch(rawSearchIndex) { const searchAfter500ms = () => { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } searchState.hideResults(); } else { searchState.timeout = setTimeout(search, 500); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index ebbe6c1ca9a..2cba32c1b50 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global getSettingValue, getVirtualKey, updateLocalStorage, updateTheme */ +/* global getSettingValue, updateLocalStorage, updateTheme */ /* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */ /* global MAIN_ID, getVar, getSettingsButton */ @@ -32,21 +32,6 @@ } } - function handleKey(ev) { - // Don't interfere with browser shortcuts - if (ev.ctrlKey || ev.altKey || ev.metaKey) { - return; - } - switch (getVirtualKey(ev)) { - case "Enter": - case "Return": - case "Space": - ev.target.checked = !ev.target.checked; - ev.preventDefault(); - break; - } - } - function showLightAndDark() { removeClass(document.getElementById("preferred-light-theme"), "hidden"); removeClass(document.getElementById("preferred-dark-theme"), "hidden"); @@ -77,8 +62,6 @@ toggle.onchange = function() { changeSetting(this.id, this.checked); }; - toggle.onkeyup = handleKey; - toggle.onkeyrelease = handleKey; }); onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => { const settingId = elem.name; diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index 9aa75517330..d999f3b36fd 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -52,12 +52,12 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const files = document.createElement("div"); files.className = "files"; if (elem[FILES_OFFSET]) { + const w = window.location.href.split("#")[0]; for (const file_text of elem[FILES_OFFSET]) { const file = document.createElement("a"); file.innerText = file_text; file.href = rootPath + "src/" + fullPath + file_text + ".html"; file.addEventListener("click", closeSidebarIfMobile); - const w = window.location.href.split("#")[0]; if (!hasFoundFile && w === file.href) { file.className = "selected"; dirEntry.open = true; diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html new file mode 100644 index 00000000000..58b220c7428 --- /dev/null +++ b/src/librustdoc/html/templates/type_layout.html @@ -0,0 +1,53 @@ +<h2 id="layout" class="small-section-header"> {# #} + Layout<a href="#layout" class="anchor">§</a> {# #} +</h2> {# #} +<div class="docblock"> {# #} + {% match type_layout_size %} + {% when Ok(type_layout_size) %} + <div class="warning"> {# #} + <p> {# #} + <strong>Note:</strong> Most layout information is <strong>completely {#+ #} + unstable</strong> and may even differ between compilations. {#+ #} + The only exception is types with certain <code>repr(...)</code> {#+ #} + attributes. Please see the Rust Reference’s {#+ #} + <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #} + chapter for details on type layout guarantees. {# #} + </p> {# #} + </div> {# #} + <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #} + {% if !variants.is_empty() %} + <p> {# #} + <strong>Size for each variant:</strong> {# #} + </p> {# #} + <ul> {# #} + {% for (name, layout_size) in variants %} + <li> {# #} + <code>{{ name }}</code>: {#+ #} + {{ layout_size|safe }} + </li> {# #} + {% endfor %} + </ul> {# #} + {% endif %} + {# This kind of layout error can occur with valid code, e.g. if you try to + get the layout of a generic type such as `Vec<T>`. #} + {% when Err(LayoutError::Unknown(_)) %} + <p> {# #} + <strong>Note:</strong> Unable to compute type layout, {#+ #} + possibly due to this type having generic parameters. {#+ #} + Layout can only be computed for concrete, fully-instantiated types. {# #} + </p> {# #} + {# This kind of error probably can't happen with valid code, but we don't + want to panic and prevent the docs from building, so we just let the + user know that we couldn't compute the layout. #} + {% when Err(LayoutError::SizeOverflow(_)) %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type was too big. {# #} + </p> {# #} + {% when Err(LayoutError::NormalizationFailure(_, _)) %} + <p> {# #} + <strong>Note:</strong> Encountered an error during type layout; {#+ #} + the type failed to be normalized. {# #} + </p> {# #} + {% endmatch %} +</div> {# #} diff --git a/src/librustdoc/html/templates/type_layout_size.html b/src/librustdoc/html/templates/type_layout_size.html new file mode 100644 index 00000000000..9c2b39edc9f --- /dev/null +++ b/src/librustdoc/html/templates/type_layout_size.html @@ -0,0 +1,12 @@ +{% if is_unsized %} + (unsized) +{% else %} + {% if size == 1 %} + 1 byte + {% else %} + {{ size +}} bytes + {% endif %} + {% if is_uninhabited %} + {# +#} (<a href="https://doc.rust-lang.org/stable/reference/glossary.html#uninhabited">uninhabited</a>) + {% endif %} +{% endif %} diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 33e80df9ed7..f2486abaaa7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -13,7 +13,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, Namespace, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::Mutability; -use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, ty}; use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution}; use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics}; @@ -772,11 +772,10 @@ fn trait_impls_for<'a>( module: DefId, ) -> FxHashSet<(DefId, DefId)> { let tcx = cx.tcx; - let iter = tcx.doc_link_traits_in_scope(module).iter().flat_map(|&trait_| { - trace!("considering explicit impl for trait {:?}", trait_); + let mut impls = FxHashSet::default(); - // Look at each trait implementation to see if it's an impl for `did` - tcx.find_map_relevant_impl(trait_, ty, TreatProjections::ForLookup, |impl_| { + for &trait_ in tcx.doc_link_traits_in_scope(module) { + tcx.for_each_relevant_impl(trait_, ty, |impl_| { let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); // Check if these are the same type. let impl_type = trait_ref.skip_binder().self_ty(); @@ -800,10 +799,13 @@ fn trait_impls_for<'a>( _ => false, }; - if saw_impl { Some((impl_, trait_)) } else { None } - }) - }); - iter.collect() + if saw_impl { + impls.insert((impl_, trait_)); + } + }); + } + + impls } /// Check for resolve collisions between a trait and its derive. diff --git a/src/llvm-project b/src/llvm-project -Subproject 585a6eb3ebf7c40fd7c1b23e3ece557b3cc2aa3 +Subproject ea6fa9c2d43aaf0f11559719eda9b54d356d541 diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index 9f113c72b93..d2e9c324af8 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -38,3 +38,27 @@ impl CiEnv { } } } + +pub mod gha { + /// All github actions log messages from this call to the Drop of the return value + /// will be grouped and hidden by default in logs. Note that nesting these does + /// not really work. + pub fn group(name: impl std::fmt::Display) -> Group { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::group::{name}"); + } + Group(()) + } + + /// A guard that closes the current github actions log group on drop. + #[must_use] + pub struct Group(()); + + impl Drop for Group { + fn drop(&mut self) { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::endgroup::"); + } + } + } +} diff --git a/src/tools/cargo b/src/tools/cargo -Subproject d0a4cbcee614fdb7ba66e860e603a00a644d71f +Subproject de80432f04da61d98dcbbc1572598071718ccfd diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index dec357ab75c..03b5a2d6d08 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { None, &format!( "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index f0a1b1dfe56..5f1fdf00be8 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -226,7 +226,8 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise, }) .fold(NeverLoopResult::Otherwise, combine_seq), - ExprKind::Yield(_, _) + ExprKind::OffsetOf(_, _) + | ExprKind::Yield(_, _) | ExprKind::Closure { .. } | ExprKind::Path(_) | ExprKind::ConstBlock(_) diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 04225beeb70..7945275393c 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -342,6 +342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::DropTemps(_) | ExprKind::Err(_) | ExprKind::InlineAsm(_) | + ExprKind::OffsetOf(_, _) | ExprKind::Let(_) | ExprKind::Lit(_) | ExprKind::Loop(_, _, _, _) | diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 0bedab05eec..eed0f1f1991 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -196,11 +196,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty< fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { let substs = cx.typeck_results().node_substs(hir_id); - let result = cx.tcx.const_eval_resolve( - cx.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ); + let result = cx + .tcx + .const_eval_resolve(cx.param_env, mir::UnevaluatedConst::new(def_id, substs), None); is_value_unfrozen_raw(cx, result, ty) } diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 1382c1a40da..98f5b47f7a0 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { None, &format!( "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index 2dac807c420..01927b6b5f1 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -558,6 +558,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { kind!("InlineAsm(_)"); out!("// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment"); }, + ExprKind::OffsetOf(container, ref fields) => { + bind!(self, container, fields); + kind!("OffsetOf({container}, {fields})"); + } ExprKind::Struct(qpath, fields, base) => { bind!(self, qpath, fields); opt_bind!(self, base); diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index bb8890dcaf9..99bfc4b5717 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -450,11 +450,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { let result = self .lcx .tcx - .const_eval_resolve( - self.param_env, - mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs), - None, - ) + .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None) .ok() .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?; let result = miri_to_const(self.lcx.tcx, result); diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 28c85717061..3df40942e7b 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -218,7 +218,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS | ExprKind::AddrOf(..) | ExprKind::Struct(..) | ExprKind::Repeat(..) - | ExprKind::Block(Block { stmts: [], .. }, _) => (), + | ExprKind::Block(Block { stmts: [], .. }, _) + | ExprKind::OffsetOf(..) => (), // Assignment might be to a local defined earlier, so don't eagerly evaluate. // Blocks with multiple statements might be expensive, so don't eagerly evaluate. diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 3ee7147828b..d972ed82c25 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -301,6 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> { (&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re), (&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r), (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re), + (&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => { + self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name) + }, _ => false, }; (is_eq && (!self.should_ignore(left) || !self.should_ignore(right))) @@ -701,6 +704,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } }, + ExprKind::OffsetOf(container, fields) => { + self.hash_ty(container); + for field in fields { + self.hash_name(field.name); + } + }, ExprKind::Let(Let { pat, init, ty, .. }) => { self.hash_expr(init); if let Some(ty) = ty { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 354b6d71aa4..ecd712f32dc 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -194,7 +194,7 @@ fn check_rvalue<'tcx>( )) } }, - Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()), + Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::UnaryOp(_, operand) => { let ty = operand.ty(body, tcx); if ty.is_integral() || ty.is_bool() { diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index a5a4a921d94..e81eadceec0 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -139,6 +139,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Field(..) | hir::ExprKind::Index(..) | hir::ExprKind::InlineAsm(..) + | hir::ExprKind::OffsetOf(..) | hir::ExprKind::ConstBlock(..) | hir::ExprKind::Lit(..) | hir::ExprKind::Loop(..) @@ -197,6 +198,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::ForLoop(..) | ast::ExprKind::Index(..) | ast::ExprKind::InlineAsm(..) + | ast::ExprKind::OffsetOf(..) | ast::ExprKind::ConstBlock(..) | ast::ExprKind::Lit(..) | ast::ExprKind::IncludedBytes(..) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 9449f0b5567..8b996c18816 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -975,7 +975,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 { } match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) { (Ok(size), _) => size, - (Err(_), ty::Tuple(list)) => list.as_substs().types().map(|t| approx_ty_size(cx, t)).sum(), + (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(), (Err(_), ty::Array(t, n)) => { n.try_eval_target_usize(cx.tcx, cx.param_env).unwrap_or_default() * approx_ty_size(cx, *t) }, diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 1dc19bac984..5dcd71cef12 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -662,6 +662,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Path(_) | ExprKind::Continue(_) | ExprKind::InlineAsm(_) + | ExprKind::OffsetOf(..) | ExprKind::Err(_) => (), } ControlFlow::Continue(()) diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index 718bc41fb99..205905d5091 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -160,6 +160,9 @@ impl rustc_driver::Callbacks for ClippyCallbacks { // MIR passes can be enabled / disabled separately, we should figure out, what passes to // use for Clippy. config.opts.unstable_opts.mir_opt_level = Some(0); + + // Disable flattening and inlining of format_args!(), so the HIR matches with the AST. + config.opts.unstable_opts.flatten_format_args = false; } } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index 0456005dce4..35ce89c7986 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -25,7 +25,7 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { let _ = string.map_or(0, |s| s.len()); let _ = num.as_ref().map_or(&0, |s| s); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); @@ -34,7 +34,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { s += 1; s }); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 23b148752cb..c8683e5aae2 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -33,7 +33,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { *s += 1; s } else { - &mut 0 + &0 }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -46,7 +46,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option<i32>) { *s += 1; s } else { - &mut 0 + &0 }; } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index a5dbf6e1f22..f5e4affb672 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -30,13 +30,13 @@ LL | let _ = if let Some(s) = &mut num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); @@ -76,13 +76,13 @@ LL | let _ = if let Some(ref mut s) = num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index aaa70bf19b2..ccce62bd5b0 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -102,6 +102,9 @@ pub struct TestProps { pub dont_check_compiler_stdout: bool, // For UI tests, allows compiler to generate arbitrary output to stderr pub dont_check_compiler_stderr: bool, + // When checking the output of stdout or stderr check + // that the lines of expected output are a subset of the actual output. + pub compare_output_lines_by_subset: bool, // Don't force a --crate-type=dylib flag on the command line // // Set this for example if you have an auxiliary test file that contains @@ -209,6 +212,7 @@ mod directives { pub const KNOWN_BUG: &'static str = "known-bug"; pub const MIR_UNIT_TEST: &'static str = "unit-test"; pub const REMAP_SRC_BASE: &'static str = "remap-src-base"; + pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset"; // This isn't a real directive, just one that is probably mistyped often pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags"; } @@ -233,6 +237,7 @@ impl TestProps { check_run_results: false, dont_check_compiler_stdout: false, dont_check_compiler_stderr: false, + compare_output_lines_by_subset: false, no_prefer_dynamic: false, pretty_expanded: false, pretty_mode: "normal".to_string(), @@ -467,6 +472,11 @@ impl TestProps { s.trim().to_string() }); config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base); + config.set_name_directive( + ln, + COMPARE_OUTPUT_LINES_BY_SUBSET, + &mut self.compare_output_lines_by_subset, + ); }); } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1a4e9b58383..f6597c72938 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1900,8 +1900,11 @@ impl<'test> TestCx<'test> { // Use a single thread for efficiency and a deterministic error message order rustc.arg("-Zthreads=1"); - // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot. - rustc.arg("--sysroot").arg(&self.config.sysroot_base); + // Optionally prevent default --sysroot if specified in test compile-flags. + if !self.props.compile_flags.iter().any(|flag| flag.starts_with("--sysroot")) { + // In stage 0, make sure we use `stage0-sysroot` instead of the bootstrap sysroot. + rustc.arg("--sysroot").arg(&self.config.sysroot_base); + } // Optionally prevent default --target if specified in test compile-flags. let custom_target = self.props.compile_flags.iter().any(|x| x.starts_with("--target")); @@ -3241,17 +3244,35 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += - self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout); + errors += self.compare_output( + stdout_kind, + &normalized_stdout, + &expected_stdout, + self.props.compare_output_lines_by_subset, + ); } if !self.props.dont_check_compiler_stderr { - errors += - self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr); + errors += self.compare_output( + stderr_kind, + &normalized_stderr, + &expected_stderr, + self.props.compare_output_lines_by_subset, + ); } } TestOutput::Run => { - errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout); - errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr); + errors += self.compare_output( + stdout_kind, + &normalized_stdout, + &expected_stdout, + self.props.compare_output_lines_by_subset, + ); + errors += self.compare_output( + stderr_kind, + &normalized_stderr, + &expected_stderr, + self.props.compare_output_lines_by_subset, + ); } } errors @@ -3335,7 +3356,12 @@ impl<'test> TestCx<'test> { ) }); - errors += self.compare_output("fixed", &fixed_code, &expected_fixed); + errors += self.compare_output( + "fixed", + &fixed_code, + &expected_fixed, + self.props.compare_output_lines_by_subset, + ); } else if !expected_fixed.is_empty() { panic!( "the `// run-rustfix` directive wasn't found but a `*.fixed` \ @@ -3793,11 +3819,38 @@ impl<'test> TestCx<'test> { } } - fn compare_output(&self, kind: &str, actual: &str, expected: &str) -> usize { + fn compare_output( + &self, + kind: &str, + actual: &str, + expected: &str, + compare_output_by_lines: bool, + ) -> usize { if actual == expected { return 0; } + let tmp; + let (expected, actual): (&str, &str) = if compare_output_by_lines { + let actual_lines: HashSet<_> = actual.lines().collect(); + let expected_lines: Vec<_> = expected.lines().collect(); + let mut used = expected_lines.clone(); + used.retain(|line| actual_lines.contains(line)); + // check if `expected` contains a subset of the lines of `actual` + if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) { + return 0; + } + if expected_lines.is_empty() { + // if we have no lines to check, force a full overwite + ("", actual) + } else { + tmp = (expected_lines.join("\n"), used.join("\n")); + (&tmp.0, &tmp.1) + } + } else { + (expected, actual) + }; + if !self.config.bless { if expected.is_empty() { println!("normalized {}:\n{}\n", kind, actual); diff --git a/src/tools/linkchecker/linkcheck.sh b/src/tools/linkchecker/linkcheck.sh index 9eeebf444a4..6c1e668a7f0 100755 --- a/src/tools/linkchecker/linkcheck.sh +++ b/src/tools/linkchecker/linkcheck.sh @@ -16,15 +16,13 @@ # # --all Check all books. This can help make sure you don't break links # from other books into your book. +# +# --path <book-path> +# Path to the root directory for the book. Default to the current +# working directory if omitted. set -e -if [ ! -f book.toml ] && [ ! -f src/SUMMARY.md ] -then - echo "Run command in root directory of the book." - exit 1 -fi - html_dir="$(rustc +nightly --print sysroot)/share/doc/rust/html" if [ ! -d "$html_dir" ] @@ -38,6 +36,8 @@ fi export MDBOOK_OUTPUT__HTML__INPUT_404="" book_name="" +# Default to the current directory +book_path="." # Iterative will avoid cleaning up, so you can quickly run it repeatedly. iterative=0 # If "1", test all books, else only this book. @@ -52,6 +52,10 @@ do --all) all_books=1 ;; + --path) + book_path="${2:-.}" + shift + ;; *) if [ -n "$book_name" ] then @@ -70,6 +74,12 @@ then exit 1 fi +if [ ! -f "$book_path/book.toml" ] && [ ! -f "$book_path/src/SUMMARY.md" ] +then + echo "Run command in root directory of the book or provide a path to the book" + exit 1 +fi + if [ ! -d "$html_dir/$book_name" ] then echo "book name \"$book_name\" not found in sysroot \"$html_dir\"" @@ -93,11 +103,11 @@ then fi echo "Building book \"$book_name\"..." -mdbook build +mdbook build "$book_path" cp -R "$html_dir" linkcheck rm -rf "linkcheck/$book_name" -cp -R book "linkcheck/$book_name" +cp -R "$book_path/book" "linkcheck/$book_name" if [ "$all_books" = "1" ] then diff --git a/src/tools/lint-docs/src/groups.rs b/src/tools/lint-docs/src/groups.rs index 2a923a61b0a..b11fb287cf4 100644 --- a/src/tools/lint-docs/src/groups.rs +++ b/src/tools/lint-docs/src/groups.rs @@ -39,11 +39,12 @@ impl<'a> LintExtractor<'a> { fn collect_groups(&self) -> Result<LintGroups, Box<dyn Error>> { let mut result = BTreeMap::new(); let mut cmd = Command::new(self.rustc_path); + cmd.env_remove("LD_LIBRARY_PATH"); cmd.arg("-Whelp"); let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?; if !output.status.success() { return Err(format!( - "failed to collect lint info: {:?}\n--- stderr\n{}--- stdout\n{}\n", + "failed to collect lint info: failed to run {cmd:?}: {:?}\n--- stderr\n{}--- stdout\n{}\n", output.status, std::str::from_utf8(&output.stderr).unwrap(), std::str::from_utf8(&output.stdout).unwrap(), diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index 034c6aa0708..fe29b9abda3 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -403,6 +403,12 @@ impl<'a> LintExtractor<'a> { fs::write(&tempfile, source) .map_err(|e| format!("failed to write {}: {}", tempfile.display(), e))?; let mut cmd = Command::new(self.rustc_path); + // NOTE: bootstrap sets `LD_LIBRARY_PATH` for building lint-docs itself. + // Unfortunately, lint-docs is a bootstrap tool while rustc is built from source, + // and sometimes the paths conflict. In particular, when using `download-rustc`, + // the LLVM versions can differ between `ci-llvm` and `ci-rustc-sysroot`. + // Unset LD_LIBRARY_PATH here so it doesn't interfere with running the compiler. + cmd.env_remove("LD_LIBRARY_PATH"); if options.contains(&"edition2015") { cmd.arg("--edition=2015"); } else { @@ -415,6 +421,9 @@ impl<'a> LintExtractor<'a> { } cmd.arg("lint_example.rs"); cmd.current_dir(tempdir.path()); + if self.verbose { + eprintln!("running: {cmd:?}"); + } let output = cmd.output().map_err(|e| format!("failed to run command {:?}\n{}", cmd, e))?; let stderr = std::str::from_utf8(&output.stderr).unwrap(); let msgs = stderr diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f67a718ba73..fc938080a0e 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -130,6 +130,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zalways-encode-mir", "-Zextra-const-ub-checks", "-Zmir-emit-retag", + "-Zmir-keep-place-mention", "-Zmir-opt-level=0", "-Zmir-enable-passes=-CheckAlignment", ]; diff --git a/src/tools/miri/tests/fail/const-ub-checks.stderr b/src/tools/miri/tests/fail/const-ub-checks.stderr index a8b7ea242b9..596a6bb4ca8 100644 --- a/src/tools/miri/tests/fail/const-ub-checks.stderr +++ b/src/tools/miri/tests/fail/const-ub-checks.stderr @@ -4,6 +4,12 @@ error[E0080]: evaluation of constant value failed LL | ptr.read(); | ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +note: erroneous constant used + --> $DIR/const-ub-checks.rs:LL:CC + | +LL | let _x = UNALIGNED_READ; + | ^^^^^^^^^^^^^^ + error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs new file mode 100644 index 00000000000..7c5f440b774 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs @@ -0,0 +1,13 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation + +fn main() { + let p = { + let b = Box::new(42); + &*b as *const i32 + }; + unsafe { + let _ = *p; //~ ERROR: dereferenced after this allocation got freed + } + panic!("this should never print"); +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr new file mode 100644 index 00000000000..7b76389c753 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed + --> $DIR/dangling_pointer_deref_underscore.rs:LL:CC + | +LL | let _ = *p; + | ^^ pointer to ALLOC was dereferenced after this allocation got freed + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/dangling_pointer_deref_underscore.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr index d41fcfd2302..9aad1fc9b02 100644 --- a/src/tools/miri/tests/fail/erroneous_const2.stderr +++ b/src/tools/miri/tests/fail/erroneous_const2.stderr @@ -4,6 +4,20 @@ error[E0080]: evaluation of constant value failed LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow +note: erroneous constant used + --> $DIR/erroneous_const2.rs:LL:CC + | +LL | println!("{}", FOO); + | ^^^ + +note: erroneous constant used + --> $DIR/erroneous_const2.rs:LL:CC + | +LL | println!("{}", FOO); + | ^^^ + | + = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. diff --git a/src/tools/miri/tests/pass/track-alloc-1.rs b/src/tools/miri/tests/pass/track-alloc-1.rs deleted file mode 100644 index 427c800dc51..00000000000 --- a/src/tools/miri/tests/pass/track-alloc-1.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Ensure that tracking early allocations doesn't ICE Miri. -// Early allocations are probably part of the runtime and therefore uninteresting, but they -// shouldn't cause a crash. -//@compile-flags: -Zmiri-track-alloc-id=1 -//@normalize-stderr-test: "[48] bytes" -> "SIZE bytes" -fn main() {} diff --git a/src/tools/miri/tests/pass/track-alloc-1.stderr b/src/tools/miri/tests/pass/track-alloc-1.stderr deleted file mode 100644 index 7206edbb701..00000000000 --- a/src/tools/miri/tests/pass/track-alloc-1.stderr +++ /dev/null @@ -1,5 +0,0 @@ -note: tracking was triggered - | - = note: created extern static allocation of SIZE bytes (alignment ALIGN bytes) with id 1 - = note: (no span available) - diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs index f7c1e683d0d..e3e5fac98c0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs @@ -382,10 +382,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(rustc_allocator, Normal, template!(Word), WarnFollowing, IMPL_DETAIL), rustc_attr!(rustc_nounwind, Normal, template!(Word), WarnFollowing, IMPL_DETAIL), gated!( - alloc_error_handler, Normal, template!(Word), WarnFollowing, - experimental!(alloc_error_handler) - ), - gated!( default_lib_allocator, Normal, template!(Word), WarnFollowing, allocator_internals, experimental!(default_lib_allocator), ), diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs index d258a024729..a9cd8e705a4 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs @@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder; mod symbol; pub use symbol::*; -use std::ops::Bound; +use std::ops::{Bound, Range}; use crate::tt; @@ -298,6 +298,10 @@ impl server::Span for RustAnalyzer { // FIXME handle span span } + fn byte_range(&mut self, _span: Self::Span) -> Range<usize> { + // FIXME handle span + Range { start: 0, end: 0 } + } fn start(&mut self, _span: Self::Span) -> LineColumn { // FIXME handle span LineColumn { line: 0, column: 0 } diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index ac96bedf2fe..824e4219136 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -399,7 +399,9 @@ pub(crate) fn format_expr( } } ast::ExprKind::Underscore => Some("_".to_owned()), - ast::ExprKind::FormatArgs(..) | ast::ExprKind::IncludedBytes(..) => { + ast::ExprKind::FormatArgs(..) + | ast::ExprKind::IncludedBytes(..) + | ast::ExprKind::OffsetOf(..) => { // These do not occur in the AST because macros aren't expanded. unreachable!() } diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index a26375ee643..ca171657407 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -499,6 +499,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Field(..) | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::InlineAsm(..) + | ast::ExprKind::OffsetOf(..) | ast::ExprKind::Let(..) | ast::ExprKind::Path(..) | ast::ExprKind::Range(..) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 0e0a517ae49..411cbc760e0 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -36,10 +36,11 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("mdbook", "MPL-2.0"), // mdbook ("colored", "MPL-2.0"), // rustfmt ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde) - ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot - ("snap", "BSD-3-Clause"), // rustc - ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) - ("self_cell", "Apache-2.0"), // rustc (fluent translations) + ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku + ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot + ("snap", "BSD-3-Clause"), // rustc + ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) + ("self_cell", "Apache-2.0"), // rustc (fluent translations) // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index b1385edf13e..c19fa8e9656 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -10,7 +10,7 @@ use std::path::{Path, PathBuf}; // FIXME: The following limits should be reduced eventually. const ENTRY_LIMIT: usize = 885; const ROOT_ENTRY_LIMIT: usize = 894; -const ISSUES_ENTRY_LIMIT: usize = 1977; +const ISSUES_ENTRY_LIMIT: usize = 1953; fn check_entries(tests_path: &Path, bad: &mut bool) { let mut directories: HashMap<PathBuf, usize> = HashMap::new(); diff --git a/tests/codegen/debuginfo-constant-locals.rs b/tests/codegen/debuginfo-constant-locals.rs new file mode 100644 index 00000000000..95a1b8c9d21 --- /dev/null +++ b/tests/codegen/debuginfo-constant-locals.rs @@ -0,0 +1,28 @@ +// compile-flags: -g -O + +// Check that simple constant values are preserved in debuginfo across both MIR opts and LLVM opts + +#![crate_type = "lib"] + +#[no_mangle] +pub fn check_it() { + let a = 1; + let b = 42; + + foo(a + b); +} + +#[inline(never)] +fn foo(x: i32) { + std::process::exit(x); +} + +// CHECK-LABEL: @check_it +// CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[a_metadata:[0-9]+]], metadata !DIExpression()) +// CHECK: call void @llvm.dbg.value(metadata i32 42, metadata ![[b_metadata:[0-9]+]], metadata !DIExpression()) + +// CHECK: ![[a_metadata]] = !DILocalVariable(name: "a" +// CHECK-SAME: line: 9 + +// CHECK: ![[b_metadata]] = !DILocalVariable(name: "b" +// CHECK-SAME: line: 10 diff --git a/tests/codegen/intrinsics/transmute-niched.rs b/tests/codegen/intrinsics/transmute-niched.rs new file mode 100644 index 00000000000..69e9b1d1206 --- /dev/null +++ b/tests/codegen/intrinsics/transmute-niched.rs @@ -0,0 +1,184 @@ +// revisions: OPT DBG +// [OPT] compile-flags: -C opt-level=3 -C no-prepopulate-passes +// [DBG] compile-flags: -C opt-level=0 -C no-prepopulate-passes +// only-64bit (so I don't need to worry about usize) +// min-llvm-version: 15.0 # this test assumes `ptr`s + +#![crate_type = "lib"] + +use std::mem::transmute; +use std::num::NonZeroU32; + +#[repr(u8)] +pub enum SmallEnum { + A = 10, + B = 11, + C = 12, +} + +// CHECK-LABEL: @check_to_enum( +#[no_mangle] +pub unsafe fn check_to_enum(x: i8) -> SmallEnum { + // OPT: %0 = icmp uge i8 %x, 10 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp ule i8 %x, 12 + // OPT: call void @llvm.assume(i1 %1) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_from_enum( +#[no_mangle] +pub unsafe fn check_from_enum(x: SmallEnum) -> i8 { + // OPT: %0 = icmp uge i8 %x, 10 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp ule i8 %x, 12 + // OPT: call void @llvm.assume(i1 %1) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_to_ordering( +#[no_mangle] +pub unsafe fn check_to_ordering(x: u8) -> std::cmp::Ordering { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +// CHECK-LABEL: @check_from_ordering( +#[no_mangle] +pub unsafe fn check_from_ordering(x: std::cmp::Ordering) -> u8 { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %x + + transmute(x) +} + +#[repr(i32)] +pub enum Minus100ToPlus100 { + A = -100, + B = -90, + C = -80, + D = -70, + E = -60, + F = -50, + G = -40, + H = -30, + I = -20, + J = -10, + K = 0, + L = 10, + M = 20, + N = 30, + O = 40, + P = 50, + Q = 60, + R = 70, + S = 80, + T = 90, + U = 100, +} + +// CHECK-LABEL: @check_enum_from_char( +#[no_mangle] +pub unsafe fn check_enum_from_char(x: char) -> Minus100ToPlus100 { + // OPT: %0 = icmp ule i32 %x, 1114111 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp uge i32 %x, -100 + // OPT: %2 = icmp ule i32 %x, 100 + // OPT: %3 = or i1 %1, %2 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i32 %x + + transmute(x) +} + +// CHECK-LABEL: @check_enum_to_char( +#[no_mangle] +pub unsafe fn check_enum_to_char(x: Minus100ToPlus100) -> char { + // OPT: %0 = icmp uge i32 %x, -100 + // OPT: %1 = icmp ule i32 %x, 100 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i32 %x, 1114111 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i32 %x + + transmute(x) +} + +// CHECK-LABEL: @check_swap_pair( +#[no_mangle] +pub unsafe fn check_swap_pair(x: (char, NonZeroU32)) -> (NonZeroU32, char) { + // OPT: %0 = icmp ule i32 %x.0, 1114111 + // OPT: call void @llvm.assume(i1 %0) + // OPT: %1 = icmp uge i32 %x.0, 1 + // OPT: call void @llvm.assume(i1 %1) + // OPT: %2 = icmp uge i32 %x.1, 1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i32 %x.1, 1114111 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: %[[P1:.+]] = insertvalue { i32, i32 } poison, i32 %x.0, 0 + // CHECK: %[[P2:.+]] = insertvalue { i32, i32 } %[[P1]], i32 %x.1, 1 + // CHECK: ret { i32, i32 } %[[P2]] + + transmute(x) +} + +// CHECK-LABEL: @check_bool_from_ordering( +#[no_mangle] +pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool { + // OPT: %0 = icmp uge i8 %x, -1 + // OPT: %1 = icmp ule i8 %x, 1 + // OPT: %2 = or i1 %0, %1 + // OPT: call void @llvm.assume(i1 %2) + // OPT: %3 = icmp ule i8 %x, 1 + // OPT: call void @llvm.assume(i1 %3) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: ret i1 %[[R]] + + transmute(x) +} + +// CHECK-LABEL: @check_bool_to_ordering( +#[no_mangle] +pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering { + // CHECK: %0 = zext i1 %x to i8 + // OPT: %1 = icmp ule i8 %0, 1 + // OPT: call void @llvm.assume(i1 %1) + // OPT: %2 = icmp uge i8 %0, -1 + // OPT: %3 = icmp ule i8 %0, 1 + // OPT: %4 = or i1 %2, %3 + // OPT: call void @llvm.assume(i1 %4) + // DBG-NOT: icmp + // DBG-NOT: assume + // CHECK: ret i8 %0 + + transmute(x) +} diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 57f901c6719..664e697c2a5 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -8,10 +8,10 @@ #![feature(inline_const)] #![allow(unreachable_code)] -use std::mem::{transmute, MaybeUninit}; +use std::mem::MaybeUninit; +use std::intrinsics::{transmute, transmute_unchecked}; -// Some of the cases here are statically rejected by `mem::transmute`, so -// we need to generate custom MIR for those cases to get to codegen. +// Some of these need custom MIR to not get removed by MIR optimizations. use std::intrinsics::mir::*; enum Never {} @@ -30,59 +30,35 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_size(x: u16) -> u32 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_size(x: u32) -> u16 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_to_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK: call void @llvm.trap mir!{ @@ -95,7 +71,7 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK-LABEL: @check_from_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { // CHECK: ret i16 poison mir!{ @@ -169,8 +145,8 @@ pub unsafe fn check_aggregate_from_bool(x: bool) -> Aggregate8 { #[no_mangle] pub unsafe fn check_byte_to_bool(x: u8) -> bool { // CHECK-NOT: alloca - // CHECK: %0 = trunc i8 %x to i1 - // CHECK: ret i1 %0 + // CHECK: %[[R:.+]] = trunc i8 %x to i1 + // CHECK: ret i1 %[[R]] transmute(x) } @@ -178,8 +154,8 @@ pub unsafe fn check_byte_to_bool(x: u8) -> bool { #[no_mangle] pub unsafe fn check_byte_from_bool(x: bool) -> u8 { // CHECK-NOT: alloca - // CHECK: %0 = zext i1 %x to i8 - // CHECK: ret i8 %0 + // CHECK: %[[R:.+]] = zext i1 %x to i8 + // CHECK: ret i8 %[[R:.+]] transmute(x) } diff --git a/tests/codegen/transmute-optimized.rs b/tests/codegen/transmute-optimized.rs new file mode 100644 index 00000000000..461dd550cd7 --- /dev/null +++ b/tests/codegen/transmute-optimized.rs @@ -0,0 +1,109 @@ +// compile-flags: -O -Z merge-functions=disabled +// min-llvm-version: 15.0 # this test uses `ptr`s +// ignore-debug + +#![crate_type = "lib"] + +// This tests that LLVM can optimize based on the niches in the source or +// destination types for transmutes. + +#[repr(u32)] +pub enum AlwaysZero32 { X = 0 } + +// CHECK-LABEL: i32 @issue_109958(i32 +#[no_mangle] +pub fn issue_109958(x: AlwaysZero32) -> i32 { + // CHECK: ret i32 0 + unsafe { std::mem::transmute(x) } +} + +// CHECK-LABEL: i1 @reference_is_null(ptr +#[no_mangle] +pub fn reference_is_null(x: &i32) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_null_is_null(ptr +#[no_mangle] +pub fn non_null_is_null(x: std::ptr::NonNull<i32>) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_zero_is_null( +#[no_mangle] +pub fn non_zero_is_null(x: std::num::NonZeroUsize) -> bool { + // CHECK: ret i1 false + let p: *const i32 = unsafe { std::mem::transmute(x) }; + p.is_null() +} + +// CHECK-LABEL: i1 @non_null_is_zero(ptr +#[no_mangle] +pub fn non_null_is_zero(x: std::ptr::NonNull<i32>) -> bool { + // CHECK: ret i1 false + let a: isize = unsafe { std::mem::transmute(x) }; + a == 0 +} + +// CHECK-LABEL: i1 @bool_ordering_is_ge(i1 +#[no_mangle] +pub fn bool_ordering_is_ge(x: bool) -> bool { + // CHECK: ret i1 true + let y: std::cmp::Ordering = unsafe { std::mem::transmute(x) }; + y.is_ge() +} + +// CHECK-LABEL: i1 @ordering_is_ge_then_transmute_to_bool(i8 +#[no_mangle] +pub fn ordering_is_ge_then_transmute_to_bool(x: std::cmp::Ordering) -> bool { + let r = x.is_ge(); + let _: bool = unsafe { std::mem::transmute(x) }; + r +} + +// CHECK-LABEL: i32 @normal_div(i32 +#[no_mangle] +pub fn normal_div(a: u32, b: u32) -> u32 { + // CHECK: call core::panicking::panic + a / b +} + +// CHECK-LABEL: i32 @div_transmute_nonzero(i32 +#[no_mangle] +pub fn div_transmute_nonzero(a: u32, b: std::num::NonZeroI32) -> u32 { + // CHECK-NOT: call core::panicking::panic + // CHECK: %[[R:.+]] = udiv i32 %a, %b + // CHECK-NEXT: ret i32 %[[R]] + // CHECK-NOT: call core::panicking::panic + let d: u32 = unsafe { std::mem::transmute(b) }; + a / d +} + +#[repr(i8)] +pub enum OneTwoThree { One = 1, Two = 2, Three = 3 } + +// CHECK-LABEL: i8 @ordering_transmute_onetwothree(i8 +#[no_mangle] +pub unsafe fn ordering_transmute_onetwothree(x: std::cmp::Ordering) -> OneTwoThree { + // CHECK: ret i8 1 + std::mem::transmute(x) +} + +// CHECK-LABEL: i8 @onetwothree_transmute_ordering(i8 +#[no_mangle] +pub unsafe fn onetwothree_transmute_ordering(x: OneTwoThree) -> std::cmp::Ordering { + // CHECK: ret i8 1 + std::mem::transmute(x) +} + +// CHECK-LABEL: i1 @char_is_negative(i32 +#[no_mangle] +pub fn char_is_negative(c: char) -> bool { + // CHECK: ret i1 false + let x: i32 = unsafe { std::mem::transmute(c) }; + x < 0 +} diff --git a/tests/codegen/transmute-scalar.rs b/tests/codegen/transmute-scalar.rs index af2cef472ec..a0894a505c7 100644 --- a/tests/codegen/transmute-scalar.rs +++ b/tests/codegen/transmute-scalar.rs @@ -1,4 +1,4 @@ -// compile-flags: -O -C no-prepopulate-passes +// compile-flags: -C opt-level=0 -C no-prepopulate-passes // min-llvm-version: 15.0 # this test assumes `ptr`s and thus no `pointercast`s #![crate_type = "lib"] @@ -10,7 +10,7 @@ // However, `bitcast`s and `ptrtoint`s and `inttoptr`s are still worth doing when // that allows us to avoid the `alloca`s entirely; see `rvalue_creates_operand`. -// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float noundef %x) +// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x) // CHECK: %0 = bitcast float %x to i32 // CHECK-NEXT: ret i32 %0 #[no_mangle] @@ -18,7 +18,7 @@ pub fn f32_to_bits(x: f32) -> u32 { unsafe { std::mem::transmute(x) } } -// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 noundef zeroext %b) +// CHECK-LABEL: define{{.*}}i8 @bool_to_byte(i1 zeroext %b) // CHECK: %0 = zext i1 %b to i8 // CHECK-NEXT: ret i8 %0 #[no_mangle] @@ -26,7 +26,7 @@ pub fn bool_to_byte(b: bool) -> u8 { unsafe { std::mem::transmute(b) } } -// CHECK-LABEL: define{{.*}}noundef zeroext i1 @byte_to_bool(i8 noundef %byte) +// CHECK-LABEL: define{{.*}}zeroext i1 @byte_to_bool(i8 %byte) // CHECK: %0 = trunc i8 %byte to i1 // CHECK-NEXT: ret i1 %0 #[no_mangle] @@ -34,14 +34,14 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool { std::mem::transmute(byte) } -// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr noundef %p) +// CHECK-LABEL: define{{.*}}ptr @ptr_to_ptr(ptr %p) // CHECK: ret ptr %p #[no_mangle] pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 { unsafe { std::mem::transmute(p) } } -// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr noundef %p) +// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int(ptr %p) // CHECK: %0 = ptrtoint ptr %p to [[USIZE]] // CHECK-NEXT: ret [[USIZE]] %0 #[no_mangle] @@ -49,7 +49,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize { unsafe { std::mem::transmute(p) } } -// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] noundef %i) +// CHECK: define{{.*}}ptr @int_to_ptr([[USIZE]] %i) // CHECK: %0 = inttoptr [[USIZE]] %i to ptr // CHECK-NEXT: ret ptr %0 #[no_mangle] diff --git a/tests/debuginfo/auxiliary/macro-stepping.rs b/tests/debuginfo/auxiliary/macro-stepping.rs index 4447dd22ddb..ae50e11440b 100644 --- a/tests/debuginfo/auxiliary/macro-stepping.rs +++ b/tests/debuginfo/auxiliary/macro-stepping.rs @@ -5,6 +5,6 @@ #[macro_export] macro_rules! new_scope { () => { - let x = 1; + let x = 1; opaque(x); } } diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index e4b2b7b79bc..a7287cffd02 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -79,22 +79,28 @@ extern crate macro_stepping; // exports new_scope!() // lldb-check:[...]#inc-loc2[...] // lldb-command:next // lldb-command:frame select +// lldb-check:[...]#inc-loc1[...] +// lldb-command:next +// lldb-command:frame select +// lldb-check:[...]#inc-loc2[...] +// lldb-command:next +// lldb-command:frame select // lldb-check:[...]#inc-loc3[...] macro_rules! foo { () => { - let a = 1; - let b = 2; - let c = 3; - } + let a = 1; opaque(a); + let b = 2; opaque(b); + let c = 3; opaque(c); + }; } macro_rules! foo2 { () => { foo!(); - let x = 1; + let x = 1; opaque(x); foo!(); - } + }; } fn main() { @@ -118,4 +124,6 @@ fn main() { fn zzz() {()} +fn opaque(_: u32) {} + include!("macro-stepping.inc"); diff --git a/tests/incremental/const-generics/change-const-param-gat.rs b/tests/incremental/const-generics/change-const-param-gat.rs new file mode 100644 index 00000000000..f1449d5681e --- /dev/null +++ b/tests/incremental/const-generics/change-const-param-gat.rs @@ -0,0 +1,29 @@ +// revisions: rpass1 rpass2 rpass3 +// compile-flags: -Zincremental-ignore-spans +#![feature(generic_associated_types)] + +// This test unsures that with_opt_const_param returns the +// def_id of the N param in the Foo::Assoc GAT. + +trait Foo { + type Assoc<const N: usize>; + fn foo( + &self, + ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }>; +} + +impl Foo for () { + type Assoc<const N: usize> = [(); N]; + fn foo( + &self, + ) -> Self::Assoc<{ if cfg!(rpass2) { 3 } else { 2 } }> { + [(); { if cfg!(rpass2) { 3 } else { 2 } }] + } +} + +fn main() { + assert_eq!( + ().foo(), + [(); { if cfg!(rpass2) { 3 } else { 2 } }] + ); +} diff --git a/tests/incremental/const-generics/change-const-param-type.rs b/tests/incremental/const-generics/change-const-param-type.rs new file mode 100644 index 00000000000..1aac1bc7d72 --- /dev/null +++ b/tests/incremental/const-generics/change-const-param-type.rs @@ -0,0 +1,68 @@ +// revisions: rpass1 rpass2 rpass3 +// compile-flags: -Zincremental-ignore-spans + +enum Foo<const N: usize> { + Variant, + Variant2(), + Variant3 {}, +} + +impl Foo<1> { + fn foo<const N: usize>(&self) -> [(); N] { [(); N] } +} + +impl Foo<2> { + fn foo<const N: u32>(self) -> usize { N as usize } +} + +struct Bar<const N: usize>; +struct Bar2<const N: usize>(); +struct Bar3<const N: usize> {} + +#[cfg(rpass1)] +struct ChangingStruct<const N: usize>; + +#[cfg(any(rpass2, rpass3))] +struct ChangingStruct<const N: u32>; + +struct S; + +impl S { + #[cfg(rpass1)] + fn changing_method<const N: usize>(self) {} + + #[cfg(any(rpass2, rpass3))] + fn changing_method<const N: u32>(self) {} +} + +// We want to verify that all goes well when the value of the const argument change. +// To avoid modifying `main`'s HIR, we use a separate constant, and use `{ FOO_ARG + 1 }` +// inside the body to keep having an `AnonConst` to compute. +const FOO_ARG: usize = if cfg!(rpass2) { 1 } else { 0 }; + +fn main() { + let foo = Foo::Variant::<{ FOO_ARG + 1 }>; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::Variant2::<{ FOO_ARG + 1 }>(); + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::Variant3::<{ FOO_ARG + 1 }> {}; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant2(); + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let foo = Foo::<{ FOO_ARG + 1 }>::Variant3 {}; + foo.foo::<{ if cfg!(rpass3) { 3 } else { 4 } }>(); + + let _ = Bar::<{ FOO_ARG + 1 }>; + let _ = Bar2::<{ FOO_ARG + 1 }>(); + let _ = Bar3::<{ FOO_ARG + 1 }> {}; + + let _ = ChangingStruct::<{ 5 }>; + let _ = S.changing_method::<{ 5 }>(); +} diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs index db367d07094..f685fe46d70 100644 --- a/tests/incremental/hashes/enum_constructors.rs +++ b/tests/incremental/hashes/enum_constructors.rs @@ -334,9 +334,9 @@ pub fn change_constructor_variant_c_like() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_variant_c_like() { let _x = Clike::C; diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs index 7aca4324233..a835b8eef8c 100644 --- a/tests/incremental/hashes/let_expressions.rs +++ b/tests/incremental/hashes/let_expressions.rs @@ -91,7 +91,7 @@ pub fn change_mutability_of_slot() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -176,7 +176,7 @@ pub fn change_mutability_of_binding_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -193,9 +193,9 @@ pub fn add_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -210,9 +210,9 @@ pub fn change_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_initializer() { let _x = 5u16; diff --git a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 19daae86589..41657b53fc1 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -7,10 +7,10 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 bb0: { - _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 // mir::Constant // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -18,4 +18,4 @@ promoted[0] in FOO: &[&i32; 1] = { } } -alloc2 (extern static: X) +alloc3 (extern static: X) diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 5b13d60052f..25ba0face6b 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -18,11 +18,11 @@ - StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 - StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 -- _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 +- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 // mir::Constant - // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 -- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } - _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 - _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -50,5 +50,5 @@ } } - -- alloc2 (extern static: X) +- alloc3 (extern static: X) diff --git a/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff new file mode 100644 index 00000000000..4e2f1b39d2b --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.concrete.ConstProp.diff @@ -0,0 +1,43 @@ +- // MIR for `concrete` before ConstProp ++ // MIR for `concrete` after ConstProp + + fn concrete() -> () { + let mut _0: (); // return place in scope 0 at $DIR/offset_of.rs:+0:15: +0:15 + let _1: usize; // in scope 0 at $DIR/offset_of.rs:+1:9: +1:10 + scope 1 { + debug x => _1; // in scope 1 at $DIR/offset_of.rs:+1:9: +1:10 + let _2: usize; // in scope 1 at $DIR/offset_of.rs:+2:9: +2:10 + scope 2 { + debug y => _2; // in scope 2 at $DIR/offset_of.rs:+2:9: +2:10 + let _3: usize; // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + scope 3 { + debug z0 => _3; // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11 + let _4: usize; // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + scope 4 { + debug z1 => _4; // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:10 +- _1 = OffsetOf(Alpha, [0]); // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 ++ _1 = const 4_usize; // scope 0 at $DIR/offset_of.rs:+1:13: +1:33 + StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:10 +- _2 = OffsetOf(Alpha, [1]); // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 ++ _2 = const 0_usize; // scope 1 at $DIR/offset_of.rs:+2:13: +2:33 + StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 +- _3 = OffsetOf(Alpha, [2, 0]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 ++ _3 = const 2_usize; // scope 2 at $DIR/offset_of.rs:+3:14: +3:36 + StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 +- _4 = OffsetOf(Alpha, [2, 1]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 ++ _4 = const 3_usize; // scope 3 at $DIR/offset_of.rs:+4:14: +4:36 + StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/offset_of.rs:+5:1: +5:2 + return; // scope 0 at $DIR/offset_of.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff new file mode 100644 index 00000000000..5c6cb47089e --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.generic.ConstProp.diff @@ -0,0 +1,39 @@ +- // MIR for `generic` before ConstProp ++ // MIR for `generic` after ConstProp + + fn generic() -> () { + let mut _0: (); // return place in scope 0 at $DIR/offset_of.rs:+0:17: +0:17 + let _1: usize; // in scope 0 at $DIR/offset_of.rs:+1:9: +1:11 + scope 1 { + debug gx => _1; // in scope 1 at $DIR/offset_of.rs:+1:9: +1:11 + let _2: usize; // in scope 1 at $DIR/offset_of.rs:+2:9: +2:11 + scope 2 { + debug gy => _2; // in scope 2 at $DIR/offset_of.rs:+2:9: +2:11 + let _3: usize; // in scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + scope 3 { + debug dx => _3; // in scope 3 at $DIR/offset_of.rs:+3:9: +3:11 + let _4: usize; // in scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + scope 4 { + debug dy => _4; // in scope 4 at $DIR/offset_of.rs:+4:9: +4:11 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/offset_of.rs:+1:9: +1:11 + _1 = OffsetOf(Gamma<T>, [0]); // scope 0 at $DIR/offset_of.rs:+1:14: +1:37 + StorageLive(_2); // scope 1 at $DIR/offset_of.rs:+2:9: +2:11 + _2 = OffsetOf(Gamma<T>, [1]); // scope 1 at $DIR/offset_of.rs:+2:14: +2:37 + StorageLive(_3); // scope 2 at $DIR/offset_of.rs:+3:9: +3:11 + _3 = OffsetOf(Delta<T>, [1]); // scope 2 at $DIR/offset_of.rs:+3:14: +3:37 + StorageLive(_4); // scope 3 at $DIR/offset_of.rs:+4:9: +4:11 + _4 = OffsetOf(Delta<T>, [2]); // scope 3 at $DIR/offset_of.rs:+4:14: +4:37 + StorageDead(_4); // scope 3 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_3); // scope 2 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_2); // scope 1 at $DIR/offset_of.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/offset_of.rs:+5:1: +5:2 + return; // scope 0 at $DIR/offset_of.rs:+5:2: +5:2 + } + } + diff --git a/tests/mir-opt/const_prop/offset_of.rs b/tests/mir-opt/const_prop/offset_of.rs new file mode 100644 index 00000000000..eabdf848079 --- /dev/null +++ b/tests/mir-opt/const_prop/offset_of.rs @@ -0,0 +1,49 @@ +// unit-test +// compile-flags: -O + +#![feature(offset_of)] + +use std::marker::PhantomData; +use std::mem::offset_of; + +struct Alpha { + x: u8, + y: u16, + z: Beta, +} + +struct Beta(u8, u8); + +struct Gamma<T> { + x: u8, + y: u16, + _t: T, +} + +#[repr(C)] +struct Delta<T> { + _phantom: PhantomData<T>, + x: u8, + y: u16, +} + +// EMIT_MIR offset_of.concrete.ConstProp.diff +fn concrete() { + let x = offset_of!(Alpha, x); + let y = offset_of!(Alpha, y); + let z0 = offset_of!(Alpha, z.0); + let z1 = offset_of!(Alpha, z.1); +} + +// EMIT_MIR offset_of.generic.ConstProp.diff +fn generic<T>() { + let gx = offset_of!(Gamma<T>, x); + let gy = offset_of!(Gamma<T>, y); + let dx = offset_of!(Delta<T>, x); + let dy = offset_of!(Delta<T>, y); +} + +fn main() { + concrete(); + generic::<()>(); +} diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir index 81cfd22db6c..7886bf19e0c 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir index 81cfd22db6c..7886bf19e0c 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir index 002e914e8fa..5bea94c7fe8 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir index 002e914e8fa..5bea94c7fe8 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.diff index 18df6f9af5f..3aebfb69e0a 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.diff @@ -8,7 +8,7 @@ + let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:14:8: 14:21 + let mut _3: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:12:18: 12:25 + scope 2 { -+ debug buffer => _3; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 ++ debug buffer => const _; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 + scope 3 { + debug index => _0; // in scope 3 at $DIR/issue_106141.rs:13:9: 13:14 + } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff index 6184a0acd18..d76cd0e2bb8 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -10,50 +10,52 @@ + scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _6: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { -+ scope 3 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ scope 4 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _4; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _8: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _9: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: u16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ } -+ } -+ scope 5 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _11: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _12: u16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ scope 6 { -+ debug x => _12; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ } -+ scope 7 { -+ scope 8 { -+ debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } + } -+ } -+ } -+ scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _13: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 10 { -+ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ scope 11 { -+ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 14 { -+ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } + } + } ++ scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } + } + } -+ scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL -+ } + } + } + } @@ -67,75 +69,81 @@ - // mir::Constant - // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 - // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::<impl u16>::unchecked_shl}, val: Value(<ZST>) } -+ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = const 65535_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _8 = Gt(_4, move _9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_12); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + -+ bb3: { -+ _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ bb2: { ++ _9 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::<u16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = _4 as u16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _7 = Result::<u16, TryFromIntError>::Ok(move _10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_12); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _11 = discriminant(_7); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<u16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { -+ _6 = Option::<u16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { -+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _14 = move ((_9 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<u16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ _12 = move ((_7 as Ok).0: u16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ _6 = Option::<u16>::Some(move _12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _5 = move ((_8 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shl::<u16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir index 726b6bbf93b..3c175ed1504 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -7,122 +7,130 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { scope 1 (inlined core::num::<impl u16>::unchecked_shl) { // at $DIR/unchecked_shifts.rs:11:7: 11:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _4: std::option::Option<u16>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - let mut _5: std::result::Result<u16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { - scope 3 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _2; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - scope 4 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _2; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _8: u16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - } - } - scope 5 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _5; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: u16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug x => _10; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - scope 8 { - debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 3 (inlined core::num::<impl u16>::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option<u16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result<u16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined <u32 as TryInto<u16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num::<impl TryFrom<u32> for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } } - } - } - scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - debug self => _4; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _11: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - scope 10 { - debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL - } - scope 11 { - scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL - scope 14 { - scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 7 (inlined Result::<u16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::<u16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option<u16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } } } + scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } } } - scope 12 (inlined Option::<u16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _11; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL - } } } } bb0: { - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = const 65535_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_2, move _7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _12 = discriminant(_4); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - } - - bb2: { StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb3: { - _5 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + bb2: { + _7 = Result::<u16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::<u16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb4: { - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = _2 as u16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = Result::<u16, TryFromIntError>::Ok(move _8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - StorageDead(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _9 = discriminant(_5); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<u16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - _4 = Option::<u16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb7: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<u16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb8: { - _10 = move ((_5 as Ok).0: u16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _4 = Option::<u16>::Some(move _10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb9: { - _3 = move ((_4 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - _0 = unchecked_shl::<u16>(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _3 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shl::<u16>(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::<u16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff index 35d5b6e72f2..f3d3e6090bb 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -10,50 +10,52 @@ + scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 + debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _6: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { -+ scope 3 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _4; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ scope 4 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL -+ debug u => _4; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _8: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _9: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ let mut _10: i16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ } -+ } -+ scope 5 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _7; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let mut _11: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ let _12: i16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ scope 6 { -+ debug x => _12; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ } -+ scope 7 { -+ scope 8 { -+ debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } + } -+ } -+ } -+ scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _13: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 10 { -+ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ scope 11 { -+ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ scope 14 { -+ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } + } + } ++ scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } + } + } -+ scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL -+ debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL -+ } + } + } + } @@ -67,75 +69,81 @@ - // mir::Constant - // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 - // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::<impl i16>::unchecked_shr}, val: Value(<ZST>) } -+ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _9 = const 32767_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _8 = Gt(_4, move _9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ switchInt(move _8) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_12); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageLive(_13); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _14) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + -+ bb3: { -+ _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ bb2: { ++ _9 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::<i16, TryFromIntError>::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { -+ StorageLive(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _10 = _4 as i16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ _7 = Result::<i16, TryFromIntError>::Ok(move _10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageDead(_10); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { -+ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL -+ StorageLive(_12); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _11 = discriminant(_7); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ switchInt(move _11) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<i16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { -+ _6 = Option::<i16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { -+ unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ _14 = move ((_9 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::<i16>::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { -+ _12 = move ((_7 as Ok).0: i16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL -+ _6 = Option::<i16>::Some(move _12); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL -+ goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { -+ _5 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_13); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _5 = move ((_8 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shr::<i16>(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir index b006085b54c..724b3c56723 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -7,122 +7,130 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { scope 1 (inlined core::num::<impl i16>::unchecked_shr) { // at $DIR/unchecked_shifts.rs:17:7: 17:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _4: std::option::Option<i16>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - let mut _5: std::result::Result<i16, std::num::TryFromIntError>; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { - scope 3 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _2; // in scope 3 at $SRC_DIR/core/src/convert/mod.rs:LL:COL - scope 4 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL - debug u => _2; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _6: bool; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _7: u32; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - let mut _8: i16; // in scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - } - } - scope 5 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _5; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let mut _9: isize; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - let _10: i16; // in scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - scope 6 { - debug x => _10; // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - } - scope 7 { - scope 8 { - debug x => const TryFromIntError(()); // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + scope 3 (inlined core::num::<impl i16>::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option<i16>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result<i16, std::num::TryFromIntError>; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined <u32 as TryInto<i16>>::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num::<impl TryFrom<u32> for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } } - } - } - scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - debug self => _4; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _11: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _12: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - scope 10 { - debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL - } - scope 11 { - scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL - scope 14 { - scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + scope 7 (inlined Result::<i16, TryFromIntError>::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::<i16>::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option<i16>; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } } } + scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } } } - scope 12 (inlined Option::<i16>::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL - debug self => _11; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL - } } } } bb0: { - StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _7 = const 32767_u32; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _6 = Gt(_2, move _7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_7); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - switchInt(move _6) -> [0: bb4, otherwise: bb3]; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { - StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageLive(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _12 = discriminant(_4); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _12) -> [1: bb9, otherwise: bb7]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - } - - bb2: { StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 } - bb3: { - _5 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + bb2: { + _7 = Result::<i16, TryFromIntError>::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL // mir::Constant // + span: no-location // + literal: Const { ty: TryFromIntError, val: Value(<ZST>) } - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::<i16, TryFromIntError>::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb4: { - StorageLive(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _8 = _2 as i16 (IntToInt); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - _5 = Result::<i16, TryFromIntError>::Ok(move _8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageDead(_8); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - goto -> bb5; // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb5: { - StorageDead(_6); // scope 4 at $SRC_DIR/core/src/convert/num.rs:LL:COL - StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _9 = discriminant(_5); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - switchInt(move _9) -> [0: bb8, 1: bb6, otherwise: bb7]; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<i16>::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb6: { - _4 = Option::<i16>::None; // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb7: { - unreachable; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::<i16>::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL } bb8: { - _10 = move ((_5 as Ok).0: i16); // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL - _4 = Option::<i16>::Some(move _10); // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL - goto -> bb1; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL } bb9: { - _3 = move ((_4 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_11); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - _0 = unchecked_shr::<i16>(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _3 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _0 = unchecked_shr::<i16>(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::<i16>}, val: Value(<ZST>) } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff index 543ddcfc44c..8a8cd896e85 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff @@ -34,7 +34,7 @@ - // + literal: Const { ty: unsafe fn(Option<T>) -> T {Option::<T>::unwrap_unchecked}, val: Value(<ZST>) } + StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + _4 = discriminant(_2); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL -+ switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _4) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL } bb1: { diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs new file mode 100644 index 00000000000..09779d789e5 --- /dev/null +++ b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.rs @@ -0,0 +1,16 @@ +// compile-flags: -Zmir-opt-level=2 -Zinline-mir +// ignore-debug: standard library debug assertions add a panic that breaks this optimization +#![crate_type = "lib"] + +pub enum Thing { + A, + B, +} + +// EMIT_MIR instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir +pub unsafe fn ub_if_b(t: Thing) -> Thing { + match t { + Thing::A => t, + Thing::B => std::hint::unreachable_unchecked(), + } +} diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir new file mode 100644 index 00000000000..acb7297310f --- /dev/null +++ b/tests/mir-opt/instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir @@ -0,0 +1,27 @@ +// MIR for `ub_if_b` after PreCodegen + +fn ub_if_b(_1: Thing) -> Thing { + debug t => _1; // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:23: +0:24 + let mut _0: Thing; // return place in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:36: +0:41 + let mut _2: isize; // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:9: +2:17 + scope 1 (inlined unreachable_unchecked) { // at $DIR/instcombine_duplicate_switch_targets_e2e.rs:14:21: 14:55 + scope 2 { + scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + + bb0: { + _2 = discriminant(_1); // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:11: +1:12 + switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:5: +1:12 + } + + bb1: { + unreachable; // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2: { + _0 = move _1; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:21: +2:22 + return; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+5:2: +5:2 + } +} diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir index 2324f53566c..f0c9ef419bd 100644 --- a/tests/mir-opt/issue_99325.main.built.after.mir +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -2,7 +2,7 @@ | User Type Annotations | 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: WithOptConstParam { did: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), const_param_did: Some(DefId(0:4 ~ issue_99325[22bb]::function_with_bytes::BYTES)) }, substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15 diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index 42b60532690..9f955b4717b 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -4,31 +4,29 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24 let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 let mut _2: std::option::Option<u32>; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 - let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 scope 1 (inlined char::methods::<impl char>::is_digit) { // at $DIR/issue_59352.rs:15:12: 15:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let mut _4: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let _5: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => const 8_u32; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _3: &std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _4: std::option::Option<u32>; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL scope 2 (inlined Option::<u32>::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug self => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _6: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _3; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _5: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } } scope 3 (inlined #[track_caller] Option::<u32>::unwrap) { // at $DIR/issue_59352.rs:15:42: 15:50 debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _8: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _7: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL scope 4 { debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL } } bb0: { - StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _5 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _4 = char::methods::<impl char>::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL // + literal: Const { ty: fn(char, u32) -> Option<u32> {char::methods::<impl char>::to_digit}, val: Value(<ZST>) } @@ -43,8 +41,8 @@ fn num_to_digit(_1: char) -> u32 { } bb2: { - _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _6 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _6) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL } bb3: { @@ -57,16 +55,15 @@ fn num_to_digit(_1: char) -> u32 { } bb5: { - _4 = &_5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _6 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + _3 = &_4; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _5 = discriminant((*_3)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 - switchInt(move _6) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { - _8 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/option.rs:LL:COL // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(<ZST>) } diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir index 4f5df133181..f1f7857a1bd 100644 --- a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir +++ b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir @@ -2,24 +2,21 @@ fn f_u64() -> () { let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16 - let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21 - debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 - let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + debug t => const 0_u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 + let _1: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 - _2 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + _1 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 // mir::Constant // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18 // + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) } } bb1: { - StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 } } diff --git a/tests/run-make-fulldeps/obtain-borrowck/driver.rs b/tests/run-make-fulldeps/obtain-borrowck/driver.rs index 9cd504f004d..7bd7bb7c1ea 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/driver.rs +++ b/tests/run-make-fulldeps/obtain-borrowck/driver.rs @@ -20,13 +20,13 @@ extern crate rustc_session; use rustc_borrowck::consumers::BodyWithBorrowckFacts; use rustc_driver::Compilation; -use rustc_hir::def_id::LocalDefId; use rustc_hir::def::DefKind; +use rustc_hir::def_id::LocalDefId; use rustc_interface::interface::Compiler; use rustc_interface::{Config, Queries}; use rustc_middle::ty::query::query_values::mir_borrowck; use rustc_middle::ty::query::{ExternProviders, Providers}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_session::Session; use std::cell::RefCell; use std::collections::HashMap; @@ -127,10 +127,7 @@ thread_local! { } fn mir_borrowck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> mir_borrowck<'tcx> { - let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts( - tcx, - ty::WithOptConstParam::unknown(def_id), - ); + let body_with_facts = rustc_borrowck::consumers::get_body_with_borrowck_facts(tcx, def_id); // SAFETY: The reader casts the 'static lifetime to 'tcx before using it. let body_with_facts: BodyWithBorrowckFacts<'static> = unsafe { std::mem::transmute(body_with_facts) }; diff --git a/tests/run-make/const-prop-lint/Makefile b/tests/run-make/const-prop-lint/Makefile new file mode 100644 index 00000000000..f29f282f787 --- /dev/null +++ b/tests/run-make/const-prop-lint/Makefile @@ -0,0 +1,9 @@ +include ../tools.mk + +# Test that emitting an error because of arithmetic +# overflow lint does not leave .o files around +# because of interrupted codegen. + +all: + $(RUSTC) input.rs; test $$? -eq 1 + ls *.o; test $$? -ne 0 diff --git a/tests/run-make/const-prop-lint/input.rs b/tests/run-make/const-prop-lint/input.rs new file mode 100644 index 00000000000..ccbdfb8d50b --- /dev/null +++ b/tests/run-make/const-prop-lint/input.rs @@ -0,0 +1,5 @@ +#![deny(arithmetic_overflow)] + +fn main() { + let x = 255u8 + 1; +} diff --git a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt index 48983ba4358..7eb33a29a92 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.generics.txt @@ -11,16 +11,16 @@ 11| 3| self.strength = new_strength; 12| 3| } ------------------ - | <generics::Firework<i32>>::set_strength: - | 10| 1| fn set_strength(&mut self, new_strength: T) { - | 11| 1| self.strength = new_strength; - | 12| 1| } - ------------------ | <generics::Firework<f64>>::set_strength: | 10| 2| fn set_strength(&mut self, new_strength: T) { | 11| 2| self.strength = new_strength; | 12| 2| } ------------------ + | <generics::Firework<i32>>::set_strength: + | 10| 1| fn set_strength(&mut self, new_strength: T) { + | 11| 1| self.strength = new_strength; + | 12| 1| } + ------------------ 13| |} 14| | 15| |impl<T> Drop for Firework<T> where T: Copy + std::fmt::Display { diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt index 4a60432c14c..9c3192c008c 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt @@ -136,10 +136,10 @@ 134| | 135| |impl std::fmt::Debug for Foo { 136| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - 137| 7| write!(f, "try and succeed")?; + 137| 9| write!(f, "try and succeed")?; ^0 - 138| 7| Ok(()) - 139| 7| } + 138| 9| Ok(()) + 139| 9| } 140| |} 141| | 142| |static mut DEBUG_LEVEL_ENABLED: bool = false; diff --git a/tests/run-make/coverage/uses_crate.rs b/tests/run-make/coverage/uses_crate.rs index 20cb05fe5b0..1ee8037a1e7 100644 --- a/tests/run-make/coverage/uses_crate.rs +++ b/tests/run-make/coverage/uses_crate.rs @@ -1,3 +1,6 @@ +// FIXME #110395 +// ignore-llvm-cov-show-diffs + #![allow(unused_assignments, unused_variables)] // compile-flags: -C opt-level=3 # validates coverage now works with optimizations extern crate used_crate; diff --git a/tests/run-make/coverage/uses_inline_crate.rs b/tests/run-make/coverage/uses_inline_crate.rs index a7fe8532be3..f7aff3c3f8a 100644 --- a/tests/run-make/coverage/uses_inline_crate.rs +++ b/tests/run-make/coverage/uses_inline_crate.rs @@ -1,3 +1,6 @@ +// FIXME #110395 +// ignore-llvm-cov-show-diffs + #![allow(unused_assignments, unused_variables)] // compile-flags: -C opt-level=3 # validates coverage now works with optimizations diff --git a/tests/run-make/issue-51671/Makefile b/tests/run-make/issue-51671/Makefile index c9364536992..00cf9134662 100644 --- a/tests/run-make/issue-51671/Makefile +++ b/tests/run-make/issue-51671/Makefile @@ -6,4 +6,3 @@ all: $(RUSTC) --emit=obj app.rs nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality - nm $(TMPDIR)/app.o | $(CGREP) __rg_oom diff --git a/tests/run-make/issue-51671/app.rs b/tests/run-make/issue-51671/app.rs index e9dc1e9744f..a9d3457bf90 100644 --- a/tests/run-make/issue-51671/app.rs +++ b/tests/run-make/issue-51671/app.rs @@ -1,5 +1,5 @@ #![crate_type = "bin"] -#![feature(lang_items, alloc_error_handler)] +#![feature(lang_items)] #![no_main] #![no_std] @@ -13,8 +13,3 @@ fn panic(_: &PanicInfo) -> ! { #[lang = "eh_personality"] fn eh() {} - -#[alloc_error_handler] -fn oom(_: Layout) -> ! { - loop {} -} diff --git a/tests/run-make/issue-69368/Makefile b/tests/run-make/issue-69368/Makefile deleted file mode 100644 index b1229d1b07f..00000000000 --- a/tests/run-make/issue-69368/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test that previously triggered a linker failure with root cause -# similar to one found in the issue #69368. -# -# The crate that provides oom lang item is missing some other lang -# items. Necessary to prevent the use of start-group / end-group. -# -# The weak lang items are defined in a separate compilation units, -# so that linker could omit them if not used. -# -# The crates that need those weak lang items are dependencies of -# crates that provide them. - -all: - $(RUSTC) a.rs - $(RUSTC) b.rs - $(RUSTC) c.rs diff --git a/tests/run-make/issue-69368/a.rs b/tests/run-make/issue-69368/a.rs deleted file mode 100644 index a54f429550e..00000000000 --- a/tests/run-make/issue-69368/a.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![crate_type = "rlib"] -#![feature(lang_items)] -#![feature(panic_unwind)] -#![no_std] - -extern crate panic_unwind; - -#[panic_handler] -pub fn panic_handler(_: &core::panic::PanicInfo) -> ! { - loop {} -} - -#[no_mangle] -extern "C" fn __rust_drop_panic() -> ! { - loop {} -} - -#[no_mangle] -extern "C" fn __rust_foreign_exception() -> ! { - loop {} -} - -#[lang = "eh_personality"] -fn eh_personality() { - loop {} -} diff --git a/tests/run-make/issue-69368/b.rs b/tests/run-make/issue-69368/b.rs deleted file mode 100644 index 4d6af026656..00000000000 --- a/tests/run-make/issue-69368/b.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![crate_type = "rlib"] -#![feature(alloc_error_handler)] -#![no_std] - -#[alloc_error_handler] -pub fn error_handler(_: core::alloc::Layout) -> ! { - panic!(); -} diff --git a/tests/run-make/issue-69368/c.rs b/tests/run-make/issue-69368/c.rs deleted file mode 100644 index 729c4249a05..00000000000 --- a/tests/run-make/issue-69368/c.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![crate_type = "bin"] -#![feature(start)] -#![no_std] - -extern crate alloc; -extern crate a; -extern crate b; - -use alloc::vec::Vec; -use core::alloc::*; - -struct Allocator; - -unsafe impl GlobalAlloc for Allocator { - unsafe fn alloc(&self, _: Layout) -> *mut u8 { - loop {} - } - - unsafe fn dealloc(&self, _: *mut u8, _: Layout) { - loop {} - } -} - -#[global_allocator] -static ALLOCATOR: Allocator = Allocator; - -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { - let mut v = Vec::new(); - for i in 0..argc { - v.push(i); - } - v.iter().sum() -} diff --git a/tests/run-make/translation/Makefile b/tests/run-make/translation/Makefile index 0acf64e5da7..07e0547cfa0 100644 --- a/tests/run-make/translation/Makefile +++ b/tests/run-make/translation/Makefile @@ -46,6 +46,8 @@ sysroot: test.rs working.ftl rm -f $(FAKEROOT)/lib/rustlib/src mkdir $(FAKEROOT)/lib/rustlib/src ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src + # When download-rustc is enabled, `$(SYSROOT)` will have a share directory. Delete the link to it. + rm -f $(FAKEROOT)/share mkdir -p $(FAKEROOT)/share/locale/zh-CN/ ln -s $(CURDIR)/working.ftl $(FAKEROOT)/share/locale/zh-CN/basic-translation.ftl $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | $(CGREP) "this is a test message" diff --git a/tests/run-make/wasm-symbols-not-exported/bar.rs b/tests/run-make/wasm-symbols-not-exported/bar.rs index 6ffbd3ec690..eb768446b4b 100644 --- a/tests/run-make/wasm-symbols-not-exported/bar.rs +++ b/tests/run-make/wasm-symbols-not-exported/bar.rs @@ -1,4 +1,4 @@ -#![feature(panic_handler, alloc_error_handler)] +#![feature(panic_handler)] #![crate_type = "cdylib"] #![no_std] @@ -24,11 +24,6 @@ pub extern fn foo(a: u32) -> u32 { a * 2 } -#[alloc_error_handler] -fn a(_: core::alloc::Layout) -> ! { - loop {} -} - #[panic_handler] fn b(_: &core::panic::PanicInfo) -> ! { loop {} diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 733be9bebba..a44ff9d3e4a 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -256,6 +256,15 @@ set-local-storage: {"rustdoc-disable-shortcuts": "false"} click: ".setting-line:last-child .setting-check span" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +// We now check that focusing a toggle and pressing Space is like clicking on it. +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "false"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} + // Make sure that "Disable keyboard shortcuts" actually took effect. press-key: "Escape" press-key: "?" diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs new file mode 100644 index 00000000000..ef9c56f7592 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.rs @@ -0,0 +1,6 @@ +// this test used to ICE +#![deny(rustdoc::broken_intra_doc_links)] +//! [Clone ()]. //~ ERROR unresolved +//! [Clone !]. //~ ERROR incompatible +//! [`Clone ()`]. //~ ERROR unresolved +//! [`Clone !`]. //~ ERROR incompatible diff --git a/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr new file mode 100644 index 00000000000..8669b0c2086 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-110495-suffix-with-space.stderr @@ -0,0 +1,54 @@ +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:3:6 + | +LL | //! [Clone ()]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace + | +note: the lint level is defined here + --> $DIR/issue-110495-suffix-with-space.rs:2:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the trait, prefix with `trait@` + | +LL - //! [Clone ()]. +LL + //! [trait@Clone ]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:4:6 + | +LL | //! [Clone !]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL - //! [Clone !]. +LL + //! [derive@Clone ]. + | + +error: unresolved link to `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:5:7 + | +LL | //! [`Clone ()`]. + | ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace + | +help: to link to the trait, prefix with `trait@` + | +LL - //! [`Clone ()`]. +LL + //! [`trait@Clone (`]. + | + +error: incompatible link kind for `Clone` + --> $DIR/issue-110495-suffix-with-space.rs:6:7 + | +LL | //! [`Clone !`]. + | ^^^^^^^ this link resolved to a derive macro, which is not a macro + | +help: to link to the derive macro, prefix with `derive@` + | +LL | //! [`derive@Clone !`]. + | +++++++ + +error: aborting due to 4 previous errors + diff --git a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs index d368db909fa..6006354eba4 100644 --- a/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs +++ b/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs @@ -29,7 +29,7 @@ pub trait Stage { // // @has - '//*[@id="associatedconstant.ARRAY1"]' \ // 'const ARRAY1: [u8; { _ }]' - const ARRAY1: [u8; Struct::new(/* ... */) + Self::ABSTRACT * 1_000]; + const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)]; // @has - '//*[@id="associatedconstant.VERBOSE"]' \ // 'const VERBOSE: [u16; { _ }]' @@ -73,10 +73,14 @@ pub struct Struct { private: () } impl Struct { const fn new() -> Self { Self { private: () } } + const fn do_something(self, x: usize) -> usize { + x + } } - +/* FIXME(const-trait): readd this impl const std::ops::Add<usize> for Struct { type Output = usize; fn add(self, _: usize) -> usize { 0 } } +*/ diff --git a/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs new file mode 100644 index 00000000000..d8953eaf597 --- /dev/null +++ b/tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs @@ -0,0 +1,24 @@ +// This is a regression test for <https://github.com/rust-lang/rust/issues/46506>. +// This test ensures that if public re-exported is re-exported, it won't be inlined. + +#![crate_name = "foo"] + +// @has 'foo/associations/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy' +// @has 'foo/associations/trait.GroupedBy.html' +pub mod associations { + mod belongs_to { + pub trait GroupedBy {} + } + pub use self::belongs_to::GroupedBy; +} + +// @has 'foo/prelude/index.html' +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports' +// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;' +pub mod prelude { + pub use associations::GroupedBy; +} diff --git a/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs b/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs new file mode 100644 index 00000000000..95ddd4c7471 --- /dev/null +++ b/tests/rustdoc/issue-94183-blanket-impl-reexported-trait.rs @@ -0,0 +1,31 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/94183>. +// This test ensures that a publicly re-exported private trait will +// appear in the blanket impl list. + +#![crate_name = "foo"] + +// @has 'foo/struct.S.html' + +mod actual_sub { + pub trait Actual {} + pub trait Another {} + + // `Another` is publicly re-exported so it should appear in the blanket impl list. + // @has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Another for T' + impl<T> Another for T {} + + trait Foo {} + + // `Foo` is not publicly re-exported nor reachable so it shouldn't appear in the + // blanket impl list. + // @!has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Foo for T' + impl<T> Foo for T {} +} + +pub use actual_sub::{Actual, Another}; + +// `Actual` is publicly re-exported so it should appear in the blanket impl list. +// @has - '//*[@id="blanket-implementations-list"]//*[@class="code-header"]' 'impl<T> Actual for T' +impl<T> Actual for T {} + +pub struct S; diff --git a/tests/rustdoc/rfc-2632-const-trait-impl.rs b/tests/rustdoc/rfc-2632-const-trait-impl.rs index 1120302ac7e..5d742dc391a 100644 --- a/tests/rustdoc/rfc-2632-const-trait-impl.rs +++ b/tests/rustdoc/rfc-2632-const-trait-impl.rs @@ -13,57 +13,57 @@ use std::marker::Destruct; pub struct S<T>(T); // @!has foo/trait.Tr.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Clone' +// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' // @!has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Clone' +// @has - '//pre[@class="rust item-decl"]/code/span[@class="where"]' ': Fn' #[const_trait] pub trait Tr<T> { // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const' - // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - fn a<A: ~const Clone + ~const Destruct>() + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + fn a<A: ~const Fn() + ~const Destruct>() where - Option<A>: ~const Clone + ~const Destruct, + Option<A>: ~const Fn() + ~const Destruct, { } } // @has - '//section[@id="impl-Tr%3CT%3E-for-T"]' '' // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]' '~const' -// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Clone' +// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const' -// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' -impl<T: ~const Clone + ~const Destruct> const Tr<T> for T +// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' +impl<T: ~const Fn() + ~const Destruct> const Tr<T> for T where - Option<T>: ~const Clone + ~const Destruct, + Option<T>: ~const Fn() + ~const Destruct, { - fn a<A: ~const Clone + ~const Destruct>() + fn a<A: ~const Fn() + ~const Destruct>() where - Option<A>: ~const Clone + ~const Destruct, + Option<A>: ~const Fn() + ~const Destruct, { } } // @!has foo/fn.foo.html '//pre[@class="rust item-decl"]/code/a[@class="trait"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Clone' +// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn' // @!has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' '~const' -// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Clone' -pub const fn foo<F: ~const Clone + ~const Destruct>() +// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Fn' +pub const fn foo<F: ~const Fn() + ~const Destruct>() where - Option<F>: ~const Clone + ~const Destruct, + Option<F>: ~const Fn() + ~const Destruct, { F::a() } impl<T> S<T> { // @!has foo/struct.S.html '//section[@id="method.foo"]/h4[@class="code-header"]' '~const' - // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn' // @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' - pub const fn foo<B, C: ~const Clone + ~const Destruct>() + // @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn' + pub const fn foo<B, C: ~const Fn() + ~const Destruct>() where - B: ~const Clone + ~const Destruct, + B: ~const Fn() + ~const Destruct, { B::a() } diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 6ba13387b04..1dd6d211b3f 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -3,8 +3,8 @@ #![feature(rustc_private)] #![crate_type = "lib"] -extern crate rustc_macros; -use rustc_macros::fluent_messages; +extern crate rustc_fluent_macro; +use rustc_fluent_macro::fluent_messages; /// Copy of the relevant `DiagnosticMessage` variant constructed by `fluent_messages` as it /// expects `crate::DiagnosticMessage` to exist. diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 3aa65d53d4e..994fc26ba02 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -7,15 +7,17 @@ #![deny(rustc::diagnostic_outside_of_impl)] extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; use rustc_errors::{ - AddToDiagnostic, IntoDiagnostic, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, Handler, DiagnosticMessage, SubdiagnosticMessage, + AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, Handler, + IntoDiagnostic, SubdiagnosticMessage, }; -use rustc_macros::{fluent_messages, Diagnostic, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; fluent_messages! { "./diagnostics.ftl" } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 6f797ebc2dd..6e670c01852 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,5 +1,5 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:41:17 + --> $DIR/diagnostics.rs:43:17 | LL | handler.struct_err("untranslatable diagnostic") | ^^^^^^^^^^ @@ -11,13 +11,13 @@ LL | #![deny(rustc::untranslatable_diagnostic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:61:14 + --> $DIR/diagnostics.rs:63:14 | LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:78:25 + --> $DIR/diagnostics.rs:80:25 | LL | let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ @@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:81:25 + --> $DIR/diagnostics.rs:83:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:81:25 + --> $DIR/diagnostics.rs:83:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index ef85fada506..80ab03ab24c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -17,8 +17,10 @@ extern crate rustc_span; use rustc_span::symbol::Ident; use rustc_span::Span; +extern crate rustc_fluent_macro; extern crate rustc_macros; -use rustc_macros::{fluent_messages, Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; extern crate rustc_middle; use rustc_middle::ty::Ty; diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 3f961449566..5e1bea4e38c 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,11 +1,11 @@ error: unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:42:1 + --> $DIR/diagnostic-derive.rs:44:1 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:45:5 + --> $DIR/diagnostic-derive.rs:47:5 | LL | Foo, | ^^^ @@ -13,7 +13,7 @@ LL | Foo, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:47:5 + --> $DIR/diagnostic-derive.rs:49:5 | LL | Bar, | ^^^ @@ -21,19 +21,19 @@ LL | Bar, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: expected parentheses: #[diag(...)] - --> $DIR/diagnostic-derive.rs:53:8 + --> $DIR/diagnostic-derive.rs:55:8 | LL | #[diag = "E0123"] | ^ error: `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:58:1 + --> $DIR/diagnostic-derive.rs:60:1 | LL | #[nonsense(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:58:1 + --> $DIR/diagnostic-derive.rs:60:1 | LL | / #[nonsense(no_crate_example, code = "E0123")] LL | | @@ -45,7 +45,7 @@ LL | | struct InvalidStructAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:65:1 + --> $DIR/diagnostic-derive.rs:67:1 | LL | / #[diag("E0123")] LL | | @@ -55,13 +55,13 @@ LL | | struct InvalidLitNestedAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:75:16 + --> $DIR/diagnostic-derive.rs:77:16 | LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:75:1 + --> $DIR/diagnostic-derive.rs:77:1 | LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")] LL | | @@ -72,7 +72,7 @@ LL | | struct InvalidNestedStructAttr1 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:81:8 + --> $DIR/diagnostic-derive.rs:83:8 | LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^ @@ -80,7 +80,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:81:1 + --> $DIR/diagnostic-derive.rs:83:1 | LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")] LL | | @@ -91,7 +91,7 @@ LL | | struct InvalidNestedStructAttr2 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:87:8 + --> $DIR/diagnostic-derive.rs:89:8 | LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^ @@ -99,7 +99,7 @@ LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:87:1 + --> $DIR/diagnostic-derive.rs:89:1 | LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")] LL | | @@ -110,7 +110,7 @@ LL | | struct InvalidNestedStructAttr3 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: unknown argument - --> $DIR/diagnostic-derive.rs:93:42 + --> $DIR/diagnostic-derive.rs:95:42 | LL | #[diag(no_crate_example, code = "E0123", slug = "foo")] | ^^^^ @@ -118,55 +118,55 @@ LL | #[diag(no_crate_example, code = "E0123", slug = "foo")] = note: only the `code` parameter is valid after the slug error: `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:100:5 + --> $DIR/diagnostic-derive.rs:102:5 | LL | #[suggestion = "bar"] | ^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:8 + --> $DIR/diagnostic-derive.rs:109:8 | LL | #[diag(no_crate_example, code = "E0456")] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:8 + --> $DIR/diagnostic-derive.rs:108:8 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:26 + --> $DIR/diagnostic-derive.rs:109:26 | LL | #[diag(no_crate_example, code = "E0456")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:26 + --> $DIR/diagnostic-derive.rs:108:26 | LL | #[diag(no_crate_example, code = "E0123")] | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:113:42 + --> $DIR/diagnostic-derive.rs:115:42 | LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:113:26 + --> $DIR/diagnostic-derive.rs:115:26 | LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] | ^^^^ error: diagnostic slug must be the first argument - --> $DIR/diagnostic-derive.rs:118:43 + --> $DIR/diagnostic-derive.rs:120:43 | LL | #[diag(no_crate_example, no_crate::example, code = "E0456")] | ^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:123:1 + --> $DIR/diagnostic-derive.rs:125:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ LL | struct KindNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:126:1 + --> $DIR/diagnostic-derive.rs:128:1 | LL | / #[diag(code = "E0456")] LL | | @@ -184,31 +184,31 @@ LL | | struct SlugNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:137:5 + --> $DIR/diagnostic-derive.rs:139:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:145:5 + --> $DIR/diagnostic-derive.rs:147:5 | LL | #[nonsense] | ^^^^^^^^^^^ error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:162:5 + --> $DIR/diagnostic-derive.rs:164:5 | LL | #[label(no_crate_label)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:170:46 + --> $DIR/diagnostic-derive.rs:172:46 | LL | #[suggestion(no_crate_suggestion, code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:175:10 + --> $DIR/diagnostic-derive.rs:177:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ expected `'}'` in format string @@ -217,7 +217,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:185:10 + --> $DIR/diagnostic-derive.rs:187:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ unmatched `}` in format string @@ -226,19 +226,19 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:205:5 + --> $DIR/diagnostic-derive.rs:207:5 | LL | #[label(no_crate_label)] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:224:5 + --> $DIR/diagnostic-derive.rs:226:5 | LL | #[suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:232:18 + --> $DIR/diagnostic-derive.rs:234:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^ @@ -246,13 +246,13 @@ LL | #[suggestion(nonsense = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:232:5 + --> $DIR/diagnostic-derive.rs:234:5 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:241:18 + --> $DIR/diagnostic-derive.rs:243:18 | LL | #[suggestion(msg = "bar")] | ^^^ @@ -260,13 +260,13 @@ LL | #[suggestion(msg = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:241:5 + --> $DIR/diagnostic-derive.rs:243:5 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:264:5 + --> $DIR/diagnostic-derive.rs:266:5 | LL | / #[suggestion(no_crate_suggestion, code = "This is suggested code")] LL | | @@ -276,79 +276,79 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: specified multiple times - --> $DIR/diagnostic-derive.rs:280:24 + --> $DIR/diagnostic-derive.rs:282:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:280:18 + --> $DIR/diagnostic-derive.rs:282:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:288:33 + --> $DIR/diagnostic-derive.rs:290:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:288:18 + --> $DIR/diagnostic-derive.rs:290:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:295:5 + --> $DIR/diagnostic-derive.rs:297:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:446:5 + --> $DIR/diagnostic-derive.rs:448:5 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:448:24 + --> $DIR/diagnostic-derive.rs:450:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:454:69 + --> $DIR/diagnostic-derive.rs:456:69 | LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] | ^^^^^^^^ error: the `#[help(...)]` attribute can only be applied to fields of type `Span`, `MultiSpan`, `bool` or `()` - --> $DIR/diagnostic-derive.rs:521:5 + --> $DIR/diagnostic-derive.rs:523:5 | LL | #[help(no_crate_help)] | ^^^^^^^^^^^^^^^^^^^^^^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/diagnostic-derive.rs:530:32 + --> $DIR/diagnostic-derive.rs:532:32 | LL | #[label(no_crate_label, foo)] | ^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:538:29 + --> $DIR/diagnostic-derive.rs:540:29 | LL | #[label(no_crate_label, foo = "...")] | ^^^ error: invalid nested attribute - --> $DIR/diagnostic-derive.rs:546:29 + --> $DIR/diagnostic-derive.rs:548:29 | LL | #[label(no_crate_label, foo("..."))] | ^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:558:5 + --> $DIR/diagnostic-derive.rs:560:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -356,13 +356,13 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:578:1 + --> $DIR/diagnostic-derive.rs:580:1 | LL | #[error(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:578:1 + --> $DIR/diagnostic-derive.rs:580:1 | LL | / #[error(no_crate_example, code = "E0123")] LL | | @@ -374,13 +374,13 @@ LL | | struct ErrorAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:585:1 + --> $DIR/diagnostic-derive.rs:587:1 | LL | #[warn_(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:585:1 + --> $DIR/diagnostic-derive.rs:587:1 | LL | / #[warn_(no_crate_example, code = "E0123")] LL | | @@ -392,13 +392,13 @@ LL | | struct WarnAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:592:1 + --> $DIR/diagnostic-derive.rs:594:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:592:1 + --> $DIR/diagnostic-derive.rs:594:1 | LL | / #[lint(no_crate_example, code = "E0123")] LL | | @@ -410,19 +410,19 @@ LL | | struct LintAttributeOnSessionDiag {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:599:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:599:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:599:1 + --> $DIR/diagnostic-derive.rs:601:1 | LL | / #[lint(no_crate_example, code = "E0123")] LL | | @@ -435,19 +435,19 @@ LL | | struct LintAttributeOnLintDiag {} = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:609:53 + --> $DIR/diagnostic-derive.rs:611:53 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:609:39 + --> $DIR/diagnostic-derive.rs:611:39 | LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] | ^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:618:24 + --> $DIR/diagnostic-derive.rs:620:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -455,7 +455,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:626:17 + --> $DIR/diagnostic-derive.rs:628:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -463,13 +463,13 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:633:5 + --> $DIR/diagnostic-derive.rs:635:5 | LL | #[suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:640:1 + --> $DIR/diagnostic-derive.rs:642:1 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -477,7 +477,7 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:647:5 + --> $DIR/diagnostic-derive.rs:649:5 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -485,13 +485,13 @@ LL | #[multipart_suggestion(no_crate_suggestion)] = help: consider creating a `Subdiagnostic` instead error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/diagnostic-derive.rs:643:24 + --> $DIR/diagnostic-derive.rs:645:24 | LL | #[multipart_suggestion()] | ^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:655:1 + --> $DIR/diagnostic-derive.rs:657:1 | LL | #[suggestion(no_crate_suggestion, code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -499,7 +499,7 @@ LL | #[suggestion(no_crate_suggestion, code = "...")] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:664:1 + --> $DIR/diagnostic-derive.rs:666:1 | LL | #[label] | ^^^^^^^^ @@ -507,31 +507,31 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:698:7 + --> $DIR/diagnostic-derive.rs:700:7 | LL | #[subdiagnostic(bad)] | ^^^^^^^^^^^^^^^^^^ error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:706:5 + --> $DIR/diagnostic-derive.rs:708:5 | LL | #[subdiagnostic = "bad"] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:714:7 + --> $DIR/diagnostic-derive.rs:716:7 | LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^ error: `eager` is the only supported nested attribute for `subdiagnostic` - --> $DIR/diagnostic-derive.rs:722:7 + --> $DIR/diagnostic-derive.rs:724:7 | LL | #[subdiagnostic("bad")] | ^^^^^^^^^^^^^^^^^^^^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:730:5 + --> $DIR/diagnostic-derive.rs:732:5 | LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -539,31 +539,31 @@ LL | #[subdiagnostic(eager)] = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:788:23 + --> $DIR/diagnostic-derive.rs:790:23 | LL | #[suggestion(code())] | ^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:796:23 + --> $DIR/diagnostic-derive.rs:798:23 | LL | #[suggestion(code(foo))] | ^^^ error: unexpected token - --> $DIR/diagnostic-derive.rs:796:23 + --> $DIR/diagnostic-derive.rs:798:23 | LL | #[suggestion(code(foo))] | ^^^ error: expected string literal - --> $DIR/diagnostic-derive.rs:805:25 + --> $DIR/diagnostic-derive.rs:807:25 | LL | #[suggestion(code = 3)] | ^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:820:5 + --> $DIR/diagnostic-derive.rs:822:5 | LL | #[suggestion(no_crate_suggestion, code = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -573,67 +573,67 @@ LL | #[suggestion(no_crate_suggestion, code = "")] = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:58:3 + --> $DIR/diagnostic-derive.rs:60:3 | LL | #[nonsense(no_crate_example, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:145:7 + --> $DIR/diagnostic-derive.rs:147:7 | LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:578:3 + --> $DIR/diagnostic-derive.rs:580:3 | LL | #[error(no_crate_example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:585:3 + --> $DIR/diagnostic-derive.rs:587:3 | LL | #[warn_(no_crate_example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:592:3 + --> $DIR/diagnostic-derive.rs:594:3 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:599:3 + --> $DIR/diagnostic-derive.rs:601:3 | LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:640:3 + --> $DIR/diagnostic-derive.rs:642:3 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:643:3 + --> $DIR/diagnostic-derive.rs:645:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:647:7 + --> $DIR/diagnostic-derive.rs:649:7 | LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` - --> $DIR/diagnostic-derive.rs:70:8 + --> $DIR/diagnostic-derive.rs:72:8 | LL | #[diag(nonsense, code = "E0123")] | ^^^^^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_34` in this scope - --> $DIR/diagnostic-derive.rs:802:10 + --> $DIR/diagnostic-derive.rs:804:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ not found in this scope @@ -641,7 +641,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:339:10 + --> $DIR/diagnostic-derive.rs:341:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 73cc1cfc03a..1bfbb60015d 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -12,12 +12,14 @@ #![crate_type = "lib"] extern crate rustc_errors; +extern crate rustc_fluent_macro; extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage}; -use rustc_macros::{fluent_messages, Subdiagnostic}; +use rustc_fluent_macro::fluent_messages; +use rustc_macros::Subdiagnostic; use rustc_span::Span; fluent_messages! { "./example.ftl" } diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 529003d90ab..fca4f506890 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,5 +1,5 @@ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:50:1 + --> $DIR/subdiagnostic-derive.rs:52:1 | LL | / #[label(no_crate_example)] LL | | @@ -9,133 +9,133 @@ LL | | } | |_^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:57:1 + --> $DIR/subdiagnostic-derive.rs:59:1 | LL | #[label] | ^^^^^^^^ error: `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:66:1 + --> $DIR/subdiagnostic-derive.rs:68:1 | LL | #[foo] | ^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:76:1 + --> $DIR/subdiagnostic-derive.rs:78:1 | LL | #[label = "..."] | ^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:85:9 + --> $DIR/subdiagnostic-derive.rs:87:9 | LL | #[label(bug = "...")] | ^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:85:1 + --> $DIR/subdiagnostic-derive.rs:87:1 | LL | #[label(bug = "...")] | ^^^^^^^^^^^^^^^^^^^^^ error: unexpected literal in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:95:9 + --> $DIR/subdiagnostic-derive.rs:97:9 | LL | #[label("...")] | ^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:104:9 + --> $DIR/subdiagnostic-derive.rs:106:9 | LL | #[label(slug = 4)] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:104:1 + --> $DIR/subdiagnostic-derive.rs:106:1 | LL | #[label(slug = 4)] | ^^^^^^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:114:9 + --> $DIR/subdiagnostic-derive.rs:116:9 | LL | #[label(slug("..."))] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:114:1 + --> $DIR/subdiagnostic-derive.rs:116:1 | LL | #[label(slug("..."))] | ^^^^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:134:9 + --> $DIR/subdiagnostic-derive.rs:136:9 | LL | #[label()] | ^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:143:27 + --> $DIR/subdiagnostic-derive.rs:145:27 | LL | #[label(no_crate_example, code = "...")] | ^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:152:27 + --> $DIR/subdiagnostic-derive.rs:154:27 | LL | #[label(no_crate_example, applicability = "machine-applicable")] | ^^^^^^^^^^^^^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:161:1 + --> $DIR/subdiagnostic-derive.rs:163:1 | LL | #[foo] | ^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:175:5 + --> $DIR/subdiagnostic-derive.rs:177:5 | LL | #[bar] | ^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:187:5 + --> $DIR/subdiagnostic-derive.rs:189:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:199:5 + --> $DIR/subdiagnostic-derive.rs:201:5 | LL | #[bar = 4] | ^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:211:5 + --> $DIR/subdiagnostic-derive.rs:213:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:223:13 + --> $DIR/subdiagnostic-derive.rs:225:13 | LL | #[label(code = "...")] | ^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:223:5 + --> $DIR/subdiagnostic-derive.rs:225:5 | LL | #[label(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:252:5 + --> $DIR/subdiagnostic-derive.rs:254:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:249:1 + --> $DIR/subdiagnostic-derive.rs:251:1 | LL | / #[label(no_crate_example)] LL | | @@ -147,13 +147,13 @@ LL | | } | |_^ error: `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:262:5 + --> $DIR/subdiagnostic-derive.rs:264:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:272:5 + --> $DIR/subdiagnostic-derive.rs:274:5 | LL | #[bar] | ^^^^^^ @@ -161,13 +161,13 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:283:5 + --> $DIR/subdiagnostic-derive.rs:285:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:294:5 + --> $DIR/subdiagnostic-derive.rs:296:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ @@ -175,7 +175,7 @@ LL | #[bar("...")] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive.rs:310:1 + --> $DIR/subdiagnostic-derive.rs:312:1 | LL | / union AC { LL | | @@ -185,73 +185,73 @@ LL | | } | |_^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:325:44 + --> $DIR/subdiagnostic-derive.rs:327:44 | LL | #[label(no_crate_example, no_crate::example)] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:338:5 + --> $DIR/subdiagnostic-derive.rs:340:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:335:5 + --> $DIR/subdiagnostic-derive.rs:337:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:344:8 + --> $DIR/subdiagnostic-derive.rs:346:8 | LL | struct AG { | ^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:381:46 + --> $DIR/subdiagnostic-derive.rs:383:46 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:381:32 + --> $DIR/subdiagnostic-derive.rs:383:32 | LL | #[suggestion(no_crate_example, code = "...", code = "...")] | ^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:399:5 + --> $DIR/subdiagnostic-derive.rs:401:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:396:5 + --> $DIR/subdiagnostic-derive.rs:398:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:409:5 + --> $DIR/subdiagnostic-derive.rs:411:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:422:1 + --> $DIR/subdiagnostic-derive.rs:424:1 | LL | #[suggestion(no_crate_example)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:432:62 + --> $DIR/subdiagnostic-derive.rs:434:62 | LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] | ^^^^^ error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:450:1 + --> $DIR/subdiagnostic-derive.rs:452:1 | LL | / #[suggestion(no_crate_example, code = "...")] LL | | @@ -261,25 +261,25 @@ LL | | } | |_^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:464:1 + --> $DIR/subdiagnostic-derive.rs:466:1 | LL | #[label] | ^^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:484:39 + --> $DIR/subdiagnostic-derive.rs:486:39 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:503:43 + --> $DIR/subdiagnostic-derive.rs:505:43 | LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] | ^^^^^^^ error: `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:526:5 + --> $DIR/subdiagnostic-derive.rs:528:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ @@ -287,7 +287,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:529:5 + --> $DIR/subdiagnostic-derive.rs:531:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:523:1 + --> $DIR/subdiagnostic-derive.rs:525:1 | LL | / #[suggestion(no_crate_example, code = "...")] LL | | @@ -307,7 +307,7 @@ LL | | } | |_^ error: invalid nested attribute - --> $DIR/subdiagnostic-derive.rs:538:42 + --> $DIR/subdiagnostic-derive.rs:540:42 | LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] | ^^^^ @@ -315,7 +315,7 @@ LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "mac = help: only `style` and `applicability` are valid nested attributes error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:538:1 + --> $DIR/subdiagnostic-derive.rs:540:1 | LL | / #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] LL | | @@ -326,19 +326,19 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:548:5 + --> $DIR/subdiagnostic-derive.rs:550:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:556:23 + --> $DIR/subdiagnostic-derive.rs:558:23 | LL | #[suggestion_part()] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:565:5 + --> $DIR/subdiagnostic-derive.rs:567:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -346,7 +346,7 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:562:1 + --> $DIR/subdiagnostic-derive.rs:564:1 | LL | / #[multipart_suggestion(no_crate_example)] LL | | @@ -358,121 +358,121 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:573:5 + --> $DIR/subdiagnostic-derive.rs:575:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: `code` is the only valid nested attribute - --> $DIR/subdiagnostic-derive.rs:579:23 + --> $DIR/subdiagnostic-derive.rs:581:23 | LL | #[suggestion_part(foo = "bar")] | ^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:583:5 + --> $DIR/subdiagnostic-derive.rs:585:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:586:5 + --> $DIR/subdiagnostic-derive.rs:588:5 | LL | #[suggestion_part()] | ^^^^^^^^^^^^^^^^^^^^ error: unexpected end of input, unexpected token in nested attribute, expected ident - --> $DIR/subdiagnostic-derive.rs:576:23 + --> $DIR/subdiagnostic-derive.rs:578:23 | LL | #[suggestion_part()] | ^ error: expected `,` - --> $DIR/subdiagnostic-derive.rs:579:27 + --> $DIR/subdiagnostic-derive.rs:581:27 | LL | #[suggestion_part(foo = "bar")] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:594:37 + --> $DIR/subdiagnostic-derive.rs:596:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:594:23 + --> $DIR/subdiagnostic-derive.rs:596:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^ error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:623:5 + --> $DIR/subdiagnostic-derive.rs:625:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:671:34 + --> $DIR/subdiagnostic-derive.rs:673:34 | LL | #[suggestion_part(code("foo"))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:671:28 + --> $DIR/subdiagnostic-derive.rs:673:28 | LL | #[suggestion_part(code("foo"))] | ^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:681:41 + --> $DIR/subdiagnostic-derive.rs:683:41 | LL | #[suggestion_part(code("foo", "bar"))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:681:28 + --> $DIR/subdiagnostic-derive.rs:683:28 | LL | #[suggestion_part(code("foo", "bar"))] | ^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:691:30 + --> $DIR/subdiagnostic-derive.rs:693:30 | LL | #[suggestion_part(code(3))] | ^ error: unexpected token - --> $DIR/subdiagnostic-derive.rs:691:28 + --> $DIR/subdiagnostic-derive.rs:693:28 | LL | #[suggestion_part(code(3))] | ^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:701:29 + --> $DIR/subdiagnostic-derive.rs:703:29 | LL | #[suggestion_part(code())] | ^ error: expected string literal - --> $DIR/subdiagnostic-derive.rs:713:30 + --> $DIR/subdiagnostic-derive.rs:715:30 | LL | #[suggestion_part(code = 3)] | ^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:755:1 + --> $DIR/subdiagnostic-derive.rs:757:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:755:1 + --> $DIR/subdiagnostic-derive.rs:757:1 | LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:764:1 + --> $DIR/subdiagnostic-derive.rs:766:1 | LL | #[suggestion_hidden(no_crate_example, code = "")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -480,7 +480,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:772:1 + --> $DIR/subdiagnostic-derive.rs:774:1 | LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -488,7 +488,7 @@ LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] = help: Use `#[suggestion(..., style = "hidden")]` instead error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:780:51 + --> $DIR/subdiagnostic-derive.rs:782:51 | LL | #[suggestion(no_crate_example, code = "", style = "foo")] | ^^^^^ @@ -496,31 +496,31 @@ LL | #[suggestion(no_crate_example, code = "", style = "foo")] = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:788:49 + --> $DIR/subdiagnostic-derive.rs:790:49 | LL | #[suggestion(no_crate_example, code = "", style = 42)] | ^ error: a diagnostic slug must be the first argument to the attribute - --> $DIR/subdiagnostic-derive.rs:796:48 + --> $DIR/subdiagnostic-derive.rs:798:48 | LL | #[suggestion(no_crate_example, code = "", style)] | ^ error: expected `= "xxx"` - --> $DIR/subdiagnostic-derive.rs:804:48 + --> $DIR/subdiagnostic-derive.rs:806:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: expected `,` - --> $DIR/subdiagnostic-derive.rs:804:48 + --> $DIR/subdiagnostic-derive.rs:806:48 | LL | #[suggestion(no_crate_example, code = "", style("foo"))] | ^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:816:5 + --> $DIR/subdiagnostic-derive.rs:818:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -529,7 +529,7 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:813:1 + --> $DIR/subdiagnostic-derive.rs:815:1 | LL | / #[suggestion(no_crate_example, code = "")] LL | | @@ -541,67 +541,67 @@ LL | | } | |_^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:66:3 + --> $DIR/subdiagnostic-derive.rs:68:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:161:3 + --> $DIR/subdiagnostic-derive.rs:163:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:175:7 + --> $DIR/subdiagnostic-derive.rs:177:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:187:7 + --> $DIR/subdiagnostic-derive.rs:189:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:199:7 + --> $DIR/subdiagnostic-derive.rs:201:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:211:7 + --> $DIR/subdiagnostic-derive.rs:213:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:272:7 + --> $DIR/subdiagnostic-derive.rs:274:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:283:7 + --> $DIR/subdiagnostic-derive.rs:285:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:294:7 + --> $DIR/subdiagnostic-derive.rs:296:7 | LL | #[bar("...")] | ^^^ error[E0425]: cannot find value `slug` in module `crate::fluent_generated` - --> $DIR/subdiagnostic-derive.rs:124:9 + --> $DIR/subdiagnostic-derive.rs:126:9 | LL | #[label(slug)] | ^^^^ not found in `crate::fluent_generated` error[E0425]: cannot find value `__code_29` in this scope - --> $DIR/subdiagnostic-derive.rs:707:10 + --> $DIR/subdiagnostic-derive.rs:709:10 | LL | #[derive(Subdiagnostic)] | ^^^^^^^^^^^^^ not found in this scope diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index dfde8c97ec2..95f27efa771 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -33,7 +33,6 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { // Find items in the local crate. let items = stable_mir::all_local_items(); - assert!(get_item(tcx, &items, (DefKind::Fn, "foo_bar")).is_some()); assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); // Find the `std` crate. @@ -52,6 +51,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { stable_mir::mir::Terminator::Return => {} other => panic!("{other:?}"), } + + let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); + let body = foo_bar.body(); + assert_eq!(body.blocks.len(), 4); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Call { .. } => {} + other => panic!("{other:?}"), + } } // Use internal API to find a function in a crate. diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs deleted file mode 100644 index cd06423e3a5..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs +++ /dev/null @@ -1,18 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -use core::alloc::Layout; - -#[alloc_error_handler] -fn oom( - info: &Layout, //~^ ERROR mismatched types -) -> () //~^^ ERROR mismatched types -{ - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr deleted file mode 100644 index de92841d7f1..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: &Layout, -LL | || ) -> () - | ||_______- arguments to this function are incorrect -LL | | { -LL | | loop {} -LL | | } - | |__^ expected `&Layout`, found `Layout` - | -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:4 - | -LL | fn oom( - | ^^^ -LL | info: &Layout, - | ------------- - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: &Layout, -LL | || ) -> () - | ||_______^ expected `!`, found `()` -LL | | { -LL | | loop {} -LL | | } - | |__- expected `!` because of return type - | - = note: expected type `!` - found unit type `()` - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs deleted file mode 100644 index 4f76257fc72..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -struct Layout; - -#[alloc_error_handler] -fn oom( - info: Layout, //~^ ERROR mismatched types -) { //~^^ ERROR mismatched types - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr deleted file mode 100644 index 7a495380f2b..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: Layout, -LL | || ) { - | ||_- arguments to this function are incorrect -LL | | loop {} -LL | | } - | |__^ expected `Layout`, found `core::alloc::Layout` - | - = note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types -note: `core::alloc::Layout` is defined in crate `core` - --> $SRC_DIR/core/src/alloc/layout.rs:LL:COL -note: `Layout` is defined in the current crate - --> $DIR/alloc-error-handler-bad-signature-2.rs:7:1 - | -LL | struct Layout; - | ^^^^^^^^^^^^^ -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:4 - | -LL | fn oom( - | ^^^ -LL | info: Layout, - | ------------ - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: Layout, -LL | || ) { - | ||_^ expected `!`, found `()` -LL | | loop {} -LL | | } - | |__- expected `!` because of return type - | - = note: expected type `!` - found unit type `()` - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs deleted file mode 100644 index ea9ad39a70d..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs +++ /dev/null @@ -1,15 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -struct Layout; - -#[alloc_error_handler] -fn oom() -> ! { //~ ERROR function takes 0 arguments but 1 argument was supplied - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr deleted file mode 100644 index eb739b149a1..00000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/alloc-error-handler-bad-signature-3.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | fn oom() -> ! { - | _-^^^^^^^^^^^^ -LL | | loop {} -LL | | } - | |_- unexpected argument of type `core::alloc::Layout` - | -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4 - | -LL | fn oom() -> ! { - | ^^^ - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/alloc-error/default-alloc-error-hook.rs b/tests/ui/alloc-error/default-alloc-error-hook.rs index 8be09500f4e..919d4b714a1 100644 --- a/tests/ui/alloc-error/default-alloc-error-hook.rs +++ b/tests/ui/alloc-error/default-alloc-error-hook.rs @@ -2,7 +2,7 @@ // ignore-emscripten no processes // ignore-sgx no processes -use std::alloc::{Layout, handle_alloc_error}; +use std::alloc::{handle_alloc_error, Layout}; use std::env; use std::process::Command; use std::str; @@ -24,5 +24,5 @@ fn main() { .strip_suffix("qemu: uncaught target signal 6 (Aborted) - core dumped\n") .unwrap_or(stderr); - assert_eq!(stderr, "memory allocation of 42 bytes failed\n"); + assert!(stderr.contains("memory allocation of 42 bytes failed")); } diff --git a/tests/ui/allocator/no_std-alloc-error-handler-custom.rs b/tests/ui/allocator/no_std-alloc-error-handler-custom.rs deleted file mode 100644 index 28926243390..00000000000 --- a/tests/ui/allocator/no_std-alloc-error-handler-custom.rs +++ /dev/null @@ -1,84 +0,0 @@ -// run-pass -// ignore-android no libc -// ignore-emscripten no libc -// ignore-sgx no libc -// ignore-wasm32 no libc -// only-linux -// compile-flags:-C panic=abort -// aux-build:helper.rs - -#![feature(rustc_private, lang_items)] -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -extern crate alloc; -extern crate libc; - -// ARM targets need these symbols -#[no_mangle] -pub fn __aeabi_unwind_cpp_pr0() {} - -#[no_mangle] -pub fn __aeabi_unwind_cpp_pr1() {} - -use alloc::boxed::Box; -use alloc::string::ToString; -use core::alloc::{GlobalAlloc, Layout}; -use core::ptr::null_mut; - -extern crate helper; - -struct MyAllocator; - -#[alloc_error_handler] -fn my_oom(layout: Layout) -> ! { - use alloc::fmt::write; - unsafe { - let size = layout.size(); - let mut s = alloc::string::String::new(); - write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); - libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); - libc::exit(0) - } -} - -unsafe impl GlobalAlloc for MyAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() } - } - unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} -} - -#[global_allocator] -static A: MyAllocator = MyAllocator; - -#[panic_handler] -fn panic(panic_info: &core::panic::PanicInfo) -> ! { - unsafe { - let s = panic_info.to_string(); - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); - libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len()); - libc::exit(1) - } -} - -// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed. -// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions -// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't -// unwind. So, for this test case we will define the symbol. -#[lang = "eh_personality"] -extern "C" fn rust_eh_personality() {} - -#[derive(Default, Debug)] -struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]); - -#[no_mangle] -fn main(_argc: i32, _argv: *const *const u8) -> isize { - let zero = Box::<Page>::new(Default::default()); - helper::work_with(&zero); - 1 -} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs new file mode 100644 index 00000000000..b1a0f39962b --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -0,0 +1,16 @@ +#![feature(associated_const_equality)] + +// Issue 110549 + +pub trait TraitWAssocConst { + const A: usize; +} + +fn foo<T: TraitWAssocConst<A = 32>>() {} + +fn bar<T: TraitWAssocConst>() { + foo::<T>(); + //~^ ERROR type mismatch resolving `<T as TraitWAssocConst>::A == 32` +} + +fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr new file mode 100644 index 00000000000..8175e510a09 --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `<T as TraitWAssocConst>::A == 32` + --> $DIR/projection-unspecified-but-bounded.rs:12:11 + | +LL | foo::<T>(); + | ^ expected `32`, found `<T as TraitWAssocConst>::A` + | + = note: expected constant `32` + found constant `<T as TraitWAssocConst>::A` +note: required by a bound in `foo` + --> $DIR/projection-unspecified-but-bounded.rs:9:28 + | +LL | fn foo<T: TraitWAssocConst<A = 32>>() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr index 7b0d1c50516..1648cfb266b 100644 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr +++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr @@ -2,5 +2,5 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: #0 [typeck] type-checking `weird` -#1 [typeck_item_bodies] type-checking all item bodies +#1 [used_trait_imports] finding used_trait_imports `weird` end of query stack diff --git a/tests/ui/issues/issue-27901.rs b/tests/ui/associated-types/issue-27901.rs index ffd90b68983..ffd90b68983 100644 --- a/tests/ui/issues/issue-27901.rs +++ b/tests/ui/associated-types/issue-27901.rs diff --git a/tests/ui/async-await/feature-self-return-type.stderr b/tests/ui/async-await/feature-self-return-type.stderr index 8924683684f..747c54b6694 100644 --- a/tests/ui/async-await/feature-self-return-type.stderr +++ b/tests/ui/async-await/feature-self-return-type.stderr @@ -4,6 +4,7 @@ error[E0597]: `bar` does not live long enough LL | let x = { | - borrow later stored here LL | let bar = 22; + | --- binding `bar` declared here LL | Foo::new(&bar).await | ^^^^ borrowed value does not live long enough LL | diff --git a/tests/ui/async-await/issue-61949-self-return-type.stderr b/tests/ui/async-await/issue-61949-self-return-type.stderr index 638b197bc02..ac85ed2887a 100644 --- a/tests/ui/async-await/issue-61949-self-return-type.stderr +++ b/tests/ui/async-await/issue-61949-self-return-type.stderr @@ -13,6 +13,7 @@ error[E0597]: `bar` does not live long enough LL | let x = { | - borrow later stored here LL | let bar = 22; + | --- binding `bar` declared here LL | Foo::new(&bar).await | ^^^^ borrowed value does not live long enough LL | diff --git a/tests/ui/async-await/issue-74047.stderr b/tests/ui/async-await/issue-74047.stderr index 28174825d8b..6bdb9ded482 100644 --- a/tests/ui/async-await/issue-74047.stderr +++ b/tests/ui/async-await/issue-74047.stderr @@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from` LL | impl TryFrom<OtherStream> for MyStream {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation | - = help: implement the missing item: `type Error = Type;` - = help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }` + = help: implement the missing item: `type Error = /* Type */;` + = help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr index 0ca14c3f3bc..047175626e3 100644 --- a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr +++ b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr @@ -1,19 +1,3 @@ -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 - | -LL | ref foo @ [.., ref mut bar] => (), - | ^^^^^^^ ----------- value is mutably borrowed by `bar` here - | | - | value is borrowed by `foo` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 - | -LL | ref foo @ Some(box ref mut s) => (), - | ^^^^^^^ --------- value is mutably borrowed by `s` here - | | - | value is borrowed by `foo` here - error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:18:5 | @@ -43,6 +27,14 @@ LL | &x; LL | drop(r); | - mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 + | +LL | ref foo @ [.., ref mut bar] => (), + | ^^^^^^^ ----------- value is mutably borrowed by `bar` here + | | + | value is borrowed by `foo` here + error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:50:5 | @@ -120,6 +112,14 @@ LL | &mut x; LL | drop(r); | - immutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 + | +LL | ref foo @ Some(box ref mut s) => (), + | ^^^^^^^ --------- value is mutably borrowed by `s` here + | | + | value is borrowed by `foo` here + error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:134:5 | diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed new file mode 100644 index 00000000000..4a8831dab95 --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.fixed @@ -0,0 +1,39 @@ +// run-rustfix +#![allow(unused)] +struct S; + +impl S { + fn call(&mut self, f: impl FnOnce((), &mut Self)) { + // change state or something ... + f((), self); + // change state or something ... + } + + fn get(&self) {} + fn set(&mut self) {} +} + +fn main() { + let mut v = S; + + v.call(|(), this: &mut S| this.get()); + //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable + v.call(|(), this: &mut S| this.set()); + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + v.call(|(), this: &mut S| { + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + _ = this; + this.set(); + this.get(); + S::get(&this); + + use std::ops::Add; + let v = 0u32; + _ = v + v; + _ = v.add(3); + }); +} diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs new file mode 100644 index 00000000000..fcd855f862d --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.rs @@ -0,0 +1,39 @@ +// run-rustfix +#![allow(unused)] +struct S; + +impl S { + fn call(&mut self, f: impl FnOnce((), &mut Self)) { + // change state or something ... + f((), self); + // change state or something ... + } + + fn get(&self) {} + fn set(&mut self) {} +} + +fn main() { + let mut v = S; + + v.call(|(), this: &mut S| v.get()); + //~^ error: cannot borrow `v` as mutable because it is also borrowed as immutable + v.call(|(), this: &mut S| v.set()); + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + v.call(|(), this: &mut S| { + //~^ error: cannot borrow `v` as mutable more than once at a time + //~| error: cannot borrow `v` as mutable more than once at a time + + _ = v; + v.set(); + v.get(); + S::get(&v); + + use std::ops::Add; + let v = 0u32; + _ = v + v; + _ = v.add(3); + }); +} diff --git a/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr new file mode 100644 index 00000000000..25974e0d008 --- /dev/null +++ b/tests/ui/borrowck/issue-109271-pass-self-into-closure.stderr @@ -0,0 +1,85 @@ +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> $DIR/issue-109271-pass-self-into-closure.rs:19:5 + | +LL | v.call(|(), this: &mut S| v.get()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | | help: try using the closure argument: `this` + | | | immutable borrow occurs here + | | immutable borrow later used by call + | mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:21:5 + | +LL | v.call(|(), this: &mut S| v.set()); + | ^^----^------------------^-^^^^^^^ + | | | | | + | | | | first borrow occurs due to use of `v` in closure + | | | | help: try using the closure argument: `this` + | | | first mutable borrow occurs here + | | first borrow later used by call + | second mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:21:12 + | +LL | v.call(|(), this: &mut S| v.set()); + | -------^^^^^^^^^^^^^^^^^^--------- + | | | | | + | | | | second borrow occurs due to use of `v` in closure + | | | second mutable borrow occurs here + | | first borrow later used by call + | first mutable borrow occurs here + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:25:5 + | +LL | v.call(|(), this: &mut S| { + | ^ ---- ------------------ first mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - first borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______^ second mutable borrow occurs here + | +help: try using the closure argument + | +LL ~ _ = this; +LL ~ this.set(); +LL ~ this.get(); +LL ~ S::get(&this); + | + +error[E0499]: cannot borrow `v` as mutable more than once at a time + --> $DIR/issue-109271-pass-self-into-closure.rs:25:12 + | +LL | v.call(|(), this: &mut S| { + | - ---- ^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here + | | | + | _____| first borrow later used by call + | | +LL | | +LL | | +LL | | +LL | | _ = v; +LL | | v.set(); + | | - second borrow occurs due to use of `v` in closure +... | +LL | | _ = v.add(3); +LL | | }); + | |______- first mutable borrow occurs here + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0499, E0502. +For more information about an error, try `rustc --explain E0499`. diff --git a/tests/ui/issues/issue-47646.rs b/tests/ui/borrowck/issue-47646.rs index ace6cdce841..ace6cdce841 100644 --- a/tests/ui/issues/issue-47646.rs +++ b/tests/ui/borrowck/issue-47646.rs diff --git a/tests/ui/issues/issue-47646.stderr b/tests/ui/borrowck/issue-47646.stderr index 84cf9237a56..84cf9237a56 100644 --- a/tests/ui/issues/issue-47646.stderr +++ b/tests/ui/borrowck/issue-47646.stderr diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs index 37b5c5d9d7a..835cd20798f 100644 --- a/tests/ui/borrowck/let_underscore_temporary.rs +++ b/tests/ui/borrowck/let_underscore_temporary.rs @@ -1,4 +1,4 @@ -// check-pass +// check-fail fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { let _ = if let Some(s) = *string { s.len() } else { 0 }; @@ -8,6 +8,7 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -21,6 +22,33 @@ fn let_underscore(string: &Option<&str>, mut num: Option<i32>) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; +} + +fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) { + let _: _ = if let Some(s) = *string { s.len() } else { 0 }; + let _: _ = if let Some(s) = &num { s } else { &0 }; + let _: _ = if let Some(s) = &mut num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; + let _: _ = if let Some(ref s) = num { s } else { &0 }; + let _: _ = if let Some(mut s) = num { + s += 1; + s + } else { + 0 + }; + let _: _ = if let Some(ref mut s) = num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed }; } diff --git a/tests/ui/borrowck/let_underscore_temporary.stderr b/tests/ui/borrowck/let_underscore_temporary.stderr new file mode 100644 index 00000000000..74f3598c4d0 --- /dev/null +++ b/tests/ui/borrowck/let_underscore_temporary.stderr @@ -0,0 +1,79 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:10:14 + | +LL | let _ = if let Some(s) = &mut num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:24:14 + | +LL | let _ = if let Some(ref mut s) = num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:36:14 + | +LL | let _: _ = if let Some(s) = &mut num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:50:14 + | +LL | let _: _ = if let Some(ref mut s) = num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr index 36606fd49f2..7e64e67f24c 100644 --- a/tests/ui/chalkify/bugs/async.stderr +++ b/tests/ui/chalkify/bugs/async.stderr @@ -18,7 +18,7 @@ LL | async fn foo(x: u32) -> u32 { #3 [mir_built] building MIR for `foo` #4 [unsafety_check_result] unsafety-checking `foo` #5 [mir_const] preparing `foo` for borrow checking -#6 [mir_promoted] processing MIR for `foo` +#6 [mir_promoted] promoting constants in MIR for `foo` #7 [mir_borrowck] borrow-checking `foo` #8 [type_of] computing type of `foo::{opaque#0}` #9 [check_mod_item_types] checking item types in top-level module diff --git a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index ad061d93cb2..8a32f0d99e7 100644 --- a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -1,17 +1,3 @@ -error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/pattern-matching-should-fail.rs:67:23 - | -LL | let c1 = || match x { }; - | ^ - | - = note: the matched value is of type `u8` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let c1 = || match x { -LL + _ => todo!(), -LL ~ }; - | - error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:8:23 | @@ -69,6 +55,20 @@ LL | let t: !; LL | match t { }; | ^ `t` used here but it isn't initialized +error[E0004]: non-exhaustive patterns: type `u8` is non-empty + --> $DIR/pattern-matching-should-fail.rs:67:23 + | +LL | let c1 = || match x { }; + | ^ + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ let c1 = || match x { +LL + _ => todo!(), +LL ~ }; + | + error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:67:23 | diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs index c0404d35b08..ae9207cf855 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(generic_const_exprs, adt_const_params, const_trait_impl)] #![allow(incomplete_features)] @@ -26,7 +28,6 @@ struct Evaluatable2<const N: usize>; fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) { bar2::<{ std::ops::Add::add(N, N) }>(); - //~^ error: unconstrained generic constant // FIXME(generic_const_exprs) make this not an error } diff --git a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr index d18c7916f5f..7f28771cee8 100644 --- a/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr +++ b/tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr @@ -1,10 +1,11 @@ -error: unconstrained generic constant - --> $DIR/unify-op-with-fn-call.rs:28:12 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/unify-op-with-fn-call.rs:10:12 | -LL | bar2::<{ std::ops::Add::add(N, N) }>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl const std::ops::Add for Foo { + | ^^^^^^^^^^^^^ | - = help: try adding a `where` bound using this expression: `where [(); { std::ops::Add::add(N, N) }]:` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to previous error diff --git a/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs b/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs deleted file mode 100644 index 85b0c6c9df8..00000000000 --- a/tests/ui/consts/auxiliary/foreign-generic-mismatch-with-const-arg.rs +++ /dev/null @@ -1 +0,0 @@ -pub fn test<const N: usize, T>() {} diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr index f199170018f..05f33c33946 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr @@ -4,13 +4,13 @@ error[E0308]: mismatched types LL | = [0; (i8::MAX + 1u8) as usize]; | ^^^ expected `i8`, found `u8` -error[E0277]: cannot add `u8` to `i8` in const contexts +error[E0277]: cannot add `u8` to `i8` --> $DIR/const-eval-overflow-3b.rs:16:20 | LL | = [0; (i8::MAX + 1u8) as usize]; | ^ no implementation for `i8 + u8` | - = help: the trait `~const Add<u8>` is not implemented for `i8` + = help: the trait `Add<u8>` is not implemented for `i8` = help: the following other types implement trait `Add<Rhs>`: <&'a i8 as Add<i8>> <&i8 as Add<&i8>> diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr index 1f8e402317a..d019f5920b5 100644 --- a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -4,13 +4,13 @@ error[E0308]: mismatched types LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^^^ expected `i8`, found `u8` -error[E0277]: cannot add `u8` to `i8` in const contexts +error[E0277]: cannot add `u8` to `i8` --> $DIR/const-eval-overflow-4b.rs:9:28 | LL | : [u32; (i8::MAX as i8 + 1u8) as usize] | ^ no implementation for `i8 + u8` | - = help: the trait `~const Add<u8>` is not implemented for `i8` + = help: the trait `Add<u8>` is not implemented for `i8` = help: the following other types implement trait `Add<Rhs>`: <&'a i8 as Add<i8>> <&i8 as Add<&i8>> diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.rs b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs index cd7c9800775..432a05756d3 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops.rs +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -1,6 +1,6 @@ fn main() {} // unconst and bad, will thus error in miri -const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR can't compare +const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR pointers cannot // unconst and bad, will thus error in miri -const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR can't compare +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR pointers cannot diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr index 12244450e7f..1f5bca273d3 100644 --- a/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr +++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr @@ -1,29 +1,18 @@ -error[E0277]: can't compare `*const i32` with `_` in const contexts - --> $DIR/const_raw_ptr_ops.rs:4:43 +error: pointers cannot be reliably compared during const eval + --> $DIR/const_raw_ptr_ops.rs:4:26 | LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; - | ^^ no implementation for `*const i32 == _` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `*const i32` -note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const` - --> $DIR/const_raw_ptr_ops.rs:4:43 - | -LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information -error[E0277]: can't compare `*const i32` with `_` in const contexts - --> $DIR/const_raw_ptr_ops.rs:6:44 +error: pointers cannot be reliably compared during const eval + --> $DIR/const_raw_ptr_ops.rs:6:27 | LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; - | ^^ no implementation for `*const i32 == _` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `*const i32` -note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const` - --> $DIR/const_raw_ptr_ops.rs:6:44 - | -LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/const-eval/generic-slice.stderr b/tests/ui/consts/const-eval/generic-slice.stderr index c38088df4d8..ff1dc29ccfd 100644 --- a/tests/ui/consts/const-eval/generic-slice.stderr +++ b/tests/ui/consts/const-eval/generic-slice.stderr @@ -4,6 +4,8 @@ error[E0597]: `x` does not live long enough LL | impl<'a, T: 'static> Generic<'a, T> { | -- lifetime `'a` defined here ... +LL | let x: &'static [T] = &[]; + | - binding `x` declared here LL | &x | ^^ | | @@ -16,6 +18,8 @@ LL | }; error[E0597]: `x` does not live long enough --> $DIR/generic-slice.rs:27:5 | +LL | let x: &[_] = &[]; + | - binding `x` declared here LL | &x | ^^ | | diff --git a/tests/ui/consts/const-eval/issue-100878.rs b/tests/ui/consts/const-eval/issue-100878.rs index 353ce505035..bd56f854c8b 100644 --- a/tests/ui/consts/const-eval/issue-100878.rs +++ b/tests/ui/consts/const-eval/issue-100878.rs @@ -1,6 +1,8 @@ // This checks that the const-eval ICE in issue #100878 does not recur. // // build-pass + +#[allow(arithmetic_overflow)] pub fn bitshift_data(data: [u8; 1]) -> u8 { data[0] << 8 } diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs index d9a74b4f3e2..ebc5543b380 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_slice_index)] const A: [(); 5] = [(), (), (), (), ()]; diff --git a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr index 775e475dfeb..403fb5e0940 100644 --- a/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr +++ b/tests/ui/consts/const-eval/ub-slice-get-unchecked.stderr @@ -1,18 +1,11 @@ -error[E0080]: evaluation of constant value failed - --> $SRC_DIR/core/src/slice/index.rs:LL:COL - | - = note: overflow executing `unchecked_sub` - | -note: inside `<std::ops::Range<usize> as SliceIndex<[()]>>::get_unchecked` - --> $SRC_DIR/core/src/slice/index.rs:LL:COL -note: inside `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` - --> $SRC_DIR/core/src/slice/mod.rs:LL:COL -note: inside `B` - --> $DIR/ub-slice-get-unchecked.rs:7:27 +error[E0015]: cannot call non-const fn `core::slice::<impl [()]>::get_unchecked::<std::ops::Range<usize>>` in constants + --> $DIR/ub-slice-get-unchecked.rs:9:29 | LL | const B: &[()] = unsafe { A.get_unchecked(3..1) }; - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ + | + = note: calls in constants are limited to constant functions, tuple structs and tuple variants error: aborting due to previous error -For more information about this error, try `rustc --explain E0080`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index 74238d0dd92..3a5d5bb46e9 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -8,11 +8,33 @@ // Don't promote const fn nop<T>(x: T) -> T { x } +// FIXME(const-hack): replace with PartialEq +#[const_trait] +trait MyEq<T> { + fn eq(self, b: T) -> bool; +} + +impl const MyEq<bool> for bool { + fn eq(self, b: bool) -> bool { + self == b + } +} + +impl const MyEq<NonDet> for bool { + fn eq(self, _: NonDet) -> bool { + true + } +} + +const fn eq<A: ~const MyEq<B>, B>(x: A, y: B) -> bool { + x.eq(y) +} + macro_rules! const_assert { ($a:expr, $b:expr) => { { - const _: () = assert!($a == $b); - assert_eq!(nop($a), nop($b)); + const _: () = assert!(eq($a, $b)); + assert!(eq(nop($a), nop($b))); } }; } @@ -47,15 +69,6 @@ macro_rules! suite_inner { #[derive(Debug)] struct NonDet; -impl const PartialEq<NonDet> for bool { - fn eq(&self, _: &NonDet) -> bool { - true - } - fn ne(&self, _: &NonDet) -> bool { - false - } -} - // The result of the `is_sign` methods are not checked for correctness, since LLVM does not // guarantee anything about the signedness of NaNs. See // https://github.com/rust-lang/rust/issues/55131. diff --git a/tests/ui/consts/const-fn-error.rs b/tests/ui/consts/const-fn-error.rs index dabbd58dbe0..50b7ce1f8c0 100644 --- a/tests/ui/consts/const-fn-error.rs +++ b/tests/ui/consts/const-fn-error.rs @@ -7,7 +7,6 @@ const fn f(x: usize) -> usize { //~| ERROR `for` is not allowed in a `const fn` //~| ERROR mutable references are not allowed in constant functions //~| ERROR cannot call non-const fn - //~| ERROR the trait bound sum += i; } sum diff --git a/tests/ui/consts/const-fn-error.stderr b/tests/ui/consts/const-fn-error.stderr index 73d235d6aec..f735b3d53ce 100644 --- a/tests/ui/consts/const-fn-error.stderr +++ b/tests/ui/consts/const-fn-error.stderr @@ -5,7 +5,7 @@ LL | / for i in 0..x { LL | | LL | | LL | | -... | +LL | | LL | | sum += i; LL | | } | |_____^ @@ -33,19 +33,6 @@ LL | for i in 0..x { = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0277]: the trait bound `std::ops::Range<usize>: Iterator` is not satisfied - --> $DIR/const-fn-error.rs:5:14 - | -LL | for i in 0..x { - | ^^^^ `std::ops::Range<usize>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<usize>` -note: the trait `Iterator` is implemented for `std::ops::Range<usize>`, but that implementation is not `const` - --> $DIR/const-fn-error.rs:5:14 - | -LL | for i in 0..x { - | ^^^^ - error[E0015]: cannot call non-const fn `<std::ops::Range<usize> as Iterator>::next` in constant functions --> $DIR/const-fn-error.rs:5:14 | @@ -55,7 +42,7 @@ LL | for i in 0..x { = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0015, E0277, E0658. +Some errors have detailed explanations: E0015, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-for.rs b/tests/ui/consts/const-for.rs index ff9c977f794..8db24853558 100644 --- a/tests/ui/consts/const-for.rs +++ b/tests/ui/consts/const-for.rs @@ -5,7 +5,6 @@ const _: () = { for _ in 0..5 {} //~^ error: cannot call //~| error: cannot convert - //~| error: the trait bound }; fn main() {} diff --git a/tests/ui/consts/const-for.stderr b/tests/ui/consts/const-for.stderr index 64f2f603b94..3fb9787c0d8 100644 --- a/tests/ui/consts/const-for.stderr +++ b/tests/ui/consts/const-for.stderr @@ -9,19 +9,6 @@ note: impl defined here, but it is not `const` = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error[E0277]: the trait bound `std::ops::Range<i32>: Iterator` is not satisfied - --> $DIR/const-for.rs:5:14 - | -LL | for _ in 0..5 {} - | ^^^^ `std::ops::Range<i32>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<i32>` -note: the trait `Iterator` is implemented for `std::ops::Range<i32>`, but that implementation is not `const` - --> $DIR/const-for.rs:5:14 - | -LL | for _ in 0..5 {} - | ^^^^ - error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants --> $DIR/const-for.rs:5:14 | @@ -31,7 +18,6 @@ LL | for _ in 0..5 {} = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-try.rs b/tests/ui/consts/const-try.rs index e199fd9ff8a..6b7ba8f1e32 100644 --- a/tests/ui/consts/const-try.rs +++ b/tests/ui/consts/const-try.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 // Demonstrates what's needed to make use of `?` in const contexts. diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr new file mode 100644 index 00000000000..37014f9b83f --- /dev/null +++ b/tests/ui/consts/const-try.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:15:12 + | +LL | impl const FromResidual<Error> for TryMe { + | ^^^^^^^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/const-try.rs:21:12 + | +LL | impl const Try for TryMe { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index f10d1c24f7d..19cee2022ac 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_type_id)] #![feature(const_trait_impl)] diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr new file mode 100644 index 00000000000..319d2b924a8 --- /dev/null +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -0,0 +1,76 @@ +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/const_cmp_type_id.rs:8:13 + | +LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/const_cmp_type_id.rs:9:13 + | +LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId < TypeId` and `TypeId > TypeId` + | + = help: the trait `~const PartialOrd` is not implemented for `TypeId` +note: the trait `PartialOrd` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constants + --> $DIR/const_cmp_type_id.rs:10:22 + | +LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs index b507492970a..be11ac7264a 100644 --- a/tests/ui/consts/fn_trait_refs.rs +++ b/tests/ui/consts/fn_trait_refs.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_fn_trait_ref_impls)] #![feature(fn_traits)] diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr new file mode 100644 index 00000000000..bfebf66701b --- /dev/null +++ b/tests/ui/consts/fn_trait_refs.stderr @@ -0,0 +1,15 @@ +error[E0635]: unknown feature `const_fn_trait_ref_impls` + --> $DIR/fn_trait_refs.rs:3:12 + | +LL | #![feature(const_fn_trait_ref_impls)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0635]: unknown feature `const_cmp` + --> $DIR/fn_trait_refs.rs:8:12 + | +LL | #![feature(const_cmp)] + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs deleted file mode 100644 index 7590abbd827..00000000000 --- a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.rs +++ /dev/null @@ -1,8 +0,0 @@ -// aux-build: foreign-generic-mismatch-with-const-arg.rs - -extern crate foreign_generic_mismatch_with_const_arg; - -fn main() { - foreign_generic_mismatch_with_const_arg::test::<1>(); - //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied -} diff --git a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr b/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr deleted file mode 100644 index 4cc03a20514..00000000000 --- a/tests/ui/consts/foreign-generic-mismatch-with-const-arg.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied - --> $DIR/foreign-generic-mismatch-with-const-arg.rs:6:46 - | -LL | foreign_generic_mismatch_with_const_arg::test::<1>(); - | ^^^^ - supplied 1 generic argument - | | - | expected 2 generic arguments - | -note: function defined here, with 2 generic parameters: `N`, `T` - --> $DIR/auxiliary/foreign-generic-mismatch-with-const-arg.rs:1:8 - | -LL | pub fn test<const N: usize, T>() {} - | ^^^^ -------------- - -help: add missing generic argument - | -LL | foreign_generic_mismatch_with_const_arg::test::<1, T>(); - | +++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/consts/issue-25826.rs b/tests/ui/consts/issue-25826.rs index c340c30a113..f5ed5aeedc3 100644 --- a/tests/ui/consts/issue-25826.rs +++ b/tests/ui/consts/issue-25826.rs @@ -1,6 +1,6 @@ fn id<T>(t: T) -> T { t } fn main() { const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - //~^ ERROR can't compare + //~^ ERROR pointers cannot println!("{}", A); } diff --git a/tests/ui/consts/issue-25826.stderr b/tests/ui/consts/issue-25826.stderr index 905c5ee6eb4..780edd2149f 100644 --- a/tests/ui/consts/issue-25826.stderr +++ b/tests/ui/consts/issue-25826.stderr @@ -1,16 +1,10 @@ -error[E0277]: can't compare `*const ()` with `*const ()` in const contexts - --> $DIR/issue-25826.rs:3:52 +error: pointers cannot be reliably compared during const eval + --> $DIR/issue-25826.rs:3:30 | LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - | ^ no implementation for `*const () < *const ()` and `*const () > *const ()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: the trait `~const PartialOrd` is not implemented for `*const ()` -note: the trait `PartialOrd` is implemented for `*const ()`, but that implementation is not `const` - --> $DIR/issue-25826.rs:3:52 - | -LL | const A: bool = unsafe { id::<u8> as *const () < id::<u16> as *const () }; - | ^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/issue-73976-monomorphic.rs b/tests/ui/consts/issue-73976-monomorphic.rs index addcc1eaab6..a3b9510036d 100644 --- a/tests/ui/consts/issue-73976-monomorphic.rs +++ b/tests/ui/consts/issue-73976-monomorphic.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 // // This test is complement to the test in issue-73976-polymorphic.rs. // In that test we ensure that polymorphic use of type_id and type_name in patterns diff --git a/tests/ui/consts/issue-73976-monomorphic.stderr b/tests/ui/consts/issue-73976-monomorphic.stderr new file mode 100644 index 00000000000..95ab78b1b23 --- /dev/null +++ b/tests/ui/consts/issue-73976-monomorphic.stderr @@ -0,0 +1,28 @@ +error[E0277]: can't compare `TypeId` with `TypeId` in const contexts + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId` + | + = help: the trait `~const PartialEq` is not implemented for `TypeId` +note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const` + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/issue-73976-monomorphic.rs:21:5 + | +LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/core/src/any.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index ce21ebdb9ac..38c8129b8cf 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -7,8 +7,9 @@ struct Foo<'a> { impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec<u32>) { self.bar[0] = baz.len(); - //~^ the trait bound `Vec<usize>: ~const Index<_>` is not satisfied - //~| the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied + //~^ ERROR: cannot call + //~| ERROR: cannot call + //~| ERROR: the trait bound } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index f4683f7f536..b4e5db44e71 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -1,15 +1,10 @@ -error[E0277]: the trait bound `Vec<usize>: ~const Index<_>` is not satisfied - --> $DIR/issue-94675.rs:9:9 +error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions + --> $DIR/issue-94675.rs:9:27 | LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize` - | - = help: the trait `~const Index<_>` is not implemented for `Vec<usize>` -note: the trait `Index<_>` is implemented for `Vec<usize>`, but that implementation is not `const` - --> $DIR/issue-94675.rs:9:9 + | ^^^^^ | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied --> $DIR/issue-94675.rs:9:9 @@ -24,6 +19,17 @@ note: the trait `IndexMut<usize>` is implemented for `Vec<usize>`, but that impl LL | self.bar[0] = baz.len(); | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/issue-94675.rs:9:9 + | +LL | self.bar[0] = baz.len(); + | ^^^^^^^^^^^ + | +note: impl defined here, but it is not `const` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs b/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs index 9a2775688c6..c5990a7f515 100644 --- a/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs +++ b/tests/ui/consts/min_const_fn/cmp_fn_pointers.rs @@ -1,6 +1,6 @@ const fn cmp(x: fn(), y: fn()) -> bool { unsafe { x == y } - //~^ ERROR can't compare + //~^ ERROR pointers cannot } fn main() {} diff --git a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr index 8a1b20a3345..3845068d841 100644 --- a/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr +++ b/tests/ui/consts/min_const_fn/cmp_fn_pointers.stderr @@ -1,16 +1,10 @@ -error[E0277]: can't compare `fn()` with `_` in const contexts - --> $DIR/cmp_fn_pointers.rs:2:16 +error: pointers cannot be reliably compared during const eval + --> $DIR/cmp_fn_pointers.rs:2:14 | LL | unsafe { x == y } - | ^^ no implementation for `fn() == _` + | ^^^^^^ | - = help: the trait `~const PartialEq<_>` is not implemented for `fn()` -note: the trait `PartialEq<_>` is implemented for `fn()`, but that implementation is not `const` - --> $DIR/cmp_fn_pointers.rs:2:16 - | -LL | unsafe { x == y } - | ^^ + = note: see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/consts/promoted_const_call.rs b/tests/ui/consts/promoted_const_call.rs index 30ae730535c..dae6cafaebb 100644 --- a/tests/ui/consts/promoted_const_call.rs +++ b/tests/ui/consts/promoted_const_call.rs @@ -1,7 +1,9 @@ #![feature(const_mut_refs)] #![feature(const_trait_impl)] + struct Panic; impl const Drop for Panic { fn drop(&mut self) { panic!(); } } + pub const fn id<T>(x: T) -> T { x } pub const C: () = { let _: &'static _ = &id(&Panic); diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr index 83cc16f6f94..1cbd8cbe699 100644 --- a/tests/ui/consts/promoted_const_call.stderr +++ b/tests/ui/consts/promoted_const_call.stderr @@ -1,5 +1,5 @@ error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:7:26 + --> $DIR/promoted_const_call.rs:9:26 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -10,7 +10,7 @@ LL | }; | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:7:30 + --> $DIR/promoted_const_call.rs:9:30 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^ - temporary value is freed at the end of this statement @@ -19,7 +19,7 @@ LL | let _: &'static _ = &id(&Panic); | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:13:26 + --> $DIR/promoted_const_call.rs:15:26 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -30,7 +30,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:13:30 + --> $DIR/promoted_const_call.rs:15:30 | LL | let _: &'static _ = &id(&Panic); | ---------- ^^^^^ - temporary value is freed at the end of this statement @@ -39,7 +39,7 @@ LL | let _: &'static _ = &id(&Panic); | type annotation requires that borrow lasts for `'static` error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:16:26 + --> $DIR/promoted_const_call.rs:18:26 | LL | let _: &'static _ = &&(Panic, 0).1; | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use @@ -50,7 +50,7 @@ LL | } | - temporary value is freed at the end of this statement error[E0716]: temporary value dropped while borrowed - --> $DIR/promoted_const_call.rs:16:27 + --> $DIR/promoted_const_call.rs:18:27 | LL | let _: &'static _ = &&(Panic, 0).1; | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use diff --git a/tests/ui/consts/rustc-impl-const-stability.rs b/tests/ui/consts/rustc-impl-const-stability.rs index 0c18efa0a02..a1a741e80e5 100644 --- a/tests/ui/consts/rustc-impl-const-stability.rs +++ b/tests/ui/consts/rustc-impl-const-stability.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![crate_type = "lib"] #![feature(staged_api)] diff --git a/tests/ui/consts/rustc-impl-const-stability.stderr b/tests/ui/consts/rustc-impl-const-stability.stderr new file mode 100644 index 00000000000..e6930da71ec --- /dev/null +++ b/tests/ui/consts/rustc-impl-const-stability.stderr @@ -0,0 +1,11 @@ +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/rustc-impl-const-stability.rs:15:12 + | +LL | impl const Default for Data { + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to previous error + diff --git a/tests/ui/consts/try-operator.rs b/tests/ui/consts/try-operator.rs index fe43b132cbd..ed69f492fb9 100644 --- a/tests/ui/consts/try-operator.rs +++ b/tests/ui/consts/try-operator.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(try_trait_v2)] #![feature(const_trait_impl)] diff --git a/tests/ui/consts/try-operator.stderr b/tests/ui/consts/try-operator.stderr new file mode 100644 index 00000000000..f6a651c5e66 --- /dev/null +++ b/tests/ui/consts/try-operator.stderr @@ -0,0 +1,9 @@ +error[E0635]: unknown feature `const_convert` + --> $DIR/try-operator.rs:6:12 + | +LL | #![feature(const_convert)] + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 81f3f269432..26986684f0c 100644 --- a/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/tests/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -15,13 +15,13 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² | ~ -error[E0277]: cannot subtract `{integer}` from `{float}` in const contexts +error[E0277]: cannot subtract `{integer}` from `{float}` --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 | LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² | ^ no implementation for `{float} - {integer}` | - = help: the trait `~const Sub<{integer}>` is not implemented for `{float}` + = help: the trait `Sub<{integer}>` is not implemented for `{float}` = help: the following other types implement trait `Sub<Rhs>`: <&'a f32 as Sub<f32>> <&'a f64 as Sub<f64>> diff --git a/tests/ui/issues/auxiliary/issue-41394.rs b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs index 2e650efc714..2e650efc714 100644 --- a/tests/ui/issues/auxiliary/issue-41394.rs +++ b/tests/ui/enum-discriminant/auxiliary/issue-41394.rs diff --git a/tests/ui/issues/issue-41394-rpass.rs b/tests/ui/enum-discriminant/issue-41394-rpass.rs index 37c6525234d..37c6525234d 100644 --- a/tests/ui/issues/issue-41394-rpass.rs +++ b/tests/ui/enum-discriminant/issue-41394-rpass.rs diff --git a/tests/ui/issues/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs index 07cad8796e1..07cad8796e1 100644 --- a/tests/ui/issues/issue-41394.rs +++ b/tests/ui/enum-discriminant/issue-41394.rs diff --git a/tests/ui/issues/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr index 1b5c64628a1..1b5c64628a1 100644 --- a/tests/ui/issues/issue-41394.stderr +++ b/tests/ui/enum-discriminant/issue-41394.stderr diff --git a/tests/ui/extenv/issue-110547.rs b/tests/ui/extenv/issue-110547.rs new file mode 100644 index 00000000000..a6fb96ac066 --- /dev/null +++ b/tests/ui/extenv/issue-110547.rs @@ -0,0 +1,7 @@ +// compile-flags: -C debug-assertions + +fn main() { + env!{"\t"}; //~ ERROR not defined at compile time + env!("\t"); //~ ERROR not defined at compile time + env!("\u{2069}"); //~ ERROR not defined at compile time +} diff --git a/tests/ui/extenv/issue-110547.stderr b/tests/ui/extenv/issue-110547.stderr new file mode 100644 index 00000000000..1219630d346 --- /dev/null +++ b/tests/ui/extenv/issue-110547.stderr @@ -0,0 +1,29 @@ +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:4:5 + | +LL | env!{"\t"}; + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable ` ` not defined at compile time + --> $DIR/issue-110547.rs:5:5 + | +LL | env!("\t"); + | ^^^^^^^^^^ + | + = help: use `std::env::var(" ")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: environment variable `` not defined at compile time + --> $DIR/issue-110547.rs:6:5 + | +LL | env!("\u{2069}"); + | ^^^^^^^^^^^^^^^^ + | + = help: use `std::env::var("")` to read the variable at run time + = note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs b/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs deleted file mode 100644 index 78d189d20b6..00000000000 --- a/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs +++ /dev/null @@ -1,16 +0,0 @@ -// compile-flags:-C panic=abort - -#![no_std] -#![no_main] - -use core::alloc::Layout; - -#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler' -fn oom(info: Layout) -> ! { - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { - loop {} -} diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr deleted file mode 100644 index f414eb463df..00000000000 --- a/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: use of unstable library feature 'alloc_error_handler' - --> $DIR/feature-gate-alloc-error-handler.rs:8:3 - | -LL | #[alloc_error_handler] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51540 <https://github.com/rust-lang/rust/issues/51540> for more information - = help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr +++ b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr +++ b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr index 165748d4430..b2a5b92ed0f 100644 --- a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr +++ b/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr @@ -9,7 +9,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut binding, &mut true, No); + | error[E0716]: temporary value dropped while borrowed --> $DIR/auto-trait-regions.rs:48:35 @@ -22,7 +26,11 @@ LL | let a = A(&mut true, &mut true, No); LL | assert_foo(a); | - borrow later used here | - = note: consider using a `let` binding to create a longer lived value +help: consider using a `let` binding to create a longer lived value + | +LL ~ let binding = true; +LL ~ let a = A(&mut true, &mut binding, No); + | error: implementation of `Foo` is not general enough --> $DIR/auto-trait-regions.rs:34:5 diff --git a/tests/ui/generator/auto-trait-regions.stderr b/tests/ui/generator/auto-trait-regions.stderr deleted file mode 100644 index 165748d4430..00000000000 --- a/tests/ui/generator/auto-trait-regions.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:48:24 - | -LL | let a = A(&mut true, &mut true, No); - | ^^^^ - temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -... -LL | assert_foo(a); - | - borrow later used here - | - = note: consider using a `let` binding to create a longer lived value - -error[E0716]: temporary value dropped while borrowed - --> $DIR/auto-trait-regions.rs:48:35 - | -LL | let a = A(&mut true, &mut true, No); - | ^^^^ - temporary value is freed at the end of this statement - | | - | creates a temporary value which is freed while still in use -... -LL | assert_foo(a); - | - borrow later used here - | - = note: consider using a `let` binding to create a longer lived value - -error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:34:5 - | -LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`... - = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef` - -error: implementation of `Foo` is not general enough - --> $DIR/auto-trait-regions.rs:54:5 - | -LL | assert_foo(gen); - | ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough - | - = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`... - = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2` - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs new file mode 100644 index 00000000000..5b10aab4b3f --- /dev/null +++ b/tests/ui/generic-associated-types/auxiliary/missing-item-sugg.rs @@ -0,0 +1,5 @@ +pub trait Foo { + type Gat<T> + where + T: std::fmt::Display; +} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.rs b/tests/ui/generic-associated-types/missing-item-sugg.rs new file mode 100644 index 00000000000..35d573d8188 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.rs @@ -0,0 +1,11 @@ +// aux-build:missing-item-sugg.rs + +extern crate missing_item_sugg; + +struct Local; +impl missing_item_sugg::Foo for Local { + //~^ ERROR not all trait items implemented, missing: `Gat` +} +//~^ HELP implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;` + +fn main() {} diff --git a/tests/ui/generic-associated-types/missing-item-sugg.stderr b/tests/ui/generic-associated-types/missing-item-sugg.stderr new file mode 100644 index 00000000000..378115f6d38 --- /dev/null +++ b/tests/ui/generic-associated-types/missing-item-sugg.stderr @@ -0,0 +1,11 @@ +error[E0046]: not all trait items implemented, missing: `Gat` + --> $DIR/missing-item-sugg.rs:6:1 + | +LL | impl missing_item_sugg::Foo for Local { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation + | + = help: implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs new file mode 100644 index 00000000000..d89c1e03688 --- /dev/null +++ b/tests/ui/generics/auxiliary/foreign-generic-mismatch.rs @@ -0,0 +1,3 @@ +pub fn const_arg<const N: usize, T>() {} + +pub fn lt_arg<'a: 'a>() {} diff --git a/tests/ui/generics/foreign-generic-mismatch.rs b/tests/ui/generics/foreign-generic-mismatch.rs new file mode 100644 index 00000000000..403fd73d7df --- /dev/null +++ b/tests/ui/generics/foreign-generic-mismatch.rs @@ -0,0 +1,10 @@ +// aux-build: foreign-generic-mismatch.rs + +extern crate foreign_generic_mismatch; + +fn main() { + foreign_generic_mismatch::const_arg::<()>(); + //~^ ERROR function takes 2 generic arguments but 1 generic argument was supplied + foreign_generic_mismatch::lt_arg::<'static, 'static>(); + //~^ ERROR function takes 1 lifetime argument but 2 lifetime arguments were supplied +} diff --git a/tests/ui/generics/foreign-generic-mismatch.stderr b/tests/ui/generics/foreign-generic-mismatch.stderr new file mode 100644 index 00000000000..5322b3f919d --- /dev/null +++ b/tests/ui/generics/foreign-generic-mismatch.stderr @@ -0,0 +1,35 @@ +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied + --> $DIR/foreign-generic-mismatch.rs:6:31 + | +LL | foreign_generic_mismatch::const_arg::<()>(); + | ^^^^^^^^^ -- supplied 1 generic argument + | | + | expected 2 generic arguments + | +note: function defined here, with 2 generic parameters: `N`, `T` + --> $DIR/auxiliary/foreign-generic-mismatch.rs:1:8 + | +LL | pub fn const_arg<const N: usize, T>() {} + | ^^^^^^^^^ -------------- - +help: add missing generic argument + | +LL | foreign_generic_mismatch::const_arg::<(), T>(); + | +++ + +error[E0107]: function takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/foreign-generic-mismatch.rs:8:31 + | +LL | foreign_generic_mismatch::lt_arg::<'static, 'static>(); + | ^^^^^^ ------- help: remove this lifetime argument + | | + | expected 1 lifetime argument + | +note: function defined here, with 1 lifetime parameter: `'a` + --> $DIR/auxiliary/foreign-generic-mismatch.rs:3:8 + | +LL | pub fn lt_arg<'a: 'a>() {} + | ^^^^^^ -- + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/auto-trait-leak.stderr b/tests/ui/impl-trait/auto-trait-leak.stderr index e6c750d0e42..aa4ee75bb75 100644 --- a/tests/ui/impl-trait/auto-trait-leak.stderr +++ b/tests/ui/impl-trait/auto-trait-leak.stderr @@ -9,7 +9,7 @@ note: ...which requires borrow-checking `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle1`... +note: ...which requires promoting constants in MIR for `cycle1`... --> $DIR/auto-trait-leak.rs:12:1 | LL | fn cycle1() -> impl Clone { @@ -55,7 +55,7 @@ note: ...which requires borrow-checking `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `cycle2`... +note: ...which requires promoting constants in MIR for `cycle2`... --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { diff --git a/tests/ui/impl-trait/issue-108591.rs b/tests/ui/impl-trait/issue-108591.rs new file mode 100644 index 00000000000..6b9d14941f2 --- /dev/null +++ b/tests/ui/impl-trait/issue-108591.rs @@ -0,0 +1,30 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +struct MyTy<'a>(Vec<u8>, &'a ()); + +impl MyTy<'_> { + fn one(&mut self) -> &mut impl Sized { + &mut self.0 + } + fn two(&mut self) -> &mut (impl Sized + 'static) { + self.one() + } +} + +type Opaque<'a> = impl Sized; +fn define<'a>() -> Opaque<'a> {} + +fn test<'a>() { + None::<&'static Opaque<'a>>; +} + +fn one<'a, 'b: 'b>() -> &'a impl Sized { + &() +} +fn two<'a, 'b>() { + one::<'a, 'b>(); +} + +fn main() {} diff --git a/tests/ui/impl-trait/issue-108592.rs b/tests/ui/impl-trait/issue-108592.rs new file mode 100644 index 00000000000..58a0ed9bf1a --- /dev/null +++ b/tests/ui/impl-trait/issue-108592.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(type_alias_impl_trait)] + +fn opaque<'a: 'a>() -> impl Sized {} +fn assert_static<T: 'static>(_: T) {} + +fn test_closure() { + let closure = |_| { + assert_static(opaque()); + }; + closure(&opaque()); +} + +type Opaque<'a> = impl Sized; +fn define<'a>() -> Opaque<'a> {} + +fn test_tait(_: &Opaque<'_>) { + None::<&'static Opaque<'_>>; +} + +fn main() {} diff --git a/tests/ui/issues/issue-36792.rs b/tests/ui/impl-trait/issue-36792.rs index 99ae633dd0e..99ae633dd0e 100644 --- a/tests/ui/issues/issue-36792.rs +++ b/tests/ui/impl-trait/issue-36792.rs diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs index 1f7b341a97e..85e12463a90 100644 --- a/tests/ui/issues/issue-25901.rs +++ b/tests/ui/issues/issue-25901.rs @@ -2,7 +2,7 @@ struct A; struct B; static S: &'static B = &A; -//~^ ERROR the trait bound +//~^ ERROR cannot perform deref coercion use std::ops::Deref; diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr index b9cac32229a..1427e43854f 100644 --- a/tests/ui/issues/issue-25901.stderr +++ b/tests/ui/issues/issue-25901.stderr @@ -1,15 +1,24 @@ -error[E0277]: the trait bound `A: Deref` is not satisfied +error[E0015]: cannot perform deref coercion on `A` in statics --> $DIR/issue-25901.rs:4:24 | LL | static S: &'static B = &A; - | ^^ the trait `~const Deref` is not implemented for `A` + | ^^ | -note: the trait `Deref` is implemented for `A`, but that implementation is not `const` - --> $DIR/issue-25901.rs:4:24 + = note: attempting to deref into `B` +note: deref defined here + --> $DIR/issue-25901.rs:10:5 | -LL | static S: &'static B = &A; - | ^^ +LL | type Target = B; + | ^^^^^^^^^^^ +note: impl defined here, but it is not `const` + --> $DIR/issue-25901.rs:9:1 + | +LL | impl Deref for A { + | ^^^^^^^^^^^^^^^^ + = note: calls in statics are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/issues/issue-33287.rs b/tests/ui/issues/issue-33287.rs index 770eb7c02bb..b3f87305781 100644 --- a/tests/ui/issues/issue-33287.rs +++ b/tests/ui/issues/issue-33287.rs @@ -1,6 +1,7 @@ // build-pass #![allow(dead_code)] #![allow(unused_variables)] +#![allow(unconditional_panic)] const A: [u32; 1] = [0]; fn test() { diff --git a/tests/ui/issues/issue-3344.stderr b/tests/ui/issues/issue-3344.stderr index 11d5999672e..e849f5d0490 100644 --- a/tests/ui/issues/issue-3344.stderr +++ b/tests/ui/issues/issue-3344.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp` LL | impl PartialOrd for Thing { | ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation | - = help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }` + = help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }` error: aborting due to previous error diff --git a/tests/ui/issues/issue-50582.stderr b/tests/ui/issues/issue-50582.stderr index 53ecc6112ff..3d527eb6b4e 100644 --- a/tests/ui/issues/issue-50582.stderr +++ b/tests/ui/issues/issue-50582.stderr @@ -7,13 +7,13 @@ LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); = note: see issue #87575 <https://github.com/rust-lang/rust/issues/87575> for more information = help: add `#![feature(const_for)]` to the crate attributes to enable -error[E0277]: cannot add `()` to `{integer}` in const contexts +error[E0277]: cannot add `()` to `{integer}` --> $DIR/issue-50582.rs:2:18 | LL | Vec::<[(); 1 + for x in 0..1 {}]>::new(); | ^ no implementation for `{integer} + ()` | - = help: the trait `~const Add<()>` is not implemented for `{integer}` + = help: the trait `Add<()>` is not implemented for `{integer}` = help: the following other types implement trait `Add<Rhs>`: <&'a f32 as Add<f32>> <&'a f64 as Add<f64>> diff --git a/tests/ui/issues/issue-6458-1.rs b/tests/ui/issues/issue-6458-1.rs deleted file mode 100644 index 184e4832b90..00000000000 --- a/tests/ui/issues/issue-6458-1.rs +++ /dev/null @@ -1,8 +0,0 @@ -// run-fail -// error-pattern:explicit panic -// ignore-emscripten no processes - -fn foo<T>(t: T) {} -fn main() { - foo(panic!()) -} diff --git a/tests/ui/issues/issue-6458-2.rs b/tests/ui/issues/issue-6458-2.rs deleted file mode 100644 index b18cae3ed1a..00000000000 --- a/tests/ui/issues/issue-6458-2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - // Unconstrained type: - format!("{:?}", None); - //~^ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/issues/issue-6458-2.stderr b/tests/ui/issues/issue-6458-2.stderr deleted file mode 100644 index 8dbdd9a2735..00000000000 --- a/tests/ui/issues/issue-6458-2.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458-2.rs:3:21 - | -LL | format!("{:?}", None); - | ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option` - | -help: consider specifying the generic argument - | -LL | format!("{:?}", None::<T>); - | +++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-6458-3.rs b/tests/ui/issues/issue-6458-3.rs deleted file mode 100644 index d4f8886e9b0..00000000000 --- a/tests/ui/issues/issue-6458-3.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::mem; - -fn main() { - mem::transmute(0); - //~^ ERROR type annotations needed [E0282] -} diff --git a/tests/ui/issues/issue-6458-3.stderr b/tests/ui/issues/issue-6458-3.stderr deleted file mode 100644 index 520efccae51..00000000000 --- a/tests/ui/issues/issue-6458-3.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458-3.rs:4:5 - | -LL | mem::transmute(0); - | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute` - | -help: consider specifying the generic arguments - | -LL | mem::transmute::<i32, Dst>(0); - | ++++++++++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-6458-4.rs b/tests/ui/issues/issue-6458-4.rs deleted file mode 100644 index 054a5c15c3f..00000000000 --- a/tests/ui/issues/issue-6458-4.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn foo(b: bool) -> Result<bool,String> { //~ ERROR mismatched types - Err("bar".to_string()); -} - -fn main() { - foo(false); -} diff --git a/tests/ui/issues/issue-6458-4.stderr b/tests/ui/issues/issue-6458-4.stderr deleted file mode 100644 index 66ccfdff236..00000000000 --- a/tests/ui/issues/issue-6458-4.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-6458-4.rs:1:20 - | -LL | fn foo(b: bool) -> Result<bool,String> { - | --- ^^^^^^^^^^^^^^^^^^^ expected `Result<bool, String>`, found `()` - | | - | implicitly returns `()` as its body has no tail or `return` expression -LL | Err("bar".to_string()); - | - help: remove this semicolon to return this value - | - = note: expected enum `Result<bool, String>` - found unit type `()` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-6458.rs b/tests/ui/issues/issue-6458.rs deleted file mode 100644 index 16718e90deb..00000000000 --- a/tests/ui/issues/issue-6458.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::marker; - -pub struct TypeWithState<State>(marker::PhantomData<State>); -pub struct MyState; - -pub fn foo<State>(_: TypeWithState<State>) {} - -pub fn bar() { - foo(TypeWithState(marker::PhantomData)); - //~^ ERROR type annotations needed [E0282] -} - -fn main() { -} diff --git a/tests/ui/issues/issue-6458.stderr b/tests/ui/issues/issue-6458.stderr deleted file mode 100644 index 2e93c13855f..00000000000 --- a/tests/ui/issues/issue-6458.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0282]: type annotations needed - --> $DIR/issue-6458.rs:9:22 - | -LL | foo(TypeWithState(marker::PhantomData)); - | ^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `PhantomData` - | -help: consider specifying the generic argument - | -LL | foo(TypeWithState(marker::PhantomData::<T>)); - | +++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/issues/issue-36744-without-calls.rs b/tests/ui/lifetimes/issue-36744-without-calls.rs index dc5dc4f13c0..dc5dc4f13c0 100644 --- a/tests/ui/issues/issue-36744-without-calls.rs +++ b/tests/ui/lifetimes/issue-36744-without-calls.rs diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr index 7ae6789285b..3879f35505c 100644 --- a/tests/ui/lifetimes/issue-69314.stderr +++ b/tests/ui/lifetimes/issue-69314.stderr @@ -12,6 +12,8 @@ LL | async fn f2(m: Msg<'_>) {} error[E0597]: `buf` does not live long enough --> $DIR/issue-69314.rs:14:19 | +LL | let mut buf = [0; 512]; + | ------- binding `buf` declared here LL | let m2 = &buf[..]; | ^^^ borrowed value does not live long enough LL | let m = Self::g(m2).await; diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs new file mode 100644 index 00000000000..2c6fcef2500 --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs @@ -0,0 +1,42 @@ +// check-pass + +#![feature(offset_of)] +#![deny(dead_code)] + +// This struct contains a projection that can only be normalized after getting the field type. +struct A<T: Project> { + a: <T as Project>::EquateParamTo, +} + +// This is the inner struct that we want to get. +struct MyFieldIsNotDead { + not_dead: u8, +} + +// These are some helpers. +// Inside the param env of `test`, we want to make it so that it considers T=MyFieldIsNotDead. +struct GenericIsEqual<T>(T); +trait Project { + type EquateParamTo; +} +impl<T> Project for GenericIsEqual<T> { + type EquateParamTo = T; +} + +fn test<T>() -> usize +where + GenericIsEqual<T>: Project<EquateParamTo = MyFieldIsNotDead>, +{ + // The first field of the A that we construct here is + // `<GenericIsEqual<T>> as Project>::EquateParamTo`. + // Typeck normalizes this and figures that the not_dead field is totally fine and accessible. + // But importantly, the normalization ends up with T, which, as we've declared in our param + // env is MyFieldDead. When we're in the param env of the `a` field, the where bound above + // is not in scope, so we don't know what T is - it's generic. + // If we use the wrong param env, the lint will ICE. + std::mem::offset_of!(A<GenericIsEqual<T>>, a.not_dead) +} + +fn main() { + test::<MyFieldIsNotDead>(); +} diff --git a/tests/ui/lint/dead-code/offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs new file mode 100644 index 00000000000..da91de3862f --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of.rs @@ -0,0 +1,44 @@ +#![feature(offset_of)] +#![deny(dead_code)] + +use std::mem::offset_of; + +struct Alpha { + a: (), + b: (), //~ ERROR field `b` is never read + c: Beta, +} + +struct Beta { + a: (), //~ ERROR field `a` is never read + b: (), +} + +struct Gamma { + a: (), //~ ERROR field `a` is never read + b: (), +} + +struct Delta { + a: (), + b: (), //~ ERROR field `b` is never read +} + +trait Trait { + type Assoc; +} +impl Trait for () { + type Assoc = Delta; +} + +struct Project<T: Trait> { + a: u8, //~ ERROR field `a` is never read + b: <T as Trait>::Assoc, +} + +fn main() { + offset_of!(Alpha, a); + offset_of!(Alpha, c.b); + offset_of!((Gamma,), 0.b); + offset_of!(Project::<()>, b.a); +} diff --git a/tests/ui/lint/dead-code/offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr new file mode 100644 index 00000000000..ed2916461cd --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of.stderr @@ -0,0 +1,50 @@ +error: field `b` is never read + --> $DIR/offset-of.rs:8:5 + | +LL | struct Alpha { + | ----- field in this struct +LL | a: (), +LL | b: (), + | ^ + | +note: the lint level is defined here + --> $DIR/offset-of.rs:2:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: field `a` is never read + --> $DIR/offset-of.rs:13:5 + | +LL | struct Beta { + | ---- field in this struct +LL | a: (), + | ^ + +error: field `a` is never read + --> $DIR/offset-of.rs:18:5 + | +LL | struct Gamma { + | ----- field in this struct +LL | a: (), + | ^ + +error: field `b` is never read + --> $DIR/offset-of.rs:24:5 + | +LL | struct Delta { + | ----- field in this struct +LL | a: (), +LL | b: (), + | ^ + +error: field `a` is never read + --> $DIR/offset-of.rs:35:5 + | +LL | struct Project<T: Trait> { + | ------- field in this struct +LL | a: u8, + | ^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/lint/issue-110573.rs b/tests/ui/lint/issue-110573.rs new file mode 100644 index 00000000000..d9f0868b765 --- /dev/null +++ b/tests/ui/lint/issue-110573.rs @@ -0,0 +1,12 @@ +// check-pass + +#![deny(warnings)] + +pub struct Struct; + +impl Struct { + #[allow(non_upper_case_globals)] + pub const Const: () = (); +} + +fn main() {} diff --git a/tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs index f30d7e2edcc..f30d7e2edcc 100644 --- a/tests/ui/issues/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs +++ b/tests/ui/lint/issue-49588-non-shorthand-field-patterns-in-pattern-macro.rs diff --git a/tests/ui/lint/lint-uppercase-variables.stderr b/tests/ui/lint/lint-uppercase-variables.stderr index 42ec9364bc6..9220828014f 100644 --- a/tests/ui/lint/lint-uppercase-variables.stderr +++ b/tests/ui/lint/lint-uppercase-variables.stderr @@ -12,12 +12,6 @@ error[E0170]: pattern binding `Foo` is named the same as one of the variants of LL | let Foo = foo::Foo::Foo; | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` -error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` - --> $DIR/lint-uppercase-variables.rs:33:17 - | -LL | fn in_param(Foo: foo::Foo) {} - | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` - warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | @@ -37,6 +31,12 @@ warning: unused variable: `Foo` LL | let Foo = foo::Foo::Foo; | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo` +error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` + --> $DIR/lint-uppercase-variables.rs:33:17 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:33:17 | diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr index 2c35647b8a3..4852c331396 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -1,15 +1,3 @@ -error: unused variable: `this_is_my_function` - --> $DIR/expect_nested_lint_levels.rs:48:9 - | -LL | let this_is_my_function = 3; - | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` - | -note: the lint level is defined here - --> $DIR/expect_nested_lint_levels.rs:45:10 - | -LL | #[forbid(unused_variables)] - | ^^^^^^^^^^^^^^^^ - warning: variable does not need to be mutable --> $DIR/expect_nested_lint_levels.rs:36:13 | @@ -25,6 +13,18 @@ note: the lint level is defined here LL | unused_mut, | ^^^^^^^^^^ +error: unused variable: `this_is_my_function` + --> $DIR/expect_nested_lint_levels.rs:48:9 + | +LL | let this_is_my_function = 3; + | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` + | +note: the lint level is defined here + --> $DIR/expect_nested_lint_levels.rs:45:10 + | +LL | #[forbid(unused_variables)] + | ^^^^^^^^^^^^^^^^ + warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:7:5 | diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr index 5942fa8aeb4..169f03aed94 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr @@ -12,12 +12,6 @@ warning: unused variable: `fox_name` LL | let fox_name = "Sir Nibbles"; | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_fox_name` -warning: unused variable: `this_should_fulfill_the_expectation` - --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9 - | -LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` - warning: variable does not need to be mutable --> $DIR/force_warn_expected_lints_fulfilled.rs:32:9 | @@ -28,6 +22,12 @@ LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*"; | = note: requested on the command line with `--force-warn unused-mut` +warning: unused variable: `this_should_fulfill_the_expectation` + --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9 + | +LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` + warning: denote infinite loops with `loop { ... }` --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5 | diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index fd9a5bcbfc4..09729eeba79 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -10,12 +10,6 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ -error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:14:5 - | -LL | b: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_b` - error: unused variable: `a` --> $DIR/lint-unused-variables.rs:22:9 | @@ -23,6 +17,12 @@ LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:14:5 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + +error: unused variable: `b` --> $DIR/lint-unused-variables.rs:29:9 | LL | b: i32, diff --git a/tests/ui/liveness/liveness-consts.stderr b/tests/ui/liveness/liveness-consts.stderr index 6199ea96c98..016debdd396 100644 --- a/tests/ui/liveness/liveness-consts.stderr +++ b/tests/ui/liveness/liveness-consts.stderr @@ -1,10 +1,9 @@ -warning: variable `a` is assigned to, but never used - --> $DIR/liveness-consts.rs:7:13 +warning: unused variable: `e` + --> $DIR/liveness-consts.rs:24:13 | -LL | let mut a = 0; - | ^ +LL | let e = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_e` | - = note: consider using `_a` instead note: the lint level is defined here --> $DIR/liveness-consts.rs:2:9 | @@ -12,21 +11,6 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` -warning: value assigned to `b` is never read - --> $DIR/liveness-consts.rs:17:5 - | -LL | b += 1; - | ^ - | - = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - -warning: unused variable: `e` - --> $DIR/liveness-consts.rs:24:13 - | -LL | let e = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_e` - warning: unused variable: `s` --> $DIR/liveness-consts.rs:33:24 | @@ -39,6 +23,29 @@ warning: unused variable: `z` LL | pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { | ^ help: if this is intentional, prefix it with an underscore: `_z` +warning: unused variable: `z` + --> $DIR/liveness-consts.rs:60:13 + | +LL | let z = 42; + | ^ help: if this is intentional, prefix it with an underscore: `_z` + +warning: variable `a` is assigned to, but never used + --> $DIR/liveness-consts.rs:7:13 + | +LL | let mut a = 0; + | ^ + | + = note: consider using `_a` instead + +warning: value assigned to `b` is never read + --> $DIR/liveness-consts.rs:17:5 + | +LL | b += 1; + | ^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` + warning: value assigned to `t` is never read --> $DIR/liveness-consts.rs:42:9 | @@ -53,11 +60,5 @@ warning: unused variable: `w` LL | let w = 10; | ^ help: if this is intentional, prefix it with an underscore: `_w` -warning: unused variable: `z` - --> $DIR/liveness-consts.rs:60:13 - | -LL | let z = 42; - | ^ help: if this is intentional, prefix it with an underscore: `_z` - warning: 8 warnings emitted diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/macros/issue-26094.rs index 2742529edd3..2742529edd3 100644 --- a/tests/ui/issues/issue-26094.rs +++ b/tests/ui/macros/issue-26094.rs diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/macros/issue-26094.stderr index ecdf48470f7..ecdf48470f7 100644 --- a/tests/ui/issues/issue-26094.stderr +++ b/tests/ui/macros/issue-26094.stderr diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs index 45a30857413..45a30857413 100644 --- a/tests/ui/issues/issue-69396-const-no-type-in-macro.rs +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.rs diff --git a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr index 89aeafebac4..89aeafebac4 100644 --- a/tests/ui/issues/issue-69396-const-no-type-in-macro.stderr +++ b/tests/ui/macros/issue-69396-const-no-type-in-macro.stderr diff --git a/tests/ui/user-defined-macro-rules.rs b/tests/ui/macros/user-defined-macro-rules.rs index 09e071ec454..09e071ec454 100644 --- a/tests/ui/user-defined-macro-rules.rs +++ b/tests/ui/macros/user-defined-macro-rules.rs diff --git a/tests/ui/mir/validate/storage-live.stderr b/tests/ui/mir/validate/storage-live.stderr index b586a865849..720fb0a90b0 100644 --- a/tests/ui/mir/validate/storage-live.stderr +++ b/tests/ui/mir/validate/storage-live.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: broken MIR in Item(WithOptConstParam { did: DefId(0:8 ~ storage_live[HASH]::multiple_storage), const_param_did: None }) (before pass CheckPackedRef) at bb0[1]: +error: internal compiler error: broken MIR in Item(DefId(0:8 ~ storage_live[HASH]::multiple_storage)) (before pass CheckPackedRef) at bb0[1]: StorageLive(_1) which already has storage here --> $DIR/storage-live.rs:22:13 | @@ -9,5 +9,5 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: #0 [mir_const] preparing `multiple_storage` for borrow checking -#1 [mir_promoted] processing MIR for `multiple_storage` +#1 [mir_promoted] promoting constants in MIR for `multiple_storage` end of query stack diff --git a/tests/ui/missing/missing-allocator.rs b/tests/ui/missing/missing-allocator.rs index 2dc509f2c63..e06e603e3bf 100644 --- a/tests/ui/missing/missing-allocator.rs +++ b/tests/ui/missing/missing-allocator.rs @@ -3,16 +3,10 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } -#[alloc_error_handler] -fn oom(_: core::alloc::Layout) -> ! { - loop {} -} - extern crate alloc; diff --git a/tests/ui/missing/missing-items/m2.stderr b/tests/ui/missing/missing-items/m2.stderr index d18fb443aa4..835c9b2aa48 100644 --- a/tests/ui/missing/missing-items/m2.stderr +++ b/tests/ui/missing/missing-items/m2.stderr @@ -5,7 +5,7 @@ LL | impl m1::X for X { | ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation | = help: implement the missing item: `const CONSTANT: u32 = 42;` - = help: implement the missing item: `type Type = Type;` + = help: implement the missing item: `type Type = /* Type */;` = help: implement the missing item: `fn method(&self, _: String) -> <Self as m1::X>::Type { todo!() }` = help: implement the missing item: `fn method2(self: Box<Self>, _: String) -> <Self as m1::X>::Type { todo!() }` = help: implement the missing item: `fn method3(_: &Self, _: String) -> <Self as m1::X>::Type { todo!() }` diff --git a/tests/ui/never_type/issue-52443.rs b/tests/ui/never_type/issue-52443.rs index 4669d7c1a35..0498a8a1625 100644 --- a/tests/ui/never_type/issue-52443.rs +++ b/tests/ui/never_type/issue-52443.rs @@ -11,5 +11,4 @@ fn main() { //~| ERROR cannot convert //~| ERROR mutable references //~| ERROR cannot call - //~| ERROR the trait bound } diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index 1233bdc5d1f..99dfce86903 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -58,19 +58,6 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable -error[E0277]: the trait bound `RangeFrom<usize>: Iterator` is not satisfied - --> $DIR/issue-52443.rs:9:21 - | -LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ `RangeFrom<usize>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `RangeFrom<usize>` -note: the trait `Iterator` is implemented for `RangeFrom<usize>`, but that implementation is not `const` - --> $DIR/issue-52443.rs:9:21 - | -LL | [(); { for _ in 0usize.. {}; 0}]; - | ^^^^^^^^ - error[E0015]: cannot call non-const fn `<RangeFrom<usize> as Iterator>::next` in constants --> $DIR/issue-52443.rs:9:21 | @@ -80,7 +67,7 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 7 previous errors; 1 warning emitted +error: aborting due to 6 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0277, E0308, E0658. +Some errors have detailed explanations: E0015, E0308, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/nll/user-annotations/adt-brace-enums.stderr b/tests/ui/nll/user-annotations/adt-brace-enums.stderr index 9e94fd5a782..900e7e25390 100644 --- a/tests/ui/nll/user-annotations/adt-brace-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-brace-enums.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeEnum::SomeVariant::<&'a u32> { t: &c }; | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-brace-structs.stderr b/tests/ui/nll/user-annotations/adt-brace-structs.stderr index cbb7f6a55a9..d61643dc6ed 100644 --- a/tests/ui/nll/user-annotations/adt-brace-structs.stderr +++ b/tests/ui/nll/user-annotations/adt-brace-structs.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeStruct::<&'a u32> { t: &c }; | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr index bca85a90d19..5b385feeedc 100644 --- a/tests/ui/nll/user-annotations/adt-nullary-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-nullary-enums.stderr @@ -34,7 +34,10 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here +LL | combine( LL | SomeEnum::SomeVariant(Cell::new(&c)), | ----------^^- | | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr index d2d85ec2b9b..766da9ec00c 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-enums.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-enums.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeEnum::SomeVariant::<&'a u32>(&c); | ^^ | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr index b7bc2a10b70..2084697e7e2 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct-calls.stderr @@ -33,7 +33,10 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here +LL | let f = SomeStruct::<&'a u32>; LL | f(&c); | --^^- | | | @@ -47,7 +50,9 @@ error[E0597]: `c` does not live long enough | LL | let f = SomeStruct::<&'a u32>; | - lifetime `'1` appears in the type of `f` -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | f(&c); | --^^- | | | diff --git a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr index 97d39da265f..c7480f52963 100644 --- a/tests/ui/nll/user-annotations/adt-tuple-struct.stderr +++ b/tests/ui/nll/user-annotations/adt-tuple-struct.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | SomeStruct::<&'a u32>(&c); | ^^ | | diff --git a/tests/ui/nll/user-annotations/fns.stderr b/tests/ui/nll/user-annotations/fns.stderr index 8b53e138d9b..abaa35e9516 100644 --- a/tests/ui/nll/user-annotations/fns.stderr +++ b/tests/ui/nll/user-annotations/fns.stderr @@ -31,7 +31,9 @@ error[E0597]: `c` does not live long enough | LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here -... +LL | let _closure = || { +LL | let c = 66; + | - binding `c` declared here LL | some_fn::<&'a u32>(&c); | -------------------^^- | | | diff --git a/tests/ui/nll/user-annotations/method-call.stderr b/tests/ui/nll/user-annotations/method-call.stderr index 3803cbf776b..b4d1ac042a2 100644 --- a/tests/ui/nll/user-annotations/method-call.stderr +++ b/tests/ui/nll/user-annotations/method-call.stderr @@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here ... +LL | let c = 66; + | - binding `c` declared here LL | a.method::<&'a u32>(b, &c); | ------------------------^^- | | | diff --git a/tests/ui/nll/user-annotations/method-ufcs-3.stderr b/tests/ui/nll/user-annotations/method-ufcs-3.stderr index 8cb995a03ce..4dd39e10827 100644 --- a/tests/ui/nll/user-annotations/method-ufcs-3.stderr +++ b/tests/ui/nll/user-annotations/method-ufcs-3.stderr @@ -33,6 +33,8 @@ error[E0597]: `c` does not live long enough LL | fn annot_reference_named_lifetime_in_closure<'a>(_: &'a u32) { | -- lifetime `'a` defined here ... +LL | let c = 66; + | - binding `c` declared here LL | <_ as Bazoom<_>>::method::<&'a u32>(&a, b, &c); | -------------------------------------------^^- | | | diff --git a/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs new file mode 100644 index 00000000000..565b7e86fc4 --- /dev/null +++ b/tests/ui/numbers-arithmetic/overflowing-neg-nonzero.rs @@ -0,0 +1,12 @@ +// run-fail +// error-pattern:thread 'main' panicked at 'attempt to negate with overflow' +// ignore-emscripten no processes +// compile-flags: -C debug-assertions + +#![allow(arithmetic_overflow)] + +use std::num::NonZeroI8; + +fn main() { + let _x = -NonZeroI8::new(i8::MIN).unwrap(); +} diff --git a/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs new file mode 100644 index 00000000000..088086cc580 --- /dev/null +++ b/tests/ui/offset-of/auxiliary/offset-of-staged-api.rs @@ -0,0 +1,33 @@ +#![crate_type = "lib"] +#![feature(staged_api)] +#![stable(feature = "stable_test_feature", since = "1.0")] + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct Unstable { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct Stable { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableField { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: u8, +} + +#[stable(feature = "stable_test_feature", since = "1.0")] +pub struct StableWithUnstableFieldType { + #[stable(feature = "stable_test_feature", since = "1.0")] + pub stable: Unstable, +} + +#[unstable(feature = "unstable_test_feature", issue = "none")] +pub struct UnstableWithStableFieldType { + #[unstable(feature = "unstable_test_feature", issue = "none")] + pub unstable: Stable, +} diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs new file mode 100644 index 00000000000..163b07454ec --- /dev/null +++ b/tests/ui/offset-of/offset-of-arg-count.rs @@ -0,0 +1,9 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +fn main() { + offset_of!(NotEnoughArguments); //~ ERROR expected one of + offset_of!(NotEnoughArgumentsWithAComma, ); //~ ERROR expected 2 arguments + offset_of!(Container, field, too many arguments); //~ ERROR expected 2 arguments +} diff --git a/tests/ui/offset-of/offset-of-arg-count.stderr b/tests/ui/offset-of/offset-of-arg-count.stderr new file mode 100644 index 00000000000..ebecc982c51 --- /dev/null +++ b/tests/ui/offset-of/offset-of-arg-count.stderr @@ -0,0 +1,20 @@ +error: expected one of `!`, `(`, `+`, `,`, `::`, or `<`, found `<eof>` + --> $DIR/offset-of-arg-count.rs:6:16 + | +LL | offset_of!(NotEnoughArguments); + | ^^^^^^^^^^^^^^^^^^ expected one of `!`, `(`, `+`, `,`, `::`, or `<` + +error: expected 2 arguments + --> $DIR/offset-of-arg-count.rs:7:5 + | +LL | offset_of!(NotEnoughArgumentsWithAComma, ); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: expected 2 arguments + --> $DIR/offset-of-arg-count.rs:8:5 + | +LL | offset_of!(Container, field, too many arguments); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs new file mode 100644 index 00000000000..a0269ca2d12 --- /dev/null +++ b/tests/ui/offset-of/offset-of-dst-field.rs @@ -0,0 +1,33 @@ +#![feature(offset_of, extern_types)] + +use std::mem::offset_of; + +struct Alpha { + x: u8, + y: u16, + z: [u8], +} + +trait Trait {} + +struct Beta { + x: u8, + y: u16, + z: dyn Trait, +} + +extern { + type Extern; +} + +struct Gamma { + x: u8, + y: u16, + z: Extern, +} + +fn main() { + offset_of!(Alpha, z); //~ ERROR the size for values of type + offset_of!(Beta, z); //~ ERROR the size for values of type + offset_of!(Gamma, z); //~ ERROR the size for values of type +} diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr new file mode 100644 index 00000000000..8e88015b07a --- /dev/null +++ b/tests/ui/offset-of/offset-of-dst-field.stderr @@ -0,0 +1,27 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:30:5 + | +LL | offset_of!(Alpha, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:31:5 + | +LL | offset_of!(Beta, z); + | ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)` + +error[E0277]: the size for values of type `Extern` cannot be known at compilation time + --> $DIR/offset-of-dst-field.rs:32:5 + | +LL | offset_of!(Gamma, z); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `Extern` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/offset-of/offset-of-enum.rs b/tests/ui/offset-of/offset-of-enum.rs new file mode 100644 index 00000000000..d73505821ff --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.rs @@ -0,0 +1,13 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +enum Alpha { + One(u8), + Two(u8), +} + +fn main() { + offset_of!(Alpha::One, 0); //~ ERROR expected type, found variant `Alpha::One` + offset_of!(Alpha, Two.0); //~ ERROR no field `Two` on type `Alpha` +} diff --git a/tests/ui/offset-of/offset-of-enum.stderr b/tests/ui/offset-of/offset-of-enum.stderr new file mode 100644 index 00000000000..6958d199fbd --- /dev/null +++ b/tests/ui/offset-of/offset-of-enum.stderr @@ -0,0 +1,19 @@ +error[E0573]: expected type, found variant `Alpha::One` + --> $DIR/offset-of-enum.rs:11:16 + | +LL | offset_of!(Alpha::One, 0); + | ^^^^^^^^^^ + | | + | not a type + | help: try using the variant's enum: `Alpha` + +error[E0609]: no field `Two` on type `Alpha` + --> $DIR/offset-of-enum.rs:12:23 + | +LL | offset_of!(Alpha, Two.0); + | ^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0573, E0609. +For more information about an error, try `rustc --explain E0573`. diff --git a/tests/ui/offset-of/offset-of-private.rs b/tests/ui/offset-of/offset-of-private.rs new file mode 100644 index 00000000000..0291b7825ca --- /dev/null +++ b/tests/ui/offset-of/offset-of-private.rs @@ -0,0 +1,16 @@ +#![feature(offset_of)] + +use std::mem::offset_of; + +mod m { + #[repr(C)] + pub struct Foo { + pub public: u8, + private: u8, + } +} + +fn main() { + offset_of!(m::Foo, public); + offset_of!(m::Foo, private); //~ ERROR field `private` of struct `Foo` is private +} diff --git a/tests/ui/offset-of/offset-of-private.stderr b/tests/ui/offset-of/offset-of-private.stderr new file mode 100644 index 00000000000..8a186dd5a02 --- /dev/null +++ b/tests/ui/offset-of/offset-of-private.stderr @@ -0,0 +1,9 @@ +error[E0616]: field `private` of struct `Foo` is private + --> $DIR/offset-of-private.rs:15:24 + | +LL | offset_of!(m::Foo, private); + | ^^^^^^^ private field + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0616`. diff --git a/tests/ui/offset-of/offset-of-unstable-with-feature.rs b/tests/ui/offset-of/offset-of-unstable-with-feature.rs new file mode 100644 index 00000000000..7d2eb46c056 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable-with-feature.rs @@ -0,0 +1,20 @@ +// check-pass +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of, unstable_test_feature)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!(Unstable, unstable); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); + offset_of!(UnstableWithStableFieldType, unstable); + offset_of!(UnstableWithStableFieldType, unstable.stable); +} diff --git a/tests/ui/offset-of/offset-of-unstable.rs b/tests/ui/offset-of/offset-of-unstable.rs new file mode 100644 index 00000000000..1e19f2091f2 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.rs @@ -0,0 +1,31 @@ +// aux-build:offset-of-staged-api.rs + +#![feature(offset_of)] + +use std::mem::offset_of; + +extern crate offset_of_staged_api; + +use offset_of_staged_api::*; + +fn main() { + offset_of!( + //~^ ERROR use of unstable library feature + Unstable, //~ ERROR use of unstable library feature + unstable + ); + offset_of!(Stable, stable); + offset_of!(StableWithUnstableField, unstable); //~ ERROR use of unstable library feature + offset_of!(StableWithUnstableFieldType, stable); + offset_of!(StableWithUnstableFieldType, stable.unstable); //~ ERROR use of unstable library feature + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable + ); + offset_of!( + //~^ ERROR use of unstable library feature + UnstableWithStableFieldType, //~ ERROR use of unstable library feature + unstable.stable + ); +} diff --git a/tests/ui/offset-of/offset-of-unstable.stderr b/tests/ui/offset-of/offset-of-unstable.stderr new file mode 100644 index 00000000000..25811a061d7 --- /dev/null +++ b/tests/ui/offset-of/offset-of-unstable.stderr @@ -0,0 +1,79 @@ +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:14:9 + | +LL | Unstable, + | ^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:23:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:28:9 + | +LL | UnstableWithStableFieldType, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:12:5 + | +LL | / offset_of!( +LL | | +LL | | Unstable, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:18:5 + | +LL | offset_of!(StableWithUnstableField, unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:20:5 + | +LL | offset_of!(StableWithUnstableFieldType, stable.unstable); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:21:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'unstable_test_feature' + --> $DIR/offset-of-unstable.rs:26:5 + | +LL | / offset_of!( +LL | | +LL | | UnstableWithStableFieldType, +LL | | unstable.stable +LL | | ); + | |_____^ + | + = help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/oom_unwind.rs b/tests/ui/oom_unwind.rs index 21a8fb2b22b..704d6f8b810 100644 --- a/tests/ui/oom_unwind.rs +++ b/tests/ui/oom_unwind.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z oom=panic +// compile-flags: -Z oom=unwind // run-pass // no-prefer-dynamic // needs-unwind diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 9305facc406..3ce48b1a72f 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -54,14 +54,6 @@ LL | ref mut a @ box ref b => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:54:11 - | -LL | fn f5(ref mut a @ box ref b: Box<NC>) { - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - error[E0382]: borrow of moved value --> $DIR/borrowck-pat-at-and-box.rs:31:9 | @@ -120,6 +112,14 @@ LL | ref mut a @ box ref b => { LL | drop(b); | - immutable borrow later used here +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:54:11 + | +LL | fn f5(ref mut a @ box ref b: Box<NC>) { + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:54:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index 13989ebadcb..1ed019f0a69 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -286,78 +286,6 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref mut a @ Some([ref b, ref mut c]) => {} | +++ -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 - | -LL | fn f1(a @ ref b: U) {} - | ^ ----- value borrowed here after move - | | - | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f1(ref a @ ref b: U) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^ ----- value borrowed here after move - | | - | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- value borrowed here after move - | | - | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 - | -LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} - | ^ --------- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} - | +++ - error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9 | @@ -447,6 +375,63 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | value moved here +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 + | +LL | fn f1(a @ ref b: U) {} + | ^ ----- value borrowed here after move + | | + | value moved into `a` here + | move occurs because `a` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f1(ref a @ ref b: U) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^ ----- value borrowed here after move + | | + | value moved into `b` here + | move occurs because `b` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- value borrowed here after move + | | + | value moved into `d` here + | move occurs because `d` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} + | +++ + error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 | @@ -457,6 +442,21 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | ^ --------- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} + | +++ + error: aborting due to 33 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 00593b2a98f..c8c4d9b8fdb 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -166,48 +166,6 @@ LL | ref mut a @ Some([b, mut c]) => {} | | value is moved into `b` here | value is mutably borrowed by `a` here -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 - | -LL | fn f1(ref a @ b: U) {} - | ^^^^^ - value is moved into `b` here - | | - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- - value is moved into `e` here - | | | - | | value is moved into `c` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- value is moved into `c` here - | | - | value is borrowed by `b` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ - value is moved into `e` here - | | - | value is borrowed by `d` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 - | -LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} - | ^^^^^^^^^ - ----- value is moved into `c` here - | | | - | | value is moved into `b` here - | value is mutably borrowed by `a` here - error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9 | @@ -306,6 +264,14 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {} | +++ +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 + | +LL | fn f1(ref a @ b: U) {} + | ^^^^^ - value is moved into `b` here + | | + | value is borrowed by `a` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 | @@ -315,6 +281,31 @@ LL | fn f1(ref a @ b: U) {} | value borrowed here after move | move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- - value is moved into `e` here + | | | + | | value is moved into `c` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- value is moved into `c` here + | | + | value is borrowed by `b` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ - value is moved into `e` here + | | + | value is borrowed by `d` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 | @@ -335,6 +326,15 @@ LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | = note: move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 + | +LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + | ^^^^^^^^^ - ----- value is moved into `c` here + | | | + | | value is moved into `b` here + | value is mutably borrowed by `a` here + error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index d6409d1b643..c0a6558a1bf 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -221,47 +221,6 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | | value is borrowed by `b` here | value is mutably borrowed by `a` here -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 - | -LL | fn f1(ref a @ ref mut b: U) {} - | ^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 - | -LL | fn f2(ref mut a @ ref b: U) {} - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 - | -LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - | ^^^^^ ----------- value is mutably borrowed by `mid` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31 | @@ -398,6 +357,47 @@ LL | LL | *b = U; | ------ mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 + | +LL | fn f1(ref a @ ref mut b: U) {} + | ^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 + | +LL | fn f2(ref mut a @ ref b: U) {} + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 + | +LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} + | ^^^^^ ----------- value is mutably borrowed by `mid` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 24189d0615c..c634ea470c5 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -194,50 +194,6 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 - | -LL | fn f1(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 - | -LL | fn f2(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 - | -LL | ref mut a @ [ - | ^^^^^^^^^ value is mutably borrowed by `a` here -LL | -LL | [ref b @ .., _], - | ----- value is borrowed by `b` here -LL | [_, ref mut mid @ ..], - | ----------- value is mutably borrowed by `mid` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is mutably borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | @@ -304,6 +260,50 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 + | +LL | fn f1(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 + | +LL | fn f2(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 + | +LL | ref mut a @ [ + | ^^^^^^^^^ value is mutably borrowed by `a` here +LL | +LL | [ref b @ .., _], + | ----- value is borrowed by `b` here +LL | [_, ref mut mid @ ..], + | ----------- value is mutably borrowed by `mid` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is mutably borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 | diff --git a/tests/ui/polymorphization/generators.stderr b/tests/ui/polymorphization/generators.stderr index 84888f6fb2f..32d49d25f02 100644 --- a/tests/ui/polymorphization/generators.stderr +++ b/tests/ui/polymorphization/generators.stderr @@ -15,12 +15,6 @@ LL | pub fn unused_type<T>() -> impl Generator<(), Yield = u32, Return = u32> + LL | || { | ^^ -note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 35:7], u32, u32>` - --> $DIR/generators.rs:86:5 - | -LL | finish(unused_type::<u32>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: item has unused generic parameters --> $DIR/generators.rs:60:5 | @@ -29,11 +23,5 @@ LL | pub fn unused_const<const T: u32>() -> impl Generator<(), Yield = u32, Retu LL | || { | ^^ -note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 60:7], u32, u32>` - --> $DIR/generators.rs:89:5 - | -LL | finish(unused_const::<1u32>()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/polymorphization/predicates.stderr b/tests/ui/polymorphization/predicates.stderr index 80bb2af25cc..a3b2f75b12d 100644 --- a/tests/ui/polymorphization/predicates.stderr +++ b/tests/ui/polymorphization/predicates.stderr @@ -1,4 +1,10 @@ error: item has unused generic parameters + --> $DIR/predicates.rs:10:4 + | +LL | fn bar<I>() { + | ^^^ - generic parameter `I` is unused + +error: item has unused generic parameters --> $DIR/predicates.rs:15:4 | LL | fn foo<I, T>(_: I) @@ -35,17 +41,5 @@ error: item has unused generic parameters LL | fn foobar<F, G>() -> usize | ^^^^^^ - generic parameter `F` is unused -error: item has unused generic parameters - --> $DIR/predicates.rs:10:4 - | -LL | fn bar<I>() { - | ^^^ - generic parameter `I` is unused - -note: the above error was encountered while instantiating `fn foo::<std::slice::Iter<'_, u32>, T>` - --> $DIR/predicates.rs:86:5 - | -LL | foo(x.iter()); - | ^^^^^^^^^^^^^ - error: aborting due to 6 previous errors diff --git a/tests/ui/polymorphization/type_parameters/closures.stderr b/tests/ui/polymorphization/type_parameters/closures.stderr index 94a4a08bd2f..5c3b46c6041 100644 --- a/tests/ui/polymorphization/type_parameters/closures.stderr +++ b/tests/ui/polymorphization/type_parameters/closures.stderr @@ -44,21 +44,6 @@ LL | pub fn unused_all<G: Default>() -> u32 { | ^^^^^^^^^^ - generic parameter `G` is unused error: item has unused generic parameters - --> $DIR/closures.rs:128:23 - | -LL | pub fn used_impl<G: Default>() -> u32 { - | - generic parameter `G` is unused -LL | -LL | let add_one = |x: u32| { - | ^^^^^^^^ - -error: item has unused generic parameters - --> $DIR/closures.rs:126:12 - | -LL | pub fn used_impl<G: Default>() -> u32 { - | ^^^^^^^^^ - generic parameter `G` is unused - -error: item has unused generic parameters --> $DIR/closures.rs:115:23 | LL | impl<F: Default> Foo<F> { @@ -76,5 +61,20 @@ LL | impl<F: Default> Foo<F> { LL | pub fn used_fn<G: Default>() -> u32 { | ^^^^^^^ +error: item has unused generic parameters + --> $DIR/closures.rs:128:23 + | +LL | pub fn used_impl<G: Default>() -> u32 { + | - generic parameter `G` is unused +LL | +LL | let add_one = |x: u32| { + | ^^^^^^^^ + +error: item has unused generic parameters + --> $DIR/closures.rs:126:12 + | +LL | pub fn used_impl<G: Default>() -> u32 { + | ^^^^^^^^^ - generic parameter `G` is unused + error: aborting due to 9 previous errors diff --git a/tests/ui/privacy/privacy2.stderr b/tests/ui/privacy/privacy2.stderr index 882f314655d..c2a33ce1f59 100644 --- a/tests/ui/privacy/privacy2.stderr +++ b/tests/ui/privacy/privacy2.stderr @@ -23,13 +23,7 @@ LL | pub fn foo() {} error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0432, E0603. For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/privacy/privacy3.stderr b/tests/ui/privacy/privacy3.stderr index 42ce456d962..22c1e48b07d 100644 --- a/tests/ui/privacy/privacy3.stderr +++ b/tests/ui/privacy/privacy3.stderr @@ -6,12 +6,6 @@ LL | use bar::gpriv; error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0432`. diff --git a/tests/ui/proc-macro/test-same-crate.rs b/tests/ui/proc-macro/test-same-crate.rs new file mode 100644 index 00000000000..c13f384fa3a --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.rs @@ -0,0 +1,16 @@ +// compile-flags: --test +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn mac(input: TokenStream) -> TokenStream { loop {} } + +#[cfg(test)] +mod test { + #[test] + fn t() { crate::mac!(A) } + //~^ ERROR can't use a procedural macro from the same crate that defines it + //~| HELP you can define integration tests in a directory named `tests` +} diff --git a/tests/ui/proc-macro/test-same-crate.stderr b/tests/ui/proc-macro/test-same-crate.stderr new file mode 100644 index 00000000000..5d12e149c3c --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.stderr @@ -0,0 +1,10 @@ +error: can't use a procedural macro from the same crate that defines it + --> $DIR/test-same-crate.rs:13:14 + | +LL | fn t() { crate::mac!(A) } + | ^^^^^^^^^^ + | + = help: you can define integration tests in a directory named `tests` + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr index 6d18d295cfc..16e1af46059 100644 --- a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -10,6 +10,12 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:41:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:30:23 | @@ -22,12 +28,6 @@ error: unused variable: `c` LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` -error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:41:27 - | -LL | #[cfg(something)] a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:48:27 | diff --git a/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs b/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs index 7d9dae52cf1..96790a87311 100644 --- a/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs +++ b/tests/ui/rfc-2632-const-trait-impl/assoc-type.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] struct NonConstAdd(i32); @@ -17,7 +19,6 @@ trait Foo { impl const Foo for NonConstAdd { type Bar = NonConstAdd; - //~^ ERROR: cannot add `NonConstAdd` to `NonConstAdd` in const contexts } #[const_trait] diff --git a/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr index 89177b0f1ac..0cffae1da8d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/assoc-type.stderr @@ -1,21 +1,8 @@ -error[E0277]: cannot add `NonConstAdd` to `NonConstAdd` in const contexts - --> $DIR/assoc-type.rs:19:16 - | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd` - | - = help: the trait `~const Add` is not implemented for `NonConstAdd` -note: the trait `Add` is implemented for `NonConstAdd`, but that implementation is not `const` - --> $DIR/assoc-type.rs:19:16 - | -LL | type Bar = NonConstAdd; - | ^^^^^^^^^^^ -note: required by a bound in `Foo::Bar` - --> $DIR/assoc-type.rs:15:15 +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/assoc-type.rs:17:22 | LL | type Bar: ~const std::ops::Add; - | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar` + | ^^^^^^^^^^^^^ error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs index b64161b6aa0..ae0c2e6bcfa 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr new file mode 100644 index 00000000000..ff53eea1110 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:7:12 + | +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-const-trait-method-pass.rs:15:12 + | +LL | impl const PartialEq for Int { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs index 50c46579086..5120e6bfb41 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] #[const_trait] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr new file mode 100644 index 00000000000..02d53cc78ee --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-in-impl.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-in-impl.rs:9:16 + | +LL | impl<T: ~const PartialEq> const MyPartialEq for T { + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs index b00ff1f2fac..3febb328a83 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.rs @@ -1,6 +1,6 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr new file mode 100644 index 00000000000..529a472e0bd --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-chain.stderr @@ -0,0 +1,23 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-chain.rs:9:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:18:32 + | +LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-chain.rs:22:40 + | +LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs index c8ded0fa7ea..e618160d3b6 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr new file mode 100644 index 00000000000..bdc6ccc8aec --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-dup-bound.stderr @@ -0,0 +1,23 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-dup-bound.rs:7:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:18:44 + | +LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-dup-bound.rs:25:37 + | +LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs index 2bc5ee512c5..fe1abbf4207 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.rs @@ -1,8 +1,9 @@ +// known-bug: #110395 #![feature(const_trait_impl)] pub const fn equals_self<T: PartialEq>(t: &T) -> bool { *t == *t - //~^ ERROR can't compare + // (remove this) ~^ ERROR can't compare } fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr index 31e6dbdab22..3963f64ad32 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-fail.stderr @@ -1,15 +1,28 @@ -error[E0277]: can't compare `T` with `_` in const contexts - --> $DIR/call-generic-method-fail.rs:4:8 +error[E0277]: can't compare `T` with `T` in const contexts + --> $DIR/call-generic-method-fail.rs:5:5 | LL | *t == *t - | ^^ no implementation for `T == _` + | ^^^^^^^^ no implementation for `T == T` | -note: the trait `PartialEq<_>` is implemented for `T`, but that implementation is not `const` - --> $DIR/call-generic-method-fail.rs:4:8 +note: the trait `PartialEq` is implemented for `T`, but that implementation is not `const` + --> $DIR/call-generic-method-fail.rs:5:5 | LL | *t == *t - | ^^ + | ^^^^^^^^ -error: aborting due to previous error +error[E0015]: cannot call non-const operator in constant functions + --> $DIR/call-generic-method-fail.rs:5:5 + | +LL | *t == *t + | ^^^^^^^^ + | + = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +help: consider further restricting this bound + | +LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool { + | ++++++++++++++++++++++++++++ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs index 40565d1b76a..09f35a27737 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.rs @@ -1,6 +1,6 @@ //! Basic test for calling methods on generic type parameters in `const fn`. -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr new file mode 100644 index 00000000000..7fbe89dba3c --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-pass.stderr @@ -0,0 +1,17 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/call-generic-method-pass.rs:9:12 + | +LL | impl const PartialEq for S { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/call-generic-method-pass.rs:18:32 + | +LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs index f66d63da693..9ba19e800dd 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -1,9 +1,10 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] pub struct Int(i32); impl const std::ops::Add for i32 { - //~^ ERROR only traits defined in the current crate can be implemented for primitive types type Output = Self; fn add(self, rhs: Self) -> Self { @@ -20,7 +21,6 @@ impl std::ops::Add for Int { } impl const std::ops::Add for Int { - //~^ ERROR conflicting implementations of trait type Output = Self; fn add(self, rhs: Self) -> Self { diff --git a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 36a09add4d3..4f858d61eeb 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,25 +1,20 @@ -error[E0117]: only traits defined in the current crate can be implemented for primitive types - --> $DIR/const-and-non-const-impl.rs:5:1 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:7:12 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^-------------^^^^^--- - | | | | - | | | `i32` is not defined in the current crate - | | `i32` is not defined in the current crate - | impl doesn't use only types from inside the current crate + | ^^^^^^^^^^^^^ | - = note: define and implement a trait or new type instead + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0119]: conflicting implementations of trait `Add` for type `Int` - --> $DIR/const-and-non-const-impl.rs:22:1 +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/const-and-non-const-impl.rs:23:12 | -LL | impl std::ops::Add for Int { - | -------------------------- first implementation here -... LL | impl const std::ops::Add for Int { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 2 previous errors -Some errors have detailed explanations: E0117, E0119. -For more information about an error, try `rustc --explain E0117`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs index b5f19e40c03..b4cc7a9e17e 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + #![feature(const_trait_impl)] #[const_trait] @@ -14,6 +16,5 @@ const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 { } const _: () = assert!(need_const_closure(Tr::a) == 42); -//~^ ERROR: the trait bound fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index ffc24ec6e92..112416a3543 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied in `fn(()) -> i32 {<() as Tr>::a}` - --> $DIR/const-closure-trait-method-fail.rs:16:23 + --> $DIR/const-closure-trait-method-fail.rs:18:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/const-closure-trait-method-fail.rs:16:23 + --> $DIR/const-closure-trait-method-fail.rs:18:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closures.rs b/tests/ui/rfc-2632-const-trait-impl/const-closures.rs index 755d8539839..7c55b51c8f5 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closures.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-closures.rs @@ -1,4 +1,4 @@ -// run-pass +// check-pass #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr index bcdc80f82f8..13350a6d14a 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr @@ -1,50 +1,26 @@ -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:23:25 | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { + | ^^^^ | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:29:26 | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +LL | const fn check<T: ~const Destruct>(_: T) {} + | ^^^^^^^^ -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:39:9 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:39:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:37:1 + | ^^^^ | -LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 6a252c5d37b..3de9d37d493 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -1,4 +1,4 @@ -// revisions: stock precise +// known-bug: #110395 #![feature(const_trait_impl)] #![feature(const_mut_refs)] #![cfg_attr(precise, feature(const_precise_live_drops))] @@ -29,15 +29,12 @@ impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { const fn check<T: ~const Destruct>(_: T) {} const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - //~^ ERROR the trait bound ConstDropImplWithBounds(PhantomData) - //~^ ERROR the trait bound ); struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { -//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not fn drop(&mut self) { T::a(); } diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr new file mode 100644 index 00000000000..375f5d2c52d --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stderr @@ -0,0 +1,50 @@ +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:32:5 + | +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:32:5 + | +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not + --> $DIR/const-drop-fail-2.rs:37:9 + | +LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { + | ^^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail-2.rs:35:1 + | +LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr index bcdc80f82f8..13350a6d14a 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr @@ -1,50 +1,26 @@ -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:23 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:23:25 | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { + | ^^^^ | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:23 - | -LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>( - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-drop-fail-2.rs:29:26 | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:33:5 - | -LL | ConstDropImplWithBounds(PhantomData) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail-2.rs:21:35 - | -LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +LL | const fn check<T: ~const Destruct>(_: T) {} + | ^^^^^^^^ -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:39:9 +error: const `impl` for trait `Drop` which is not marked with `#[const_trait]` + --> $DIR/const-drop-fail-2.rs:39:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:37:1 + | ^^^^ | -LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 40caada51d7..e745cbd2442 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -11,7 +11,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | | } = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -36,7 +36,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:16:8 + --> $DIR/const-drop-fail.rs:18:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index c4bdb9ef5e5..1c37648ff1c 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -1,3 +1,5 @@ +// known-bug: #110395 + // revisions: stock precise #![feature(const_trait_impl)] #![feature(const_mut_refs)] @@ -24,8 +26,6 @@ const fn check<T: ~const Destruct>(_: T) {} macro_rules! check_all { ($($exp:expr),*$(,)?) => {$( const _: () = check($exp); - //~^ ERROR can't drop - //~| ERROR can't drop )*}; } diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 40caada51d7..e745cbd2442 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -11,7 +11,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -24,7 +24,7 @@ LL | | } = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` @@ -36,7 +36,7 @@ LL | | } | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:26:23 + --> $DIR/const-drop-fail.rs:28:23 | LL | const _: () = check($exp); | ^^^^^^^^^^^ @@ -47,7 +47,7 @@ LL | | ConstImplWithDropGlue(NonTrivialDrop), LL | | } | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` - --> $DIR/const-drop-fail.rs:16:8 + --> $DIR/const-drop-fail.rs:18:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs index 0622f96e70d..f396deff4fe 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![allow(incomplete_features)] #![feature( associated_type_bounds, diff --git a/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr new file mode 100644 index 00000000000..f9078e22791 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-impl-trait.stderr @@ -0,0 +1,39 @@ +error[E0635]: unknown feature `const_cmp` + --> $DIR/const-impl-trait.rs:6:5 + | +LL | const_cmp, + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:12:30 + | +LL | const fn cmp(a: &impl ~const PartialEq) -> bool { + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:16:30 + | +LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct) + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:17:20 + | +LL | -> impl ~const PartialEq + ~const Destruct + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:24:29 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy; + | ^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const-impl-trait.rs:28:29 + | +LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy { + | ^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs index 348ca0ab190..dba3ad7f870 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.rs @@ -1,4 +1,5 @@ #[derive_const(Default)] //~ ERROR use of unstable library feature +//~^ ERROR not marked with `#[const_trait]` pub struct S; fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr index cc9bdd2715f..6a81f96d88d 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-gate.stderr @@ -6,6 +6,16 @@ LL | #[derive_const(Default)] | = help: add `#![feature(derive_const)]` to the crate attributes to enable -error: aborting due to previous error +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-gate.rs:1:16 + | +LL | #[derive_const(Default)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs index ed6699f3724..b575ea8dae2 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -1,3 +1,4 @@ +// known-bug: #110395 #![feature(derive_const)] pub struct A; @@ -8,7 +9,5 @@ impl Default for A { #[derive_const(Default)] pub struct S(A); -//~^ cannot call non-const fn -//~| the trait bound fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 653037ef398..1c69ad43171 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -1,38 +1,12 @@ -error[E0277]: the trait bound `A: Default` is not satisfied - --> $DIR/derive-const-non-const-type.rs:10:14 +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-non-const-type.rs:10:16 | LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ the trait `~const Default` is not implemented for `A` + | ^^^^^^^ | -note: the trait `Default` is implemented for `A`, but that implementation is not `const` - --> $DIR/derive-const-non-const-type.rs:10:14 - | -LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ - = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `A` with `#[derive(Default)]` - | -LL + #[derive(Default)] -LL | pub struct A; - | - -error[E0015]: cannot call non-const fn `<A as Default>::default` in constant functions - --> $DIR/derive-const-non-const-type.rs:10:14 - | -LL | #[derive_const(Default)] - | ------- in this derive macro expansion -LL | pub struct S(A); - | ^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs index d1fbeac8598..69098542b7e 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] pub struct A; diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr new file mode 100644 index 00000000000..88054096e63 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -0,0 +1,53 @@ +error[E0635]: unknown feature `const_cmp` + --> $DIR/derive-const-use.rs:2:30 + | +LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + | ^^^^^^^^^ + +error[E0635]: unknown feature `const_default_impls` + --> $DIR/derive-const-use.rs:2:41 + | +LL | #![feature(const_trait_impl, const_cmp, const_default_impls, derive_const)] + | ^^^^^^^^^^^^^^^^^^^ + +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:6:12 + | +LL | impl const Default for A { + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:10:12 + | +LL | impl const PartialEq for A { + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Default` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:14:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-use.rs:14:25 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs index 72edfbc97e4..2a5d0176ba0 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(derive_const)] #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr new file mode 100644 index 00000000000..fa78326587c --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-with-params.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]` + --> $DIR/derive-const-with-params.rs:6:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/derive-const-with-params.rs:6:16 + | +LL | #[derive_const(PartialEq)] + | ^^^^^^^^^ + | + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs b/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs index 5495b531cff..d665c4479c9 100644 --- a/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs +++ b/tests/ui/rfc-2632-const-trait-impl/generic-bound.rs @@ -1,4 +1,4 @@ -// run-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr new file mode 100644 index 00000000000..1b21d7c0e0e --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/generic-bound.stderr @@ -0,0 +1,11 @@ +error: const `impl` for trait `Add` which is not marked with `#[const_trait]` + --> $DIR/generic-bound.rs:16:15 + | +LL | impl<T> const std::ops::Add for S<T> { + | ^^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs index 1a4509b1869..dff8a244453 100644 --- a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs +++ b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr new file mode 100644 index 00000000000..cfdda4713a7 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/non-const-op-in-closure-in-const.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/non-const-op-in-closure-in-const.rs:10:51 + | +LL | impl<A, B> const Convert<B> for A where B: ~const From<A> { + | ^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs index 9ab170f0920..5c2a3f80170 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs +++ b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.rs @@ -11,13 +11,16 @@ pub trait A { fn a() -> u32; } -impl<T: ~const Default> const A for T { +#[const_trait] +pub trait Spec {} + +impl<T: ~const Spec> const A for T { default fn a() -> u32 { 2 } } -impl<T: Default + Sup> A for T { +impl<T: Spec + Sup> A for T { //~^ ERROR: cannot specialize //~| ERROR: missing `~const` qualifier fn a() -> u32 { diff --git a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr index 843fc6ce84d..1ffdc50e589 100644 --- a/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/specializing-constness.stderr @@ -1,14 +1,14 @@ error: cannot specialize on const impl with non-const impl - --> $DIR/specializing-constness.rs:20:1 + --> $DIR/specializing-constness.rs:23:1 | -LL | impl<T: Default + Sup> A for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<T: Spec + Sup> A for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing `~const` qualifier for specialization - --> $DIR/specializing-constness.rs:20:9 + --> $DIR/specializing-constness.rs:23:9 | -LL | impl<T: Default + Sup> A for T { - | ^^^^^^^ +LL | impl<T: Spec + Sup> A for T { + | ^^^^ error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr new file mode 100644 index 00000000000..78aab9469e8 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr @@ -0,0 +1,9 @@ +error[E0635]: unknown feature `const_default_impls` + --> $DIR/std-impl-gate.rs:6:46 + | +LL | #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))] + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0635`. diff --git a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs index 2f54c09e31c..e9e5e0235df 100644 --- a/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs +++ b/tests/ui/rfc-2632-const-trait-impl/std-impl-gate.rs @@ -1,7 +1,7 @@ // This tests feature gates for const impls in the standard library. // revisions: stock gated -//[gated] run-pass +//[gated] known-bug: #110395 #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))] diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs index 334fc4cb847..8d56295e738 100644 --- a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -1,4 +1,4 @@ -// check-pass +// known-bug: #110395 #![feature(staged_api)] #![feature(const_trait_impl)] diff --git a/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr new file mode 100644 index 00000000000..35dc1ca129b --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -0,0 +1,20 @@ +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: aborting due to 2 previous errors + diff --git a/tests/ui/span/issue-23729.stderr b/tests/ui/span/issue-23729.stderr index f88ce6c88db..cd854e61f2f 100644 --- a/tests/ui/span/issue-23729.stderr +++ b/tests/ui/span/issue-23729.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item` LL | impl Iterator for Recurrence { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation | - = help: implement the missing item: `type Item = Type;` + = help: implement the missing item: `type Item = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr index 46a820f1b76..83a9e8c9b98 100644 --- a/tests/ui/span/issue-23827.stderr +++ b/tests/ui/span/issue-23827.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output` LL | impl<C: Component> FnOnce<(C,)> for Prototype { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation | - = help: implement the missing item: `type Output = Type;` + = help: implement the missing item: `type Output = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/issue-24356.stderr b/tests/ui/span/issue-24356.stderr index a1f9b255020..cf666e8b4a7 100644 --- a/tests/ui/span/issue-24356.stderr +++ b/tests/ui/span/issue-24356.stderr @@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target` LL | impl Deref for Thing { | ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation | - = help: implement the missing item: `type Target = Type;` + = help: implement the missing item: `type Target = /* Type */;` error: aborting due to previous error diff --git a/tests/ui/span/send-is-not-static-std-sync-2.stderr b/tests/ui/span/send-is-not-static-std-sync-2.stderr index b0267fa6f43..c825cc8d668 100644 --- a/tests/ui/span/send-is-not-static-std-sync-2.stderr +++ b/tests/ui/span/send-is-not-static-std-sync-2.stderr @@ -25,8 +25,6 @@ LL | }; error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:31:25 | -LL | let (_tx, rx) = { - | --- borrow later used here LL | let x = 1; | - binding `x` declared here LL | let (tx, rx) = mpsc::channel(); diff --git a/tests/ui/specialization/const_trait_impl.rs b/tests/ui/specialization/const_trait_impl.rs index 05ba4c8d45d..b1ec58c3df3 100644 --- a/tests/ui/specialization/const_trait_impl.rs +++ b/tests/ui/specialization/const_trait_impl.rs @@ -1,4 +1,5 @@ -// check-pass +// known-bug: #110395 + #![feature(const_trait_impl, min_specialization, rustc_attrs)] #[rustc_specialization_trait] diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr new file mode 100644 index 00000000000..d13cd8f5555 --- /dev/null +++ b/tests/ui/specialization/const_trait_impl.stderr @@ -0,0 +1,20 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:34:16 + | +LL | impl<T: ~const Default> const A for T { + | ^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:40:16 + | +LL | impl<T: ~const Default + ~const Sup> const A for T { + | ^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/const_trait_impl.rs:46:16 + | +LL | impl<T: ~const Default + ~const Sub> const A for T { + | ^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/static/issue-18118.stderr b/tests/ui/static/issue-18118.stderr index 49798a148de..035be2b1202 100644 --- a/tests/ui/static/issue-18118.stderr +++ b/tests/ui/static/issue-18118.stderr @@ -1,6 +1,8 @@ error[E0597]: `p` does not live long enough --> $DIR/issue-18118.rs:4:9 | +LL | let p = 3; + | - binding `p` declared here LL | &p | ^^ | | diff --git a/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs new file mode 100644 index 00000000000..b026035a6a1 --- /dev/null +++ b/tests/ui/suggestions/auxiliary/missing-assoc-fn-applicable-suggestions.rs @@ -0,0 +1,16 @@ +pub trait TraitB { + type Item; +} + +pub trait TraitA<A> { + type Type; + + fn bar<T>(_: T) -> Self; + + fn baz<T>(_: T) -> Self + where + T: TraitB, + <T as TraitB>::Item: Copy; + + const A: usize; +} diff --git a/tests/ui/suggestions/issue-109436.stderr b/tests/ui/suggestions/issue-109436.stderr index 48518b33d12..c479326f935 100644 --- a/tests/ui/suggestions/issue-109436.stderr +++ b/tests/ui/suggestions/issue-109436.stderr @@ -2,7 +2,7 @@ error[E0277]: the trait bound `Foo: Into<_>` is not satisfied --> $DIR/issue-109436.rs:12:22 | LL | let b: Bar = foo.into(); - | ^^^^ the trait `~const Into<_>` is not implemented for `Foo` + | ^^^^ the trait `Into<_>` is not implemented for `Foo` | = note: required for `Foo` to implement `Into<Bar>` help: consider borrowing here diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.rs b/tests/ui/suggestions/issue-71394-no-from-impl.rs index 0c35deb51e7..63f12a91282 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.rs +++ b/tests/ui/suggestions/issue-71394-no-from-impl.rs @@ -1,3 +1,8 @@ +// ignore-wasm +// ignore-msvc +// ignore-emscripten +// ignore-uwp + fn main() { let data: &[u8] = &[0; 10]; let _: &[i8] = data.into(); diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr index a5e6f5b5ffc..5c36a385a46 100644 --- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr +++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr @@ -1,10 +1,11 @@ error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied - --> $DIR/issue-71394-no-from-impl.rs:3:25 + --> $DIR/issue-71394-no-from-impl.rs:8:25 | LL | let _: &[i8] = data.into(); | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]` | = help: the following other types implement trait `From<T>`: + <&'input [u8] as From<gimli::read::endian_slice::EndianSlice<'input, Endian>>> <[T; LANES] as From<Simd<T, LANES>>> <[bool; LANES] as From<Mask<T, LANES>>> = note: required for `&[u8]` to implement `Into<&[i8]>` diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed deleted file mode 100644 index a0cb39a3f8a..00000000000 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.fixed +++ /dev/null @@ -1,21 +0,0 @@ -// run-rustfix -trait TraitB { - type Item; -} - -trait TraitA<A> { - type Type; - fn bar<T>(_: T) -> Self; - fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; -} - -struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented -fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() } -fn bar<T>(_: T) -> Self { todo!() } -type Type = Type; -} - -fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs index c80ede1b2be..11e0c9a3a72 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.rs @@ -1,18 +1,15 @@ -// run-rustfix -trait TraitB { - type Item; -} +// aux-build:missing-assoc-fn-applicable-suggestions.rs -trait TraitA<A> { - type Type; - fn bar<T>(_: T) -> Self; - fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; -} +extern crate missing_assoc_fn_applicable_suggestions; +use missing_assoc_fn_applicable_suggestions::TraitA; struct S; -struct Type; - -impl TraitA<()> for S { //~ ERROR not all trait items implemented +impl TraitA<()> for S { + //~^ ERROR not all trait items implemented } +//~^ HELP implement the missing item: `type Type = /* Type */;` +//~| HELP implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }` +//~| HELP implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }` +//~| HELP implement the missing item: `const A: usize = 42;` fn main() {} diff --git a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr index 4c75fbe4c78..4c2d2776d3d 100644 --- a/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr +++ b/tests/ui/suggestions/missing-assoc-fn-applicable-suggestions.stderr @@ -1,15 +1,13 @@ -error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz` - --> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1 +error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A` + --> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1 | -LL | type Type; - | --------- `Type` from trait -LL | fn bar<T>(_: T) -> Self; - | ------------------------ `bar` from trait -LL | fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy; - | ------------------------------------------------------------------- `baz` from trait -... LL | impl TraitA<()> for S { - | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation + | ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation + | + = help: implement the missing item: `type Type = /* Type */;` + = help: implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }` + = help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }` + = help: implement the missing item: `const A: usize = 42;` error: aborting due to previous error diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr index 136ec2152e0..77fa9562878 100644 --- a/tests/ui/suggestions/missing-assoc-fn.stderr +++ b/tests/ui/suggestions/missing-assoc-fn.stderr @@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter` LL | impl FromIterator<()> for X { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation | - = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }` + = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }` error: aborting due to 3 previous errors diff --git a/tests/ui/issues/issue-22384.rs b/tests/ui/traits/issue-22384.rs index 98988f27ecc..98988f27ecc 100644 --- a/tests/ui/issues/issue-22384.rs +++ b/tests/ui/traits/issue-22384.rs diff --git a/tests/ui/issues/issue-22384.stderr b/tests/ui/traits/issue-22384.stderr index 1f767a443d0..1f767a443d0 100644 --- a/tests/ui/issues/issue-22384.stderr +++ b/tests/ui/traits/issue-22384.stderr diff --git a/tests/ui/traits/new-solver/borrowck-error.rs b/tests/ui/traits/new-solver/borrowck-error.rs new file mode 100644 index 00000000000..4787a2c7e11 --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next + +use std::collections::HashMap; + +fn foo() -> &'static HashMap<i32, i32> +{ + &HashMap::new() + //~^ ERROR cannot return reference to temporary value +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/borrowck-error.stderr b/tests/ui/traits/new-solver/borrowck-error.stderr new file mode 100644 index 00000000000..a7d8201747a --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/borrowck-error.rs:7:5 + | +LL | &HashMap::new() + | ^-------------- + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr index 576fc6a4f8d..c943a4918ba 100644 --- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr +++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr @@ -29,7 +29,7 @@ note: ...which requires borrow-checking `Alpha::V3::{constant#0}`... | LL | V3 = Self::V1 {} as u8 + 2, | ^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires processing MIR for `Alpha::V3::{constant#0}`... +note: ...which requires promoting constants in MIR for `Alpha::V3::{constant#0}`... --> $DIR/self-in-enum-definition.rs:5:10 | LL | V3 = Self::V1 {} as u8 + 2, diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.rs b/tests/ui/typeck/bad-recursive-type-sig-infer.rs new file mode 100644 index 00000000000..9812d8c3811 --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.rs @@ -0,0 +1,11 @@ +fn a() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn b() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn main() {} diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.stderr b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr new file mode 100644 index 00000000000..e145da5623a --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:1:11 + | +LL | fn a() -> _ { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:6:11 + | +LL | fn b() -> _ { + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index a450dbb82d1..46aed0f603e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -227,6 +227,4 @@ fn evens_squared(n: usize) -> _ { } const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); -//~^ ERROR the trait bound -//~| ERROR the trait bound -//~| ERROR the placeholder +//~^ ERROR the placeholder diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bc6c9fd0779..bc02547c65e 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -437,37 +437,17 @@ LL | fn evens_squared(n: usize) -> _ { | not allowed in type signatures | help: replace with an appropriate return type: `impl Iterator<Item = usize>` -error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied - --> $DIR/typeck_type_placeholder_item.rs:229:22 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^ `std::ops::Range<{integer}>` is not an iterator - | - = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>` -note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const` - --> $DIR/typeck_type_placeholder_item.rs:229:14 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^ - -error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied - --> $DIR/typeck_type_placeholder_item.rs:229:45 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:229:10 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator + | ^ not allowed in type signatures | - = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` -note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const` +note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named --> $DIR/typeck_type_placeholder_item.rs:229:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:229:10 - | -LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^ not allowed in type signatures + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:140:31 @@ -677,7 +657,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error: aborting due to 73 previous errors +error: aborting due to 71 previous errors -Some errors have detailed explanations: E0121, E0277, E0282, E0403. +Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`.  | 
